Support :any architecture qualifiers for multiarch

Multiarch adds a Depends: foo:any syntax, permitted only if the
target of the dependency is "Multi-Arch: allowed".  This has
been supported by dpkg and apt for some time and is now safe to
use in unstable.

[Adam D. Barratt: adjusted to use consts.py]

Signed-off-by: Adam D. Barratt <adam@adam-barratt.org.uk>
debian
Colin Watson 12 years ago committed by Adam D. Barratt
parent a799ce3df1
commit b9f6417351

@ -218,7 +218,7 @@ from britney_util import (old_libraries_format, same_source, undo_changes,
eval_uninst, newly_uninst, make_migrationitem) eval_uninst, newly_uninst, make_migrationitem)
from consts import (VERSION, SECTION, BINARIES, MAINTAINER, FAKESRC, from consts import (VERSION, SECTION, BINARIES, MAINTAINER, FAKESRC,
SOURCE, SOURCEVER, ARCHITECTURE, DEPENDS, CONFLICTS, SOURCE, SOURCEVER, ARCHITECTURE, DEPENDS, CONFLICTS,
PROVIDES, RDEPENDS, RCONFLICTS) PROVIDES, RDEPENDS, RCONFLICTS, MULTIARCH)
__author__ = 'Fabio Tranchitella and the Debian Release Team' __author__ = 'Fabio Tranchitella and the Debian Release Team'
__version__ = '2.0' __version__ = '2.0'
@ -524,6 +524,7 @@ class Britney(object):
pkg, pkg,
version, version,
get_field('Architecture'), get_field('Architecture'),
get_field('Multi-Arch'),
None, # Pre-depends - leave as None for the C-code None, # Pre-depends - leave as None for the C-code
deps, deps,
', '.join(final_conflicts_list) or None, ', '.join(final_conflicts_list) or None,
@ -824,7 +825,7 @@ class Britney(object):
binaries = self.binaries[suite][arch][0] binaries = self.binaries[suite][arch][0]
for pkg in binaries: for pkg in binaries:
output = "Package: %s\n" % pkg output = "Package: %s\n" % pkg
for key, k in ((SECTION, 'Section'), (ARCHITECTURE, 'Architecture'), (SOURCE, 'Source'), (VERSION, 'Version'), for key, k in ((SECTION, 'Section'), (ARCHITECTURE, 'Architecture'), (MULTIARCH, 'Multi-Arch'), (SOURCE, 'Source'), (VERSION, 'Version'),
(DEPENDS, 'Depends'), (PROVIDES, 'Provides'), (CONFLICTS, 'Conflicts')): (DEPENDS, 'Depends'), (PROVIDES, 'Provides'), (CONFLICTS, 'Conflicts')):
if not binaries[pkg][key]: continue if not binaries[pkg][key]: continue
if key == SOURCE: if key == SOURCE:
@ -880,12 +881,19 @@ class Britney(object):
# for every package, version and operation in the block # for every package, version and operation in the block
for name, version, op in block: for name, version, op in block:
if ":" in name:
name, archqual = name.split(":", 1)
else:
archqual = None
# look for the package in unstable # look for the package in unstable
if name in binaries[0]: if name in binaries[0]:
package = binaries[0][name] package = binaries[0][name]
# check the versioned dependency (if present) # check the versioned dependency and architecture qualifier
# (if present)
if op == '' and version == '' or apt_pkg.check_dep(package[VERSION], op, version): if op == '' and version == '' or apt_pkg.check_dep(package[VERSION], op, version):
packages.append(name) if archqual is None or (archqual == 'any' and package[MULTIARCH] == 'allowed'):
packages.append(name)
# look for the package in the virtual packages list and loop on them # look for the package in the virtual packages list and loop on them
for prov in binaries[1].get(name, []): for prov in binaries[1].get(name, []):
@ -893,7 +901,9 @@ class Britney(object):
package = binaries[0][prov] package = binaries[0][prov]
# A provides only satisfies an unversioned dependency # A provides only satisfies an unversioned dependency
# (per Policy Manual §7.5) # (per Policy Manual §7.5)
if op == '' and version == '': # A provides only satisfies a dependency without an
# architecture qualifier (per analysis of apt code)
if op == '' and version == '' and archqual is None:
packages.append(prov) packages.append(prov)
return (len(packages) > 0, packages) return (len(packages) > 0, packages)

