From d4fe805a51d5a8e9b39c1f4d51b132891c84169b Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Wed, 27 Feb 2019 16:29:31 +0100 Subject: rewriter: Added docs --- docs/markdown/Rewriter.md | 183 +++++++++++++++++++++++++++++++++++++ docs/markdown/snippets/rewriter.md | 18 ++++ docs/sitemap.txt | 1 + 3 files changed, 202 insertions(+) create mode 100644 docs/markdown/Rewriter.md create mode 100644 docs/markdown/snippets/rewriter.md (limited to 'docs') diff --git a/docs/markdown/Rewriter.md b/docs/markdown/Rewriter.md new file mode 100644 index 000000000..89591fa36 --- /dev/null +++ b/docs/markdown/Rewriter.md @@ -0,0 +1,183 @@ +--- +short-description: Automatic modification of the build system files +... + +# Meson file rewriter + +Since version 0.50.0, meson has the functionality to perform some basic +modification on the `meson.build` files from the command line. The currently +supported operations are: + +- For build targets: + - Add/Remove source files + - Add/Remove targets + - Modify a select set of kwargs + - Print some JSON information +- For dependencies: + - Modify a select set of kwargs +- For the project function: + - Modify a select set of kwargs + - Modify the default options list + +The rewriter has both, a normal command line interface and a "script mode". The +normal CLI is mostly designed for everyday use. The "script mode", on the +other hand, is meant to be used by external programs (IDEs, graphical +frontends, etc.) + +## Using the rewriter + +All rewriter functions are accessed via `meson rewrite` (or the rewriter alias +`meson rw`). The meson rewriter assumes that it is run inside the project root +directory. If this isn't the case, use `--sourcedir` to specify the actual +project source directory. + +### Adding and removing sources + +The most common operations will probably be the adding and removing of source +files to a build target. This can be easily done with: + +```bash +meson rewrite target {add/rm} [list of sources] +``` + +For instance, given the following example + +```meson +src = ['main.cpp', 'fileA.cpp'] + +exe1 = executable('testExe', src) +``` + +the source `fileB.cpp` can be added with: + +```bash +meson rewrite target testExe add fileB.cpp +``` + +After executing this command, the new `meson.build` will look like this: + +```meson +src = ['main.cpp', 'fileA.cpp', 'fileB.cpp'] + +exe1 = executable('testExe', src) +``` + +In this case, `exe1` could also have been used for the target name, since the +rewriter also takes assignments and internal meson IDs into consideration when +searching for the target in the `meson.build` files. + +For more information see the help output of the rewriter target command. + +### Setting the project version + +It is also possible to set kwargs of specific functions with the rewriter. The +general command for setting or removing kwargs is: + +```bash +meson rewriter kwargs {set/delete} ... +``` + +For instance, setting the project version can be achieved with this command: + +```bash +meson rewriter kwargs set project '' version 1.0.0 +``` + +Currently, only the following function types are supported: + +- dependency +- target (any build target, the function ID is the target name/ID) +- project (the function ID can be anything since project() can only be called once) + +For more information see the help output of the rewriter kwargs command. + +### Setting the project default options + +For setting and deleting default options, use the following command: + +```bash +meson rewrite default-options {set/delete} ... +``` + +## Using the "script mode" + +The "script mode" should be the preferred API for party programs, since it +offers more flexibility and higher API stability. The "scripts" are stored +in JSON format and executed with `meson rewrite command `. + +The JSON format is defined as follows: + +```json +[ + { + "type": "function to execute", + ... + }, { + "type": "other function", + ... + }, + ... +] +``` + +Each object in the main array must have a `type` entry which specifies which +function should be executed. + +Currently, the following functions are supported: + +- target +- kwargs +- default_options + +### Target modification format + +The format for the type `target` is defined as follows: + +```json +{ + "type": "target", + "target": "target ID/name/assignment variable", + "operation": "one of ['src_add', 'src_rm', 'tgt_rm', 'tgt_add', 'info']", + "sources": ["list", "of", "source", "files", "to", "add, remove"], + "subdir": "subdir where the new target should be added (only has an effect for operation 'tgt_add')", + "target_type": "function name of the new target -- same as in the CLI (only has an effect for operation 'tgt_add')" +} +``` + +The keys `sources`, `subdir` and `target_type` are optional. + +### kwargs modification format + +The format for the type `target` is defined as follows: + +```json +{ + "type": "kwargs", + "function": "one of ['dependency', 'target', 'project']", + "id": "function ID", + "operation": "one of ['set', 'delete', 'add', 'remove', 'remove_regex', 'info']", + "kwargs": { + "key1": "value1", + "key2": "value2", + ... + } +} +``` + +### Default options modification format + +The format for the type `default_options` is defined as follows: + +```json +{ + "type": "default_options", + "operation": "one of ['set', 'delete']", + "options": { + "opt1": "value1", + "opt2": "value2", + ... + } +} +``` + +For operation `delete`, the values of the `options` can be anything (including `null`) diff --git a/docs/markdown/snippets/rewriter.md b/docs/markdown/snippets/rewriter.md new file mode 100644 index 000000000..7a4621deb --- /dev/null +++ b/docs/markdown/snippets/rewriter.md @@ -0,0 +1,18 @@ +## Meson file rewriter + +This release adds the functionality to perform some basic modification +on the `meson.build` files from the command line. The currently +supported operations are: + +- For build targets: + - Add/Remove source files + - Add/Remove targets + - Modify a select set of kwargs + - Print some JSON information +- For dependencies: + - Modify a select set of kwargs +- For the project function: + - Modify a select set of kwargs + - Modify the default options list + +For more information see the rewriter documentation. diff --git a/docs/sitemap.txt b/docs/sitemap.txt index 69876416a..bea2a316c 100644 --- a/docs/sitemap.txt +++ b/docs/sitemap.txt @@ -60,6 +60,7 @@ index.md Reference-manual.md Reference-tables.md Style-guide.md + Rewriter.md FAQ.md Reproducible-builds.md howtox.md -- cgit v1.2.3 From eabc35340dc0fd63d70058f93c94674bc7782c19 Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Sat, 2 Mar 2019 11:18:13 +0100 Subject: rewriter: Enforce an empty project ID string --- docs/markdown/Rewriter.md | 2 +- mesonbuild/rewriter.py | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/markdown/Rewriter.md b/docs/markdown/Rewriter.md index 89591fa36..4550170ca 100644 --- a/docs/markdown/Rewriter.md +++ b/docs/markdown/Rewriter.md @@ -87,7 +87,7 @@ Currently, only the following function types are supported: - dependency - target (any build target, the function ID is the target name/ID) -- project (the function ID can be anything since project() can only be called once) +- project (the function ID must be an empty string since project() can only be called once) For more information see the help output of the rewriter kwargs command. diff --git a/mesonbuild/rewriter.py b/mesonbuild/rewriter.py index 58223015b..b344ce6ec 100644 --- a/mesonbuild/rewriter.py +++ b/mesonbuild/rewriter.py @@ -479,6 +479,8 @@ class Rewriter: node = None arg_node = None if cmd['function'] == 'project': + if cmd['id'] != '': + mlog.error('The ID for the function type project must be an empty string --> skipping') node = self.interpreter.project_node arg_node = node.args elif cmd['function'] == 'target': -- cgit v1.2.3 From c98987c19efabac06296c0e65692b7822db95a72 Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Sat, 2 Mar 2019 11:45:26 +0100 Subject: rewriter: Fixed docs. --- docs/markdown/Rewriter.md | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) (limited to 'docs') diff --git a/docs/markdown/Rewriter.md b/docs/markdown/Rewriter.md index 4550170ca..46b117ebd 100644 --- a/docs/markdown/Rewriter.md +++ b/docs/markdown/Rewriter.md @@ -99,10 +99,48 @@ For setting and deleting default options, use the following command: meson rewrite default-options {set/delete} ... ``` +## Limitations + +Rewriting a meson file is not guranteed to keep the indentation of the modified +functions. Additionally, comments inside a modified statement will be removed. +Furthermore, all source files will be sorted alphabetically. + +For instance adding `e.c` to srcs in the following code + +```meson +# Important comment + +srcs = [ +'a.c', 'c.c', 'f.c', +# something important about b + 'b.c', 'd.c', 'g.c' +] + +# COMMENT +``` + +would result in the following code: + +```meson +# Important comment + +srcs = [ + 'a.c', + 'b.c', + 'c.c', + 'd.c', + 'e.c', + 'f.c', + 'g.c' +] + +# COMMENT +``` + ## Using the "script mode" -The "script mode" should be the preferred API for party programs, since it -offers more flexibility and higher API stability. The "scripts" are stored +The "script mode" should be the preferred API for third party programs, since +it offers more flexibility and higher API stability. The "scripts" are stored in JSON format and executed with `meson rewrite command `. The JSON format is defined as follows: -- cgit v1.2.3 From 1290330894f5c2ad77684b1b3985a7ba17114ccb Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Sat, 2 Mar 2019 12:29:54 +0100 Subject: rewriter: Renamed tgt_{add,rm} --> target_{add,rm} --- docs/markdown/Rewriter.md | 2 +- mesonbuild/rewriter.py | 12 ++++++------ test cases/rewrite/1 basic/addTgt.json | 2 +- test cases/rewrite/1 basic/rmTgt.json | 4 ++-- test cases/rewrite/2 subdirs/addTgt.json | 2 +- test cases/rewrite/2 subdirs/rmTgt.json | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) (limited to 'docs') diff --git a/docs/markdown/Rewriter.md b/docs/markdown/Rewriter.md index 46b117ebd..332c9f752 100644 --- a/docs/markdown/Rewriter.md +++ b/docs/markdown/Rewriter.md @@ -175,7 +175,7 @@ The format for the type `target` is defined as follows: { "type": "target", "target": "target ID/name/assignment variable", - "operation": "one of ['src_add', 'src_rm', 'tgt_rm', 'tgt_add', 'info']", + "operation": "one of ['src_add', 'src_rm', 'target_rm', 'target_add', 'info']", "sources": ["list", "of", "source", "files", "to", "add, remove"], "subdir": "subdir where the new target should be added (only has an effect for operation 'tgt_add')", "target_type": "function name of the new target -- same as in the CLI (only has an effect for operation 'tgt_add')" diff --git a/mesonbuild/rewriter.py b/mesonbuild/rewriter.py index b344ce6ec..196fc3b79 100644 --- a/mesonbuild/rewriter.py +++ b/mesonbuild/rewriter.py @@ -306,7 +306,7 @@ rewriter_keys = { }, 'target': { 'target': (str, None, None), - 'operation': (str, None, ['src_add', 'src_rm', 'tgt_rm', 'tgt_add', 'info']), + 'operation': (str, None, ['src_add', 'src_rm', 'target_rm', 'target_add', 'info']), 'sources': (list, [], None), 'subdir': (str, '', None), 'target_type': (str, 'executable', ['both_libraries', 'executable', 'jar', 'library', 'shared_library', 'shared_module', 'static_library']), @@ -571,7 +571,7 @@ class Rewriter: def process_target(self, cmd): mlog.log('Processing target', mlog.bold(cmd['target']), 'operation', mlog.cyan(cmd['operation'])) target = self.find_target(cmd['target']) - if target is None and cmd['operation'] != 'tgt_add': + if target is None and cmd['operation'] != 'target_add': mlog.error('Unknown target "{}" --> skipping'.format(cmd['target'])) return @@ -678,7 +678,7 @@ class Rewriter: if root not in self.modefied_nodes: self.modefied_nodes += [root] - elif cmd['operation'] == 'tgt_add': + elif cmd['operation'] == 'target_add': if target is not None: mlog.error('Can not add target', mlog.bold(cmd['target']), 'because it already exists') return @@ -705,7 +705,7 @@ class Rewriter: tgt_ass_node.accept(AstIndentationGenerator()) self.to_add_nodes += [src_ass_node, tgt_ass_node] - elif cmd['operation'] == 'tgt_rm': + elif cmd['operation'] == 'target_rm': to_remove = self.find_assignment_node(target['node']) if to_remove is None: to_remove = target['node'] @@ -841,8 +841,8 @@ class Rewriter: target_operation_map = { 'add': 'src_add', 'rm': 'src_rm', - 'add_target': 'tgt_add', - 'rm_target': 'tgt_rm', + 'add_target': 'target_add', + 'rm_target': 'target_rm', 'info': 'info', } diff --git a/test cases/rewrite/1 basic/addTgt.json b/test cases/rewrite/1 basic/addTgt.json index 432e299da..2f4e7e256 100644 --- a/test cases/rewrite/1 basic/addTgt.json +++ b/test cases/rewrite/1 basic/addTgt.json @@ -2,7 +2,7 @@ { "type": "target", "target": "trivialprog10", - "operation": "tgt_add", + "operation": "target_add", "sources": ["new1.cpp", "new2.cpp"], "target_type": "shared_library" } diff --git a/test cases/rewrite/1 basic/rmTgt.json b/test cases/rewrite/1 basic/rmTgt.json index 577415748..9861f05d6 100644 --- a/test cases/rewrite/1 basic/rmTgt.json +++ b/test cases/rewrite/1 basic/rmTgt.json @@ -7,11 +7,11 @@ { "type": "target", "target": "trivialprog1", - "operation": "tgt_rm" + "operation": "target_rm" }, { "type": "target", "target": "trivialprog9", - "operation": "tgt_rm" + "operation": "target_rm" } ] diff --git a/test cases/rewrite/2 subdirs/addTgt.json b/test cases/rewrite/2 subdirs/addTgt.json index 01e9a6e84..2e1e8bc30 100644 --- a/test cases/rewrite/2 subdirs/addTgt.json +++ b/test cases/rewrite/2 subdirs/addTgt.json @@ -2,7 +2,7 @@ { "type": "target", "target": "newLib", - "operation": "tgt_add", + "operation": "target_add", "sources": ["new1.cpp", "new2.cpp"], "target_type": "shared_library", "subdir": "sub2" diff --git a/test cases/rewrite/2 subdirs/rmTgt.json b/test cases/rewrite/2 subdirs/rmTgt.json index 73a7b1dba..9b112f98b 100644 --- a/test cases/rewrite/2 subdirs/rmTgt.json +++ b/test cases/rewrite/2 subdirs/rmTgt.json @@ -2,6 +2,6 @@ { "type": "target", "target": "something", - "operation": "tgt_rm" + "operation": "target_rm" } ] -- cgit v1.2.3 From 90b557e38af2df9e68f72c96d0f22f0e7bc37e91 Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Sat, 2 Mar 2019 12:40:31 +0100 Subject: rewriter: Remove command alias --- docs/markdown/Rewriter.md | 7 +++---- mesonbuild/mesonmain.py | 2 +- mesonbuild/rewriter.py | 6 +++--- 3 files changed, 7 insertions(+), 8 deletions(-) (limited to 'docs') diff --git a/docs/markdown/Rewriter.md b/docs/markdown/Rewriter.md index 332c9f752..ce769d41b 100644 --- a/docs/markdown/Rewriter.md +++ b/docs/markdown/Rewriter.md @@ -26,10 +26,9 @@ frontends, etc.) ## Using the rewriter -All rewriter functions are accessed via `meson rewrite` (or the rewriter alias -`meson rw`). The meson rewriter assumes that it is run inside the project root -directory. If this isn't the case, use `--sourcedir` to specify the actual -project source directory. +All rewriter functions are accessed via `meson rewrite`. The meson rewriter +assumes that it is run inside the project root directory. If this isn't the +case, use `--sourcedir` to specify the actual project source directory. ### Adding and removing sources diff --git a/mesonbuild/mesonmain.py b/mesonbuild/mesonmain.py index bd19da541..822a943c1 100644 --- a/mesonbuild/mesonmain.py +++ b/mesonbuild/mesonmain.py @@ -57,7 +57,7 @@ class CommandLineParser: self.add_command('help', self.add_help_arguments, self.run_help_command, help='Print help of a subcommand') self.add_command('rewrite', lambda parser: rewriter.add_arguments(parser, self.formater), rewriter.run, - help='Modify the project definition', aliases=['rw']) + help='Modify the project definition') # Hidden commands self.add_command('runpython', self.add_runpython_arguments, self.run_runpython_command, diff --git a/mesonbuild/rewriter.py b/mesonbuild/rewriter.py index 196fc3b79..a47a3a1c1 100644 --- a/mesonbuild/rewriter.py +++ b/mesonbuild/rewriter.py @@ -39,7 +39,7 @@ def add_arguments(parser, formater=None): subparsers = parser.add_subparsers(dest='type', title='Rewriter commands', description='Rewrite command to execute') # Target - tgt_parser = subparsers.add_parser('target', aliases=['tgt'], help='Modify a target', formatter_class=formater) + tgt_parser = subparsers.add_parser('target', help='Modify a target', formatter_class=formater) tgt_parser.add_argument('-s', '--subdir', default='', dest='subdir', help='Subdirectory of the new target (only for the "add_target" action)') tgt_parser.add_argument('--type', dest='tgt_type', choices=rewriter_keys['target']['target_type'][2], default='executable', help='Type of the target to add (only for the "add_target" action)') @@ -58,13 +58,13 @@ def add_arguments(parser, formater=None): kw_parser.add_argument('kwargs', nargs='*', help='Pairs of keyword and value') # Default options - def_parser = subparsers.add_parser('default-options', aliases=['def'], help='Modify the project default options', formatter_class=formater) + def_parser = subparsers.add_parser('default-options', help='Modify the project default options', formatter_class=formater) def_parser.add_argument('operation', choices=rewriter_keys['default_options']['operation'][2], help='Action to execute') def_parser.add_argument('options', nargs='*', help='Key, value pairs of configuration option') # JSON file/command - cmd_parser = subparsers.add_parser('command', aliases=['cmd'], help='Execute a JSON array of commands', formatter_class=formater) + cmd_parser = subparsers.add_parser('command', help='Execute a JSON array of commands', formatter_class=formater) cmd_parser.add_argument('json', help='JSON string or file to execute') class RequiredKeys: -- cgit v1.2.3 From ff5e7eb104d015c462fdae2de76c967bf00c27ad Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Sat, 2 Mar 2019 17:03:51 +0100 Subject: rewriter: Updated docs --- docs/markdown/Rewriter.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs') diff --git a/docs/markdown/Rewriter.md b/docs/markdown/Rewriter.md index ce769d41b..b88b4a8bd 100644 --- a/docs/markdown/Rewriter.md +++ b/docs/markdown/Rewriter.md @@ -61,9 +61,9 @@ src = ['main.cpp', 'fileA.cpp', 'fileB.cpp'] exe1 = executable('testExe', src) ``` -In this case, `exe1` could also have been used for the target name, since the -rewriter also takes assignments and internal meson IDs into consideration when -searching for the target in the `meson.build` files. +In this case, `exe1` could also have been used for the target name. This is +possible because the rewriter also searches for assignments and unique meson +IDs, which can be acquired with introspection. For more information see the help output of the rewriter target command. -- cgit v1.2.3 From e724fd5438a20836be1b270c1f851502ac97fdd4 Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Sat, 2 Mar 2019 17:41:25 +0100 Subject: rewriter: Handle duplicate target --- docs/markdown/Rewriter.md | 3 ++- mesonbuild/ast/interpreter.py | 5 +++-- mesonbuild/ast/introspection.py | 7 ++++--- mesonbuild/rewriter.py | 24 ++++++++++++++-------- run_unittests.py | 9 ++++++++ test cases/rewrite/4 same name targets/addSrc.json | 8 ++++++++ test cases/rewrite/4 same name targets/info.json | 12 +++++++++++ test cases/rewrite/4 same name targets/meson.build | 6 ++++++ .../rewrite/4 same name targets/sub1/meson.build | 3 +++ 9 files changed, 63 insertions(+), 14 deletions(-) create mode 100644 test cases/rewrite/4 same name targets/addSrc.json create mode 100644 test cases/rewrite/4 same name targets/info.json create mode 100644 test cases/rewrite/4 same name targets/meson.build create mode 100644 test cases/rewrite/4 same name targets/sub1/meson.build (limited to 'docs') diff --git a/docs/markdown/Rewriter.md b/docs/markdown/Rewriter.md index b88b4a8bd..8d465973e 100644 --- a/docs/markdown/Rewriter.md +++ b/docs/markdown/Rewriter.md @@ -63,7 +63,8 @@ exe1 = executable('testExe', src) In this case, `exe1` could also have been used for the target name. This is possible because the rewriter also searches for assignments and unique meson -IDs, which can be acquired with introspection. +IDs, which can be acquired with introspection. If there are multiple targets +with the same name, meson will do nothing and print an error message. For more information see the help output of the rewriter target command. diff --git a/mesonbuild/ast/interpreter.py b/mesonbuild/ast/interpreter.py index b2cd3f53e..01277f08f 100644 --- a/mesonbuild/ast/interpreter.py +++ b/mesonbuild/ast/interpreter.py @@ -51,6 +51,7 @@ class AstInterpreter(interpreterbase.InterpreterBase): self.visitors = visitors self.visited_subdirs = {} self.assignments = {} + self.assign_vals = {} self.reverse_assignment = {} self.funcs.update({'project': self.func_do_nothing, 'test': self.func_do_nothing, @@ -161,7 +162,7 @@ class AstInterpreter(interpreterbase.InterpreterBase): self.assignments[node.var_name] += [node.value] # Save a reference to the value node if hasattr(node.value, 'ast_id'): self.reverse_assignment[node.value.ast_id] = node - self.evaluate_statement(node.value) # Evaluate the value just in case + self.assign_vals[node.var_name] += [self.evaluate_statement(node.value)] def evaluate_indexing(self, node): return 0 @@ -200,7 +201,7 @@ class AstInterpreter(interpreterbase.InterpreterBase): self.assignments[node.var_name] = [node.value] # Save a reference to the value node if hasattr(node.value, 'ast_id'): self.reverse_assignment[node.value.ast_id] = node - self.evaluate_statement(node.value) # Evaluate the value just in case + self.assign_vals[node.var_name] = [self.evaluate_statement(node.value)] # Evaluate the value just in case def flatten_args(self, args, include_unknown_args: bool = False): # Resolve mparser.ArrayNode if needed diff --git a/mesonbuild/ast/introspection.py b/mesonbuild/ast/introspection.py index 12cb37990..5745d298a 100644 --- a/mesonbuild/ast/introspection.py +++ b/mesonbuild/ast/introspection.py @@ -194,7 +194,7 @@ class IntrospectionInterpreter(AstInterpreter): empty_sources = [] # Passing the unresolved sources list causes errors target = targetclass(name, self.subdir, self.subproject, is_cross, empty_sources, objects, self.environment, kwargs_reduced) - self.targets += [{ + new_target = { 'name': target.get_basename(), 'id': target.get_id(), 'type': target.get_typename(), @@ -206,9 +206,10 @@ class IntrospectionInterpreter(AstInterpreter): 'sources': source_nodes, 'kwargs': kwargs, 'node': node, - }] + } - return + self.targets += [new_target] + return new_target def build_library(self, node, args, kwargs): default_library = self.coredata.get_builtin_option('default_library') diff --git a/mesonbuild/rewriter.py b/mesonbuild/rewriter.py index 52c5a6f6c..2a41b2edb 100644 --- a/mesonbuild/rewriter.py +++ b/mesonbuild/rewriter.py @@ -379,23 +379,31 @@ class Rewriter: sys.stderr.write(json.dumps(self.info_dump, indent=2)) def find_target(self, target: str): - def check_list(name: str): + def check_list(name: str) -> List[BaseNode]: + result = [] for i in self.interpreter.targets: if name == i['name'] or name == i['id']: - return i - return None + result += [i] + return result - tgt = check_list(target) - if tgt is not None: - return tgt + targets = check_list(target) + if targets: + if len(targets) == 1: + return targets[0] + else: + mlog.error('There are multiple targets matching', mlog.bold(target)) + for i in targets: + mlog.error(' -- Target name', mlog.bold(i['name']), 'with ID', mlog.bold(i['id'])) + mlog.error('Please try again with the unique ID of the target --> skipping') + return None # Check the assignments + tgt = None if target in self.interpreter.assignments: node = self.interpreter.assignments[target][0] if isinstance(node, FunctionNode): if node.func_name in ['executable', 'jar', 'library', 'shared_library', 'shared_module', 'static_library', 'both_libraries']: - name = self.interpreter.flatten_args(node.args)[0] - tgt = check_list(name) + tgt = self.interpreter.assign_vals[target][0] return tgt diff --git a/run_unittests.py b/run_unittests.py index dc8ff6fe5..408a7af97 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -5401,6 +5401,15 @@ class RewriterTests(BasePlatformTests): } self.assertDictEqual(out, expected) + def test_target_same_name_skip(self): + self.prime('4 same name targets') + out = self.rewrite(self.builddir, os.path.join(self.builddir, 'addSrc.json')) + out = self.rewrite(self.builddir, os.path.join(self.builddir, 'info.json')) + expected = {'name': 'myExe', 'sources': ['main.cpp']} + self.assertEqual(len(out['target']), 2) + for _, val in out['target'].items(): + self.assertDictEqual(expected, val) + def test_kwargs_info(self): self.prime('3 kwargs') out = self.rewrite(self.builddir, os.path.join(self.builddir, 'info.json')) diff --git a/test cases/rewrite/4 same name targets/addSrc.json b/test cases/rewrite/4 same name targets/addSrc.json new file mode 100644 index 000000000..98d0d1ebf --- /dev/null +++ b/test cases/rewrite/4 same name targets/addSrc.json @@ -0,0 +1,8 @@ +[ + { + "type": "target", + "target": "myExe", + "operation": "src_add", + "sources": ["a1.cpp", "a2.cpp"] + } +] diff --git a/test cases/rewrite/4 same name targets/info.json b/test cases/rewrite/4 same name targets/info.json new file mode 100644 index 000000000..a9fc2ddc6 --- /dev/null +++ b/test cases/rewrite/4 same name targets/info.json @@ -0,0 +1,12 @@ +[ + { + "type": "target", + "target": "exe1", + "operation": "info" + }, + { + "type": "target", + "target": "exe2", + "operation": "info" + } +] diff --git a/test cases/rewrite/4 same name targets/meson.build b/test cases/rewrite/4 same name targets/meson.build new file mode 100644 index 000000000..384fa2b4e --- /dev/null +++ b/test cases/rewrite/4 same name targets/meson.build @@ -0,0 +1,6 @@ +project('rewrite same name targets', 'cpp') + +src1 = ['main.cpp'] + +exe1 = executable('myExe', src1) +subdir('sub1') diff --git a/test cases/rewrite/4 same name targets/sub1/meson.build b/test cases/rewrite/4 same name targets/sub1/meson.build new file mode 100644 index 000000000..ac53667ae --- /dev/null +++ b/test cases/rewrite/4 same name targets/sub1/meson.build @@ -0,0 +1,3 @@ +src2 = ['main.cpp'] + +exe2 = executable('myExe', src2) -- cgit v1.2.3 From dd5791309e7dcd0a156063784a60245d8088da14 Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Sun, 3 Mar 2019 09:18:48 +0100 Subject: rewriter: Document info operation --- docs/markdown/Rewriter.md | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'docs') diff --git a/docs/markdown/Rewriter.md b/docs/markdown/Rewriter.md index 8d465973e..30e0bc1e2 100644 --- a/docs/markdown/Rewriter.md +++ b/docs/markdown/Rewriter.md @@ -219,3 +219,13 @@ The format for the type `default_options` is defined as follows: ``` For operation `delete`, the values of the `options` can be anything (including `null`) + +## Extracting information + +The rewriter also offers operation `info` for the types `target` and `kwargs`. +When this operation is used, meson will print a JSON dump to stderr, containing +all available information to the rewriter about the build target / function +kwargs in question. + +The output format is guaranteed to be backwards compatible, but new keys may be +added in the future. -- cgit v1.2.3 From 0a3b91c1c9f8ae6d8db6a20e25c862766ea09f2c Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Sun, 3 Mar 2019 10:53:36 +0100 Subject: rewriter: Mark the info output as experimental --- docs/markdown/Rewriter.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'docs') diff --git a/docs/markdown/Rewriter.md b/docs/markdown/Rewriter.md index 30e0bc1e2..f143ac066 100644 --- a/docs/markdown/Rewriter.md +++ b/docs/markdown/Rewriter.md @@ -227,5 +227,4 @@ When this operation is used, meson will print a JSON dump to stderr, containing all available information to the rewriter about the build target / function kwargs in question. -The output format is guaranteed to be backwards compatible, but new keys may be -added in the future. +The output format is currently experimental and may change in the future. -- cgit v1.2.3 From 976c136ab6897809ba94bd1ada1a8cd831236cfa Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Sun, 3 Mar 2019 11:13:11 +0100 Subject: rewriter: Mark the CLI as experimental --- docs/markdown/Rewriter.md | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'docs') diff --git a/docs/markdown/Rewriter.md b/docs/markdown/Rewriter.md index f143ac066..73611e951 100644 --- a/docs/markdown/Rewriter.md +++ b/docs/markdown/Rewriter.md @@ -24,6 +24,12 @@ normal CLI is mostly designed for everyday use. The "script mode", on the other hand, is meant to be used by external programs (IDEs, graphical frontends, etc.) +The rewriter itself is considered stable, however the user interface and the +"script mode" API might change in the future. These changes may also break +backwards comaptibility to older releases. + +We are also open to suggestions for API improvements. + ## Using the rewriter All rewriter functions are accessed via `meson rewrite`. The meson rewriter -- cgit v1.2.3 From 594bf678c7aaf676ce02d7d8a7d33e04c42c6b39 Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Sun, 3 Mar 2019 14:58:36 +0100 Subject: rewriter: Require '/' for the project ID --- docs/markdown/Rewriter.md | 4 ++-- mesonbuild/rewriter.py | 2 +- run_unittests.py | 16 ++++++++-------- test cases/rewrite/3 kwargs/add.json | 6 +++--- test cases/rewrite/3 kwargs/defopts_delete.json | 2 +- test cases/rewrite/3 kwargs/info.json | 2 +- test cases/rewrite/3 kwargs/remove.json | 6 +++--- test cases/rewrite/3 kwargs/remove_regex.json | 4 ++-- test cases/rewrite/3 kwargs/set.json | 2 +- 9 files changed, 22 insertions(+), 22 deletions(-) (limited to 'docs') diff --git a/docs/markdown/Rewriter.md b/docs/markdown/Rewriter.md index 73611e951..b6301d637 100644 --- a/docs/markdown/Rewriter.md +++ b/docs/markdown/Rewriter.md @@ -86,14 +86,14 @@ meson rewriter kwargs {set/delete} For instance, setting the project version can be achieved with this command: ```bash -meson rewriter kwargs set project '' version 1.0.0 +meson rewriter kwargs set project / version 1.0.0 ``` Currently, only the following function types are supported: - dependency - target (any build target, the function ID is the target name/ID) -- project (the function ID must be an empty string since project() can only be called once) +- project (the function ID must be `/` since project() can only be called once) For more information see the help output of the rewriter kwargs command. diff --git a/mesonbuild/rewriter.py b/mesonbuild/rewriter.py index 2e50f2073..6a97dd063 100644 --- a/mesonbuild/rewriter.py +++ b/mesonbuild/rewriter.py @@ -500,7 +500,7 @@ class Rewriter: node = None arg_node = None if cmd['function'] == 'project': - if cmd['id'] != '': + if cmd['id'] != '/': mlog.error('The ID for the function type project must be an empty string', *self.on_error()) self.handle_error() node = self.interpreter.project_node diff --git a/run_unittests.py b/run_unittests.py index 2471e4439..dba957a3e 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -5415,7 +5415,7 @@ class RewriterTests(BasePlatformTests): out = self.rewrite(self.builddir, os.path.join(self.builddir, 'info.json')) expected = { 'kwargs': { - 'project#': {'version': '0.0.1'}, + 'project#/': {'version': '0.0.1'}, 'target#tgt1': {'build_by_default': True}, 'dependency#dep1': {'required': False} } @@ -5428,7 +5428,7 @@ class RewriterTests(BasePlatformTests): out = self.rewrite(self.builddir, os.path.join(self.builddir, 'info.json')) expected = { 'kwargs': { - 'project#': {'version': '0.0.2', 'meson_version': '0.50.0', 'license': ['GPL', 'MIT']}, + 'project#/': {'version': '0.0.2', 'meson_version': '0.50.0', 'license': ['GPL', 'MIT']}, 'target#tgt1': {'build_by_default': False, 'build_rpath': '/usr/local', 'dependencies': 'dep1'}, 'dependency#dep1': {'required': True, 'method': 'cmake'} } @@ -5441,7 +5441,7 @@ class RewriterTests(BasePlatformTests): out = self.rewrite(self.builddir, os.path.join(self.builddir, 'info.json')) expected = { 'kwargs': { - 'project#': {'version': '0.0.1', 'license': ['GPL', 'MIT', 'BSD']}, + 'project#/': {'version': '0.0.1', 'license': ['GPL', 'MIT', 'BSD']}, 'target#tgt1': {'build_by_default': True}, 'dependency#dep1': {'required': False} } @@ -5454,7 +5454,7 @@ class RewriterTests(BasePlatformTests): out = self.rewrite(self.builddir, os.path.join(self.builddir, 'info.json')) expected = { 'kwargs': { - 'project#': {'version': '0.0.1', 'license': 'GPL'}, + 'project#/': {'version': '0.0.1', 'license': 'GPL'}, 'target#tgt1': {'build_by_default': True}, 'dependency#dep1': {'required': False} } @@ -5467,7 +5467,7 @@ class RewriterTests(BasePlatformTests): out = self.rewrite(self.builddir, os.path.join(self.builddir, 'info.json')) expected = { 'kwargs': { - 'project#': {'version': '0.0.1', 'default_options': ['buildtype=release', 'debug=true']}, + 'project#/': {'version': '0.0.1', 'default_options': ['buildtype=release', 'debug=true']}, 'target#tgt1': {'build_by_default': True}, 'dependency#dep1': {'required': False} } @@ -5480,7 +5480,7 @@ class RewriterTests(BasePlatformTests): out = self.rewrite(self.builddir, os.path.join(self.builddir, 'info.json')) expected = { 'kwargs': { - 'project#': {}, + 'project#/': {}, 'target#tgt1': {}, 'dependency#dep1': {'required': False} } @@ -5493,7 +5493,7 @@ class RewriterTests(BasePlatformTests): out = self.rewrite(self.builddir, os.path.join(self.builddir, 'info.json')) expected = { 'kwargs': { - 'project#': {'version': '0.0.1', 'default_options': ['buildtype=release', 'debug=True', 'cpp_std=c++11']}, + 'project#/': {'version': '0.0.1', 'default_options': ['buildtype=release', 'debug=True', 'cpp_std=c++11']}, 'target#tgt1': {'build_by_default': True}, 'dependency#dep1': {'required': False} } @@ -5506,7 +5506,7 @@ class RewriterTests(BasePlatformTests): out = self.rewrite(self.builddir, os.path.join(self.builddir, 'info.json')) expected = { 'kwargs': { - 'project#': {'version': '0.0.1', 'default_options': ['cpp_std=c++14', 'debug=true']}, + 'project#/': {'version': '0.0.1', 'default_options': ['cpp_std=c++14', 'debug=true']}, 'target#tgt1': {'build_by_default': True}, 'dependency#dep1': {'required': False} } diff --git a/test cases/rewrite/3 kwargs/add.json b/test cases/rewrite/3 kwargs/add.json index e398b7bbe..2148a1e49 100644 --- a/test cases/rewrite/3 kwargs/add.json +++ b/test cases/rewrite/3 kwargs/add.json @@ -2,7 +2,7 @@ { "type": "kwargs", "function": "project", - "id": "", + "id": "/", "operation": "set", "kwargs": { "license": "GPL" @@ -11,7 +11,7 @@ { "type": "kwargs", "function": "project", - "id": "", + "id": "/", "operation": "add", "kwargs": { "license": ["MIT"] @@ -20,7 +20,7 @@ { "type": "kwargs", "function": "project", - "id": "", + "id": "/", "operation": "add", "kwargs": { "license": "BSD" diff --git a/test cases/rewrite/3 kwargs/defopts_delete.json b/test cases/rewrite/3 kwargs/defopts_delete.json index 06232dd12..4fe39e2a2 100644 --- a/test cases/rewrite/3 kwargs/defopts_delete.json +++ b/test cases/rewrite/3 kwargs/defopts_delete.json @@ -2,7 +2,7 @@ { "type": "kwargs", "function": "project", - "id": "", + "id": "/", "operation": "set", "kwargs": { "default_options": ["cpp_std=c++14", "buildtype=release", "debug=true"] diff --git a/test cases/rewrite/3 kwargs/info.json b/test cases/rewrite/3 kwargs/info.json index 5fd1a6428..0eed4048e 100644 --- a/test cases/rewrite/3 kwargs/info.json +++ b/test cases/rewrite/3 kwargs/info.json @@ -2,7 +2,7 @@ { "type": "kwargs", "function": "project", - "id": "", + "id": "/", "operation": "info" }, { diff --git a/test cases/rewrite/3 kwargs/remove.json b/test cases/rewrite/3 kwargs/remove.json index bd7596f04..5dc783667 100644 --- a/test cases/rewrite/3 kwargs/remove.json +++ b/test cases/rewrite/3 kwargs/remove.json @@ -2,7 +2,7 @@ { "type": "kwargs", "function": "project", - "id": "", + "id": "/", "operation": "set", "kwargs": { "license": ["GPL", "MIT", "BSD"] @@ -11,7 +11,7 @@ { "type": "kwargs", "function": "project", - "id": "", + "id": "/", "operation": "remove", "kwargs": { "license": ["MIT"] @@ -20,7 +20,7 @@ { "type": "kwargs", "function": "project", - "id": "", + "id": "/", "operation": "remove", "kwargs": { "license": "BSD" diff --git a/test cases/rewrite/3 kwargs/remove_regex.json b/test cases/rewrite/3 kwargs/remove_regex.json index fcb04ebc0..104310158 100644 --- a/test cases/rewrite/3 kwargs/remove_regex.json +++ b/test cases/rewrite/3 kwargs/remove_regex.json @@ -2,7 +2,7 @@ { "type": "kwargs", "function": "project", - "id": "", + "id": "/", "operation": "set", "kwargs": { "default_options": ["cpp_std=c++14", "buildtype=release", "debug=true"] @@ -11,7 +11,7 @@ { "type": "kwargs", "function": "project", - "id": "", + "id": "/", "operation": "remove_regex", "kwargs": { "default_options": ["cpp_std=.*"] diff --git a/test cases/rewrite/3 kwargs/set.json b/test cases/rewrite/3 kwargs/set.json index 7d60c4f42..a56c5991d 100644 --- a/test cases/rewrite/3 kwargs/set.json +++ b/test cases/rewrite/3 kwargs/set.json @@ -2,7 +2,7 @@ { "type": "kwargs", "function": "project", - "id": "", + "id": "/", "operation": "set", "kwargs": { "version": "0.0.2", -- cgit v1.2.3