aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles Brunet <charles.brunet@optelgroup.com>2023-10-10 12:09:15 -0400
committerJussi Pakkanen <jpakkane@gmail.com>2024-02-23 21:11:56 +0200
commit138e0fe9841b44a6d0402b66bbd0c10966cfe87b (patch)
tree6ef0d07b225a96880daed110ed94ff951d43c4c5
parentdb8246b3fc52994eac2cccd1416e64e36c3369e2 (diff)
downloadmeson-138e0fe9841b44a6d0402b66bbd0c10966cfe87b.zip
meson-138e0fe9841b44a6d0402b66bbd0c10966cfe87b.tar.gz
meson-138e0fe9841b44a6d0402b66bbd0c10966cfe87b.tar.bz2
env.unset method
-rw-r--r--docs/markdown/snippets/environment_unset.md4
-rw-r--r--docs/yaml/objects/env.yaml7
-rw-r--r--mesonbuild/interpreter/interpreterobjects.py7
-rw-r--r--mesonbuild/utils/core.py17
-rw-r--r--test cases/common/273 environment/meson.build50
-rw-r--r--test cases/common/273 environment/testenv.py12
6 files changed, 97 insertions, 0 deletions
diff --git a/docs/markdown/snippets/environment_unset.md b/docs/markdown/snippets/environment_unset.md
new file mode 100644
index 0000000..887bc0d
--- /dev/null
+++ b/docs/markdown/snippets/environment_unset.md
@@ -0,0 +1,4 @@
+## New `unset()` method on `environment` objects
+
+[[@env]] now has an [[env.unset]] method to ensure an existing environment
+is *not* defined.
diff --git a/docs/yaml/objects/env.yaml b/docs/yaml/objects/env.yaml
index d784c68..714da4f 100644
--- a/docs/yaml/objects/env.yaml
+++ b/docs/yaml/objects/env.yaml
@@ -82,3 +82,10 @@ methods:
description: The values to set
kwargs_inherit: env.append
+
+- name: unset
+ returns: void
+ since: 1.4.0
+ description: |
+ Unset the specified environment variable. If this variable does not exist,
+ nothing happens.
diff --git a/mesonbuild/interpreter/interpreterobjects.py b/mesonbuild/interpreter/interpreterobjects.py
index 4320cf5..9aefc2f 100644
--- a/mesonbuild/interpreter/interpreterobjects.py
+++ b/mesonbuild/interpreter/interpreterobjects.py
@@ -285,6 +285,7 @@ class EnvironmentVariablesHolder(ObjectHolder[mesonlib.EnvironmentVariables], Mu
def __init__(self, obj: mesonlib.EnvironmentVariables, interpreter: 'Interpreter'):
super().__init__(obj, interpreter)
self.methods.update({'set': self.set_method,
+ 'unset': self.unset_method,
'append': self.append_method,
'prepend': self.prepend_method,
})
@@ -309,6 +310,12 @@ class EnvironmentVariablesHolder(ObjectHolder[mesonlib.EnvironmentVariables], Mu
name, values = args
self.held_object.set(name, values, kwargs['separator'])
+ @FeatureNew('environment.unset', '1.4.0')
+ @typed_pos_args('environment.unset', str)
+ @noKwargs
+ def unset_method(self, args: T.Tuple[str], kwargs: TYPE_kwargs) -> None:
+ self.held_object.unset(args[0])
+
@typed_pos_args('environment.append', str, varargs=str, min_varargs=1)
@typed_kwargs('environment.append', ENV_SEPARATOR_KW)
def append_method(self, args: T.Tuple[str, T.List[str]], kwargs: 'EnvironmentSeparatorKW') -> None:
diff --git a/mesonbuild/utils/core.py b/mesonbuild/utils/core.py
index 1b005cf..92f9d2c 100644
--- a/mesonbuild/utils/core.py
+++ b/mesonbuild/utils/core.py
@@ -63,6 +63,7 @@ class EnvironmentVariables(HoldableObject):
self.envvars: T.List[T.Tuple[T.Callable[[T.Dict[str, str], str, T.List[str], str, T.Optional[str]], str], str, T.List[str], str]] = []
# The set of all env vars we have operations for. Only used for self.has_name()
self.varnames: T.Set[str] = set()
+ self.unset_vars: T.Set[str] = set()
if values:
init_func = getattr(self, init_method)
@@ -92,16 +93,30 @@ class EnvironmentVariables(HoldableObject):
for method, name, values, separator in other.envvars:
self.varnames.add(name)
self.envvars.append((method, name, values, separator))
+ if name in self.unset_vars:
+ self.unset_vars.remove(name)
+ self.unset_vars.update(other.unset_vars)
def set(self, name: str, values: T.List[str], separator: str = os.pathsep) -> None:
+ if name in self.unset_vars:
+ raise MesonException(f'You cannot set the already unset variable {name!r}')
self.varnames.add(name)
self.envvars.append((self._set, name, values, separator))
+ def unset(self, name: str) -> None:
+ if name in self.varnames:
+ raise MesonException(f'You cannot unset the {name!r} variable because it is already set')
+ self.unset_vars.add(name)
+
def append(self, name: str, values: T.List[str], separator: str = os.pathsep) -> None:
+ if name in self.unset_vars:
+ raise MesonException(f'You cannot append to unset variable {name!r}')
self.varnames.add(name)
self.envvars.append((self._append, name, values, separator))
def prepend(self, name: str, values: T.List[str], separator: str = os.pathsep) -> None:
+ if name in self.unset_vars:
+ raise MesonException(f'You cannot prepend to unset variable {name!r}')
self.varnames.add(name)
self.envvars.append((self._prepend, name, values, separator))
@@ -124,6 +139,8 @@ class EnvironmentVariables(HoldableObject):
for method, name, values, separator in self.envvars:
default_value = default_fmt.format(name) if default_fmt else None
env[name] = method(env, name, values, separator, default_value)
+ for name in self.unset_vars:
+ env.pop(name, None)
return env
diff --git a/test cases/common/273 environment/meson.build b/test cases/common/273 environment/meson.build
new file mode 100644
index 0000000..af15c1b
--- /dev/null
+++ b/test cases/common/273 environment/meson.build
@@ -0,0 +1,50 @@
+project(
+ 'environment',
+ meson_version: '>=1.4.0',
+)
+
+testenv = find_program(files('testenv.py'))
+
+
+env = environment()
+env.unset('foo')
+test('not set', testenv, args: ['foo'], env: env)
+
+testcase expect_error('You cannot set the already unset variable \'foo\'')
+ env.set('foo', 'bar')
+endtestcase
+
+testcase expect_error('You cannot append to unset variable \'foo\'')
+ env.append('foo', 'bar')
+endtestcase
+
+testcase expect_error('You cannot prepend to unset variable \'foo\'')
+ env.prepend('foo', 'bar')
+endtestcase
+
+
+env1 = environment('foo=bar', method: 'append', separator: ':')
+env1.append('foo', 'baz', separator: ':')
+test('append', testenv, args: ['foo', 'bar:baz'], env: env1)
+
+testcase expect_error('You cannot unset the \'foo\' variable because it is already set')
+ env1.unset('foo')
+endtestcase
+
+
+env2 = environment(['foo=baz'], method: 'prepend', separator: ':')
+env2.prepend('foo', 'bar', separator: ':')
+test('prepend', testenv, args: ['foo', 'bar:baz'], env: env2)
+
+testcase expect_error('You cannot unset the \'foo\' variable because it is already set')
+ env2.unset('foo')
+endtestcase
+
+
+env3 = environment({'foo': 'foobar'}, method: 'set', separator: ':')
+env3.set('foo', 'qux')
+test('reset', testenv, args: ['foo', 'qux'], env: env3)
+
+testcase expect_error('You cannot unset the \'foo\' variable because it is already set')
+ env3.unset('foo')
+endtestcase
diff --git a/test cases/common/273 environment/testenv.py b/test cases/common/273 environment/testenv.py
new file mode 100644
index 0000000..1a59b82
--- /dev/null
+++ b/test cases/common/273 environment/testenv.py
@@ -0,0 +1,12 @@
+#!/usr/bin/env python3
+
+import os
+import sys
+
+key = sys.argv[1]
+expected = sys.argv[2] if len(sys.argv) > 2 else None
+
+if os.environ.get(key) == expected:
+ sys.exit(0)
+
+sys.exit(f'Expected {expected!r}, was {os.environ.get(key)!r}')