@ -29,11 +29,12 @@ FAKESRC = 4
SOURCE = 2 SOURCE = 2
SOURCEVER = 3 SOURCEVER = 3
ARCHITECTURE = 4 ARCHITECTURE = 4
# PREDEPENDS = 5 - No longer used by the python code MULTIARCH = 5
# PREDEPENDS = 6 - No longer used by the python code
# - The C-code needs it for alignment reasons and still check it # - The C-code needs it for alignment reasons and still check it
# but ignore it if it is None (so keep it None). # but ignore it if it is None (so keep it None).
DEPENDS = 6 DEPENDS = 7
CONFLICTS = 7 CONFLICTS = 8
PROVIDES = 8 PROVIDES = 9
RDEPENDS = 9 RDEPENDS = 10
RCONFLICTS = 10 RCONFLICTS = 11

@ -106,23 +106,29 @@ static PyObject *dpkgpackages_add_binary(dpkgpackages *self, PyObject *args) {
pyString = PyList_GetItem(value, 5); pyString = PyList_GetItem(value, 5);
if (pyString == NULL) return NULL; if (pyString == NULL) return NULL;
if (pyString != Py_None) {
pkg->multiarch = PyString_AsString(pyString);
} else pkg->multiarch = NULL;
pyString = PyList_GetItem(value, 6);
if (pyString == NULL) return NULL;
if (pyString != Py_None) { if (pyString != Py_None) {
pkg->depends[0] = read_dep_andor(PyString_AsString(pyString)); pkg->depends[0] = read_dep_andor(PyString_AsString(pyString));
} else pkg->depends[0] = NULL; } else pkg->depends[0] = NULL;
pyString = PyList_GetItem(value, 6); pyString = PyList_GetItem(value, 7);
if (pyString == NULL) return NULL; if (pyString == NULL) return NULL;
if (pyString != Py_None) { if (pyString != Py_None) {
pkg->depends[1] = read_dep_andor(PyString_AsString(pyString)); pkg->depends[1] = read_dep_andor(PyString_AsString(pyString));
} else pkg->depends[1] = NULL; } else pkg->depends[1] = NULL;
pyString = PyList_GetItem(value, 7); pyString = PyList_GetItem(value, 8);
if (pyString == NULL) return NULL; if (pyString == NULL) return NULL;
if (pyString != Py_None) { if (pyString != Py_None) {
pkg->conflicts = read_dep_and(PyString_AsString(pyString)); pkg->conflicts = read_dep_and(PyString_AsString(pyString));
} else pkg->conflicts = NULL; } else pkg->conflicts = NULL;
pyString = PyList_GetItem(value, 8); pyString = PyList_GetItem(value, 9);
if (pyString == NULL) return NULL; if (pyString == NULL) return NULL;
if (pyString != Py_None) { if (pyString != Py_None) {
pkg->provides = read_packagenames(PyString_AsString(pyString)); pkg->provides = read_packagenames(PyString_AsString(pyString));
@ -204,12 +210,13 @@ static PyObject *build_system(PyObject *self, PyObject *args) {
# SOURCE = 2 # SOURCE = 2
# SOURCEVER = 3 # SOURCEVER = 3
# ARCHITECTURE = 4 # ARCHITECTURE = 4
# PREDEPENDS = 5 # MULTIARCH = 5
# DEPENDS = 6 # PREDEPENDS = 6
# CONFLICTS = 7 # DEPENDS = 7
# PROVIDES = 8 # CONFLICTS = 8
# RDEPENDS = 9 # PROVIDES = 9
# RCONFLICTS = 10 # RDEPENDS = 10
# RCONFLICTS = 11
*/ */
dpkg_packages *dpkg_pkgs = new_packages(arch); dpkg_packages *dpkg_pkgs = new_packages(arch);
@ -244,23 +251,29 @@ static PyObject *build_system(PyObject *self, PyObject *args) {
pyString = PyList_GetItem(value, 5); pyString = PyList_GetItem(value, 5);
if (pyString == NULL) continue; if (pyString == NULL) continue;
if (pyString != Py_None) {
pkg->multiarch = PyString_AsString(pyString);
} else pkg->multiarch = NULL;
pyString = PyList_GetItem(value, 6);
if (pyString == NULL) continue;
if (pyString != Py_None) { if (pyString != Py_None) {
pkg->depends[0] = read_dep_andor(PyString_AsString(pyString)); pkg->depends[0] = read_dep_andor(PyString_AsString(pyString));
} else pkg->depends[0] = NULL; } else pkg->depends[0] = NULL;
pyString = PyList_GetItem(value, 6); pyString = PyList_GetItem(value, 7);
if (pyString == NULL) continue; if (pyString == NULL) continue;
if (pyString != Py_None) { if (pyString != Py_None) {
pkg->depends[1] = read_dep_andor(PyString_AsString(pyString)); pkg->depends[1] = read_dep_andor(PyString_AsString(pyString));
} else pkg->depends[1] = NULL; } else pkg->depends[1] = NULL;
pyString = PyList_GetItem(value, 7); pyString = PyList_GetItem(value, 8);
if (pyString == NULL) continue; if (pyString == NULL) continue;
if (pyString != Py_None) { if (pyString != Py_None) {
pkg->conflicts = read_dep_and(PyString_AsString(pyString)); pkg->conflicts = read_dep_and(PyString_AsString(pyString));
} else pkg->conflicts = NULL; } else pkg->conflicts = NULL;
pyString = PyList_GetItem(value, 8); pyString = PyList_GetItem(value, 9);
if (pyString == NULL) continue; if (pyString == NULL) continue;
if (pyString != Py_None) { if (pyString != Py_None) {
pkg->provides = read_packagenames(PyString_AsString(pyString)); pkg->provides = read_packagenames(PyString_AsString(pyString));

@ -24,7 +24,8 @@ static collpackagelist *get_matching(dpkg_packages *pkgs, deplist *depopts, int
static deplist *read_deplist(char **buf, char sep, char end); static deplist *read_deplist(char **buf, char sep, char end);
static dependency *read_dependency(char **buf, char *end); static dependency *read_dependency(char **buf, char *end);
static void add_virtualpackage(virtualpkgtbl *vpkgs, char *package, static void add_virtualpackage(virtualpkgtbl *vpkgs, char *package,
char *version, dpkg_collected_package *cpkg); char *version, char *multiarch,
dpkg_collected_package *cpkg);
static void remove_virtualpackage(virtualpkgtbl *vpkgs, char *pkgname, static void remove_virtualpackage(virtualpkgtbl *vpkgs, char *pkgname,
dpkg_collected_package *cpkg); dpkg_collected_package *cpkg);
static char *read_packagename(char **buf, char *end); static char *read_packagename(char **buf, char *end);
@ -177,9 +178,9 @@ void add_package(dpkg_packages *pkgs, dpkg_package *pkg)
add_packagetbl(pkgs->packages, cpkg->pkg->package, cpkg); add_packagetbl(pkgs->packages, cpkg->pkg->package, cpkg);
add_virtualpackage(pkgs->virtualpkgs, cpkg->pkg->package, add_virtualpackage(pkgs->virtualpkgs, cpkg->pkg->package,
cpkg->pkg->version, cpkg); cpkg->pkg->version, cpkg->pkg->multiarch, cpkg);
for (v = cpkg->pkg->provides; v != NULL; v = v->next) { for (v = cpkg->pkg->provides; v != NULL; v = v->next) {
add_virtualpackage(pkgs->virtualpkgs, v->value, NULL, cpkg); add_virtualpackage(pkgs->virtualpkgs, v->value, NULL, NULL, cpkg);
} }
} }
@ -246,7 +247,8 @@ static void remove_virtualpackage(virtualpkgtbl *vpkgs, char *pkgname,
} }
static void add_virtualpackage(virtualpkgtbl *vpkgs, char *package, static void add_virtualpackage(virtualpkgtbl *vpkgs, char *package,
char *version, dpkg_collected_package *cpkg) char *version, char *multiarch,
dpkg_collected_package *cpkg)
{ {
dpkg_provision value; dpkg_provision value;
virtualpkg *list, **addto; virtualpkg *list, **addto;
@ -254,6 +256,7 @@ static void add_virtualpackage(virtualpkgtbl *vpkgs, char *package,
value.pkg = cpkg; value.pkg = cpkg;
value.version = version; value.version = version;
value.multiarch = multiarch;
list = lookup_virtualpkgtbl(vpkgs, package); list = lookup_virtualpkgtbl(vpkgs, package);
shouldreplace = (list != NULL); shouldreplace = (list != NULL);
@ -398,11 +401,11 @@ deplistlist *read_dep_andor(char *buf) {
static dependency *read_dependency(char **buf, char *end) { static dependency *read_dependency(char **buf, char *end) {
dependency *dep; dependency *dep;
char *name; char *name;
char newend[10]; char newend[11];
DEBUG_ONLY( char *strend = *buf + strlen(*buf); ) DEBUG_ONLY( char *strend = *buf + strlen(*buf); )
assert(strlen(end) <= 8); assert(strlen(end) <= 8);
newend[0] = '('; strcpy(newend + 1, end); newend[0] = '('; newend[1] = ':'; strcpy(newend + 2, end);
name = my_strdup(read_until_char(buf, newend)); name = my_strdup(read_until_char(buf, newend));
if (name == NULL) return NULL; if (name == NULL) return NULL;
@ -411,6 +414,13 @@ static dependency *read_dependency(char **buf, char *end) {
if (dep == NULL) die("read_dependency alloc 1:"); if (dep == NULL) die("read_dependency alloc 1:");
dep->package = name; dep->package = name;
if (**buf == ':') {
(*buf)++;
dep->archqual = my_strdup(read_until_char(buf, newend));
if (dep->archqual == NULL) return NULL;
} else
dep->archqual = NULL;
while(isspace(**buf)) (*buf)++; while(isspace(**buf)) (*buf)++;
@ -465,7 +475,7 @@ static dependency *read_dependency(char **buf, char *end) {
} }
while (isspace(**buf)) (*buf)++; while (isspace(**buf)) (*buf)++;
newend[0] = ')'; newend[0] = ')'; strcpy(newend + 1, end);
dep->version = my_strdup(read_until_char(buf, newend)); dep->version = my_strdup(read_until_char(buf, newend));
while (isspace(**buf)) (*buf)++; while (isspace(**buf)) (*buf)++;
@ -509,6 +519,14 @@ static collpackagelist **get_matching_low(collpackagelist **addto,
} }
} }
if (dep->archqual != NULL) {
if (strcmp(dep->archqual, "any") == 0) {
if (strcmp(vpkg->value.multiarch, "allowed") != 0)
add = 0;
} else
add = 0;
}
if (add) { if (add) {
insert_l_collpackagelist(addto, vpkg->value.pkg, line); insert_l_collpackagelist(addto, vpkg->value.pkg, line);
addto = &(*addto)->next; addto = &(*addto)->next;

@ -33,6 +33,7 @@ extern char *dependency_relation_sym[];
typedef struct dependency dependency; typedef struct dependency dependency;
struct dependency { struct dependency {
char *package; char *package;
char *archqual;
dependency_relation op; dependency_relation op;
char *version; char *version;
}; };
@ -48,6 +49,7 @@ typedef struct dpkg_package dpkg_package;
struct dpkg_package { struct dpkg_package {
char *package; char *package;
char *version; char *version;
char *multiarch;
char *source; char *source;
char *source_ver; char *source_ver;
@ -102,6 +104,7 @@ LIST(collpackagelist, dpkg_collected_package *);
typedef struct dpkg_provision dpkg_provision; typedef struct dpkg_provision dpkg_provision;
struct dpkg_provision { struct dpkg_provision {
char *version; char *version;
char *multiarch;
dpkg_collected_package *pkg; dpkg_collected_package *pkg;
}; };

Loading…
Cancel
Save