From c9bae5d8f1be0652bcec0871cd5af2afbb8937f0 Mon Sep 17 00:00:00 2001
From: Anders Blomdell <anders.blomdell@control.lth.se>
Date: Wed, 20 Apr 2022 17:00:56 +0200
Subject: [PATCH] Installer refactoring

---
 Makefile             |  18 ++++--
 src/mio/exception.py |   6 ++
 src/mio/installer.py | 150 +++++++++++++++++++++++++++----------------
 tests/test.mio       |  14 ----
 4 files changed, 112 insertions(+), 76 deletions(-)
 delete mode 100644 tests/test.mio

diff --git a/Makefile b/Makefile
index 208d4e1..1e91b0c 100644
--- a/Makefile
+++ b/Makefile
@@ -9,13 +9,17 @@ mio2: src/mio.py $(sort $(wildcard src/mio/*.py)) Makefile
 mio3: src/mio.py $(sort $(wildcard src/mio/*.py)) Makefile
 	(cd src ; apa --interpreter=/usr/bin/python3 \
 		      -o ../$@ $(filter %.py, $(^:src/%=%)))
-
-test3:
-	mkdir test_install
+.PHONY: test
+test:
+	./mio3 --noyum \
+	       --path $(realpath test) \
+	       --prefix test/install \
+	       --install /test/test1
 	./mio3 --noyum \
-	       --path $(realpath tests) \
-	       --prefix test_install \
-	       --install /test/test 
+	       --path $(realpath test) \
+	       --prefix test/install \
+	       -vvv --reachable-files  hostinfo.xml
 
+.PHONY: clean
 clean:
-	rm -rf test_install
+	rm -rf test/install
diff --git a/src/mio/exception.py b/src/mio/exception.py
index ad9f9c8..09e996e 100755
--- a/src/mio/exception.py
+++ b/src/mio/exception.py
@@ -118,6 +118,12 @@ class NonAbsolutePath(MioException):
                               "Path is not absolute",
                               [(decl, path)]),
 
+class InvalidTag(MioException):
+    def __init__(self, decl, rejected):
+        MioException.__init__(self,
+                              "Context does not allow tag",
+                              [(decl, rejected)]),
+
 def Report(err, decl, action=None):
     traceback.print_exc()
     message = "%s:%s" % (decl._url, decl._line)
diff --git a/src/mio/installer.py b/src/mio/installer.py
index 2af36c7..3777131 100755
--- a/src/mio/installer.py
+++ b/src/mio/installer.py
@@ -29,6 +29,14 @@ except ImportError:
     pass
 
 class Installer:
+    # add_node tag filtering
+    EMPTY = frozenset()
+    ALL = frozenset(['description','dependency','pre','post',
+                     'rpm','dir','symlink','file',
+                     'select','when'])
+    SELECT_REJECT = frozenset(['dependency','rpm'])
+    DEPENDENCY_IGNORE = frozenset(['dependency'])
+
     def __init__(self, repository):
         self.repository = repository
         self.rpmdir = []
@@ -58,61 +66,9 @@ class Installer:
             chain = list(chain)
             chain.append(group)
             for node in g._children:
-                if node._tag == 'description':
-                    pass
-
-                elif node._tag == 'dependency':
-                    # Dependencies are handled after everything else
-                    pass
-
-                elif node._tag == 'pre':
-                    if node.command[0]:
-                        group.add_pre(command_node(node))
-                    if node.script[0]:
-                        group.add_pre(script_node(node))
-
-                elif node._tag == 'post':
-                    if node.command[0]:
-                        group.add_post(command_node(node))
-                    if node.script[0]:
-                        group.add_post(script_node(node))
-
-                elif node._tag == 'rpm':
-                    rpm = rpm_node(node.name[0], node, group)
-
-                    if rpm in exclude:
-                        mio.log.log(CHATTY,
-                                    "excluding rpm '%s'" % node.name[0])
-                    else:
-                        group.add_rpm(rpm)
-                 
-                elif node._tag == 'dir':
-                    dir = dir_node(node.name[0], node, group)
-                    if dir in exclude:
-                        mio.log.log(CHATTY,
-                                    "excluding dir '%s'" % node.name[0])
-                    else:
-                        group.add_dir(dir)
-                    
-                elif node._tag == 'symlink':
-                    symlink = symlink_node(node.name[0], node, group)
-                    if symlink in exclude:
-                        mio.log.log(CHATTY,
-                                    "excluding symlink '%s'" % node.name[0])
-                    else:
-                        group.add_symlink(symlink)
-                    
-                elif node._tag == 'file':
-                    file = file_node(node.name[0], node, group)
-                    if file in exclude:
-                        mio.log.log(CHATTY,
-                                    "excluding file '%s'" % node.name[0])
-                    else:
-                        group.add_file(file)
+                self.add_node(group, node, exclude,ignore=self.DEPENDENCY_IGNORE)
+                pass
 
-                else:
-                    raise Exception("unknown tag '%s'" % node._tag)
-                    
             if group in self.group:
                 (old_group, old_chain) = self.group[group][0]
                 try:
@@ -139,7 +95,91 @@ class Installer:
                         group.add_dependency(dep)
 
         return result
-        
+
+    def add_node(self, group, node, exclude,ignore=EMPTY,reject=EMPTY):
+        if node._tag in reject:
+            raise InvalidTag(node, reject)
+        if node._tag in ignore:
+            return
+        if node._tag == 'description':
+            pass
+        elif node._tag == 'dependency':
+            # Dependencies are handled after everything else
+            pass
+        elif node._tag == 'pre':
+            if node.command[0]:
+                group.add_pre(command_node(node))
+                pass
+            if node.script[0]:
+                group.add_pre(script_node(node))
+                pass
+            pass
+        elif node._tag == 'post':
+            if node.command[0]:
+                group.add_post(command_node(node))
+                pass
+            if node.script[0]:
+                group.add_post(script_node(node))
+                pass
+            pass
+        elif node._tag == 'rpm':
+            rpm = rpm_node(node.name[0], node, group)
+            if rpm in exclude:
+                mio.log.log(CHATTY,
+                            "excluding rpm '%s'" % node.name[0])
+                pass
+            else:
+                group.add_rpm(rpm)
+                pass
+            pass
+        elif node._tag == 'dir':
+            dir = dir_node(node.name[0], node, group)
+            if dir in exclude:
+                mio.log.log(CHATTY,
+                            "excluding dir '%s'" % node.name[0])
+                pass
+            else:
+                group.add_dir(dir)
+                pass
+            pass
+        elif node._tag == 'symlink':
+            symlink = symlink_node(node.name[0], node, group)
+            if symlink in exclude:
+                mio.log.log(CHATTY,
+                            "excluding symlink '%s'" % node.name[0])
+                pass
+            else:
+                group.add_symlink(symlink)
+                pass
+            pass
+        elif node._tag == 'file':
+            file = file_node(node.name[0], node, group)
+            if file in exclude:
+                mio.log.log(CHATTY,
+                            "excluding file '%s'" % node.name[0])
+                pass
+            else:
+                group.add_file(file)
+                pass
+            pass
+        elif node._tag == 'select':
+            print('IMPLEMENT select!!!!')
+            select_group = group_node('select', None, self)
+            for node in node._children:
+                self.add_node(select_group, node, exclude,
+                              reject=self.SELECT_REJECT)
+                pass
+            pass
+        elif node._tag == 'when':
+            print('IMPLEMENT when!!!!')
+            when_group = group_node('when', None, self)
+            for node in node._children:
+                self.add_node(when_group, node, exclude, reject=reject)
+                pass
+            pass
+        else:
+            raise Exception("unknown tag '%s'" % node._tag)
+        pass
 
     def add_rpm(self, rpm):
         if rpm.decl.rpms[0:]:
diff --git a/tests/test.mio b/tests/test.mio
deleted file mode 100644
index d783ebb..0000000
--- a/tests/test.mio
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<mio name='test' files='.'
-     scripts='./scripts' mode='0644' dirmode='0755'>
-
-  <group name='test'>
-    <pre command='echo pre $(pwd)'/>
-    <file name='/tmp/test.mio' source='test.mio'/>
-    <symlink name='/tmp/copy_of_test.mio' value='test.mio'/>
-    <post command='echo post $(pwd)'/>
-    <!--systemd service='x'/>-->
-  </group>
-  
-</mio>
-- 
GitLab