From e37d32aa9dfa1cac47b6f50a86b25b0317d58c3a Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Sat, 16 Feb 2019 14:48:11 +0100 Subject: rewriter: Basic default_options support --- mesonbuild/rewriter.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/mesonbuild/rewriter.py b/mesonbuild/rewriter.py index fa26571..2bb1bc7 100644 --- a/mesonbuild/rewriter.py +++ b/mesonbuild/rewriter.py @@ -213,7 +213,7 @@ class MTypeList(MTypeBase): removed_list += [i] self.node.args.arguments = removed_list -class MtypeStrList(MTypeList): +class MTypeStrList(MTypeList): def __init__(self, node: mparser.BaseNode): super().__init__(node) @@ -268,8 +268,8 @@ rewriter_func_kwargs = { 'not_found_message': MTypeStr, 'required': MTypeBool, 'static': MTypeBool, - 'version': MtypeStrList, - 'modules': MtypeStrList + 'version': MTypeStrList, + 'modules': MTypeStrList }, 'target': { 'build_by_default': MTypeBool, @@ -285,8 +285,9 @@ rewriter_func_kwargs = { 'pie': MTypeBool }, 'project': { + 'default_options': MTypeStrList, 'meson_version': MTypeStr, - 'license': MtypeStrList, + 'license': MTypeStrList, 'subproject_dir': MTypeStr, 'version': MTypeStr } -- cgit v1.1 From 74bb79e26e17acbf6176e32089e7e27991f5d2d3 Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Sat, 16 Feb 2019 18:09:54 +0100 Subject: rewriter: Remove matching regex from list --- mesonbuild/rewriter.py | 41 ++++++++++++++++++++++----- run_unittests.py | 14 +++++++++ test cases/rewrite/3 kwargs/remove_regex.json | 20 +++++++++++++ 3 files changed, 68 insertions(+), 7 deletions(-) create mode 100644 test cases/rewrite/3 kwargs/remove_regex.json diff --git a/mesonbuild/rewriter.py b/mesonbuild/rewriter.py index 2bb1bc7..5c13471 100644 --- a/mesonbuild/rewriter.py +++ b/mesonbuild/rewriter.py @@ -29,7 +29,7 @@ from . import mlog, mparser, environment from functools import wraps from pprint import pprint from .mparser import Token, ArrayNode, ArgumentNode, AssignmentNode, IdNode, FunctionNode, StringNode -import json, os +import json, os, re class RewriterException(MesonException): pass @@ -109,6 +109,10 @@ class MTypeBase: # Overwrite in derived class mlog.warning('Cannot remove a value of type', mlog.bold(type(self).__name__), '--> skipping') + def remove_regex(self, value): + # Overwrite in derived class + mlog.warning('Cannot remove a regex in type', mlog.bold(type(self).__name__), '--> skipping') + class MTypeStr(MTypeBase): def __init__(self, node: mparser.BaseNode): super().__init__(node) @@ -165,7 +169,11 @@ class MTypeList(MTypeBase): self.node = self._new_node() self.node.args.arguments += [tmp] - def _check_is_equal(self, node, value): + def _check_is_equal(self, node, value) -> bool: + # Overwrite in derived class + return False + + def _check_regex_matches(self, node, regex: str) -> bool: # Overwrite in derived class return False @@ -197,10 +205,10 @@ class MTypeList(MTypeBase): for i in value: self.node.args.arguments += [self._new_element_node(i)] - def remove_value(self, value): + def _remove_helper(self, value, equal_func): def check_remove_node(node): for j in value: - if self._check_is_equal(i, j): + if equal_func(i, j): return True return False @@ -213,6 +221,12 @@ class MTypeList(MTypeBase): removed_list += [i] self.node.args.arguments = removed_list + def remove_value(self, value): + self._remove_helper(value, self._check_is_equal) + + def remove_regex(self, regex: str): + self._remove_helper(regex, self._check_regex_matches) + class MTypeStrList(MTypeList): def __init__(self, node: mparser.BaseNode): super().__init__(node) @@ -220,11 +234,16 @@ class MTypeStrList(MTypeList): def _new_element_node(self, value): return mparser.StringNode(mparser.Token('', '', 0, 0, 0, None, str(value))) - def _check_is_equal(self, node, value): + def _check_is_equal(self, node, value) -> bool: if isinstance(node, mparser.StringNode): return node.value == value return False + def _check_regex_matches(self, node, regex: str) -> bool: + if isinstance(node, mparser.StringNode): + return re.match(regex, node.value) is not None + return False + def supported_element_nodes(self): return [mparser.StringNode] @@ -235,11 +254,16 @@ class MTypeIDList(MTypeList): def _new_element_node(self, value): return mparser.IdNode(mparser.Token('', '', 0, 0, 0, None, str(value))) - def _check_is_equal(self, node, value): + def _check_is_equal(self, node, value) -> bool: if isinstance(node, mparser.IdNode): return node.value == value return False + def _check_regex_matches(self, node, regex: str) -> bool: + if isinstance(node, mparser.StringNode): + return re.match(regex, node.value) is not None + return False + def supported_element_nodes(self): return [mparser.IdNode] @@ -247,7 +271,7 @@ rewriter_keys = { 'kwargs': { 'function': (str, None, None), 'id': (str, None, None), - 'operation': (str, None, ['set', 'delete', 'add', 'remove', 'info']), + 'operation': (str, None, ['set', 'delete', 'add', 'remove', 'remove_regex', 'info']), 'kwargs': (dict, {}, None) }, 'target': { @@ -451,6 +475,9 @@ class Rewriter: elif cmd['operation'] == 'remove': mlog.log(' -- Removing', mlog.yellow(val_str), 'from', mlog.bold(key)) modifyer.remove_value(val) + elif cmd['operation'] == 'remove_regex': + mlog.log(' -- Removing all values matching', mlog.yellow(val_str), 'from', mlog.bold(key)) + modifyer.remove_regex(val) # Write back the result arg_node.kwargs[key] = modifyer.get_node() diff --git a/run_unittests.py b/run_unittests.py index fbd51df..57b19e1 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -5299,6 +5299,20 @@ class RewriterTests(BasePlatformTests): } self.assertDictEqual(out, expected) + def test_kwargs_remove_regex(self): + self.prime('3 kwargs') + self.rewrite(self.builddir, os.path.join(self.builddir, 'remove_regex.json')) + out = self.rewrite(self.builddir, os.path.join(self.builddir, 'info.json')) + out = self.extract_test_data(out) + expected = { + 'kwargs': { + 'project#': {'version': '0.0.1', 'default_options': ['buildtype=release', 'debug=true']}, + 'target#tgt1': {'build_by_default': True}, + 'dependency#dep1': {'required': False} + } + } + self.assertDictEqual(out, expected) + def test_kwargs_delete(self): self.prime('3 kwargs') self.rewrite(self.builddir, os.path.join(self.builddir, 'delete.json')) diff --git a/test cases/rewrite/3 kwargs/remove_regex.json b/test cases/rewrite/3 kwargs/remove_regex.json new file mode 100644 index 0000000..a938ae0 --- /dev/null +++ b/test cases/rewrite/3 kwargs/remove_regex.json @@ -0,0 +1,20 @@ +[ + { + "type": "kwargs", + "function": "project", + "id": "", + "operation": "set", + "kwargs": { + "default_options": ["cpp_std=c++17", "buildtype=release", "debug=true"] + } + }, + { + "type": "kwargs", + "function": "project", + "id": "", + "operation": "remove_regex", + "kwargs": { + "default_options": ["cpp_std=.*"] + } + } +] -- cgit v1.1 From 9e247cb52e65dd62450990fbb9a2c3935e8f11ab Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Sat, 16 Feb 2019 19:57:50 +0100 Subject: rewriter: Set and delete default options --- mesonbuild/rewriter.py | 49 +++++++++++++++++++++++++ run_unittests.py | 28 ++++++++++++++ test cases/rewrite/3 kwargs/defopts_delete.json | 18 +++++++++ test cases/rewrite/3 kwargs/defopts_set.json | 24 ++++++++++++ 4 files changed, 119 insertions(+) create mode 100644 test cases/rewrite/3 kwargs/defopts_delete.json create mode 100644 test cases/rewrite/3 kwargs/defopts_set.json diff --git a/mesonbuild/rewriter.py b/mesonbuild/rewriter.py index 5c13471..f5f8b61 100644 --- a/mesonbuild/rewriter.py +++ b/mesonbuild/rewriter.py @@ -268,6 +268,10 @@ class MTypeIDList(MTypeList): return [mparser.IdNode] rewriter_keys = { + 'default_options': { + 'operation': (str, None, ['set', 'delete']), + 'options': (dict, {}, None) + }, 'kwargs': { 'function': (str, None, None), 'id': (str, None, None), @@ -325,6 +329,7 @@ class Rewriter: self.to_remove_nodes = [] self.to_add_nodes = [] self.functions = { + 'default_options': self.process_default_options, 'kwargs': self.process_kwargs, 'target': self.process_target, } @@ -393,6 +398,50 @@ class Rewriter: return dep + @RequiredKeys(rewriter_keys['default_options']) + def process_default_options(self, cmd): + # First, remove the old values + kwargs_cmd = { + 'function': 'project', + 'id': "", + 'operation': 'remove_regex', + 'kwargs': { + 'default_options': ['{}=.*'.format(x) for x in cmd['options'].keys()] + } + } + self.process_kwargs(kwargs_cmd) + + # Then add the new values + if cmd['operation'] != 'set': + return + + kwargs_cmd['operation'] = 'add' + kwargs_cmd['kwargs']['default_options'] = [] + + cdata = self.interpreter.coredata + options = { + **cdata.builtins, + **cdata.backend_options, + **cdata.base_options, + **cdata.compiler_options.build, + **cdata.user_options + } + + for key, val in cmd['options'].items(): + if key not in options: + mlog.error('Unknown options', mlog.bold(key), '--> skipping') + continue + + try: + val = options[key].validate_value(val) + except MesonException as e: + mlog.error('Unable to set', mlog.bold(key), mlog.red(str(e)), '--> skipping') + continue + + kwargs_cmd['kwargs']['default_options'] += ['{}={}'.format(key, val)] + + self.process_kwargs(kwargs_cmd) + @RequiredKeys(rewriter_keys['kwargs']) def process_kwargs(self, cmd): mlog.log('Processing function type', mlog.bold(cmd['function']), 'with id', mlog.cyan("'" + cmd['id'] + "'")) diff --git a/run_unittests.py b/run_unittests.py index 57b19e1..272a38b 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -5327,6 +5327,34 @@ class RewriterTests(BasePlatformTests): } self.assertDictEqual(out, expected) + def test_default_options_set(self): + self.prime('3 kwargs') + self.rewrite(self.builddir, os.path.join(self.builddir, 'defopts_set.json')) + out = self.rewrite(self.builddir, os.path.join(self.builddir, 'info.json')) + out = self.extract_test_data(out) + expected = { + 'kwargs': { + '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} + } + } + self.assertDictEqual(out, expected) + + def test_default_options_delete(self): + self.prime('3 kwargs') + self.rewrite(self.builddir, os.path.join(self.builddir, 'defopts_delete.json')) + out = self.rewrite(self.builddir, os.path.join(self.builddir, 'info.json')) + out = self.extract_test_data(out) + expected = { + 'kwargs': { + 'project#': {'version': '0.0.1', 'default_options': ['cpp_std=c++17', 'debug=true']}, + 'target#tgt1': {'build_by_default': True}, + 'dependency#dep1': {'required': False} + } + } + self.assertDictEqual(out, expected) + class NativeFileTests(BasePlatformTests): def setUp(self): diff --git a/test cases/rewrite/3 kwargs/defopts_delete.json b/test cases/rewrite/3 kwargs/defopts_delete.json new file mode 100644 index 0000000..0ed6d92 --- /dev/null +++ b/test cases/rewrite/3 kwargs/defopts_delete.json @@ -0,0 +1,18 @@ +[ + { + "type": "kwargs", + "function": "project", + "id": "", + "operation": "set", + "kwargs": { + "default_options": ["cpp_std=c++17", "buildtype=release", "debug=true"] + } + }, + { + "type": "default_options", + "operation": "delete", + "options": { + "buildtype": null + } + } +] diff --git a/test cases/rewrite/3 kwargs/defopts_set.json b/test cases/rewrite/3 kwargs/defopts_set.json new file mode 100644 index 0000000..ce67ac1 --- /dev/null +++ b/test cases/rewrite/3 kwargs/defopts_set.json @@ -0,0 +1,24 @@ +[ + { + "type": "default_options", + "operation": "set", + "options": { + "cpp_std": "c++17" + } + }, + { + "type": "default_options", + "operation": "set", + "options": { + "buildtype": "release", + "debug": true + } + }, + { + "type": "default_options", + "operation": "set", + "options": { + "cpp_std": "c++11" + } + } +] -- cgit v1.1 From 16b6b2d41196367084b9a7ed3392ca1d427e6bd7 Mon Sep 17 00:00:00 2001 From: Daniel Mensinger Date: Sat, 16 Feb 2019 20:34:30 +0100 Subject: Use c++14 instead of c++17 in the tests --- run_unittests.py | 2 +- test cases/rewrite/3 kwargs/defopts_delete.json | 2 +- test cases/rewrite/3 kwargs/defopts_set.json | 2 +- test cases/rewrite/3 kwargs/remove_regex.json | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/run_unittests.py b/run_unittests.py index 272a38b..e6df87a 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -5348,7 +5348,7 @@ class RewriterTests(BasePlatformTests): out = self.extract_test_data(out) expected = { 'kwargs': { - 'project#': {'version': '0.0.1', 'default_options': ['cpp_std=c++17', '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/defopts_delete.json b/test cases/rewrite/3 kwargs/defopts_delete.json index 0ed6d92..06232dd 100644 --- a/test cases/rewrite/3 kwargs/defopts_delete.json +++ b/test cases/rewrite/3 kwargs/defopts_delete.json @@ -5,7 +5,7 @@ "id": "", "operation": "set", "kwargs": { - "default_options": ["cpp_std=c++17", "buildtype=release", "debug=true"] + "default_options": ["cpp_std=c++14", "buildtype=release", "debug=true"] } }, { diff --git a/test cases/rewrite/3 kwargs/defopts_set.json b/test cases/rewrite/3 kwargs/defopts_set.json index ce67ac1..f8f855f 100644 --- a/test cases/rewrite/3 kwargs/defopts_set.json +++ b/test cases/rewrite/3 kwargs/defopts_set.json @@ -3,7 +3,7 @@ "type": "default_options", "operation": "set", "options": { - "cpp_std": "c++17" + "cpp_std": "c++14" } }, { diff --git a/test cases/rewrite/3 kwargs/remove_regex.json b/test cases/rewrite/3 kwargs/remove_regex.json index a938ae0..fcb04eb 100644 --- a/test cases/rewrite/3 kwargs/remove_regex.json +++ b/test cases/rewrite/3 kwargs/remove_regex.json @@ -5,7 +5,7 @@ "id": "", "operation": "set", "kwargs": { - "default_options": ["cpp_std=c++17", "buildtype=release", "debug=true"] + "default_options": ["cpp_std=c++14", "buildtype=release", "debug=true"] } }, { -- cgit v1.1