Skip to content

Commit

Permalink
Implements new value_to functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
ndejong committed Sep 28, 2024
1 parent 5c300a0 commit e8c2d1a
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 1 deletion.
34 changes: 34 additions & 0 deletions docs/content/definition-attributes/value-to.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# value_to

The `value_to` definition-attribute makes it possible to send the generated `value` to either STDOUT or STDERR.

This can be helpful in circumstances when a quick debug reveal is required or you need to provide some kind of
user response.


### Example - to STDERR

```yaml
env-alias:

EXAMPLE_STDERR:
name: null
value: "This is a message that will get sent to STDERR"
value_to: "<STDERR>"
```
### Example - to STDOUT
```yaml
env-alias:

EXAMPLE_STDOUT_CONTENT:
name: null
exec: "date"

EXAMPLE_STDOUT:
name: null
exec: 'echo "The date is ${EXAMPLE_STDOUT_CONTENT} - boom!"'
value_to: "<STDOUT>"
```
2 changes: 1 addition & 1 deletion docs/content/examples/terraform-aws-project.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ values are contained within.
env-alias:

TF_PLUGIN_CACHE_DIR_CREATE:
name: null
exec: 'mkdir -p ~/.terraform.d/plugin-cache'
name: none

TF_PLUGIN_CACHE_DIR:
value: '~/.terraform.d/plugin-cache'
Expand Down
1 change: 1 addition & 0 deletions docs/mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ nav:
- definition-attributes/selector.md
- definition-attributes/name.md
- definition-attributes/value.md
- definition-attributes/value-to.md
- definition-attributes/exec.md
- definition-attributes/override.md
- definition-attributes/keepass-password.md
Expand Down
8 changes: 8 additions & 0 deletions src/env_alias/lib/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@ def generate(self) -> None:
self.values_generated[definition.name] = value
os.environ[definition.name] = str(value) # exists at this process and sub-process only

if definition.value_to:
if definition.value_to == "<stderr>":
print(value, file=sys.stderr)
elif definition.value_to == "<stdout>":
print(value, file=sys.stdout)
else:
raise EnvAliasException("Unsupported 'value_to' value encountered.")

if definition._is_internal_only is True:
logger.debug(
f"Definition for {definition.name!r} defines a 'null' name for env-alias internal "
Expand Down
6 changes: 6 additions & 0 deletions src/env_alias/models/envalias_definition.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class EnvAliasDefinition:

parser: Union[str, None] = None
selector: Union[str, None] = _UNSET_SENTINEL
value_to: Union[str, None] = None

keepass_password: Union[str, None] = None
ansible_vault_password: Union[str, None] = None
Expand All @@ -39,6 +40,11 @@ def __post_init__(self) -> None:
if not self.source and not self.exec and not self.value and not self.ansible_vault_password_file:
raise EnvAliasException(f"Must have one 'source', 'exec' or 'value' {_EXCEPTION_END}")

if isinstance(self.value_to, str):
self.value_to = self.value_to.lower()
if self.value_to not in ("<stderr>", "<stdout>"):
raise EnvAliasException(f"Invalid 'value_to' value, must be '<stderr>' or '<stdout>' {_EXCEPTION_END}")

if self.keepass_password and self.ansible_vault_password:
raise EnvAliasException(f"Cannot use both 'keepass_password' and 'ansible_vault_password' {_EXCEPTION_END}")
if self.ansible_vault_password_file and (self.exec or self.source or self.value or self.keepass_password):
Expand Down
75 changes: 75 additions & 0 deletions tests/test_value_to.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import os
import random
import string
import tempfile
from pathlib import Path

from env_alias.lib.generator import EnvAliasGenerator


def test_value_to_stderr_01(capsys):
sentinal = "XXXX_foobar01_XXXX"
yaml = f"""
EXAMPLE:
name: null
value: "{sentinal}"
value_to: "<stderr>"
"""

config_file = __generate_config_file(yaml)
EnvAliasGenerator(config_file=config_file).generate()
os.unlink(config_file)

captured_stderr = capsys.readouterr().err.rstrip()
assert sentinal == captured_stderr

captured_stdout = capsys.readouterr().out.rstrip()
assert len(captured_stdout) == 0


def test_value_to_stderr_01_upper(capsys):
sentinal = "XXXX_foobar01_XXXX"
yaml = f"""
EXAMPLE:
name: null
value: "{sentinal}"
value_to: "<STDERR>"
"""

config_file = __generate_config_file(yaml)
EnvAliasGenerator(config_file=config_file).generate()
os.unlink(config_file)

captured_stderr = capsys.readouterr().err.rstrip()
assert sentinal == captured_stderr

captured_stdout = capsys.readouterr().out.rstrip()
assert len(captured_stdout) == 0


def test_value_to_stderr_02(capsys):
sentinal = "XXXX_foobar02_XXXX"
yaml = f"""
EXAMPLE:
name: null
value: "{sentinal}"
value_to: "<stdout>"
"""

config_file = __generate_config_file(yaml)
EnvAliasGenerator(config_file=config_file).generate()
os.unlink(config_file)

captured_stdout = capsys.readouterr().out.rstrip()
assert sentinal == captured_stdout

captured_stderr = capsys.readouterr().err.rstrip()
assert len(captured_stderr) == 0


def __generate_config_file(yaml_config) -> Path:
config = "env-alias:" + yaml_config
filename = os.path.join(tempfile.gettempdir(), "".join(random.choice(string.ascii_lowercase) for i in range(8)))
with open(filename, "w") as f:
f.write(config)
return Path(filename)

0 comments on commit e8c2d1a

Please sign in to comment.