diff options
-rw-r--r-- | docs/markdown/External-commands.md | 9 | ||||
-rw-r--r-- | docs/markdown/Reference-manual.md | 18 | ||||
-rw-r--r-- | docs/markdown/Release-notes-for-0.52.0.md | 11 | ||||
-rw-r--r-- | docs/markdown/Videos.md | 3 | ||||
-rw-r--r-- | docs/markdown/Wrap-dependency-system-manual.md | 8 | ||||
-rw-r--r-- | docs/markdown/snippets/blocks.md | 3 | ||||
-rw-r--r-- | docs/markdown/snippets/check-disabler.md | 5 | ||||
-rw-r--r-- | docs/markdown/snippets/depth.md | 7 | ||||
-rw-r--r-- | docs/markdown/snippets/env_dict.md | 8 | ||||
-rw-r--r-- | mesonbuild/interpreter.py | 64 | ||||
-rw-r--r-- | mesonbuild/wrap/wrap.py | 19 | ||||
-rw-r--r-- | test cases/unit/69 test env value/meson.build | 10 | ||||
-rwxr-xr-x | test cases/unit/69 test env value/test.py | 6 |
13 files changed, 127 insertions, 44 deletions
diff --git a/docs/markdown/External-commands.md b/docs/markdown/External-commands.md index 4c8c8e4..cafd280 100644 --- a/docs/markdown/External-commands.md +++ b/docs/markdown/External-commands.md @@ -16,7 +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: +Since 0.52.0, you can pass the command environment as a dictionary: + +```meson +run_command('command', 'arg1', 'arg2', env: {'FOO': 'bar'}) +``` + +Since 0.50.0, you can also pass the command +[`environment`](Reference-manual.html#environment-object) object: ```meson env = environment() diff --git a/docs/markdown/Reference-manual.md b/docs/markdown/Reference-manual.md index f296e43..6009d30 100644 --- a/docs/markdown/Reference-manual.md +++ b/docs/markdown/Reference-manual.md @@ -104,7 +104,10 @@ Add a custom test setup that can be used to run the tests with a custom setup, for example under Valgrind. The keyword arguments are the following: -- `env` an [environment object](#environment-object) to use a custom environment +- `env` environment variables to set, such as `['NAME1=value1', + 'NAME2=value2']`, or an [`environment()` + object](#environment-object) which allows more sophisticated + environment juggling. *Since 0.52.0* a dictionary is also accepted. - `exe_wrapper` a list containing the wrapper command or script followed by the arguments to it - `gdb` if `true`, the tests are also run under `gdb` - `timeout_multiplier` a number to multiply the test timeout with @@ -491,12 +494,16 @@ Print the argument string and halts the build process. ### environment() ``` meson - environment_object environment() + environment_object environment(...) ``` Returns an empty [environment variable object](#environment-object). Added in 0.35.0. +Since *0.52.0* takes an optional dictionary as first argument. If +provided, each key/value pair is added into the `environment_object` +as if `set()` method was called for each of them. + ### executable() ``` meson @@ -1256,7 +1263,10 @@ This function supports the following keyword arguments: 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 + - `env` environment variables to set, such as `['NAME1=value1', + 'NAME2=value2']`, or an [`environment()` + object](#environment-object) which allows more sophisticated + environment juggling. *Since 0.52.0* a dictionary is also accepted. Since 0.50.0 See also [External commands](External-commands.md). @@ -1489,7 +1499,7 @@ Keyword arguments are the following: - `env` environment variables to set, such as `['NAME1=value1', 'NAME2=value2']`, or an [`environment()` object](#environment-object) which allows more sophisticated - environment juggling + environment juggling. *Since 0.52.0* a dictionary is also accepted. - `is_parallel` when false, specifies that no other test must be running at the same time as this test diff --git a/docs/markdown/Release-notes-for-0.52.0.md b/docs/markdown/Release-notes-for-0.52.0.md index de317df..f5bbcc3 100644 --- a/docs/markdown/Release-notes-for-0.52.0.md +++ b/docs/markdown/Release-notes-for-0.52.0.md @@ -3,13 +3,4 @@ title: Release 0.52.0 short-description: Release notes for 0.52.0 ... -# New features - -## Allow checking if a variable is a disabler - -Added the function `is_disabler(var)`. Returns true if a variable is a disabler -and false otherwise. - -## Add blocks dependency - -Add `dependency('blocks')` to use the Clang blocks extension. +# Notable changes in this version diff --git a/docs/markdown/Videos.md b/docs/markdown/Videos.md index 65fccfe..f2e37a7 100644 --- a/docs/markdown/Videos.md +++ b/docs/markdown/Videos.md @@ -4,6 +4,9 @@ short-description: Videos about Meson # Videos + - [Behind the Scenes of a C++ Build + System](https://www.youtube.com/watch?v=34KzT2yvQuM) CppCon 2019 + - [Compiling Multi-Million Line C++ Code Bases Effortlessly with the Meson Build system](https://www.youtube.com/watch?v=SCZLnopmYBM), CppCon 2018 diff --git a/docs/markdown/Wrap-dependency-system-manual.md b/docs/markdown/Wrap-dependency-system-manual.md index 619492a..22ba589 100644 --- a/docs/markdown/Wrap-dependency-system-manual.md +++ b/docs/markdown/Wrap-dependency-system-manual.md @@ -143,6 +143,14 @@ automatically by adding the following *(since 0.48.0)*: clone-recursive = true ``` +Setting the clone depth is supported using the `depth` directive *(since 0.52.0)*. +Note that git always allow shallowly cloning branches, but in order to clone commit ids +shallowly, the server must support `uploadpack.allowReachableSHA1InWant=true`. + +```ini +depth = 1 +``` + ## Using wrapped projects Wraps provide a convenient way of obtaining a project into your subproject directory. diff --git a/docs/markdown/snippets/blocks.md b/docs/markdown/snippets/blocks.md new file mode 100644 index 0000000..917ee54 --- /dev/null +++ b/docs/markdown/snippets/blocks.md @@ -0,0 +1,3 @@ +## Add blocks dependency + +Add `dependency('blocks')` to use the Clang blocks extension. diff --git a/docs/markdown/snippets/check-disabler.md b/docs/markdown/snippets/check-disabler.md new file mode 100644 index 0000000..9670792 --- /dev/null +++ b/docs/markdown/snippets/check-disabler.md @@ -0,0 +1,5 @@ +## Allow checking if a variable is a disabler + +Added the function `is_disabler(var)`. Returns true if a variable is a disabler +and false otherwise. + diff --git a/docs/markdown/snippets/depth.md b/docs/markdown/snippets/depth.md new file mode 100644 index 0000000..bdb032c --- /dev/null +++ b/docs/markdown/snippets/depth.md @@ -0,0 +1,7 @@ +## Add `depth` option to `wrap-git` + +To allow shallow cloning, an option `depth` has been added to `wrap-git`. +This applies recursively to submodules when `clone-recursive` is set to `true`. + +Note that the git server may have to be configured to support shallow cloning +not only for branches but also for tags. diff --git a/docs/markdown/snippets/env_dict.md b/docs/markdown/snippets/env_dict.md new file mode 100644 index 0000000..5949806 --- /dev/null +++ b/docs/markdown/snippets/env_dict.md @@ -0,0 +1,8 @@ +## Support taking environment values from a dictionary + +`environment()` now accepts a dictionary as first argument. If +provided, each key/value pair is added into the `environment_object` +as if `set()` method was called for each of them. + +On the various functions that take an `env:` keyword argument, you may +now give a dictionary. diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py index e0b17db..2a77eaa 100644 --- a/mesonbuild/interpreter.py +++ b/mesonbuild/interpreter.py @@ -222,13 +222,28 @@ class ConfigureFileHolder(InterpreterObject, ObjectHolder): class EnvironmentVariablesHolder(MutableInterpreterObject, ObjectHolder): - def __init__(self): + def __init__(self, initial_values=None): MutableInterpreterObject.__init__(self) ObjectHolder.__init__(self, build.EnvironmentVariables()) self.methods.update({'set': self.set_method, 'append': self.append_method, 'prepend': self.prepend_method, }) + if isinstance(initial_values, dict): + for k, v in initial_values.items(): + self.set_method([k, v], {}) + elif isinstance(initial_values, list): + for e in initial_values: + if '=' not in e: + raise InterpreterException('Env var definition must be of type key=val.') + (k, val) = e.split('=', 1) + k = k.strip() + val = val.strip() + if ' ' in k: + raise InterpreterException('Env var key must not have spaces in it.') + self.set_method([k, val], {}) + elif initial_values: + raise AssertionError('Unsupported EnvironmentVariablesHolder initial_values') def __repr__(self): repr_str = "<{0}: {1}>" @@ -267,7 +282,7 @@ class EnvironmentVariablesHolder(MutableInterpreterObject, ObjectHolder): class ConfigurationDataHolder(MutableInterpreterObject, ObjectHolder): - def __init__(self, pv): + def __init__(self, pv, initial_values=None): MutableInterpreterObject.__init__(self) self.used = False # These objects become immutable after use in configure_file. ObjectHolder.__init__(self, build.ConfigurationData(), pv) @@ -279,6 +294,11 @@ class ConfigurationDataHolder(MutableInterpreterObject, ObjectHolder): 'get_unquoted': self.get_unquoted_method, 'merge_from': self.merge_from_method, }) + if isinstance(initial_values, dict): + for k, v in initial_values.items(): + self.set_method([k, v], {}) + elif initial_values: + raise AssertionError('Unsupported ConfigurationDataHolder initial_values') def is_used(self): return self.used @@ -2610,15 +2630,13 @@ external dependencies (including libraries) must go to "dependencies".''') if len(args) > 1: raise InterpreterException('configuration_data takes only one optional positional arguments') elif len(args) == 1: + FeatureNew('configuration_data dictionary', '0.49.0').use(self.subproject) initial_values = args[0] if not isinstance(initial_values, dict): raise InterpreterException('configuration_data first argument must be a dictionary') else: initial_values = {} - cdata = ConfigurationDataHolder(self.subproject) - for k, v in initial_values.items(): - cdata.set_method([k, v], {}) - return cdata + return ConfigurationDataHolder(self.subproject, initial_values) def set_backend(self): # The backend is already set when parsing subprojects @@ -3357,19 +3375,14 @@ This will become a hard error in the future.''' % kwargs['input'], location=self envlist = kwargs.get('env', EnvironmentVariablesHolder()) if isinstance(envlist, EnvironmentVariablesHolder): env = envlist.held_object + elif isinstance(envlist, dict): + FeatureNew('environment dictionary', '0.52.0').use(self.subproject) + env = EnvironmentVariablesHolder(envlist) + env = env.held_object else: envlist = listify(envlist) # Convert from array to environment object - env = EnvironmentVariablesHolder() - for e in envlist: - if '=' not in e: - raise InterpreterException('Env var definition must be of type key=val.') - (k, val) = e.split('=', 1) - k = k.strip() - val = val.strip() - if ' ' in k: - raise InterpreterException('Env var key must not have spaces in it.') - env.set_method([k, val], {}) + env = EnvironmentVariablesHolder(envlist) env = env.held_object return env @@ -3668,10 +3681,8 @@ This will become a hard error in the future.''' % kwargs['input'], location=self if 'configuration' in kwargs: conf = kwargs['configuration'] if isinstance(conf, dict): - cdata = ConfigurationDataHolder(self.subproject) - for k, v in conf.items(): - cdata.set_method([k, v], {}) - conf = cdata + FeatureNew('configure_file.configuration dictionary', '0.49.0').use(self.subproject) + conf = ConfigurationDataHolder(self.subproject, conf) elif not isinstance(conf, ConfigurationDataHolder): raise InterpreterException('Argument "configuration" is not of type configuration_data') mlog.log('Configuring', mlog.bold(output), 'using configuration') @@ -3935,9 +3946,18 @@ different subdirectory. argsdict[lang] = argsdict.get(lang, []) + args @noKwargs - @noPosargs + @noArgsFlattening def func_environment(self, node, args, kwargs): - return EnvironmentVariablesHolder() + if len(args) > 1: + raise InterpreterException('environment takes only one optional positional arguments') + elif len(args) == 1: + FeatureNew('environment positional arguments', '0.52.0').use(self.subproject) + initial_values = args[0] + if not isinstance(initial_values, dict) and not isinstance(initial_values, list): + raise InterpreterException('environment first argument must be a dictionary or a list') + else: + initial_values = {} + return EnvironmentVariablesHolder(initial_values) @stringArgs @noKwargs diff --git a/mesonbuild/wrap/wrap.py b/mesonbuild/wrap/wrap.py index 4b2a323..89bc307 100644 --- a/mesonbuild/wrap/wrap.py +++ b/mesonbuild/wrap/wrap.py @@ -226,16 +226,21 @@ class Resolver: self.apply_patch() def get_git(self): + # git doesn't support directly cloning shallowly for commits, + # so we follow https://stackoverflow.com/a/43136160 + subprocess.check_call(['git', 'init', self.directory], cwd=self.subdir_root) + subprocess.check_call(['git', 'remote', 'add', 'origin', self.wrap.get('url')], + cwd=self.dirname) + git_options = [] revno = self.wrap.get('revision') - subprocess.check_call(['git', 'clone', self.wrap.get('url'), - self.directory], cwd=self.subdir_root) - if revno.lower() != 'head': - if subprocess.call(['git', 'checkout', revno], cwd=self.dirname) != 0: - subprocess.check_call(['git', 'fetch', self.wrap.get('url'), revno], cwd=self.dirname) - subprocess.check_call(['git', 'checkout', revno], cwd=self.dirname) + if self.wrap.values.get('depth', '') != '': + git_options.extend(['--depth', self.wrap.values.get('depth')]) + subprocess.check_call(['git', 'fetch'] + git_options + ['origin', revno], + cwd=self.dirname) + subprocess.check_call(['git', 'checkout', revno], cwd=self.dirname) if self.wrap.values.get('clone-recursive', '').lower() == 'true': subprocess.check_call(['git', 'submodule', 'update', - '--init', '--checkout', '--recursive'], + '--init', '--checkout', '--recursive'] + git_options, cwd=self.dirname) push_url = self.wrap.values.get('push-url') if push_url: diff --git a/test cases/unit/69 test env value/meson.build b/test cases/unit/69 test env value/meson.build new file mode 100644 index 0000000..aa3dbc3 --- /dev/null +++ b/test cases/unit/69 test env value/meson.build @@ -0,0 +1,10 @@ +project('test env value') + +testpy = find_program('test.py') + +val = ['1', '2', '3'] +foreach v: val + test('check env', testpy, args: [v], env: {'TEST_VAR': v}) +endforeach +test('check env', testpy, args: ['4'], env: environment({'TEST_VAR': '4'})) +test('check env', testpy, args: ['5'], env: environment(['TEST_VAR=5'])) diff --git a/test cases/unit/69 test env value/test.py b/test cases/unit/69 test env value/test.py new file mode 100755 index 0000000..0cc7645 --- /dev/null +++ b/test cases/unit/69 test env value/test.py @@ -0,0 +1,6 @@ +#!/usr/bin/env python3 + +import os +import sys + +assert(os.environ['TEST_VAR'] == sys.argv[1]) |