-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support appending/prepending to environment variables
- Loading branch information
Showing
7 changed files
with
199 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
from __future__ import annotations | ||
|
||
from string import Template | ||
from typing import Mapping | ||
|
||
from .options.string import StringOption | ||
|
||
|
||
def substitute_environment_options( | ||
env: dict[str, str], config_env: Mapping[str, StringOption | None] | ||
): | ||
"""Given the environment-like options in config_env, update the environment | ||
in env. Supports simple template expansion using ${VAR}.""" | ||
|
||
def _template_expand(a): | ||
return Template(a).substitute(env) | ||
|
||
for k, v in config_env.items(): | ||
if v is None: | ||
continue | ||
assert isinstance(v, StringOption) | ||
# Perform template substitution on the different components | ||
for attr in "value", "append", "append_path", "prepend", "prepend_path": | ||
a = getattr(v, attr) | ||
if a is not None: | ||
setattr(v, attr, _template_expand(a)) | ||
if v.remove: | ||
v.remove = [_template_expand(r) for r in v.remove] | ||
# If we're appending or prepending to the original value, we need | ||
# to set the initial value to the current value in the environment | ||
if ( | ||
k in env | ||
and not v.value | ||
and (v.append or v.prepend or v.append_path or v.prepend_path) | ||
): | ||
v.value = env[k] | ||
str_v = v.finalize() | ||
if str_v is not None: | ||
env[k] = str_v | ||
elif k in env: | ||
del env[k] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
import os | ||
|
||
from py_build_cmake.config.environment import ( | ||
StringOption, | ||
substitute_environment_options, | ||
) | ||
|
||
|
||
def test_environment_value(): | ||
env = {"FOO": "bar"} | ||
env_opts = {"BAZ": StringOption(value="abc")} | ||
substitute_environment_options(env, env_opts) | ||
assert env == {"FOO": "bar", "BAZ": "abc"} | ||
|
||
|
||
def test_environment_value_empty_string(): | ||
env = {"FOO": "bar"} | ||
env_opts = {"BAZ": StringOption(value="")} | ||
substitute_environment_options(env, env_opts) | ||
assert env == {"FOO": "bar", "BAZ": ""} | ||
|
||
|
||
def test_environment_value_expand(): | ||
env = {"FOO": "bar", "DEF": "def"} | ||
env_opts = {"BAZ": StringOption(value="abc$DEF")} | ||
substitute_environment_options(env, env_opts) | ||
assert env == {"FOO": "bar", "DEF": "def", "BAZ": "abcdef"} | ||
|
||
|
||
def test_environment_value_expand_braces(): | ||
env = {"FOO": "bar", "DEF": "def"} | ||
env_opts = {"BAZ": StringOption(value="abc${DEF}ghi")} | ||
substitute_environment_options(env, env_opts) | ||
assert env == {"FOO": "bar", "DEF": "def", "BAZ": "abcdefghi"} | ||
|
||
|
||
def test_environment_value_escape(): | ||
env = {"FOO": "bar", "DEF": "def"} | ||
env_opts = {"BAZ": StringOption(value="abc$${DEF}")} | ||
substitute_environment_options(env, env_opts) | ||
assert env == {"FOO": "bar", "DEF": "def", "BAZ": "abc${DEF}"} | ||
|
||
|
||
def test_environment_value_escape_dollar(): | ||
env = {"FOO": "bar", "DEF": "def"} | ||
env_opts = {"BAZ": StringOption(value="abc$$f")} | ||
substitute_environment_options(env, env_opts) | ||
assert env == {"FOO": "bar", "DEF": "def", "BAZ": "abc$f"} | ||
|
||
|
||
def test_environment_append(): | ||
env = {"FOO": "bar", "BAZ": "abc"} | ||
env_opts = {"BAZ": StringOption(append="def")} | ||
substitute_environment_options(env, env_opts) | ||
assert env == {"FOO": "bar", "BAZ": "abcdef"} | ||
|
||
|
||
def test_environment_append_empty(): | ||
env = {"FOO": "bar"} | ||
env_opts = {"BAZ": StringOption(append="def")} | ||
substitute_environment_options(env, env_opts) | ||
assert env == {"FOO": "bar", "BAZ": "def"} | ||
|
||
|
||
def test_environment_prepend(): | ||
env = {"FOO": "bar", "BAZ": "abc"} | ||
env_opts = {"BAZ": StringOption(prepend="def")} | ||
substitute_environment_options(env, env_opts) | ||
assert env == {"FOO": "bar", "BAZ": "defabc"} | ||
|
||
|
||
def test_environment_prepend_empty(): | ||
env = {"FOO": "bar"} | ||
env_opts = {"BAZ": StringOption(prepend="def")} | ||
substitute_environment_options(env, env_opts) | ||
assert env == {"FOO": "bar", "BAZ": "def"} | ||
|
||
|
||
def test_environment_append_path(): | ||
env = {"FOO": "bar", "BAZ": "abc"} | ||
env_opts = {"BAZ": StringOption(append_path="def")} | ||
substitute_environment_options(env, env_opts) | ||
assert env == {"FOO": "bar", "BAZ": "abc" + os.pathsep + "def"} | ||
|
||
|
||
def test_environment_append_path_empty(): | ||
env = {"FOO": "bar"} | ||
env_opts = {"BAZ": StringOption(append_path="def")} | ||
substitute_environment_options(env, env_opts) | ||
assert env == {"FOO": "bar", "BAZ": "def"} | ||
|
||
|
||
def test_environment_prepend_path(): | ||
env = {"FOO": "bar", "BAZ": "abc"} | ||
env_opts = {"BAZ": StringOption(prepend_path="def")} | ||
substitute_environment_options(env, env_opts) | ||
assert env == {"FOO": "bar", "BAZ": "def" + os.pathsep + "abc"} | ||
|
||
|
||
def test_environment_prepend_path_empty(): | ||
env = {"FOO": "bar"} | ||
env_opts = {"BAZ": StringOption(prepend_path="def")} | ||
substitute_environment_options(env, env_opts) | ||
assert env == {"FOO": "bar", "BAZ": "def"} | ||
|
||
|
||
def test_environment_clear(): | ||
env = {"FOO": "bar", "BAZ": "abc"} | ||
env_opts = {"BAZ": StringOption(clear=True)} | ||
substitute_environment_options(env, env_opts) | ||
assert env == {"FOO": "bar"} | ||
|
||
|
||
def test_environment_clear_empty(): | ||
env = {"FOO": "bar"} | ||
env_opts = {"BAZ": StringOption(clear=True)} | ||
substitute_environment_options(env, env_opts) | ||
assert env == {"FOO": "bar"} |