Merge pull request #4939 from mensinda/rwDefOpts

rewriter: Set and delete project default options
pull/4988/head
Jussi Pakkanen 6 years ago committed by GitHub
commit 97555cf6d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 99
      mesonbuild/rewriter.py
  2. 42
      run_unittests.py
  3. 18
      test cases/rewrite/3 kwargs/defopts_delete.json
  4. 24
      test cases/rewrite/3 kwargs/defopts_set.json
  5. 20
      test cases/rewrite/3 kwargs/remove_regex.json

@ -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,18 +221,29 @@ class MTypeList(MTypeBase):
removed_list += [i]
self.node.args.arguments = removed_list
class MtypeStrList(MTypeList):
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)
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,19 +254,28 @@ 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]
rewriter_keys = {
'default_options': {
'operation': (str, None, ['set', 'delete']),
'options': (dict, {}, None)
},
'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': {
@ -268,8 +296,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 +313,9 @@ rewriter_func_kwargs = {
'pie': MTypeBool
},
'project': {
'default_options': MTypeStrList,
'meson_version': MTypeStr,
'license': MtypeStrList,
'license': MTypeStrList,
'subproject_dir': MTypeStr,
'version': MTypeStr
}
@ -300,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,
}
@ -368,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'] + "'"))
@ -450,6 +524,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()

@ -5310,6 +5310,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'))
@ -5324,6 +5338,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++14', 'debug=true']},
'target#tgt1': {'build_by_default': True},
'dependency#dep1': {'required': False}
}
}
self.assertDictEqual(out, expected)
class NativeFileTests(BasePlatformTests):
def setUp(self):

@ -0,0 +1,18 @@
[
{
"type": "kwargs",
"function": "project",
"id": "",
"operation": "set",
"kwargs": {
"default_options": ["cpp_std=c++14", "buildtype=release", "debug=true"]
}
},
{
"type": "default_options",
"operation": "delete",
"options": {
"buildtype": null
}
}
]

@ -0,0 +1,24 @@
[
{
"type": "default_options",
"operation": "set",
"options": {
"cpp_std": "c++14"
}
},
{
"type": "default_options",
"operation": "set",
"options": {
"buildtype": "release",
"debug": true
}
},
{
"type": "default_options",
"operation": "set",
"options": {
"cpp_std": "c++11"
}
}
]

@ -0,0 +1,20 @@
[
{
"type": "kwargs",
"function": "project",
"id": "",
"operation": "set",
"kwargs": {
"default_options": ["cpp_std=c++14", "buildtype=release", "debug=true"]
}
},
{
"type": "kwargs",
"function": "project",
"id": "",
"operation": "remove_regex",
"kwargs": {
"default_options": ["cpp_std=.*"]
}
}
]
Loading…
Cancel
Save