1 |
Author: grobian |
2 |
Date: 2008-04-14 17:49:59 +0000 (Mon, 14 Apr 2008) |
3 |
New Revision: 9893 |
4 |
|
5 |
Modified: |
6 |
main/branches/prefix/bin/emerge-webrsync |
7 |
main/branches/prefix/pym/_emerge/__init__.py |
8 |
main/branches/prefix/pym/portage/sets/files.py |
9 |
Log: |
10 |
Merged from trunk 9869:9891 |
11 |
|
12 |
| 9870 | Make _dep_check_composite_db match() return multiple slots | |
13 |
| zmedico | so that it behaves more like other dbapi instances would, | |
14 |
| | and also make it inherit from dbapi. | |
15 |
|
16 |
| 9871 | Fix _dep_check_composite_db.match() so that it doesn't | |
17 |
| zmedico | exempt the highest slot from visibility checks. | |
18 |
|
19 |
| 9872 | Fix the _dep_check_composite_db visibility filtering some | |
20 |
| zmedico | more. | |
21 |
|
22 |
| 9873 | Improve lookahead for new-style virtuals: * Substitue the | |
23 |
| zmedico | graph tree for the vartree in dep_check() since we want atom | |
24 |
| | selections to be consistent with package selections have | |
25 |
| | already been made. * Add the selected package to the graph | |
26 |
| | as soon as possible so that later dep_check() calls can use | |
27 |
| | it as feedback for making more consistent atom selections. * | |
28 |
| | Expand all slots of new-style virtuals inside | |
29 |
| | _dep_check_composite_db so that lookahead examines a matched | |
30 |
| | slots. This solves some cases of bug #1343, and extends the | |
31 |
| | fix for bug #141118 to work in cases when a virtual is not | |
32 |
| | yet installed but it has been pulled into the graph. | |
33 |
|
34 |
| 9874 | To optimize consistency of atom selections, add all of the | |
35 |
| zmedico | root packages to the graph before processing any | |
36 |
| | dependencies. | |
37 |
|
38 |
| 9879 | * For optimal atom selection, use PackageVirtualDbapi | |
39 |
| zmedico | instances in place of the vardb for all dep_check() calls. * | |
40 |
| | Replace dep_check_trees in depgraph.validate_blockers() with | |
41 |
| | the equivalent self._graph_trees reference. | |
42 |
|
43 |
| 9881 | Fix buggy logic in WorldSet.load() that causes it to discard | |
44 |
| zmedico | all of it's atoms in some cases (leading to loss of the | |
45 |
| | whole world file). | |
46 |
|
47 |
| 9882 | Fix some more broken logic inside WorldSet.load(). | |
48 |
| zmedico | | |
49 |
|
50 |
| 9883 | s/timetasmp/timestamp/ | |
51 |
| zmedico | | |
52 |
|
53 |
| 9884 | Split out a depgraph._add_dep() method. | |
54 |
| zmedico | | |
55 |
|
56 |
| 9885 | Call depgraph._add_dep() to add package dependencies to the | |
57 |
| zmedico | graph as soon as possible rather than pushing them onto the | |
58 |
| | stack. | |
59 |
|
60 |
| 9886 | Fix some breakage in the allow_unsatisfied handling. | |
61 |
| zmedico | | |
62 |
|
63 |
| 9890 | When regenerating USE_EXPAND in config.setcpv(), improve | |
64 |
| zmedico | performance by using regular expression instead of | |
65 |
| | str.startswith(). | |
66 |
|
67 |
| 9891 | Revert back to using startwith because I screwed up my | |
68 |
| zmedico | benchmark and it turns out starswith is faster than using | |
69 |
| | regular expressions. | |
70 |
|
71 |
|
72 |
Modified: main/branches/prefix/bin/emerge-webrsync |
73 |
=================================================================== |
74 |
--- main/branches/prefix/bin/emerge-webrsync 2008-04-14 17:48:19 UTC (rev 9892) |
75 |
+++ main/branches/prefix/bin/emerge-webrsync 2008-04-14 17:49:59 UTC (rev 9893) |
76 |
@@ -260,7 +260,7 @@ |
77 |
# |
78 |
if [ ${have_files} -eq 1 ]; then |
79 |
|
80 |
- vecho "Getting snapshot timetasmp ..." |
81 |
+ vecho "Getting snapshot timestamp ..." |
82 |
local snapshot_timestamp=$(get_snapshot_timestamp "${file}") |
83 |
|
84 |
if [ ${ignore_timestamp} == 0 ]; then |
85 |
|
86 |
Modified: main/branches/prefix/pym/_emerge/__init__.py |
87 |
=================================================================== |
88 |
--- main/branches/prefix/pym/_emerge/__init__.py 2008-04-14 17:48:19 UTC (rev 9892) |
89 |
+++ main/branches/prefix/pym/_emerge/__init__.py 2008-04-14 17:49:59 UTC (rev 9893) |
90 |
@@ -1620,11 +1620,13 @@ |
91 |
pass |
92 |
graph_tree.dbapi = fakedb |
93 |
self._graph_trees[myroot] = {} |
94 |
- self._graph_trees[myroot]["porttree"] = graph_tree |
95 |
- self._graph_trees[myroot]["vartree"] = self.trees[myroot]["vartree"] |
96 |
- del vardb, fakedb |
97 |
self._filtered_trees[myroot] = {} |
98 |
- self._filtered_trees[myroot]["vartree"] = self.trees[myroot]["vartree"] |
99 |
+ # Substitute the graph tree for the vartree in dep_check() since we |
100 |
+ # want atom selections to be consistent with package selections |
101 |
+ # have already been made. |
102 |
+ self._graph_trees[myroot]["porttree"] = graph_tree |
103 |
+ self._graph_trees[myroot]["vartree"] = graph_tree |
104 |
+ self._filtered_trees[myroot]["vartree"] = graph_tree |
105 |
def filtered_tree(): |
106 |
pass |
107 |
filtered_tree.dbapi = self._dep_check_composite_db(self, myroot) |
108 |
@@ -1795,69 +1797,75 @@ |
109 |
return None |
110 |
|
111 |
def _create_graph(self, allow_unsatisfied=False): |
112 |
- debug = "--debug" in self.myopts |
113 |
- buildpkgonly = "--buildpkgonly" in self.myopts |
114 |
- nodeps = "--nodeps" in self.myopts |
115 |
- empty = "empty" in self.myparams |
116 |
- deep = "deep" in self.myparams |
117 |
- consistent = "consistent" in self.myparams |
118 |
dep_stack = self._dep_stack |
119 |
while dep_stack: |
120 |
dep = dep_stack.pop() |
121 |
if isinstance(dep, Package): |
122 |
- if not self._add_pkg_deps(dep): |
123 |
+ if not self._add_pkg_deps(dep, |
124 |
+ allow_unsatisfied=allow_unsatisfied): |
125 |
return 0 |
126 |
continue |
127 |
- update = "--update" in self.myopts and dep.depth <= 1 |
128 |
- if dep.blocker: |
129 |
- if not buildpkgonly and \ |
130 |
- not nodeps and \ |
131 |
- dep.parent not in self._slot_collision_nodes: |
132 |
- if dep.parent.onlydeps: |
133 |
- # It's safe to ignore blockers if the |
134 |
- # parent is an --onlydeps node. |
135 |
- continue |
136 |
- # The blocker applies to the root where |
137 |
- # the parent is or will be installed. |
138 |
- self.blocker_parents.setdefault( |
139 |
- ("blocks", dep.parent.root, dep.atom), set()).add( |
140 |
- dep.parent) |
141 |
- continue |
142 |
- dep_pkg, existing_node = self._select_package(dep.root, dep.atom, |
143 |
- onlydeps=dep.onlydeps) |
144 |
- if not dep_pkg: |
145 |
- if allow_unsatisfied: |
146 |
- self._unsatisfied_deps.append(dep) |
147 |
- continue |
148 |
- self._unsatisfied_deps_for_display.append( |
149 |
- ((dep.root, dep.atom), {"myparent":dep.parent})) |
150 |
+ if not self._add_dep(dep, allow_unsatisfied=allow_unsatisfied): |
151 |
return 0 |
152 |
- # In some cases, dep_check will return deps that shouldn't |
153 |
- # be proccessed any further, so they are identified and |
154 |
- # discarded here. Try to discard as few as possible since |
155 |
- # discarded dependencies reduce the amount of information |
156 |
- # available for optimization of merge order. |
157 |
- if dep.priority.satisfied and \ |
158 |
- not (existing_node or empty or deep or update): |
159 |
- myarg = None |
160 |
- if dep.root == self.target_root: |
161 |
- try: |
162 |
- myarg = self._iter_atoms_for_pkg(dep_pkg).next() |
163 |
- except StopIteration: |
164 |
- pass |
165 |
- except portage.exception.InvalidDependString: |
166 |
- if not dep_pkg.installed: |
167 |
- # This shouldn't happen since the package |
168 |
- # should have been masked. |
169 |
- raise |
170 |
- if not myarg: |
171 |
- if consistent: |
172 |
- self._ignored_deps.append(dep) |
173 |
- continue |
174 |
+ return 1 |
175 |
|
176 |
- if not self._add_pkg(dep_pkg, dep.parent, |
177 |
- priority=dep.priority, depth=dep.depth): |
178 |
- return 0 |
179 |
+ def _add_dep(self, dep, allow_unsatisfied=False): |
180 |
+ debug = "--debug" in self.myopts |
181 |
+ buildpkgonly = "--buildpkgonly" in self.myopts |
182 |
+ nodeps = "--nodeps" in self.myopts |
183 |
+ empty = "empty" in self.myparams |
184 |
+ deep = "deep" in self.myparams |
185 |
+ consistent = "consistent" in self.myparams |
186 |
+ update = "--update" in self.myopts and dep.depth <= 1 |
187 |
+ if dep.blocker: |
188 |
+ if not buildpkgonly and \ |
189 |
+ not nodeps and \ |
190 |
+ dep.parent not in self._slot_collision_nodes: |
191 |
+ if dep.parent.onlydeps: |
192 |
+ # It's safe to ignore blockers if the |
193 |
+ # parent is an --onlydeps node. |
194 |
+ return 1 |
195 |
+ # The blocker applies to the root where |
196 |
+ # the parent is or will be installed. |
197 |
+ self.blocker_parents.setdefault( |
198 |
+ ("blocks", dep.parent.root, dep.atom), set()).add( |
199 |
+ dep.parent) |
200 |
+ return 1 |
201 |
+ dep_pkg, existing_node = self._select_package(dep.root, dep.atom, |
202 |
+ onlydeps=dep.onlydeps) |
203 |
+ if not dep_pkg: |
204 |
+ if allow_unsatisfied: |
205 |
+ self._unsatisfied_deps.append(dep) |
206 |
+ return 1 |
207 |
+ self._unsatisfied_deps_for_display.append( |
208 |
+ ((dep.root, dep.atom), {"myparent":dep.parent})) |
209 |
+ return 0 |
210 |
+ # In some cases, dep_check will return deps that shouldn't |
211 |
+ # be proccessed any further, so they are identified and |
212 |
+ # discarded here. Try to discard as few as possible since |
213 |
+ # discarded dependencies reduce the amount of information |
214 |
+ # available for optimization of merge order. |
215 |
+ if dep.priority.satisfied and \ |
216 |
+ not (existing_node or empty or deep or update): |
217 |
+ myarg = None |
218 |
+ if dep.root == self.target_root: |
219 |
+ try: |
220 |
+ myarg = self._iter_atoms_for_pkg(dep_pkg).next() |
221 |
+ except StopIteration: |
222 |
+ pass |
223 |
+ except portage.exception.InvalidDependString: |
224 |
+ if not dep_pkg.installed: |
225 |
+ # This shouldn't happen since the package |
226 |
+ # should have been masked. |
227 |
+ raise |
228 |
+ if not myarg: |
229 |
+ if consistent: |
230 |
+ self._ignored_deps.append(dep) |
231 |
+ return 1 |
232 |
+ |
233 |
+ if not self._add_pkg(dep_pkg, dep.parent, |
234 |
+ priority=dep.priority, depth=dep.depth): |
235 |
+ return 0 |
236 |
return 1 |
237 |
|
238 |
def _add_pkg(self, pkg, myparent, priority=None, depth=0): |
239 |
@@ -2011,7 +2019,7 @@ |
240 |
dep_stack.append(pkg) |
241 |
return 1 |
242 |
|
243 |
- def _add_pkg_deps(self, pkg): |
244 |
+ def _add_pkg_deps(self, pkg, allow_unsatisfied=False): |
245 |
|
246 |
mytype = pkg.type_name |
247 |
myroot = pkg.root |
248 |
@@ -2085,10 +2093,11 @@ |
249 |
mypriority = dep_priority.copy() |
250 |
if not blocker and vardb.match(atom): |
251 |
mypriority.satisfied = True |
252 |
- self._dep_stack.append( |
253 |
- Dependency(atom=atom, |
254 |
- blocker=blocker, depth=depth, parent=pkg, |
255 |
- priority=mypriority, root=dep_root)) |
256 |
+ if not self._add_dep(Dependency(atom=atom, |
257 |
+ blocker=blocker, depth=depth, parent=pkg, |
258 |
+ priority=mypriority, root=dep_root), |
259 |
+ allow_unsatisfied=allow_unsatisfied): |
260 |
+ return 0 |
261 |
if debug: |
262 |
print "Exiting...", jbigkey |
263 |
except ValueError, e: |
264 |
@@ -2405,6 +2414,7 @@ |
265 |
while args: |
266 |
arg = args.pop() |
267 |
for atom in arg.set: |
268 |
+ self.spinner.update() |
269 |
atom_cp = portage.dep_getkey(atom) |
270 |
try: |
271 |
pprovided = pprovideddict.get(portage.dep_getkey(atom)) |
272 |
@@ -2453,9 +2463,14 @@ |
273 |
arg.name in ("system", "world")): |
274 |
return 0, myfavorites |
275 |
|
276 |
- self._dep_stack.append( |
277 |
- Dependency(atom=atom, onlydeps=onlydeps, root=myroot, parent=arg)) |
278 |
- if not self._create_graph(): |
279 |
+ dep = Dependency(atom=atom, onlydeps=onlydeps, |
280 |
+ root=myroot, parent=arg) |
281 |
+ |
282 |
+ # Add the selected package to the graph as soon as possible |
283 |
+ # so that later dep_check() calls can use it as feedback |
284 |
+ # for making more consistent atom selections. |
285 |
+ if not self._add_pkg(pkg, dep.parent, |
286 |
+ priority=dep.priority, depth=dep.depth): |
287 |
if isinstance(arg, SetArg): |
288 |
sys.stderr.write(("\n\n!!! Problem resolving " + \ |
289 |
"dependencies for %s from %s\n") % \ |
290 |
@@ -2464,6 +2479,7 @@ |
291 |
sys.stderr.write(("\n\n!!! Problem resolving " + \ |
292 |
"dependencies for %s\n") % atom) |
293 |
return 0, myfavorites |
294 |
+ |
295 |
except portage.exception.MissingSignature, e: |
296 |
portage.writemsg("\n\n!!! A missing gpg signature is preventing portage from calculating the\n") |
297 |
portage.writemsg("!!! required dependencies. This is a security feature enabled by the admin\n") |
298 |
@@ -2485,6 +2501,11 @@ |
299 |
print >> sys.stderr, "!!!", str(e), getattr(e, "__module__", None) |
300 |
raise |
301 |
|
302 |
+ # Now that the root packages have been added to the graph, |
303 |
+ # process the dependencies. |
304 |
+ if not self._create_graph(): |
305 |
+ return 0, myfavorites |
306 |
+ |
307 |
missing=0 |
308 |
if "--usepkgonly" in self.myopts: |
309 |
for xs in self.digraph.all_nodes(): |
310 |
@@ -2978,18 +2999,6 @@ |
311 |
# due to the performance penalty that is incurred by all the |
312 |
# additional dep_check calls that are required. |
313 |
|
314 |
- # Optimization hack for dep_check calls that minimizes the |
315 |
- # available matches by replacing the portdb with a fakedbapi |
316 |
- # instance. |
317 |
- class FakePortageTree(object): |
318 |
- def __init__(self, mydb): |
319 |
- self.dbapi = mydb |
320 |
- dep_check_trees = {} |
321 |
- for myroot in self.trees: |
322 |
- dep_check_trees[myroot] = self.trees[myroot].copy() |
323 |
- dep_check_trees[myroot]["porttree"] = \ |
324 |
- FakePortageTree(self.mydbapi[myroot]) |
325 |
- |
326 |
dep_keys = ["DEPEND","RDEPEND","PDEPEND"] |
327 |
for myroot in self.trees: |
328 |
vardb = self.trees[myroot]["vartree"].dbapi |
329 |
@@ -3025,7 +3034,7 @@ |
330 |
try: |
331 |
success, atoms = portage.dep_check(depstr, |
332 |
final_db, pkgsettings, myuse=myuse, |
333 |
- trees=dep_check_trees, myroot=myroot) |
334 |
+ trees=self._graph_trees, myroot=myroot) |
335 |
except Exception, e: |
336 |
if isinstance(e, SystemExit): |
337 |
raise |
338 |
@@ -4358,7 +4367,7 @@ |
339 |
fakedb[myroot].cpv_inject(pkg) |
340 |
self.spinner.update() |
341 |
|
342 |
- class _dep_check_composite_db(object): |
343 |
+ class _dep_check_composite_db(portage.dbapi): |
344 |
""" |
345 |
A dbapi-like interface that is optimized for use in dep_check() calls. |
346 |
This is built on top of the existing depgraph package selection logic. |
347 |
@@ -4367,6 +4376,7 @@ |
348 |
via dep_check(). |
349 |
""" |
350 |
def __init__(self, depgraph, root): |
351 |
+ portage.dbapi.__init__(self) |
352 |
self._depgraph = depgraph |
353 |
self._root = root |
354 |
self._match_cache = {} |
355 |
@@ -4383,24 +4393,58 @@ |
356 |
if not pkg: |
357 |
ret = [] |
358 |
else: |
359 |
- if pkg.installed and "selective" not in self._depgraph.myparams: |
360 |
- try: |
361 |
- arg = self._depgraph._iter_atoms_for_pkg(pkg).next() |
362 |
- except (StopIteration, portage.exception.InvalidDependString): |
363 |
- arg = None |
364 |
- if arg: |
365 |
- ret = [] |
366 |
- if ret is None and pkg.installed and \ |
367 |
- not visible(self._depgraph.pkgsettings[pkg.root], pkg): |
368 |
- # For disjunctive || deps, this will cause alternative |
369 |
- # atoms or packages to be selected if available. |
370 |
- ret = [] |
371 |
- if ret is None: |
372 |
+ # Return the highest available from select_package() as well as |
373 |
+ # any matching slots in the graph db. |
374 |
+ slots = set() |
375 |
+ slots.add(pkg.metadata["SLOT"]) |
376 |
+ atom_cp = portage.dep_getkey(atom) |
377 |
+ if pkg.cp.startswith("virtual/"): |
378 |
+ # For new-style virtual lookahead that occurs inside |
379 |
+ # dep_check(), examine all slots. This is needed |
380 |
+ # so that newer slots will not unnecessarily be pulled in |
381 |
+ # when a satisfying lower slot is already installed. For |
382 |
+ # example, if virtual/jdk-1.4 is satisfied via kaffe then |
383 |
+ # there's no need to pull in a newer slot to satisfy a |
384 |
+ # virtual/jdk dependency. |
385 |
+ for db, pkg_type, built, installed, db_keys in \ |
386 |
+ self._depgraph._filtered_trees[self._root]["dbs"]: |
387 |
+ for cpv in db.match(atom): |
388 |
+ if portage.cpv_getkey(cpv) != pkg.cp: |
389 |
+ continue |
390 |
+ slots.add(db.aux_get(cpv, ["SLOT"])[0]) |
391 |
+ ret = [] |
392 |
+ if self._visible(pkg): |
393 |
self._cpv_pkg_map[pkg.cpv] = pkg |
394 |
- ret = [pkg.cpv] |
395 |
+ ret.append(pkg.cpv) |
396 |
+ slots.remove(pkg.metadata["SLOT"]) |
397 |
+ while slots: |
398 |
+ slot_atom = "%s:%s" % (atom_cp, slots.pop()) |
399 |
+ pkg, existing = self._depgraph._select_package( |
400 |
+ self._root, slot_atom) |
401 |
+ if not pkg: |
402 |
+ continue |
403 |
+ if not self._visible(pkg): |
404 |
+ continue |
405 |
+ self._cpv_pkg_map[pkg.cpv] = pkg |
406 |
+ ret.append(pkg.cpv) |
407 |
+ if ret: |
408 |
+ self._cpv_sort_ascending(ret) |
409 |
self._match_cache[orig_atom] = ret |
410 |
return ret[:] |
411 |
|
412 |
+ def _visible(self, pkg): |
413 |
+ if pkg.installed and "selective" not in self._depgraph.myparams: |
414 |
+ try: |
415 |
+ arg = self._depgraph._iter_atoms_for_pkg(pkg).next() |
416 |
+ except (StopIteration, portage.exception.InvalidDependString): |
417 |
+ arg = None |
418 |
+ if arg: |
419 |
+ return False |
420 |
+ if pkg.installed and \ |
421 |
+ not visible(self._depgraph.pkgsettings[pkg.root], pkg): |
422 |
+ return False |
423 |
+ return True |
424 |
+ |
425 |
def _dep_expand(self, atom): |
426 |
""" |
427 |
This is only needed for old installed packages that may |
428 |
|
429 |
Modified: main/branches/prefix/pym/portage/sets/files.py |
430 |
=================================================================== |
431 |
--- main/branches/prefix/pym/portage/sets/files.py 2008-04-14 17:48:19 UTC (rev 9892) |
432 |
+++ main/branches/prefix/pym/portage/sets/files.py 2008-04-14 17:49:59 UTC (rev 9893) |
433 |
@@ -184,6 +184,7 @@ |
434 |
def load(self): |
435 |
atoms = [] |
436 |
nonatoms = [] |
437 |
+ atoms_changed = False |
438 |
# load atoms and non-atoms from different files so the worldfile is |
439 |
# backwards-compatible with older versions and other PMs, even though |
440 |
# it's supposed to be private state data :/ |
441 |
@@ -204,6 +205,9 @@ |
442 |
data = {} |
443 |
atoms = data.keys() |
444 |
self._mtime = mtime |
445 |
+ atoms_changed = True |
446 |
+ else: |
447 |
+ atoms.extend(self._atoms) |
448 |
try: |
449 |
mtime = os.stat(self._filename2).st_mtime |
450 |
except (OSError, IOError): |
451 |
@@ -221,7 +225,10 @@ |
452 |
data = {} |
453 |
nonatoms = data.keys() |
454 |
self._mtime2 = mtime |
455 |
- if self._atoms != atoms or self._nonatoms != nonatoms: |
456 |
+ atoms_changed = True |
457 |
+ else: |
458 |
+ nonatoms.extend(self._nonatoms) |
459 |
+ if atoms_changed: |
460 |
self._setAtoms(atoms+nonatoms) |
461 |
|
462 |
def _ensure_dirs(self): |
463 |
|
464 |
-- |
465 |
gentoo-commits@l.g.o mailing list |