Merge pull request #72 from Martin819/develop
Allow to use '..' as a reference to higher level in class structure
diff --git a/README-extensions.rst b/README-extensions.rst
index 6693256..d321fa1 100644
--- a/README-extensions.rst
+++ b/README-extensions.rst
@@ -340,17 +340,19 @@
--------------------------------
Load referenced class from a relative location to the current class.
-To load class from relative location start the class uri with "." char.
+To load class from relative location start the class uri with "." or ".." char.
The only supported reference is to nested tree structure below the current class.
You are allowed to use syntax for relative uri to required class on any place on your model (first class loaded, init.yml, regular class .yml).
The feature is expected to improve flexibility while sharing classes between your models.
+Please mpte that you can't use '..' without any calss following. If you want simply up in the sctructure, type in '..init'.
+
It's a new feature use it with care and mind that using "relative syntax" lower traceability of
your pillar composition.
-Example usage of relative class name:
+Example usage of relative class name using '.' and '..':
.. code-block:: yaml
@@ -366,6 +368,12 @@
classes:
- .defaults
+.. code-block:: yaml
+
+ #/etc/reclass/classes/component/configuration/init.yml
+ classes:
+ - ..defaults
+
Inventory Queries
-----------------
diff --git a/reclass/storage/yamldata.py b/reclass/storage/yamldata.py
index 034832d..a38b589 100644
--- a/reclass/storage/yamldata.py
+++ b/reclass/storage/yamldata.py
@@ -54,17 +54,32 @@
return self._data
def set_absolute_names(self, name, names):
- parent = '.'.join(name.split('.')[0:-1])
new_names = []
for n in names:
if n[0] == '.':
+ dots = self.count_dots(n)
+ levels_up = (dots * (-1))
+ parent = '.'.join(name.split('.')[0:levels_up])
if parent == '':
- n = n[1:]
+ n = n[dots:]
else:
- n = parent + n
+ n = parent + n[dots - 1:]
new_names.append(n)
return new_names
+ def yield_dots(self, value):
+ try:
+ idx = value.index('.')
+ except ValueError:
+ return
+ if idx == 0:
+ yield '.'
+ for dot in self.yield_dots(value[1:]):
+ yield dot
+
+ def count_dots(self, value):
+ return len(list(self.yield_dots(value)))
+
def get_entity(self, name, settings):
#if name is None:
# name = self._uri
diff --git a/reclass/tests/data/02/classes/four.yml b/reclass/tests/data/02/classes/four.yml
new file mode 100644
index 0000000..1f9873c
--- /dev/null
+++ b/reclass/tests/data/02/classes/four.yml
@@ -0,0 +1,2 @@
+parameters:
+ four_alpha: 3
diff --git a/reclass/tests/data/02/classes/init.yml b/reclass/tests/data/02/classes/init.yml
new file mode 100644
index 0000000..e40b899
--- /dev/null
+++ b/reclass/tests/data/02/classes/init.yml
@@ -0,0 +1,2 @@
+parameters:
+ alpha_init: 5
\ No newline at end of file
diff --git a/reclass/tests/data/02/classes/one/alpha.yml b/reclass/tests/data/02/classes/one/alpha.yml
index a13cc5c..9454cd0 100644
--- a/reclass/tests/data/02/classes/one/alpha.yml
+++ b/reclass/tests/data/02/classes/one/alpha.yml
@@ -1,7 +1,13 @@
classes:
- .beta
- two.beta
+- ..four
+- ..two.gamma
+- ..init
parameters:
test1: ${one_beta}
test2: ${two_beta}
+ test3: ${four_alpha}
+ test4: ${two_gamma}
+ test5: ${alpha_init}
diff --git a/reclass/tests/data/02/classes/two/gamma.yml b/reclass/tests/data/02/classes/two/gamma.yml
new file mode 100644
index 0000000..a1d71da
--- /dev/null
+++ b/reclass/tests/data/02/classes/two/gamma.yml
@@ -0,0 +1,2 @@
+parameters:
+ two_gamma: 4
diff --git a/reclass/tests/test_core.py b/reclass/tests/test_core.py
index ced18e8..4827177 100644
--- a/reclass/tests/test_core.py
+++ b/reclass/tests/test_core.py
@@ -62,13 +62,13 @@
def test_relative_class_names(self):
reclass = self._core('02')
node = reclass.nodeinfo('relative')
- params = { 'test1': 1, 'test2': 2, 'one_beta': 1, 'two_beta': 2, '_reclass_': { 'environment': 'base', 'name': { 'full': 'relative', 'short': 'relative' } } }
+ params = { 'test1': 1, 'test2': 2, 'test3': 3, 'test4': 4, 'test5': 5, 'one_beta': 1, 'two_beta': 2, 'four_alpha': 3, 'two_gamma': 4, 'alpha_init': 5, '_reclass_': { 'environment': 'base', 'name': { 'full': 'relative', 'short': 'relative' } } }
self.assertEqual(node['parameters'], params)
def test_top_relative_class_names(self):
reclass = self._core('02')
node = reclass.nodeinfo('top_relative')
- params = { 'test1': 1, 'test2': 2, 'one_beta': 1, 'two_beta': 2, '_reclass_': { 'environment': 'base', 'name': { 'full': 'top_relative', 'short': 'top_relative' } } }
+ params = { 'test1': 1, 'test2': 2, 'test3': 3, 'test4': 4, 'test5': 5, 'one_beta': 1, 'two_beta': 2, 'four_alpha': 3, 'two_gamma': 4, 'alpha_init': 5, '_reclass_': { 'environment': 'base', 'name': { 'full': 'top_relative', 'short': 'top_relative' } } }
self.assertEqual(node['parameters'], params)
def test_compose_node_names(self):