]> git.decadent.org.uk Git - dak.git/commitdiff
Add parser for Package-List field.
authorAnsgar Burchardt <ansgar@debian.org>
Sun, 22 Jun 2014 20:27:37 +0000 (22:27 +0200)
committerAnsgar Burchardt <ansgar@debian.org>
Thu, 31 Jul 2014 19:19:28 +0000 (21:19 +0200)
daklib/packagelist.py [new file with mode: 0644]
tests/test_packagelist.py [new file with mode: 0644]

diff --git a/daklib/packagelist.py b/daklib/packagelist.py
new file mode 100644 (file)
index 0000000..82653a0
--- /dev/null
@@ -0,0 +1,128 @@
+"""parse Package-List field
+
+@copyright: 2014, Ansgar Burchardt <ansgar@debian.org>
+@license: GPL-2+
+"""
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+from daklib.architecture import match_architecture
+from daklib.utils import extract_component_from_section
+
+class InvalidSource(Exception):
+    pass
+
+class PackageListEntry(object):
+    def __init__(self, name, package_type, section, component, priority, **other):
+        self.name = name
+        self.package_type = package_type
+        self.section = section
+        self.component = component
+        self.priority = priority
+        self.other = other
+    @property
+    def architectures(self):
+        archs = self.other.get("arch", None)
+        if archs is None:
+            return None
+        return archs.split(',')
+    def built_on_architecture(self, architecture):
+        archs = self.architectures
+        if archs is None:
+            return None
+        for arch in archs:
+            if match_architecture(architecture, arch):
+                return True
+        return False
+    def built_in_suite(self, suite):
+        built = False
+        for arch in suite.architectures:
+            built_on_arch = self.built_on_architecture(arch.arch_string)
+            if built_on_arch:
+                return True
+            if built_on_arch is None:
+                built = None
+        return built
+
+class PackageList(object):
+    def __init__(self, source):
+        self._source = source
+        if 'Package-List' in self._source:
+            self._parse()
+        elif 'Binary' in self._source:
+            self._parse_fallback()
+        else:
+            raise InvalidSource('Source package has neither Package-List nor Binary field.')
+    def _parse(self):
+        self.package_list = {}
+
+        for line in self._source['Package-List'].split("\n"):
+            if not line:
+                continue
+            fields = line.split()
+            if len(fields) < 4:
+                raise InvalidSource("Package-List entry has less than four fields.")
+
+            # <name> <type> <component/section> <priority> [arch=<arch>[,<arch>]...]
+            name = fields[0]
+            package_type = fields[1]
+            component, section = extract_component_from_section(fields[2])
+            priority = fields[3]
+            other = dict(kv.split('=', 1) for kv in fields[4:])
+
+            entry = PackageListEntry(name, package_type, section, component, priority, **other)
+            self.package_list[name] = entry
+
+    def _parse_fallback(self):
+        self.package_list = {}
+
+        for binary in self._source['Binary'].split():
+            name = binary
+            package_type = None
+            component = None
+            section = None
+            priority = None
+            other = dict()
+
+            entry = PackageListEntry(name, package_type, section, component, priority, **other)
+            self.package_list[name] = entry
+
+    def packages_for_suite(self, suite):
+        packages = []
+        for entry in self.package_list.values():
+            built = entry.built_in_suite(suite)
+            if built or built is None:
+                packages.append(entry)
+        return packages
+
+    def has_arch_indep_packages(self):
+        has_arch_indep = False
+        for entry in self.package_list.values():
+            built = entry.built_on_architecture('all')
+            if built:
+                return True
+            if built is None:
+                has_arch_indep = None
+        return has_arch_indep
+
+    def has_arch_dep_packages(self):
+        has_arch_dep = False
+        for entry in self.package_list.values():
+            built_on_all = entry.built_on_architecture('all')
+            if built_on_all == False:
+                return True
+            if built_on_all is None:
+                has_arch_dep = None
+        return has_arch_dep
diff --git a/tests/test_packagelist.py b/tests/test_packagelist.py
new file mode 100644 (file)
index 0000000..7f3629a
--- /dev/null
@@ -0,0 +1,177 @@
+#! /usr/bin/python
+#
+# Copyright (C) 2014, Ansgar Burchardt <ansgar@debian.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+from base_test import DakTestCase
+import unittest
+from daklib.packagelist import PackageList, InvalidSource
+
+class FakeArchitecture(object):
+    def __init__(self, name):
+        self.arch_string = name
+
+class FakeSuite(object):
+    def __init__(self, *architectures):
+        self.architectures = [ FakeArchitecture(a) for a in architectures ]
+
+source_all = {
+    'Package-List': '\n libdune-common-doc deb doc optional arch=all\n',
+    'Binary': 'libdune-common-doc\n',
+    }
+
+source_any = {
+    'Package-List': '\n libdune-common-dev deb libdevel optional arch=any\n',
+    'Binary': 'libdune-common-dev\n',
+    }
+
+source_all_any = {
+    'Package-List': '\n libdune-common-dev deb libdevel optional arch=any\nlibdune-common-doc deb doc optional arch=all\n',
+    'Binary': 'libdune-common-dev libdune-common-doc\n',
+    }
+
+source_amd64 = {
+    'Package-List': '\n libdune-common-dev deb libdevel optional arch=amd64\n',
+    'Binary': 'libdune-common-dev\n',
+    }
+
+source_linuxany = {
+    'Package-List': '\n libdune-common-dev deb libdevel optional arch=linux-any\n',
+    'Binary': 'libdune-common-dev\n',
+    }
+
+source_noarch = {
+    'Package-List': '\n libdune-common-dev deb libdevel optional\n',
+    'Binary': 'libdune-common-dev\n',
+}
+
+source_fallback = {
+    'Binary': 'libdune-common-dev\n',
+}
+
+class TestPackageList(DakTestCase):
+    def testArchAll(self):
+        pl = PackageList(source_all)
+
+        self.assertTrue(pl.has_arch_indep_packages())
+        self.assertFalse(pl.has_arch_dep_packages())
+
+        suite_amd64 = FakeSuite('amd64')
+        p_amd64 = pl.packages_for_suite(suite_amd64)
+        self.assertEqual(len(p_amd64), 0)
+
+        suite_all = FakeSuite('all')
+        p_all = pl.packages_for_suite(suite_all)
+        self.assertEqual(len(p_all), 1)
+
+        suite_all_amd64 = FakeSuite('amd64', 'all')
+        p_all_amd64 = pl.packages_for_suite(suite_all_amd64)
+        self.assertEqual(len(p_all_amd64), 1)
+
+    def testArchAny(self):
+        pl = PackageList(source_any)
+
+        self.assertFalse(pl.has_arch_indep_packages())
+        self.assertTrue(pl.has_arch_dep_packages())
+
+        suite_amd64 = FakeSuite('amd64')
+        p_amd64 = pl.packages_for_suite(suite_amd64)
+        self.assertEqual(len(p_amd64), 1)
+
+        suite_all = FakeSuite('all')
+        p_all = pl.packages_for_suite(suite_all)
+        self.assertEqual(len(p_all), 0)
+
+        suite_all_amd64 = FakeSuite('amd64', 'all')
+        p_all_amd64 = pl.packages_for_suite(suite_all_amd64)
+        self.assertEqual(len(p_all_amd64), 1)
+
+    def testArchAnyAll(self):
+        pl = PackageList(source_all_any)
+
+        self.assertTrue(pl.has_arch_indep_packages())
+        self.assertTrue(pl.has_arch_dep_packages())
+
+        suite_amd64 = FakeSuite('amd64')
+        p_amd64 = pl.packages_for_suite(suite_amd64)
+        self.assertEqual(len(p_amd64), 1)
+
+        suite_amd64_i386 = FakeSuite('amd64', 'i386')
+        p_amd64_i386 = pl.packages_for_suite(suite_amd64_i386)
+        self.assertEqual(len(p_amd64_i386), 1)
+
+        suite_all = FakeSuite('all')
+        p_all = pl.packages_for_suite(suite_all)
+        self.assertEqual(len(p_all), 1)
+
+        suite_all_amd64 = FakeSuite('amd64', 'all')
+        p_all_amd64 = pl.packages_for_suite(suite_all_amd64)
+        self.assertEqual(len(p_all_amd64), 2)
+
+    def testArchAmd64(self):
+        pl = PackageList(source_amd64)
+
+        self.assertFalse(pl.has_arch_indep_packages())
+        self.assertTrue(pl.has_arch_dep_packages())
+
+        suite_amd64 = FakeSuite('amd64')
+        p_amd64 = pl.packages_for_suite(suite_amd64)
+        self.assertEqual(len(p_amd64), 1)
+
+        suite_i386 = FakeSuite('i386')
+        p_i386 = pl.packages_for_suite(suite_i386)
+        self.assertEqual(len(p_i386), 0)
+
+    def testArchLinuxAny(self):
+        pl = PackageList(source_linuxany)
+
+        self.assertFalse(pl.has_arch_indep_packages())
+        self.assertTrue(pl.has_arch_dep_packages())
+
+        suite_amd64 = FakeSuite('amd64')
+        p_amd64 = pl.packages_for_suite(suite_amd64)
+        self.assertEqual(len(p_amd64), 1)
+
+        suite_i386 = FakeSuite('i386')
+        p_i386 = pl.packages_for_suite(suite_i386)
+        self.assertEqual(len(p_i386), 1)
+
+        suite_kfreebsdi386 = FakeSuite('kfreebsd-i386')
+        p_kfreebsdi386 = pl.packages_for_suite(suite_kfreebsdi386)
+        self.assertEqual(len(p_kfreebsdi386), 0)
+
+    def testNoArch(self):
+        pl = PackageList(source_noarch)
+
+        self.assertIsNone(pl.has_arch_indep_packages())
+        self.assertIsNone(pl.has_arch_dep_packages())
+
+        suite_amd64 = FakeSuite('amd64')
+        p_amd64 = pl.packages_for_suite(suite_amd64)
+        self.assertEqual(len(p_amd64), 1)
+
+    def testFallback(self):
+        pl = PackageList(source_fallback)
+
+        self.assertIsNone(pl.has_arch_indep_packages())
+        self.assertIsNone(pl.has_arch_dep_packages())
+
+        suite_amd64 = FakeSuite('amd64')
+        p_amd64 = pl.packages_for_suite(suite_amd64)
+        self.assertEqual(len(p_amd64), 1)
+
+if __name__ == '__main__':
+    unittest.main()