Teach excuse_unsat_deps() about components ogre model

master
Dimitri John Ledkov 8 years ago committed by Martin Pitt
parent 158d7ca479
commit d2cde7de2b

@ -213,7 +213,7 @@ from britney2.utils import (old_libraries_format, undo_changes,
create_provides_map, read_release_file, create_provides_map, read_release_file,
read_sources_file, get_dependency_solvers, read_sources_file, get_dependency_solvers,
invalidate_excuses, compile_nuninst, invalidate_excuses, compile_nuninst,
ensuredir, ensuredir, get_component, allowed_component,
) )
__author__ = 'Fabio Tranchitella and the Debian Release Team' __author__ = 'Fabio Tranchitella and the Debian Release Team'
@ -1102,11 +1102,16 @@ class Britney(object):
return True return True
is_all_ok = True is_all_ok = True
# Don't check components when testing PPAs, as they do not have this concept
if self.options.adt_ppas:
component = None
else:
component = get_component(binary_u.section)
# for every dependency block (formed as conjunction of disjunction) # for every dependency block (formed as conjunction of disjunction)
for block, block_txt in zip(parse_depends(deps), deps.split(',')): for block, block_txt in zip(parse_depends(deps), deps.split(',')):
# if the block is satisfied in testing, then skip the block # if the block is satisfied in testing, then skip the block
packages = get_dependency_solvers(block, binaries_t_a, provides_t_a) packages = get_dependency_solvers(block, binaries_t_a, provides_t_a, component=component)
if packages: if packages:
for p in packages: for p in packages:
if p not in binaries_s_a: if p not in binaries_s_a:
@ -1115,7 +1120,7 @@ class Britney(object):
continue continue
# check if the block can be satisfied in the source suite, and list the solving packages # check if the block can be satisfied in the source suite, and list the solving packages
packages = get_dependency_solvers(block, binaries_s_a, provides_s_a) packages = get_dependency_solvers(block, binaries_s_a, provides_s_a, component=component)
packages = [binaries_s_a[p].source for p in packages] packages = [binaries_s_a[p].source for p in packages]
# if the dependency can be satisfied by the same source package, skip the block: # if the dependency can be satisfied by the same source package, skip the block:

@ -34,3 +34,9 @@ DEPENDS = 6
CONFLICTS = 7 CONFLICTS = 7
PROVIDES = 8 PROVIDES = 8
ESSENTIAL = 9 ESSENTIAL = 9
# components
MAIN = 0
RESTRICTED = 1
UNIVERSE = 2
MULTIVERSE = 3

