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

avocado.core.tree: Support for using

Support for '!using' flag. It extends the current leaf location
of the provided path. It can't completely change the location,
it only extends the base.
Signed-off-by: NLukáš Doktor <ldoktor@redhat.com>
上级 e1fe14f2
......@@ -47,6 +47,7 @@ except ImportError:
# Mapping for yaml flags
YAML_INCLUDE = 0
YAML_USING = 1
class TreeNode(object):
......@@ -324,17 +325,31 @@ def _create_from_yaml(path, cls_node=TreeNode):
def tree_node_from_values(name, values):
""" Create `name` node and add values """
node = cls_node(str(name))
using = ''
for value in values:
if isinstance(value, TreeNode):
node.add_child(value)
elif isinstance(value[0], Control):
# Include file
ypath = value[1]
if not os.path.isabs(ypath):
ypath = os.path.join(os.path.dirname(path), ypath)
node.merge(_create_from_yaml(ypath, cls_node))
if value[0] == YAML_INCLUDE:
# Include file
ypath = value[1]
if not os.path.isabs(ypath):
ypath = os.path.join(os.path.dirname(path), ypath)
node.merge(_create_from_yaml(ypath, cls_node))
elif value[0] == YAML_USING:
if using:
raise ValueError("!using can be used only once per "
"node! (%s:%s)" % (path, name))
using = value[1]
if using[0] == '/':
using = using[1:]
if using[-1] == '/':
using = using[:-1]
else:
node.value[value[0]] = value[1]
if using:
for name in using.split('/')[::-1]:
node = cls_node(name, children=[node])
return node
def mapping_to_tree_loader(loader, node):
......@@ -360,6 +375,8 @@ def _create_from_yaml(path, cls_node=TreeNode):
Loader.add_constructor(u'!include',
lambda loader, node: Control(YAML_INCLUDE))
Loader.add_constructor(u'!using',
lambda loader, node: Control(YAML_USING))
Loader.add_constructor(yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG,
mapping_to_tree_loader)
......
......@@ -66,6 +66,51 @@ The ending nodes (the leafs on the tree) will become part of all lower-level
However, the precedence is evaluated in top-down or ``last defined`` order.
In other words, the last parsed has precedence over earlier definitions.
Additionally you can prepend multiple nodes to the given node by using
`!using : $prepended/path`. This is useful when extending complex structure,
for example imagine having distro variants in separate ymal files. In the
end you want to merge them into the `/os` node. The main file can be simply::
# main.yaml
os:
!include : os/fedora/21.yaml
....
And each file can look either like this::
# fedora/21.yaml
fedora:
21:
some: value
or you can use `!using` which prepends the `fedora/21`::
# fedora/21.yaml
!using : /fedora/21
some: value
To be precise there is a way to define the structure in the main yaml file::
# main.yaml
os:
fedora:
21:
!include : fedora_21.yaml
Or use recursive `!include` (slower)::
# main.yaml
os:
fedora:
!include : os/fedora.yaml
# os/fedora.yaml
21:
!include : fedora/21.yaml
# os/fedora/21.yaml
some: value
Due to yaml nature, it's __mandatory__ to put space between `!using` and `:`!
.. _keys_and_values:
Keys and Values
......
# Put everything into /virt
!using : /virt
# Following line makes it look exactly as mux-selftest.yaml
!include : mux-selftest.yaml
distro:
......@@ -5,4 +7,8 @@ distro:
!include : mux-selftest-distro.yaml
# This creates new branch the usual way
new_node:
# Put this new_node into /absolutely/fresh/ ('/' are automatically
# removed during parse time, absolute location is not supported and
# not even planned)
!using : /absolutely/fresh/
new_value: "something"
......@@ -157,12 +157,14 @@ class TestTree(unittest.TestCase):
exp = ['intel', 'amd', 'arm', 'scsi', 'virtio', 'fedora', 'mint', '6',
'7', 'prod', 'new_node']
act = tree2.get_leaves()
oldroot = tree2.children[0]
self.assertEqual(exp, act)
self.assertEqual({'enterprise': True},
tree2.children[1].children[2].value)
oldroot.children[1].children[2].value)
self.assertEqual({'init': 'systemd'},
tree2.children[1].children[0].value)
self.assertEqual({'new_value': 'something'}, tree2.children[3].value)
oldroot.children[1].children[0].value)
self.assertEqual({'new_value': 'something'},
oldroot.children[3].children[0].children[0].value)
class TestPathParent(unittest.TestCase):
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册