summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apt/debfile.py56
-rw-r--r--debian/changelog4
-rw-r--r--po/python-apt.pot34
-rw-r--r--tests/data/test_debs/multiarch-test1_i386.debbin0 -> 978 bytes
-rw-r--r--tests/test_debfile.py13
-rw-r--r--tests/test_debfile_multiarch.py55
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
new file mode 100644
index 00000000..439a9f46
--- /dev/null
+++ b/tests/data/test_debs/multiarch-test1_i386.deb
Binary files differ
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()