@ -38,6 +38,7 @@ from britney2.consts import (VERSION, PROVIDES, DEPENDS, CONFLICTS,
ARCHITECTURE, SECTION, ARCHITECTURE, SECTION,
SOURCE, MAINTAINER, MULTIARCH, SOURCE, MAINTAINER, MULTIARCH,
ESSENTIAL) ESSENTIAL)
from britney2.consts import (MAIN, RESTRICTED, UNIVERSE, MULTIVERSE)
from britney2.migrationitem import MigrationItem, UnversionnedMigrationItem from britney2.migrationitem import MigrationItem, UnversionnedMigrationItem
@ -745,13 +746,17 @@ def read_sources_file(filename, sources=None, intern=sys.intern):
return sources return sources
def get_dependency_solvers(block, binaries_s_a, provides_s_a, *, empty_set=frozenset()): def get_dependency_solvers(block, binaries_s_a, provides_s_a, *, empty_set=frozenset(), component=None):
"""Find the packages which satisfy a dependency block """Find the packages which satisfy a dependency block
This method returns the list of packages which satisfy a dependency This method returns the list of packages which satisfy a dependency
block (as returned by apt_pkg.parse_depends) in a package table block (as returned by apt_pkg.parse_depends) in a package table
for a given suite and architecture (a la self.binaries[suite][arch]) for a given suite and architecture (a la self.binaries[suite][arch])
If component was not specified, use all available (multiverse). This is to
avoid britney pretending that a bunch of things are non-installable in
release pocket, and start trading components-mismatches things.
:param block: The dependency block as parsed by apt_pkg.parse_depends :param block: The dependency block as parsed by apt_pkg.parse_depends
:param binaries_s_a: A dict mapping package names to the relevant BinaryPackage :param binaries_s_a: A dict mapping package names to the relevant BinaryPackage
:param provides_s_a: A dict mapping package names to their providers (as generated by parse_provides) :param provides_s_a: A dict mapping package names to their providers (as generated by parse_provides)
@ -774,7 +779,8 @@ def get_dependency_solvers(block, binaries_s_a, provides_s_a, *, empty_set=froze
# (if present) # (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):
if archqual is None or (archqual == 'any' and package.multi_arch == 'allowed'): if archqual is None or (archqual == 'any' and package.multi_arch == 'allowed'):
packages.append(name) if component is None or allowed_component(component, get_component(package.section)):
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, prov_version in provides_s_a.get(name, empty_set): for prov, prov_version in provides_s_a.get(name, empty_set):
@ -865,3 +871,34 @@ def compile_nuninst(binaries_t, inst_tester, architectures, nobreakall_arches):
nuninst[arch].remove(pkg_name) nuninst[arch].remove(pkg_name)
return nuninst return nuninst
def get_component(section):
"""Parse section and return component
Given a section, return component. Packages in MAIN have no
prefix, all others have <component>/ prefix.
"""
name2component = {
"restricted": RESTRICTED,
"universe": UNIVERSE,
"multiverse": MULTIVERSE
}
if '/' in section:
return name2component[section.split('/', 1)[0]]
return MAIN
def allowed_component(me, dep):
"""Check if I can depend on the other component"""
component_dependencies = {
MAIN: [MAIN],
RESTRICTED: [MAIN, RESTRICTED],
UNIVERSE: [MAIN, UNIVERSE],
MULTIVERSE: [MAIN, RESTRICTED, UNIVERSE, MULTIVERSE],
}
return dep in component_dependencies[me]

@ -0,0 +1,52 @@
#!/usr/bin/python3
# (C) 2014 - 2016 Canonical Ltd.
#
# 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.
import os
import sys
import unittest
PROJECT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, PROJECT_DIR)
from britney2.utils import get_component, allowed_component
from britney2.consts import MAIN, RESTRICTED, UNIVERSE, MULTIVERSE
class UtilTests(unittest.TestCase):
def test_get_component(self):
self.assertEqual(get_component('utils'), MAIN)
self.assertEqual(get_component('utils'), MAIN)
self.assertEqual(get_component('restricted/admin'), RESTRICTED)
self.assertEqual(get_component('universe/web'), UNIVERSE)
self.assertEqual(get_component('multiverse/libs'), MULTIVERSE)
def test_allowed_component(self):
self.assertTrue(allowed_component(MAIN, MAIN))
self.assertFalse(allowed_component(MAIN, UNIVERSE))
self.assertFalse(allowed_component(MAIN, MULTIVERSE))
self.assertFalse(allowed_component(MAIN, RESTRICTED))
self.assertTrue(allowed_component(RESTRICTED, MAIN))
self.assertFalse(allowed_component(RESTRICTED, UNIVERSE))
self.assertFalse(allowed_component(RESTRICTED, MULTIVERSE))
self.assertTrue(allowed_component(RESTRICTED, RESTRICTED))
self.assertTrue(allowed_component(UNIVERSE, MAIN))
self.assertTrue(allowed_component(UNIVERSE, UNIVERSE))
self.assertFalse(allowed_component(UNIVERSE, MULTIVERSE))
self.assertFalse(allowed_component(UNIVERSE, RESTRICTED))
self.assertTrue(allowed_component(MULTIVERSE, MAIN))
self.assertTrue(allowed_component(MULTIVERSE, UNIVERSE))
self.assertTrue(allowed_component(MULTIVERSE, MULTIVERSE))
self.assertTrue(allowed_component(MULTIVERSE, RESTRICTED))
if __name__ == '__main__':
unittest.main()
Loading…
Cancel
Save