aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXavier Claessens <xclaesse@gmail.com>2021-03-23 11:48:17 -0400
committerGitHub <noreply@github.com>2021-03-23 17:48:17 +0200
commit1be13710adba2126f5731fccdf698a9d405a9d67 (patch)
tree6b2c2038b9003b3a85a265c1525daae9139b1a98
parentde9df5128c03d016ec9463f705422f2e1df4c49a (diff)
downloadmeson-1be13710adba2126f5731fccdf698a9d405a9d67.zip
meson-1be13710adba2126f5731fccdf698a9d405a9d67.tar.gz
meson-1be13710adba2126f5731fccdf698a9d405a9d67.tar.bz2
environment(): Allow stacking append() and prepend() (#8547)
* environment(): Allow stacking append() and prepend() * Update docs/markdown/Reference-manual.md Co-authored-by: Elliott Sales de Andrade <quantum.analyst@gmail.com> Co-authored-by: Elliott Sales de Andrade <quantum.analyst@gmail.com>
-rw-r--r--docs/markdown/Reference-manual.md15
-rw-r--r--docs/markdown/snippets/environment.md16
-rw-r--r--mesonbuild/build.py2
-rw-r--r--mesonbuild/interpreter.py14
-rwxr-xr-xrun_unittests.py11
-rw-r--r--test cases/common/34 run program/check-env.py6
-rw-r--r--test cases/common/34 run program/meson.build6
-rw-r--r--test cases/unit/63 test env does not stack/meson.build12
-rwxr-xr-xtest cases/unit/63 test env does not stack/script.py9
9 files changed, 48 insertions, 43 deletions
diff --git a/docs/markdown/Reference-manual.md b/docs/markdown/Reference-manual.md
index 6e18e68..74f3324 100644
--- a/docs/markdown/Reference-manual.md
+++ b/docs/markdown/Reference-manual.md
@@ -2752,8 +2752,19 @@ tests and other functions. It has the following methods.
joined by the separator, e.g. `env.set('FOO', 'BAR'),` sets envvar
`FOO` to value `BAR`. See `append()` above for how separators work.
-**Note:** All these methods overwrite the previously-defined value(s)
-if called twice with the same `varname`.
+*Since 0.58.0* `append()` and `prepend()` methods can be called multiple times
+on the same `varname`. Earlier Meson versions would warn and only the last
+operation took effect.
+
+```meson
+env = environment()
+
+# MY_PATH will be '0:1:2:3'
+env.set('MY_PATH', '1')
+env.append('MY_PATH', '2')
+env.append('MY_PATH', '3')
+env.prepend('MY_PATH', '0')
+```
### `external library` object
diff --git a/docs/markdown/snippets/environment.md b/docs/markdown/snippets/environment.md
new file mode 100644
index 0000000..1ed102d
--- /dev/null
+++ b/docs/markdown/snippets/environment.md
@@ -0,0 +1,16 @@
+## Multiple append() and prepend() in `environment()` object
+
+`append()` and `prepend()` methods can now be called multiple times
+on the same `varname`. Earlier Meson versions would warn and only the last
+opperation was taking effect.
+
+```meson
+env = environment()
+
+# MY_PATH will be '0:1:2:3'
+env.set('MY_PATH', '1')
+env.append('MY_PATH', '2')
+env.append('MY_PATH', '3')
+env.prepend('MY_PATH', '0')
+```
+
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index 547394f..adba208 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -433,7 +433,7 @@ class EnvironmentVariables:
def get_env(self, full_env: T.Dict[str, str]) -> T.Dict[str, str]:
env = full_env.copy()
for method, name, values, separator in self.envvars:
- env[name] = method(full_env, name, values, separator)
+ env[name] = method(env, name, values, separator)
return env
class Target:
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index cbb2324..dbc655f 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -241,9 +241,9 @@ class ConfigureFileHolder(InterpreterObject, ObjectHolder[build.ConfigureFile]):
class EnvironmentVariablesHolder(MutableInterpreterObject, ObjectHolder[build.EnvironmentVariables]):
- def __init__(self, initial_values=None):
+ def __init__(self, initial_values=None, subproject: str = ''):
MutableInterpreterObject.__init__(self)
- ObjectHolder.__init__(self, build.EnvironmentVariables())
+ ObjectHolder.__init__(self, build.EnvironmentVariables(), subproject)
self.methods.update({'set': self.set_method,
'append': self.append_method,
'prepend': self.prepend_method,
@@ -274,12 +274,10 @@ class EnvironmentVariablesHolder(MutableInterpreterObject, ObjectHolder[build.En
return separator
def warn_if_has_name(self, name: str) -> None:
- # Warn when someone tries to use append() or prepend() on an env var
- # which already has an operation set on it. People seem to think that
- # multiple append/prepend operations stack, but they don't.
+ # Multiple append/prepend operations was not supported until 0.58.0.
if self.held_object.has_name(name):
- mlog.warning(f'Overriding previous value of environment variable {name!r} with a new one',
- location=self.current_node)
+ m = f'Overriding previous value of environment variable {name!r} with a new one'
+ FeatureNew('0.58.0', m).use(self.subproject)
@stringArgs
@permittedKwargs({'separator'})
@@ -4772,7 +4770,7 @@ This warning will become a hard error in a future Meson release.
raise InterpreterException('environment first argument must be a dictionary or a list')
else:
initial_values = {}
- return EnvironmentVariablesHolder(initial_values)
+ return EnvironmentVariablesHolder(initial_values, self.subproject)
@stringArgs
@noKwargs
diff --git a/run_unittests.py b/run_unittests.py
index 28ef486..a53a43a 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -2525,17 +2525,6 @@ class AllPlatformTests(BasePlatformTests):
self.build()
self.run_tests()
- def test_env_ops_dont_stack(self):
- '''
- Test that env ops prepend/append do not stack, and that this usage issues a warning
- '''
- testdir = os.path.join(self.unit_test_dir, '63 test env does not stack')
- out = self.init(testdir)
- self.assertRegex(out, r'WARNING: Overriding.*TEST_VAR_APPEND')
- self.assertRegex(out, r'WARNING: Overriding.*TEST_VAR_PREPEND')
- self.assertNotRegex(out, r'WARNING: Overriding.*TEST_VAR_SET')
- self.run_tests()
-
def test_testrepeat(self):
testdir = os.path.join(self.common_test_dir, '207 tap tests')
self.init(testdir)
diff --git a/test cases/common/34 run program/check-env.py b/test cases/common/34 run program/check-env.py
new file mode 100644
index 0000000..7f106c6
--- /dev/null
+++ b/test cases/common/34 run program/check-env.py
@@ -0,0 +1,6 @@
+#!/usr/bin/env python3
+
+import os
+
+assert os.environ['MY_PATH'] == os.pathsep.join(['0', '1', '2'])
+
diff --git a/test cases/common/34 run program/meson.build b/test cases/common/34 run program/meson.build
index 93897e3..8e472fd 100644
--- a/test cases/common/34 run program/meson.build
+++ b/test cases/common/34 run program/meson.build
@@ -77,3 +77,9 @@ if dd.found()
assert(ret.returncode() == 0, 'failed to run dd: ' + ret.stderr())
assert(ret.stdout() == '', 'stdout is "@0@" instead of empty'.format(ret.stdout()))
endif
+
+env = environment()
+env.append('MY_PATH', '1')
+env.append('MY_PATH', '2')
+env.prepend('MY_PATH', '0')
+run_command('check-env.py', env: env, check: true)
diff --git a/test cases/unit/63 test env does not stack/meson.build b/test cases/unit/63 test env does not stack/meson.build
deleted file mode 100644
index 01f2637..0000000
--- a/test cases/unit/63 test env does not stack/meson.build
+++ /dev/null
@@ -1,12 +0,0 @@
-project('test env var stacking')
-
-testenv = environment()
-testenv.set('TEST_VAR_SET', 'some-value')
-testenv.set('TEST_VAR_APPEND', 'some-value')
-testenv.set('TEST_VAR_PREPEND', 'some-value')
-
-testenv.append('TEST_VAR_APPEND', 'another-value-append', separator: ':')
-testenv.prepend('TEST_VAR_PREPEND', 'another-value-prepend', separator: ':')
-testenv.set('TEST_VAR_SET', 'another-value-set')
-
-test('check env', find_program('script.py'), env: testenv)
diff --git a/test cases/unit/63 test env does not stack/script.py b/test cases/unit/63 test env does not stack/script.py
deleted file mode 100755
index 2a76673..0000000
--- a/test cases/unit/63 test env does not stack/script.py
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/usr/bin/env python3
-
-import os
-
-for name in ('append', 'prepend', 'set'):
- envname = 'TEST_VAR_' + name.upper()
- value = 'another-value-' + name
- envvalue = os.environ[envname]
- assert (envvalue == value), (name, envvalue)