diff options
| -rw-r--r-- | apt/debfile.py | 56 | ||||
| -rw-r--r-- | debian/changelog | 4 | ||||
| -rw-r--r-- | po/python-apt.pot | 34 | ||||
| -rw-r--r-- | tests/data/test_debs/multiarch-test1_i386.deb | bin | 0 -> 978 bytes | |||
| -rw-r--r-- | tests/test_debfile.py | 13 | ||||
| -rw-r--r-- | tests/test_debfile_multiarch.py | 55 |
6 files changed, 129 insertions, 33 deletions
diff --git a/apt/debfile.py b/apt/debfile.py index 17f1dbd9..160a4a72 100644 --- a/apt/debfile.py +++ b/apt/debfile.py @@ -55,6 +55,7 @@ class DebPackage(object): self._need_pkgs = [] self._check_was_run = False self._failure_string = "" + self._multiarch = None if filename: self.open(filename) @@ -85,6 +86,35 @@ class DebPackage(object): self.filename)] return files + # helper that will return a pkgname with a multiarch suffix if needed + def _maybe_append_multiarch_suffix(self, pkgname, + in_conflict_checking=False): + # trivial cases + if not self._multiarch: + return pkgname + elif self._cache.is_virtual_package(pkgname): + return pkgname + elif self._cache[pkgname].candidate.architecture == "all": + return pkgname + # now do the real multiarch checking + multiarch_pkgname = "%s:%s" % (pkgname, self._multiarch) + # the upper layers will handle this + if not multiarch_pkgname in self._cache: + return multiarch_pkgname + # now check the multiarch state + cand = self._cache[multiarch_pkgname].candidate._cand + #print pkgname, multiarch_pkgname, cand.multi_arch + # the default is to add the suffix, unless its a pkg that can satify + # foreign dependencies + if cand.multi_arch & cand.MULTI_ARCH_FOREIGN: + return pkgname + # for conflicts we need a special case here, any not multiarch enabled + # package has a implicit conflict + if (in_conflict_checking and + not (cand.multi_arch & cand.MULTI_ARCH_SAME)): + return pkgname + return multiarch_pkgname + def _is_or_group_satisfied(self, or_group): """Return True if at least one dependency of the or-group is satisfied. @@ -98,6 +128,9 @@ class DebPackage(object): ver = dep[1] oper = dep[2] + # multiarch + depname = self._maybe_append_multiarch_suffix(depname) + # check for virtual pkgs if not depname in self._cache: if self._cache.is_virtual_package(depname): @@ -133,6 +166,9 @@ class DebPackage(object): for dep in or_group: depname, ver, oper = dep + # multiarch + depname = self._maybe_append_multiarch_suffix(depname) + # if we don't have it in the cache, it may be virtual if not depname in self._cache: if not self._cache.is_virtual_package(depname): @@ -205,6 +241,11 @@ class DebPackage(object): ver = dep[1] oper = dep[2] + # FIXME: is this good enough? i.e. will apt always populate + # the cache with conflicting pkgnames for our arch? + depname = self._maybe_append_multiarch_suffix( + depname, in_conflict_checking=True) + # check conflicts with virtual pkgs if not depname in self._cache: # FIXME: we have to check for virtual replaces here as @@ -405,9 +446,14 @@ class DebPackage(object): return False arch = self._sections["Architecture"] if arch != "all" and arch != apt_pkg.config.find("APT::Architecture"): - self._dbg(1, "ERROR: Wrong architecture dude!") - self._failure_string = _("Wrong architecture '%s'") % arch - return False + if arch in apt_pkg.get_architectures(): + self._multiarch = arch + self.pkgname = "%s:%s" % (self.pkgname, self._multiarch) + self._dbg(1, "Found multiarch arch: '%s'" % arch) + else: + self._dbg(1, "ERROR: Wrong architecture dude!") + self._failure_string = _("Wrong architecture '%s'") % arch + return False # check version if self.compare_to_version_in_cache() == self.VERSION_OUTDATED: @@ -673,7 +719,7 @@ class DscSrcPackage(DebPackage): def _test(): """Test function""" from apt.cache import Cache - from apt.progress import DpkgInstallProgress + from apt.progress.base import InstallProgress cache = Cache() @@ -695,7 +741,7 @@ def _test(): print d.filelist print "Installing ..." - ret = d.install(DpkgInstallProgress()) + ret = d.install(InstallProgress()) print ret #s = DscSrcPackage(cache, "../tests/3ddesktop_0.2.9-6.dsc") diff --git a/debian/changelog b/debian/changelog index d5b68082..2b16a2bd 100644 --- a/debian/changelog +++ b/debian/changelog @@ -2,6 +2,10 @@ python-apt (0.8.3) UNRELEASED; urgency=low [ Alexey Feldgendler ] * handle architecture-specific conflicts correctly (LP: #829138) + + [ Michael Vogt ] + * lp:~mvo/python-apt/debfile-multiarch: + - add multiarch support to the debfile.py code -- Michael Vogt <michael.vogt@ubuntu.com> Thu, 08 Dec 2011 17:26:37 +0100 diff --git a/po/python-apt.pot b/po/python-apt.pot index 8772e88b..f1aecc59 100644 --- a/po/python-apt.pot +++ b/po/python-apt.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2011-12-01 13:58+0100\n" +"POT-Creation-Date: 2011-12-08 20:01+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -474,23 +474,23 @@ msgid "" "Please check your Internet connection." msgstr "" -#: ../apt/debfile.py:84 +#: ../apt/debfile.py:85 #, python-format msgid "List of files for '%s' could not be read" msgstr "" -#: ../apt/debfile.py:169 +#: ../apt/debfile.py:205 #, python-format msgid "Dependency is not satisfiable: %s\n" msgstr "" -#: ../apt/debfile.py:190 +#: ../apt/debfile.py:226 #, python-format msgid "Conflicts with the installed package '%s'" msgstr "" #. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation -#: ../apt/debfile.py:329 +#: ../apt/debfile.py:371 #, python-format msgid "" "Breaks existing package '%(pkgname)s' dependency %(depname)s " @@ -498,63 +498,63 @@ msgid "" msgstr "" #. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation -#: ../apt/debfile.py:345 +#: ../apt/debfile.py:387 #, python-format msgid "" "Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " "%(targetver)s)" msgstr "" -#: ../apt/debfile.py:355 +#: ../apt/debfile.py:397 #, python-format msgid "" "Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " "the '%(debfile)s' provides it via: '%(provides)s'" msgstr "" -#: ../apt/debfile.py:403 +#: ../apt/debfile.py:445 msgid "No Architecture field in the package" msgstr "" -#: ../apt/debfile.py:408 +#: ../apt/debfile.py:455 #, python-format msgid "Wrong architecture '%s'" msgstr "" #. the deb is older than the installed -#: ../apt/debfile.py:415 +#: ../apt/debfile.py:462 msgid "A later version is already installed" msgstr "" -#: ../apt/debfile.py:440 +#: ../apt/debfile.py:487 msgid "Failed to satisfy all dependencies (broken cache)" msgstr "" -#: ../apt/debfile.py:470 +#: ../apt/debfile.py:517 #, python-format msgid "Cannot install '%s'" msgstr "" -#: ../apt/debfile.py:514 +#: ../apt/debfile.py:561 msgid "Python-debian module not available" msgstr "" -#: ../apt/debfile.py:557 +#: ../apt/debfile.py:604 msgid "" "Automatically decompressed:\n" "\n" msgstr "" -#: ../apt/debfile.py:563 +#: ../apt/debfile.py:610 msgid "Automatically converted to printable ascii:\n" msgstr "" -#: ../apt/debfile.py:653 +#: ../apt/debfile.py:700 #, python-format msgid "Install Build-Dependencies for source package '%s' that builds %s\n" msgstr "" -#: ../apt/debfile.py:664 +#: ../apt/debfile.py:711 msgid "An essential package would be removed" msgstr "" diff --git a/tests/data/test_debs/multiarch-test1_i386.deb b/tests/data/test_debs/multiarch-test1_i386.deb Binary files differnew file mode 100644 index 00000000..439a9f46 --- /dev/null +++ b/tests/data/test_debs/multiarch-test1_i386.deb diff --git a/tests/test_debfile.py b/tests/test_debfile.py index af04af26..04a6b65a 100644 --- a/tests/test_debfile.py +++ b/tests/test_debfile.py @@ -17,8 +17,8 @@ sys.path.insert(0, get_library_dir()) import apt_pkg import apt.debfile -class TestDebfilee(unittest.TestCase): - """ test the apt cache """ +class TestDebfile(unittest.TestCase): + """ test the debfile """ TEST_DEBS = [ # conflicts with apt @@ -131,15 +131,6 @@ Description: testpackage for gdebi - contains usr/bin/binary for file reading # we need to support python2.6 self.assertTrue(raised) - def test_multiarch_deb(self): - if apt_pkg.get_architectures() != ["amd64", "i386"]: - logging.warn("skipping test because running on a non-multiarch system") - return - deb = apt.debfile.DebPackage("./data/test_debs/multiarch-test1_i386.deb") - res = deb.check() - # FIXME: do something sensible with the multiarch test - - if __name__ == "__main__": #logging.basicConfig(level=logging.DEBUG) diff --git a/tests/test_debfile_multiarch.py b/tests/test_debfile_multiarch.py new file mode 100644 index 00000000..7c02a32a --- /dev/null +++ b/tests/test_debfile_multiarch.py @@ -0,0 +1,55 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# Copyright (C) 2010 Michael Vogt <mvo@ubuntu.com> +# +# Copying and distribution of this file, with or without modification, +# are permitted in any medium without royalty provided the copyright +# notice and this notice are preserved. +"""Unit tests for verifying the correctness of DebPackage in apt.debfile.""" +import os +import logging +import unittest + +from test_all import get_library_dir +import sys +sys.path.insert(0, get_library_dir()) +import apt +import apt_pkg +import apt.debfile + +class TestDebfileMultiarch(unittest.TestCase): + """ test the multiarch debfile """ + + def test_multiarch_deb_check(self): + if apt_pkg.get_architectures() != ["amd64", "i386"]: + logging.warn("skipping test because running on a non-multiarch system") + return + deb = apt.debfile.DebPackage( + "./data/test_debs/multiarch-test1_i386.deb") + missing = deb.missing_deps + #print missing + self.assertFalse("dpkg:i386" in missing) + + def test_multiarch_conflicts(self): + cache = apt.Cache() + # WARNING: this assumes that lib3ds-1-3 is a non-multiarch lib + # use "lib3ds-1-3" as a test to see if non-multiach lib conflicts work + canary = "lib3ds-1-3" + if not canary in cache: + logging.warn("skipping test because %s is missing" % canary) + return + cache[canary].mark_install() + deb = apt.debfile.DebPackage( + "./data/test_debs/multiarch-test1_i386.deb", cache=cache) + # this deb should now not be installable + installable = deb.check() + #print deb._failure_string + self.assertFalse(installable) + self.assertEqual(deb._failure_string, + "Conflicts with the installed package 'lib3ds-1-3'") + + + +if __name__ == "__main__": + unittest.main() |
