Add initial code
[ta/build-tools.git] / tools / rpm.py
diff --git a/tools/rpm.py b/tools/rpm.py
new file mode 100755 (executable)
index 0000000..efd7365
--- /dev/null
@@ -0,0 +1,99 @@
+# Copyright 2019 Nokia
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import re
+
+
+class RpmData(dict):
+
+    @property
+    def name(self):
+        return self['Name']
+
+    @property
+    def epoch(self):
+        return self.get('Epoch', '0')
+
+    @property
+    def version(self):
+        return self['Version']
+
+    @property
+    def release(self):
+        return self['Release']
+
+    @property
+    def arch(self):
+        return self['Architecture']
+
+    @property
+    def vendor(self):
+        return self.get('Vendor', '')
+
+    @property
+    def license(self):
+        return self.get('License', '')
+
+    def __str__(self):
+        return '{}-{}-{}.{}'.format(self.name,
+                                    self.version,
+                                    self.release,
+                                    self.arch)
+
+    def is_same_package_as(self, other):
+        for attr in ['name', 'epoch', 'version', 'release', 'arch']:
+            if getattr(self, attr) != getattr(other, attr):
+                return False
+        return True
+
+
+class RpmInfoParser(object):
+    """
+    Parse 'rpm -qi' output
+    """
+
+    def parse_file(self, rpm_info_installed_file_path):
+        with open(rpm_info_installed_file_path, 'r') as f:
+            return self.parse_multiple(f.read())
+
+    def parse_multiple(self, rpm_info_output_multiple):
+        packages = []
+        package_index = -1
+        for line in rpm_info_output_multiple.splitlines():
+            if re.match(r'^Name\s+:.*', line):
+                packages.append(line)
+                package_index += 1
+            else:
+                packages[package_index] += '\n' + line
+        return [self.parse_package(pkg) for pkg in packages]
+
+    @staticmethod
+    def parse_package(rpm_info_output):
+        result = RpmData()
+        current_key = None
+        colon_location = rpm_info_output.splitlines()[0].find(':')
+        matcher = re.compile(r'^([A-Z][A-Za-z0-9 ]{{{}}}):( ?| .+)$'.format(colon_location - 1))
+        for line in rpm_info_output.splitlines():
+            match = matcher.match(line)
+            if match:
+                parsed_key = match.group(1).rstrip()
+                parsed_value = match.group(2).strip()
+                result[parsed_key] = parsed_value
+                current_key = parsed_key
+            else:
+                if not result[current_key]:
+                    result[current_key] = line
+                else:
+                    result[current_key] = result[current_key] + '\n' + line
+        return result