summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Tojnar <jtojnar@gmail.com>2019-01-20 07:15:20 +0100
committerJussi Pakkanen <jpakkane@gmail.com>2019-01-27 19:24:15 +0200
commit33d82201bd4114d9bd81b45bce86d7938bc30869 (patch)
tree303de8077bedcdec5d82615547f2fd151675b386
parentc07e5124bcb2eb5f4a078fe537d42c5ff64e60af (diff)
downloadmeson-33d82201bd4114d9bd81b45bce86d7938bc30869.tar.gz
run_command: add env kwarg
-rw-r--r--docs/markdown/External-commands.md8
-rw-r--r--docs/markdown/Reference-manual.md6
-rw-r--r--docs/markdown/snippets/run_command_env.md9
-rw-r--r--mesonbuild/interpreter.py26
-rw-r--r--test cases/common/36 run program/meson.build6
5 files changed, 42 insertions, 13 deletions
diff --git a/docs/markdown/External-commands.md b/docs/markdown/External-commands.md
index 9336ec314..4c8c8e49f 100644
--- a/docs/markdown/External-commands.md
+++ b/docs/markdown/External-commands.md
@@ -16,6 +16,14 @@ output = r.stdout().strip()
errortxt = r.stderr().strip()
```
+Additionally, since 0.50.0, you can pass the command [`environment`](Reference-manual.html#environment-object) object:
+
+```meson
+env = environment()
+env.set('FOO', 'bar')
+run_command('command', 'arg1', 'arg2', env: env)
+```
+
The `run_command` function returns an object that can be queried for
return value and text written to stdout and stderr. The `strip` method
call is used to strip trailing and leading whitespace from
diff --git a/docs/markdown/Reference-manual.md b/docs/markdown/Reference-manual.md
index e913e25ca..db438134b 100644
--- a/docs/markdown/Reference-manual.md
+++ b/docs/markdown/Reference-manual.md
@@ -1183,12 +1183,14 @@ and Meson will set three environment variables `MESON_SOURCE_ROOT`,
directory, build directory and subdirectory the target was defined in,
respectively.
-This function has one keyword argument.
+This function supports the following keyword arguments:
- `check` takes a boolean. If `true`, the exit status code of the command will
be checked, and the configuration will fail if it is non-zero. The default is
`false`.
Since 0.47.0
+ - `env` an [environment object](#environment-object) to use a custom environment
+ Since 0.50.0
See also [External commands](External-commands.md).
@@ -2175,7 +2177,7 @@ and has the following methods:
This object is returned by [`environment()`](#environment) and stores
detailed information about how environment variables should be set
during tests. It should be passed as the `env` keyword argument to
-tests. It has the following methods.
+tests and other functions. It has the following methods.
- `append(varname, value1, value2, ...)` appends the given values to
the old value of the environment variable, e.g. `env.append('FOO',
diff --git a/docs/markdown/snippets/run_command_env.md b/docs/markdown/snippets/run_command_env.md
new file mode 100644
index 000000000..dfa5ac5bd
--- /dev/null
+++ b/docs/markdown/snippets/run_command_env.md
@@ -0,0 +1,9 @@
+## `run_command` accepts `env` kwarg
+
+You can pass [`environment`](Reference-manual.html#environment-object) object to [`run_command`](Reference-manual.html#run-command), just like to `test`:
+
+```meson
+env = environment()
+env.set('FOO', 'bar')
+run_command('command', 'arg1', 'arg2', env: env)
+```
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index ee571fdc0..aff46d13f 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -143,31 +143,32 @@ class TryRunResultHolder(InterpreterObject):
class RunProcess(InterpreterObject):
- def __init__(self, cmd, args, source_dir, build_dir, subdir, mesonintrospect, in_builddir=False, check=False, capture=True):
+ def __init__(self, cmd, args, env, source_dir, build_dir, subdir, mesonintrospect, in_builddir=False, check=False, capture=True):
super().__init__()
if not isinstance(cmd, ExternalProgram):
raise AssertionError('BUG: RunProcess must be passed an ExternalProgram')
self.capture = capture
- pc, self.stdout, self.stderr = self.run_command(cmd, args, source_dir, build_dir, subdir, mesonintrospect, in_builddir, check)
+ pc, self.stdout, self.stderr = self.run_command(cmd, args, env, source_dir, build_dir, subdir, mesonintrospect, in_builddir, check)
self.returncode = pc.returncode
self.methods.update({'returncode': self.returncode_method,
'stdout': self.stdout_method,
'stderr': self.stderr_method,
})
- def run_command(self, cmd, args, source_dir, build_dir, subdir, mesonintrospect, in_builddir, check=False):
+ def run_command(self, cmd, args, env, source_dir, build_dir, subdir, mesonintrospect, in_builddir, check=False):
command_array = cmd.get_command() + args
- env = {'MESON_SOURCE_ROOT': source_dir,
- 'MESON_BUILD_ROOT': build_dir,
- 'MESON_SUBDIR': subdir,
- 'MESONINTROSPECT': ' '.join([shlex.quote(x) for x in mesonintrospect]),
- }
+ menv = {'MESON_SOURCE_ROOT': source_dir,
+ 'MESON_BUILD_ROOT': build_dir,
+ 'MESON_SUBDIR': subdir,
+ 'MESONINTROSPECT': ' '.join([shlex.quote(x) for x in mesonintrospect]),
+ }
if in_builddir:
cwd = os.path.join(build_dir, subdir)
else:
cwd = os.path.join(source_dir, subdir)
child_env = os.environ.copy()
- child_env.update(env)
+ child_env.update(menv)
+ child_env = env.get_env(child_env)
stdout = subprocess.PIPE if self.capture else subprocess.DEVNULL
mlog.debug('Running command:', ' '.join(command_array))
try:
@@ -1954,7 +1955,7 @@ permitted_kwargs = {'add_global_arguments': {'language', 'native'},
'install_subdir': {'exclude_files', 'exclude_directories', 'install_dir', 'install_mode', 'strip_directory'},
'jar': build.known_jar_kwargs,
'project': {'version', 'meson_version', 'default_options', 'license', 'subproject_dir'},
- 'run_command': {'check', 'capture'},
+ 'run_command': {'check', 'capture', 'env'},
'run_target': {'command', 'depends'},
'shared_library': build.known_shlib_kwargs,
'shared_module': build.known_shmod_kwargs,
@@ -2259,6 +2260,7 @@ external dependencies (including libraries) must go to "dependencies".''')
if not isinstance(actual, wanted):
raise InvalidArguments('Incorrect argument type.')
+ @FeatureNewKwargs('run_command', '0.50.0', ['env'])
@FeatureNewKwargs('run_command', '0.47.0', ['check', 'capture'])
@permittedKwargs(permitted_kwargs['run_command'])
def func_run_command(self, node, args, kwargs):
@@ -2277,6 +2279,8 @@ external dependencies (including libraries) must go to "dependencies".''')
if not isinstance(check, bool):
raise InterpreterException('Check must be boolean.')
+ env = self.unpack_env_kwarg(kwargs)
+
m = 'must be a string, or the output of find_program(), files() '\
'or configure_file(), or a compiler object; not {!r}'
if isinstance(cmd, ExternalProgramHolder):
@@ -2326,7 +2330,7 @@ external dependencies (including libraries) must go to "dependencies".''')
if not a.startswith('..'):
if a not in self.build_def_files:
self.build_def_files.append(a)
- return RunProcess(cmd, expanded_args, srcdir, builddir, self.subdir,
+ return RunProcess(cmd, expanded_args, env, srcdir, builddir, self.subdir,
self.environment.get_build_command() + ['introspect'],
in_builddir=in_builddir, check=check, capture=capture)
diff --git a/test cases/common/36 run program/meson.build b/test cases/common/36 run program/meson.build
index a05cea3fb..93897e3f8 100644
--- a/test cases/common/36 run program/meson.build
+++ b/test cases/common/36 run program/meson.build
@@ -65,6 +65,12 @@ ret = run_command(py3, '-c', 'print("some output")', capture : false)
assert(ret.returncode() == 0, 'failed to run python3: ' + ret.stderr())
assert(ret.stdout() == '', 'stdout is "@0@" instead of empty'.format(ret.stdout()))
+c_env = environment()
+c_env.append('CUSTOM_ENV_VAR', 'FOOBAR')
+ret = run_command(py3, '-c', 'import os; print(os.environ.get("CUSTOM_ENV_VAR"))', env : c_env)
+assert(ret.returncode() == 0, 'failed to run python3: ' + ret.stderr())
+assert(ret.stdout() == 'FOOBAR\n', 'stdout is "@0@" instead of FOOBAR'.format(ret.stdout()))
+
dd = find_program('dd', required : false)
if dd.found()
ret = run_command(dd, 'if=/dev/urandom', 'bs=10', 'count=1', capture: false)