diff options
Diffstat (limited to 'reconfigure/includers/auto.py')
-rw-r--r-- | reconfigure/includers/auto.py | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/reconfigure/includers/auto.py b/reconfigure/includers/auto.py new file mode 100644 index 0000000..16844ca --- /dev/null +++ b/reconfigure/includers/auto.py @@ -0,0 +1,68 @@ +from base import BaseIncluder +from reconfigure.nodes import * +import glob +import os + + +class AutoIncluder (BaseIncluder): + """ + This base includer automatically walks the node tree and loads the include files from ``IncludeNode.files`` properties. ``files`` is supposed to contain absolute path, relative path or a shell wildcard. + """ + + def compose(self, origin, tree): + self.compose_rec(origin, origin, tree) + return tree + + def compose_rec(self, root, origin, node): + if not node.origin: + node.origin = origin + for child in node.children: + self.compose_rec(root, origin, child) + for child in node.children: + spec = self.is_include(child) + if spec: + files = spec + if node.origin and not files.startswith('/'): + files = os.path.join(os.path.split(root)[0], files) + if '*' in files or '.' in files: + files = glob.glob(files) + else: + files = [files] + for file in files: + if file in self.content_map: + content = self.content_map[file] + else: + content = open(file, 'r').read() + subtree = self.parser.parse(content) + node.children.extend(subtree.children) + self.compose_rec(root, file, subtree) + node.children[node.children.index(child)] = IncludeNode(spec) + + def decompose(self, tree): + result = {} + result[tree.origin] = self.decompose_rec(tree, result) + return result + + def decompose_rec(self, node, result): + for child in node.children: + if child.__class__ == IncludeNode: + replacement = self.remove_include(child) + if replacement: + node.children[node.children.index(child)] = replacement + else: + if child.origin != node.origin: + node.children.remove(child) + result.setdefault(child.origin, RootNode()).children.append(self.decompose_rec(child, result)) + else: + self.decompose_rec(child, result) + return node + + def is_include(self, node): + """ + Should return whether the node is an include node and return file pattern glob if it is + """ + + def remove_include(self, node): + """ + Shoud transform :class:`reconfigure.nodes.IncludeNode` into a normal Node to be stringified into the file + """ |