rewriter: create {add,rm}_extra_files commands

Add ability to mutate a target's `extra_files` list through the
rewriter.

The logic is copied from sources add/rm, but changes the `extra_files`
kwarg instead of the sources positional argument.
Has additional logic to handle creating the `extra_files` list if it
doesn't exist.
pull/9738/head
Celeste Wouters 3 years ago committed by Daniel Mensinger
parent a2934ca9d1
commit c5148d8c73
  1. 13
      docs/markdown/Rewriter.md
  2. 26
      docs/markdown/snippets/rewriter_extra_files.md
  3. 99
      mesonbuild/rewriter.py
  4. 111
      test cases/rewrite/6 extra_files/addExtraFiles.json
  5. 57
      test cases/rewrite/6 extra_files/info.json
  6. 21
      test cases/rewrite/6 extra_files/meson.build
  7. 93
      test cases/rewrite/6 extra_files/rmExtraFiles.json
  8. 155
      unittests/rewritetests.py

@ -77,6 +77,17 @@ and print an error message.
For more information see the help output of the rewriter target
command.
### Adding and removing `extra_files`
*Since 0.61.0*
In the same way you can add and remove source files from a target, you can modify a target's
`extra_files` list:
```bash
meson rewrite target <target name/id> {add_extra_files/rm_extra_files} [list of extra files]
```
### Setting the project version
It is also possible to set kwargs of specific functions with the
@ -191,7 +202,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', 'target_rm', 'target_add', 'info']",
"operation": "one of ['src_add', 'src_rm', 'target_rm', 'target_add', 'extra_files_add', 'extra_files_rm', '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')"

@ -0,0 +1,26 @@
## `meson rewrite` can modify `extra_files`
The build script rewriter can now modify targets' `extra_files` lists,
or create them if absent. It it used in the same way as with rewriting
source lists:
```bash
meson rewrite target <target name/id> {add_extra_files/rm_extra_files} [list of extra files]
```
The rewriter's script mode also supports these actions:
```json
{
"type": "target",
"target": "<target name>",
"operation": "extra_files_add / extra_files_rm",
"sources": ["list", "of", "extra", "files", "to", "add, remove"],
}
```
## `meson rewrite target <target> info` outputs *target*'s `extra_files`
Targets' `extra_files` lists are now included in the rewriter's target info dump
as a list of file paths, in the same way `sources` are. This applies to both
`meson rewrite` CLI and script mode.

