1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
# Copyright 1999-2009 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
import sys
import portage
from portage import os
from portage import digraph
from portage._sets.base import InternalPackageSet
from _emerge.BlockerCache import BlockerCache
from _emerge.show_invalid_depstring_notice import show_invalid_depstring_notice
if sys.hexversion >= 0x3000000:
long = int
class BlockerDB(object):
def __init__(self, fake_vartree):
root_config = fake_vartree._root_config
self._root_config = root_config
self._vartree = root_config.trees["vartree"]
self._portdb = root_config.trees["porttree"].dbapi
self._dep_check_trees = None
self._fake_vartree = fake_vartree
self._dep_check_trees = {
self._vartree.root : {
"porttree" : fake_vartree,
"vartree" : fake_vartree,
}}
def findInstalledBlockers(self, new_pkg):
"""
Search for installed run-time blockers in the root where
new_pkg is planned to be installed. This ignores build-time
blockers, since new_pkg is assumed to be built already.
"""
blocker_cache = BlockerCache(self._vartree.root, self._vartree.dbapi)
dep_keys = ["RDEPEND", "PDEPEND"]
settings = self._vartree.settings
stale_cache = set(blocker_cache)
fake_vartree = self._fake_vartree
dep_check_trees = self._dep_check_trees
vardb = fake_vartree.dbapi
installed_pkgs = list(vardb)
for inst_pkg in installed_pkgs:
stale_cache.discard(inst_pkg.cpv)
cached_blockers = blocker_cache.get(inst_pkg.cpv)
if cached_blockers is not None and \
cached_blockers.counter != long(inst_pkg.metadata["COUNTER"]):
cached_blockers = None
if cached_blockers is not None:
blocker_atoms = cached_blockers.atoms
else:
# Use aux_get() to trigger FakeVartree global
# updates on *DEPEND when appropriate.
depstr = " ".join(vardb.aux_get(inst_pkg.cpv, dep_keys))
success, atoms = portage.dep_check(depstr,
vardb, settings, myuse=inst_pkg.use.enabled,
trees=dep_check_trees, myroot=inst_pkg.root)
if not success:
pkg_location = os.path.join(inst_pkg.root,
portage.VDB_PATH, inst_pkg.category, inst_pkg.pf)
portage.writemsg("!!! %s/*DEPEND: %s\n" % \
(pkg_location, atoms), noiselevel=-1)
continue
blocker_atoms = [atom for atom in atoms \
if atom.startswith("!")]
blocker_atoms.sort()
counter = long(inst_pkg.metadata["COUNTER"])
blocker_cache[inst_pkg.cpv] = \
blocker_cache.BlockerData(counter, blocker_atoms)
for cpv in stale_cache:
del blocker_cache[cpv]
blocker_cache.flush()
blocker_parents = digraph()
blocker_atoms = []
for pkg in installed_pkgs:
for blocker_atom in blocker_cache[pkg.cpv].atoms:
blocker_atom = blocker_atom.lstrip("!")
blocker_atoms.append(blocker_atom)
blocker_parents.add(blocker_atom, pkg)
blocker_atoms = InternalPackageSet(initial_atoms=blocker_atoms)
blocking_pkgs = set()
for atom in blocker_atoms.iterAtomsForPackage(new_pkg):
blocking_pkgs.update(blocker_parents.parent_nodes(atom))
# Check for blockers in the other direction.
depstr = " ".join(new_pkg.metadata[k] for k in dep_keys)
success, atoms = portage.dep_check(depstr,
vardb, settings, myuse=new_pkg.use.enabled,
trees=dep_check_trees, myroot=new_pkg.root)
if not success:
# We should never get this far with invalid deps.
show_invalid_depstring_notice(new_pkg, depstr, atoms)
assert False
blocker_atoms = [atom.lstrip("!") for atom in atoms \
if atom[:1] == "!"]
if blocker_atoms:
blocker_atoms = InternalPackageSet(initial_atoms=blocker_atoms)
for inst_pkg in installed_pkgs:
try:
next(blocker_atoms.iterAtomsForPackage(inst_pkg))
except (portage.exception.InvalidDependString, StopIteration):
continue
blocking_pkgs.add(inst_pkg)
return blocking_pkgs
def discardBlocker(self, pkg):
"""Discard a package from the list of potential blockers."""
self._fake_vartree.cpv_discard(pkg)
for slot_match in self._fake_vartree.dbapi.match_pkgs(pkg.slot_atom):
if slot_match.cp == pkg.cp:
self._fake_vartree.cpv_discard(pkg)
|