提交 a8b96a03 编写于 作者: L Lukáš Doktor

avocado.core.tree: Support for remove_value

This patch adds support for '!remove_value' yaml tag. It can be used
to remove certain value from previously existing values. This happens
during merge before value is updated.
Signed-off-by: NLukáš Doktor <ldoktor@redhat.com>
上级 5f68bb47
......@@ -50,6 +50,7 @@ except ImportError:
YAML_INCLUDE = 0
YAML_USING = 1
YAML_REMOVE_NODE = 2
YAML_REMOVE_VALUE = 3
class Control(object): # Few methods pylint: disable=R0903
......@@ -129,7 +130,6 @@ class TreeNode(object):
added as children (recursively they get either appended at the end
or merged into existing node in the previous position.
"""
self.value.update(other.value)
for ctrl in other.ctrl:
if isinstance(ctrl, Control):
if ctrl.code == YAML_REMOVE_NODE:
......@@ -140,6 +140,15 @@ class TreeNode(object):
remove.append(child)
for child in remove:
self.children.remove(child)
elif ctrl.code == YAML_REMOVE_VALUE:
remove = []
regexp = re.compile(ctrl.value)
for key in self.value.iterkeys():
if regexp.match(key):
remove.append(key)
for key in remove:
self.value.pop(key, None)
self.value.update(other.value)
for child in other.children:
self.add_child(child)
......@@ -350,6 +359,9 @@ def _create_from_yaml(path, cls_node=TreeNode):
elif value[0].code == YAML_REMOVE_NODE:
value[0].value = value[1] # set the name
node.ctrl.append(value[0]) # add "blue pill" of death
elif value[0].code == YAML_REMOVE_VALUE:
value[0].value = value[1] # set the name
node.ctrl.append(value[0])
else:
node.value[value[0]] = value[1]
if using:
......@@ -384,6 +396,8 @@ def _create_from_yaml(path, cls_node=TreeNode):
lambda loader, node: Control(YAML_USING))
Loader.add_constructor(u'!remove_node',
lambda loader, node: Control(YAML_REMOVE_NODE))
Loader.add_constructor(u'!remove_value',
lambda loader, node: Control(YAML_REMOVE_VALUE))
Loader.add_constructor(yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG,
mapping_to_tree_loader)
......
......@@ -163,6 +163,22 @@ And lists::
The list above will become ``['-O2', '-g', '-Wall']`` to Python. In fact,
YAML is compatible to JSON.
It's also possible to remove key using python's regexp, which can be useful
when extending upstream file using downstream yaml files. This is done by
`!remove_value : $value_name` directive::
debug:
CFLAGS: '-O0 -g'
debug:
!remove_value: CFLAGS
removes the CFLAGS value completely from the debug node. This happens during
the merge and only once. So if you switch the two, CFLAGS would be defined.
Due to yaml nature, it's __mandatory__ to put space between `!remove_value`
and `:`!
.. _environment:
Environment
......
......@@ -10,6 +10,15 @@ distro:
# This is a new /distro/mint appended as latest child
mint:
new_mint: True
fedora:
!remove_value : init.*
new_init: systemd
gentoo:
# This modifies the value of 'is_cool'
is_cool: True
# And this removes the original 'is_cool'
# Setting happens after ctrl so it should be created'
!remove_value : is_cool
# This creates new branch the usual way
new_node:
# Put this new_node into /absolutely/fresh/ ('/' are automatically
......
......@@ -4,3 +4,5 @@ RHEL:
init: 'systemv'
7:
init: 'systemd'
gentoo:
is_cool: False
......@@ -153,14 +153,16 @@ class TestTree(unittest.TestCase):
def test_advanced_yaml(self):
tree2 = tree.create_from_yaml(['examples/mux-selftest-advanced.yaml'])
exp = ['intel', 'amd', 'arm', 'scsi', 'virtio', 'fedora', '6',
'7', 'mint', 'prod', 'new_node']
'7', 'gentoo', 'mint', 'prod', 'new_node']
act = tree2.get_leaves()
oldroot = tree2.children[0]
self.assertEqual(exp, act)
self.assertEqual({'enterprise': True},
oldroot.children[1].children[1].value)
self.assertEqual({'init': 'systemd'},
self.assertEqual({'new_init': 'systemd'},
oldroot.children[1].children[0].value)
self.assertEqual({'is_cool': True},
oldroot.children[1].children[2].value)
self.assertEqual({'new_value': 'something'},
oldroot.children[3].children[0].children[0].value)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册