@ -46,7 +46,7 @@ def add_arguments(parser, formatter=None):
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)')
tgt_parser.add_argument('target', help='Name or ID of the target')
tgt_parser.add_argument('operation', choices=['add', 'rm', 'add_target', 'rm_target', 'info'],
tgt_parser.add_argument('operation', choices=['add', 'rm', 'add_target', 'rm_target', 'add_extra_files', 'rm_extra_files', 'info'],
help='Action to execute')
tgt_parser.add_argument('sources', nargs='*', help='Sources to add/remove')
@ -308,7 +308,7 @@ rewriter_keys = {
},
'target': {
'target': (str, None, None),
'operation': (str, None, ['src_add', 'src_rm', 'target_rm', 'target_add', 'info']),
'operation': (str, None, ['src_add', 'src_rm', 'target_rm', 'target_add', 'extra_files_add', 'extra_files_rm', 'info']),
'sources': (list, [], None),
'subdir': (str, '', None),
'target_type': (str, 'executable', ['both_libraries', 'executable', 'jar', 'library', 'shared_library', 'shared_module', 'static_library']),
@ -709,6 +709,91 @@ class Rewriter:
if root not in self.modified_nodes:
self.modified_nodes += [root]
elif cmd['operation'] == 'extra_files_add':
tgt_function: FunctionNode = target['node']
mark_array = True
try:
node = target['extra_files'][0]
except IndexError:
# Specifying `extra_files` with a list that flattens to empty gives an empty
# target['extra_files'] list, account for that.
try:
extra_files_key = next(k for k in tgt_function.args.kwargs.keys() if isinstance(k, IdNode) and k.value == 'extra_files')
node = tgt_function.args.kwargs[extra_files_key]
except StopIteration:
# Target has no extra_files kwarg, create one
node = ArrayNode(ArgumentNode(Token('', tgt_function.filename, 0, 0, 0, None, '[]')), tgt_function.end_lineno, tgt_function.end_colno, tgt_function.end_lineno, tgt_function.end_colno)
tgt_function.args.kwargs[IdNode(Token('string', tgt_function.filename, 0, 0, 0, None, 'extra_files'))] = node
mark_array = False
if tgt_function not in self.modified_nodes:
self.modified_nodes += [tgt_function]
target['extra_files'] = [node]
if isinstance(node, IdNode):
node = self.interpreter.assignments[node.value]
target['extra_files'] = [node]
if not isinstance(node, ArrayNode):
mlog.error('Target', mlog.bold(cmd['target']), 'extra_files argument must be a list', *self.on_error())
return self.handle_error()
# Generate the current extra files list
extra_files_list = []
for i in target['extra_files']:
for j in arg_list_from_node(i):
if isinstance(j, StringNode):
extra_files_list += [j.value]
# Generate the new String nodes
to_append = []
for i in sorted(set(cmd['sources'])):
if i in extra_files_list:
mlog.log(' -- Extra file', mlog.green(i), 'is already defined for the target --> skipping')
continue
mlog.log(' -- Adding extra file', mlog.green(i), 'at',
mlog.yellow(f'{node.filename}:{node.lineno}'))
token = Token('string', node.filename, 0, 0, 0, None, i)
to_append += [StringNode(token)]
# Append to the AST at the right place
arg_node = node.args
arg_node.arguments += to_append
# Mark the node as modified
if arg_node not in to_sort_nodes:
to_sort_nodes += [arg_node]
# If the extra_files array is newly created, don't mark it as its parent function node already is,
# otherwise this would cause double modification.
if mark_array and node not in self.modified_nodes:
self.modified_nodes += [node]
elif cmd['operation'] == 'extra_files_rm':
# Helper to find the exact string node and its parent
def find_node(src):
for i in target['extra_files']:
for j in arg_list_from_node(i):
if isinstance(j, StringNode):
if j.value == src:
return i, j
return None, None
for i in cmd['sources']:
# Try to find the node with the source string
root, string_node = find_node(i)
if root is None:
mlog.warning(' -- Unable to find extra file', mlog.green(i), 'in the target')
continue
# Remove the found string node from the argument list
arg_node = root.args
mlog.log(' -- Removing extra file', mlog.green(i), 'from',
mlog.yellow(f'{string_node.filename}:{string_node.lineno}'))
arg_node.arguments.remove(string_node)
# Mark the node as modified
if arg_node not in to_sort_nodes and not isinstance(root, FunctionNode):
to_sort_nodes += [arg_node]
if root not in self.modified_nodes:
self.modified_nodes += [root]
elif cmd['operation'] == 'target_add':
if target is not None:
mlog.error('Can not add target', mlog.bold(cmd['target']), 'because it already exists', *self.on_error())
@ -756,9 +841,15 @@ class Rewriter:
for j in arg_list_from_node(i):
if isinstance(j, StringNode):
src_list += [j.value]
extra_files_list = []
for i in target['extra_files']:
for j in arg_list_from_node(i):
if isinstance(j, StringNode):
extra_files_list += [j.value]
test_data = {
'name': target['name'],
'sources': src_list
'sources': src_list,
'extra_files': extra_files_list
}
self.add_info('target', target['id'], test_data)
@ -879,6 +970,8 @@ target_operation_map = {
'rm': 'src_rm',
'add_target': 'target_add',
'rm_target': 'target_rm',
'add_extra_files': 'extra_files_add',
'rm_extra_files': 'extra_files_rm',
'info': 'info',
}

@ -0,0 +1,111 @@
[
{
"type": "target",
"target": "trivialprog1",
"operation": "extra_files_add",
"sources": ["a2.hpp", "a1.hpp", "a2.hpp"]
},
{
"type": "target",
"target": "trivialprog2",
"operation": "extra_files_add",
"sources": ["a7.hpp"]
},
{
"type": "target",
"target": "trivialprog3",
"operation": "extra_files_add",
"sources": ["a5.hpp"]
},
{
"type": "target",
"target": "trivialprog4",
"operation": "extra_files_add",
"sources": ["a5.hpp"]
},
{
"type": "target",
"target": "trivialprog5",
"operation": "extra_files_add",
"sources": ["a3.hpp"]
},
{
"type": "target",
"target": "trivialprog7",
"operation": "extra_files_add",
"sources": ["a6.hpp", "a1.hpp"]
},
{
"type": "target",
"target": "trivialprog8",
"operation": "extra_files_add",
"sources": ["a2.hpp", "a7.hpp"]
},
{
"type": "target",
"target": "trivialprog9",
"operation": "extra_files_add",
"sources": ["a9.hpp", "a8.hpp"]
},
{
"type": "target",
"target": "trivialprog10",
"operation": "extra_files_add",
"sources": ["a4.hpp", "a1.hpp"]
},
{
"type": "target",
"target": "trivialprog0",
"operation": "info"
},
{
"type": "target",
"target": "trivialprog1",
"operation": "info"
},
{
"type": "target",
"target": "trivialprog2",
"operation": "info"
},
{
"type": "target",
"target": "trivialprog3",
"operation": "info"
},
{
"type": "target",
"target": "trivialprog4",
"operation": "info"
},
{
"type": "target",
"target": "trivialprog5",
"operation": "info"
},
{
"type": "target",
"target": "trivialprog6",
"operation": "info"
},
{
"type": "target",
"target": "trivialprog7",
"operation": "info"
},
{
"type": "target",
"target": "trivialprog8",
"operation": "info"
},
{
"type": "target",
"target": "trivialprog9",
"operation": "info"
},
{
"type": "target",
"target": "trivialprog10",
"operation": "info"
}
]

@ -0,0 +1,57 @@
[
{
"type": "target",
"target": "trivialprog0",
"operation": "info"
},
{
"type": "target",
"target": "trivialprog1",
"operation": "info"
},
{
"type": "target",
"target": "exe2",
"operation": "info"
},
{
"type": "target",
"target": "trivialprog3",
"operation": "info"
},
{
"type": "target",
"target": "exe4",
"operation": "info"
},
{
"type": "target",
"target": "trivialprog5",
"operation": "info"
},
{
"type": "target",
"target": "exe6",
"operation": "info"
},
{
"type": "target",
"target": "trivialprog7",
"operation": "info"
},
{
"type": "target",
"target": "exe8",
"operation": "info"
},
{
"type": "target",
"target": "trivialprog9",
"operation": "info"
},
{
"type": "target",
"target": "trivialprog10",
"operation": "info"
}
]

@ -0,0 +1,21 @@
project('rewritetest', 'cpp')
ef1 = ['main.hpp', 'fileA.hpp']
ef2 = files(['fileB.hpp', 'fileC.hpp'])
ef3 = ef1
ef4 = [ef3]
ef5 = []
# Magic comment
exe0 = executable('trivialprog0', 'main.cpp', extra_files : ef1 + ef2)
exe1 = executable('trivialprog1', 'main.cpp', extra_files : ef1)
exe2 = executable('trivialprog2', 'main.cpp', extra_files : [ef2])
exe3 = executable('trivialprog3', 'main.cpp', extra_files : ['main.hpp', 'fileA.hpp'])
exe4 = executable('trivialprog4', 'main.cpp', extra_files : ['main.hpp', ['fileA.hpp']])
exe5 = executable('trivialprog5', 'main.cpp', extra_files : [ef2, 'main.hpp'])
exe6 = executable('trivialprog6', 'main.cpp', extra_files : ef3)
executable('trivialprog7', 'main.cpp', extra_files : ef4)
exe8 = executable('trivialprog8', 'main.cpp', extra_files : [])
exe9 = executable('trivialprog9', 'main.cpp')
exe10 = executable('trivialprog10', 'main.cpp', extra_files : ef5)

@ -0,0 +1,93 @@
[
{
"type": "target",
"target": "trivialprog1",
"operation": "extra_files_rm",
"sources": ["fileA.hpp"]
},
{
"type": "target",
"target": "trivialprog3",
"operation": "extra_files_rm",
"sources": ["fileA.hpp"]
},
{
"type": "target",
"target": "trivialprog4",
"operation": "extra_files_rm",
"sources": ["fileA.hpp"]
},
{
"type": "target",
"target": "trivialprog5",
"operation": "extra_files_rm",
"sources": ["fileB.hpp"]
},
{
"type": "target",
"target": "trivialprog6",
"operation": "extra_files_rm",
"sources": ["fileA.hpp"]
},
{
"type": "target",
"target": "trivialprog7",
"operation": "extra_files_rm",
"sources": ["fileA.hpp"]
},
{
"type": "target",
"target": "trivialprog0",
"operation": "info"
},
{
"type": "target",
"target": "trivialprog1",
"operation": "info"
},
{
"type": "target",
"target": "trivialprog2",
"operation": "info"
},
{
"type": "target",
"target": "trivialprog3",
"operation": "info"
},
{
"type": "target",
"target": "trivialprog4",
"operation": "info"
},
{
"type": "target",
"target": "trivialprog5",
"operation": "info"
},
{
"type": "target",
"target": "trivialprog6",
"operation": "info"
},
{
"type": "target",
"target": "trivialprog7",
"operation": "info"
},
{
"type": "target",
"target": "trivialprog8",
"operation": "info"
},
{
"type": "target",
"target": "trivialprog9",
"operation": "info"
},
{
"type": "target",
"target": "trivialprog10",
"operation": "info"
}
]

@ -56,16 +56,16 @@ class RewriterTests(BasePlatformTests):
out = self.rewrite(self.builddir, os.path.join(self.builddir, 'info.json'))
expected = {
'target': {
'trivialprog0@exe': {'name': 'trivialprog0', 'sources': ['main.cpp', 'fileA.cpp', 'fileB.cpp', 'fileC.cpp']},
'trivialprog1@exe': {'name': 'trivialprog1', 'sources': ['main.cpp', 'fileA.cpp']},
'trivialprog2@exe': {'name': 'trivialprog2', 'sources': ['fileB.cpp', 'fileC.cpp']},
'trivialprog3@exe': {'name': 'trivialprog3', 'sources': ['main.cpp', 'fileA.cpp']},
'trivialprog4@exe': {'name': 'trivialprog4', 'sources': ['main.cpp', 'fileA.cpp']},
'trivialprog5@exe': {'name': 'trivialprog5', 'sources': ['main.cpp', 'fileB.cpp', 'fileC.cpp']},
'trivialprog6@exe': {'name': 'trivialprog6', 'sources': ['main.cpp', 'fileA.cpp']},
'trivialprog7@exe': {'name': 'trivialprog7', 'sources': ['fileB.cpp', 'fileC.cpp', 'main.cpp', 'fileA.cpp']},
'trivialprog8@exe': {'name': 'trivialprog8', 'sources': ['main.cpp', 'fileA.cpp']},
'trivialprog9@exe': {'name': 'trivialprog9', 'sources': ['main.cpp', 'fileA.cpp']},
'trivialprog0@exe': {'name': 'trivialprog0', 'sources': ['main.cpp', 'fileA.cpp', 'fileB.cpp', 'fileC.cpp'], 'extra_files': []},
'trivialprog1@exe': {'name': 'trivialprog1', 'sources': ['main.cpp', 'fileA.cpp'], 'extra_files': []},
'trivialprog2@exe': {'name': 'trivialprog2', 'sources': ['fileB.cpp', 'fileC.cpp'], 'extra_files': []},
'trivialprog3@exe': {'name': 'trivialprog3', 'sources': ['main.cpp', 'fileA.cpp'], 'extra_files': []},
'trivialprog4@exe': {'name': 'trivialprog4', 'sources': ['main.cpp', 'fileA.cpp'], 'extra_files': []},
'trivialprog5@exe': {'name': 'trivialprog5', 'sources': ['main.cpp', 'fileB.cpp', 'fileC.cpp'], 'extra_files': []},
'trivialprog6@exe': {'name': 'trivialprog6', 'sources': ['main.cpp', 'fileA.cpp'], 'extra_files': []},
'trivialprog7@exe': {'name': 'trivialprog7', 'sources': ['fileB.cpp', 'fileC.cpp', 'main.cpp', 'fileA.cpp'], 'extra_files': []},
'trivialprog8@exe': {'name': 'trivialprog8', 'sources': ['main.cpp', 'fileA.cpp'], 'extra_files': []},
'trivialprog9@exe': {'name': 'trivialprog9', 'sources': ['main.cpp', 'fileA.cpp'], 'extra_files': []},
}
}
self.assertDictEqual(out, expected)
@ -75,16 +75,16 @@ class RewriterTests(BasePlatformTests):
out = self.rewrite(self.builddir, os.path.join(self.builddir, 'addSrc.json'))
expected = {
'target': {
'trivialprog0@exe': {'name': 'trivialprog0', 'sources': ['a1.cpp', 'a2.cpp', 'a6.cpp', 'fileA.cpp', 'main.cpp', 'a7.cpp', 'fileB.cpp', 'fileC.cpp']},
'trivialprog1@exe': {'name': 'trivialprog1', 'sources': ['a1.cpp', 'a2.cpp', 'a6.cpp', 'fileA.cpp', 'main.cpp']},
'trivialprog2@exe': {'name': 'trivialprog2', 'sources': ['a7.cpp', 'fileB.cpp', 'fileC.cpp']},
'trivialprog3@exe': {'name': 'trivialprog3', 'sources': ['a5.cpp', 'fileA.cpp', 'main.cpp']},
'trivialprog4@exe': {'name': 'trivialprog4', 'sources': ['a5.cpp', 'main.cpp', 'fileA.cpp']},
'trivialprog5@exe': {'name': 'trivialprog5', 'sources': ['a3.cpp', 'main.cpp', 'a7.cpp', 'fileB.cpp', 'fileC.cpp']},
'trivialprog6@exe': {'name': 'trivialprog6', 'sources': ['main.cpp', 'fileA.cpp', 'a4.cpp']},
'trivialprog7@exe': {'name': 'trivialprog7', 'sources': ['fileB.cpp', 'fileC.cpp', 'a1.cpp', 'a2.cpp', 'a6.cpp', 'fileA.cpp', 'main.cpp']},
'trivialprog8@exe': {'name': 'trivialprog8', 'sources': ['a1.cpp', 'a2.cpp', 'a6.cpp', 'fileA.cpp', 'main.cpp']},
'trivialprog9@exe': {'name': 'trivialprog9', 'sources': ['a1.cpp', 'a2.cpp', 'a6.cpp', 'fileA.cpp', 'main.cpp']},
'trivialprog0@exe': {'name': 'trivialprog0', 'sources': ['a1.cpp', 'a2.cpp', 'a6.cpp', 'fileA.cpp', 'main.cpp', 'a7.cpp', 'fileB.cpp', 'fileC.cpp'], 'extra_files': []},
'trivialprog1@exe': {'name': 'trivialprog1', 'sources': ['a1.cpp', 'a2.cpp', 'a6.cpp', 'fileA.cpp', 'main.cpp'], 'extra_files': []},
'trivialprog2@exe': {'name': 'trivialprog2', 'sources': ['a7.cpp', 'fileB.cpp', 'fileC.cpp'], 'extra_files': []},
'trivialprog3@exe': {'name': 'trivialprog3', 'sources': ['a5.cpp', 'fileA.cpp', 'main.cpp'], 'extra_files': []},
'trivialprog4@exe': {'name': 'trivialprog4', 'sources': ['a5.cpp', 'main.cpp', 'fileA.cpp'], 'extra_files': []},
'trivialprog5@exe': {'name': 'trivialprog5', 'sources': ['a3.cpp', 'main.cpp', 'a7.cpp', 'fileB.cpp', 'fileC.cpp'], 'extra_files': []},
'trivialprog6@exe': {'name': 'trivialprog6', 'sources': ['main.cpp', 'fileA.cpp', 'a4.cpp'], 'extra_files': []},
'trivialprog7@exe': {'name': 'trivialprog7', 'sources': ['fileB.cpp', 'fileC.cpp', 'a1.cpp', 'a2.cpp', 'a6.cpp', 'fileA.cpp', 'main.cpp'], 'extra_files': []},
'trivialprog8@exe': {'name': 'trivialprog8', 'sources': ['a1.cpp', 'a2.cpp', 'a6.cpp', 'fileA.cpp', 'main.cpp'], 'extra_files': []},
'trivialprog9@exe': {'name': 'trivialprog9', 'sources': ['a1.cpp', 'a2.cpp', 'a6.cpp', 'fileA.cpp', 'main.cpp'], 'extra_files': []},
}
}
self.assertDictEqual(out, expected)
@ -100,7 +100,7 @@ class RewriterTests(BasePlatformTests):
inf = json.dumps([{"type": "target", "target": "trivialprog1", "operation": "info"}])
self.rewrite(self.builddir, add)
out = self.rewrite(self.builddir, inf)
expected = {'target': {'trivialprog1@exe': {'name': 'trivialprog1', 'sources': ['a1.cpp', 'a2.cpp', 'a6.cpp', 'fileA.cpp', 'main.cpp']}}}
expected = {'target': {'trivialprog1@exe': {'name': 'trivialprog1', 'sources': ['a1.cpp', 'a2.cpp', 'a6.cpp', 'fileA.cpp', 'main.cpp'], 'extra_files': []}}}
self.assertDictEqual(out, expected)
def test_target_remove_sources(self):
@ -108,16 +108,16 @@ class RewriterTests(BasePlatformTests):
out = self.rewrite(self.builddir, os.path.join(self.builddir, 'rmSrc.json'))
expected = {
'target': {
'trivialprog0@exe': {'name': 'trivialprog0', 'sources': ['main.cpp', 'fileC.cpp']},
'trivialprog1@exe': {'name': 'trivialprog1', 'sources': ['main.cpp']},
'trivialprog2@exe': {'name': 'trivialprog2', 'sources': ['fileC.cpp']},
'trivialprog3@exe': {'name': 'trivialprog3', 'sources': ['main.cpp']},
'trivialprog4@exe': {'name': 'trivialprog4', 'sources': ['main.cpp']},
'trivialprog5@exe': {'name': 'trivialprog5', 'sources': ['main.cpp', 'fileC.cpp']},
'trivialprog6@exe': {'name': 'trivialprog6', 'sources': ['main.cpp']},
'trivialprog7@exe': {'name': 'trivialprog7', 'sources': ['fileC.cpp', 'main.cpp']},
'trivialprog8@exe': {'name': 'trivialprog8', 'sources': ['main.cpp']},
'trivialprog9@exe': {'name': 'trivialprog9', 'sources': ['main.cpp']},
'trivialprog0@exe': {'name': 'trivialprog0', 'sources': ['main.cpp', 'fileC.cpp'], 'extra_files': []},
'trivialprog1@exe': {'name': 'trivialprog1', 'sources': ['main.cpp'], 'extra_files': []},
'trivialprog2@exe': {'name': 'trivialprog2', 'sources': ['fileC.cpp'], 'extra_files': []},
'trivialprog3@exe': {'name': 'trivialprog3', 'sources': ['main.cpp'], 'extra_files': []},
'trivialprog4@exe': {'name': 'trivialprog4', 'sources': ['main.cpp'], 'extra_files': []},
'trivialprog5@exe': {'name': 'trivialprog5', 'sources': ['main.cpp', 'fileC.cpp'], 'extra_files': []},
'trivialprog6@exe': {'name': 'trivialprog6', 'sources': ['main.cpp'], 'extra_files': []},
'trivialprog7@exe': {'name': 'trivialprog7', 'sources': ['fileC.cpp', 'main.cpp'], 'extra_files': []},
'trivialprog8@exe': {'name': 'trivialprog8', 'sources': ['main.cpp'], 'extra_files': []},
'trivialprog9@exe': {'name': 'trivialprog9', 'sources': ['main.cpp'], 'extra_files': []},
}
}
self.assertDictEqual(out, expected)
@ -129,7 +129,7 @@ class RewriterTests(BasePlatformTests):
def test_target_subdir(self):
self.prime('2 subdirs')
out = self.rewrite(self.builddir, os.path.join(self.builddir, 'addSrc.json'))
expected = {'name': 'something', 'sources': ['first.c', 'second.c', 'third.c']}
expected = {'name': 'something', 'sources': ['first.c', 'second.c', 'third.c'], 'extra_files': []}
self.assertDictEqual(list(out['target'].values())[0], expected)
# Check the written file
@ -143,13 +143,13 @@ class RewriterTests(BasePlatformTests):
expected = {
'target': {
'trivialprog2@exe': {'name': 'trivialprog2', 'sources': ['fileB.cpp', 'fileC.cpp']},
'trivialprog3@exe': {'name': 'trivialprog3', 'sources': ['main.cpp', 'fileA.cpp']},
'trivialprog4@exe': {'name': 'trivialprog4', 'sources': ['main.cpp', 'fileA.cpp']},
'trivialprog5@exe': {'name': 'trivialprog5', 'sources': ['main.cpp', 'fileB.cpp', 'fileC.cpp']},
'trivialprog6@exe': {'name': 'trivialprog6', 'sources': ['main.cpp', 'fileA.cpp']},
'trivialprog7@exe': {'name': 'trivialprog7', 'sources': ['fileB.cpp', 'fileC.cpp', 'main.cpp', 'fileA.cpp']},
'trivialprog8@exe': {'name': 'trivialprog8', 'sources': ['main.cpp', 'fileA.cpp']},
'trivialprog2@exe': {'name': 'trivialprog2', 'sources': ['fileB.cpp', 'fileC.cpp'], 'extra_files': []},
'trivialprog3@exe': {'name': 'trivialprog3', 'sources': ['main.cpp', 'fileA.cpp'], 'extra_files': []},
'trivialprog4@exe': {'name': 'trivialprog4', 'sources': ['main.cpp', 'fileA.cpp'], 'extra_files': []},
'trivialprog5@exe': {'name': 'trivialprog5', 'sources': ['main.cpp', 'fileB.cpp', 'fileC.cpp'], 'extra_files': []},
'trivialprog6@exe': {'name': 'trivialprog6', 'sources': ['main.cpp', 'fileA.cpp'], 'extra_files': []},
'trivialprog7@exe': {'name': 'trivialprog7', 'sources': ['fileB.cpp', 'fileC.cpp', 'main.cpp', 'fileA.cpp'], 'extra_files': []},
'trivialprog8@exe': {'name': 'trivialprog8', 'sources': ['main.cpp', 'fileA.cpp'], 'extra_files': []},
}
}
self.assertDictEqual(out, expected)
@ -161,17 +161,17 @@ class RewriterTests(BasePlatformTests):
expected = {
'target': {
'trivialprog0@exe': {'name': 'trivialprog0', 'sources': ['main.cpp', 'fileA.cpp', 'fileB.cpp', 'fileC.cpp']},
'trivialprog1@exe': {'name': 'trivialprog1', 'sources': ['main.cpp', 'fileA.cpp']},
'trivialprog2@exe': {'name': 'trivialprog2', 'sources': ['fileB.cpp', 'fileC.cpp']},
'trivialprog3@exe': {'name': 'trivialprog3', 'sources': ['main.cpp', 'fileA.cpp']},
'trivialprog4@exe': {'name': 'trivialprog4', 'sources': ['main.cpp', 'fileA.cpp']},
'trivialprog5@exe': {'name': 'trivialprog5', 'sources': ['main.cpp', 'fileB.cpp', 'fileC.cpp']},
'trivialprog6@exe': {'name': 'trivialprog6', 'sources': ['main.cpp', 'fileA.cpp']},
'trivialprog7@exe': {'name': 'trivialprog7', 'sources': ['fileB.cpp', 'fileC.cpp', 'main.cpp', 'fileA.cpp']},
'trivialprog8@exe': {'name': 'trivialprog8', 'sources': ['main.cpp', 'fileA.cpp']},
'trivialprog9@exe': {'name': 'trivialprog9', 'sources': ['main.cpp', 'fileA.cpp']},
'trivialprog10@sha': {'name': 'trivialprog10', 'sources': ['new1.cpp', 'new2.cpp']},
'trivialprog0@exe': {'name': 'trivialprog0', 'sources': ['main.cpp', 'fileA.cpp', 'fileB.cpp', 'fileC.cpp'], 'extra_files': []},
'trivialprog1@exe': {'name': 'trivialprog1', 'sources': ['main.cpp', 'fileA.cpp'], 'extra_files': []},
'trivialprog2@exe': {'name': 'trivialprog2', 'sources': ['fileB.cpp', 'fileC.cpp'], 'extra_files': []},
'trivialprog3@exe': {'name': 'trivialprog3', 'sources': ['main.cpp', 'fileA.cpp'], 'extra_files': []},
'trivialprog4@exe': {'name': 'trivialprog4', 'sources': ['main.cpp', 'fileA.cpp'], 'extra_files': []},
'trivialprog5@exe': {'name': 'trivialprog5', 'sources': ['main.cpp', 'fileB.cpp', 'fileC.cpp'], 'extra_files': []},
'trivialprog6@exe': {'name': 'trivialprog6', 'sources': ['main.cpp', 'fileA.cpp'], 'extra_files': []},
'trivialprog7@exe': {'name': 'trivialprog7', 'sources': ['fileB.cpp', 'fileC.cpp', 'main.cpp', 'fileA.cpp'], 'extra_files': []},
'trivialprog8@exe': {'name': 'trivialprog8', 'sources': ['main.cpp', 'fileA.cpp'], 'extra_files': []},
'trivialprog9@exe': {'name': 'trivialprog9', 'sources': ['main.cpp', 'fileA.cpp'], 'extra_files': []},
'trivialprog10@sha': {'name': 'trivialprog10', 'sources': ['new1.cpp', 'new2.cpp'], 'extra_files': []},
}
}
self.assertDictEqual(out, expected)
@ -186,7 +186,7 @@ class RewriterTests(BasePlatformTests):
self.prime('2 subdirs')
self.rewrite(self.builddir, os.path.join(self.builddir, 'addTgt.json'))
out = self.rewrite(self.builddir, os.path.join(self.builddir, 'info.json'))
expected = {'name': 'something', 'sources': ['first.c', 'second.c']}
expected = {'name': 'something', 'sources': ['first.c', 'second.c'], 'extra_files': []}
self.assertDictEqual(out['target']['94b671c@@something@exe'], expected)
def test_target_source_sorting(self):
@ -228,7 +228,8 @@ class RewriterTests(BasePlatformTests):
'a666.c',
'b1.c',
'c2.c'
]
],
'extra_files': []
}
}
}
@ -238,7 +239,7 @@ class RewriterTests(BasePlatformTests):
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']}
expected = {'name': 'myExe', 'sources': ['main.cpp'], 'extra_files': []}
self.assertEqual(len(out['target']), 2)
for val in out['target'].values():
self.assertDictEqual(expected, val)
@ -345,3 +346,51 @@ class RewriterTests(BasePlatformTests):
}
}
self.assertDictEqual(out, expected)
def test_target_add_extra_files(self):
self.prime('6 extra_files')
out = self.rewrite(self.builddir, os.path.join(self.builddir, 'addExtraFiles.json'))
expected = {
'target': {
'trivialprog0@exe': {'name': 'trivialprog0', 'sources': ['main.cpp'], 'extra_files': ['a1.hpp', 'a2.hpp', 'a6.hpp', 'fileA.hpp', 'main.hpp', 'a7.hpp', 'fileB.hpp', 'fileC.hpp']},
'trivialprog1@exe': {'name': 'trivialprog1', 'sources': ['main.cpp'], 'extra_files': ['a1.hpp', 'a2.hpp', 'a6.hpp', 'fileA.hpp', 'main.hpp']},
'trivialprog2@exe': {'name': 'trivialprog2', 'sources': ['main.cpp'], 'extra_files': ['a7.hpp', 'fileB.hpp', 'fileC.hpp']},
'trivialprog3@exe': {'name': 'trivialprog3', 'sources': ['main.cpp'], 'extra_files': ['a5.hpp', 'fileA.hpp', 'main.hpp']},
'trivialprog4@exe': {'name': 'trivialprog4', 'sources': ['main.cpp'], 'extra_files': ['a5.hpp', 'main.hpp', 'fileA.hpp']},
'trivialprog5@exe': {'name': 'trivialprog5', 'sources': ['main.cpp'], 'extra_files': ['a3.hpp', 'main.hpp', 'a7.hpp', 'fileB.hpp', 'fileC.hpp']},
'trivialprog6@exe': {'name': 'trivialprog6', 'sources': ['main.cpp'], 'extra_files': ['a1.hpp', 'a2.hpp', 'a6.hpp', 'fileA.hpp', 'main.hpp']},
'trivialprog7@exe': {'name': 'trivialprog7', 'sources': ['main.cpp'], 'extra_files': ['a1.hpp', 'a2.hpp', 'a6.hpp', 'fileA.hpp', 'main.hpp']},
'trivialprog8@exe': {'name': 'trivialprog8', 'sources': ['main.cpp'], 'extra_files': ['a2.hpp', 'a7.hpp']},
'trivialprog9@exe': {'name': 'trivialprog9', 'sources': ['main.cpp'], 'extra_files': ['a8.hpp', 'a9.hpp']},
'trivialprog10@exe': {'name': 'trivialprog10', 'sources': ['main.cpp'], 'extra_files': ['a1.hpp', 'a4.hpp']},
}
}
self.assertDictEqual(out, expected)
# Check the written file
out = self.rewrite(self.builddir, os.path.join(self.builddir, 'info.json'))
self.assertDictEqual(out, expected)
def test_target_remove_extra_files(self):
self.prime('6 extra_files')
out = self.rewrite(self.builddir, os.path.join(self.builddir, 'rmExtraFiles.json'))
expected = {
'target': {
'trivialprog0@exe': {'name': 'trivialprog0', 'sources': ['main.cpp'], 'extra_files': ['main.hpp', 'fileC.hpp']},
'trivialprog1@exe': {'name': 'trivialprog1', 'sources': ['main.cpp'], 'extra_files': ['main.hpp']},
'trivialprog2@exe': {'name': 'trivialprog2', 'sources': ['main.cpp'], 'extra_files': ['fileC.hpp']},
'trivialprog3@exe': {'name': 'trivialprog3', 'sources': ['main.cpp'], 'extra_files': ['main.hpp']},
'trivialprog4@exe': {'name': 'trivialprog4', 'sources': ['main.cpp'], 'extra_files': ['main.hpp']},
'trivialprog5@exe': {'name': 'trivialprog5', 'sources': ['main.cpp'], 'extra_files': ['main.hpp', 'fileC.hpp']},
'trivialprog6@exe': {'name': 'trivialprog6', 'sources': ['main.cpp'], 'extra_files': ['main.hpp']},
'trivialprog7@exe': {'name': 'trivialprog7', 'sources': ['main.cpp'], 'extra_files': ['main.hpp']},
'trivialprog8@exe': {'name': 'trivialprog8', 'sources': ['main.cpp'], 'extra_files': []},
'trivialprog9@exe': {'name': 'trivialprog9', 'sources': ['main.cpp'], 'extra_files': []},
'trivialprog10@exe': {'name': 'trivialprog10', 'sources': ['main.cpp'], 'extra_files': []},
}
}
self.assertDictEqual(out, expected)
# Check the written file
out = self.rewrite(self.builddir, os.path.join(self.builddir, 'info.json'))
self.assertDictEqual(out, expected)

Loading…
Cancel
Save