Gentoo Archives: gentoo-commits

From: "Fabian Groffen (grobian)" <grobian@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] portage r9374 - in main/branches/prefix: bin pym/_emerge pym/portage/dbapi pym/portage/sets
Date: Sat, 23 Feb 2008 23:37:54
Message-Id: E1JT3wF-0002Vo-3J@stork.gentoo.org
1 Author: grobian
2 Date: 2008-02-23 23:37:49 +0000 (Sat, 23 Feb 2008)
3 New Revision: 9374
4
5 Modified:
6 main/branches/prefix/bin/repoman
7 main/branches/prefix/pym/_emerge/__init__.py
8 main/branches/prefix/pym/portage/dbapi/vartree.py
9 main/branches/prefix/pym/portage/sets/dbapi.py
10 Log:
11 Merged from trunk 9335:9351
12
13 | 9336 | Fix package selection logic in order to prevent downgrade in |
14 | zmedico | cases when selective is True and the currently installed |
15 | | version does not have a matching ebuild in the tree. For |
16 | | example, this type of situation is likely to occur if the |
17 | | user somehow obtains a binary package that has a newer |
18 | | version than any of the ebuilds in the portage tree. If |
19 | | package maintainers want to encourage a downgrade in a case |
20 | | like this then they should use package.mask so that the user |
21 | | receives a warning about the installed package being masked. |
22
23 | 9337 | Fix --newuse reinstall logic broken by the previous commit. |
24 | zmedico | |
25
26 | 9338 | Update the DepPriority documentation so that the table shows |
27 | zmedico | all the currently supported priorities and categories. |
28
29 | 9339 | Bug #201045 - Use a topological sort to create an unmerge |
30 | zmedico | order such that each package is unmerged before it's |
31 | | dependencies. This is necessary to avoid breaking things |
32 | | that may need to run during pkg_prerm or pkg_postrm phases. |
33
34 | 9340 | Make depclean code filter out blocker atoms where |
35 | zmedico | appropriate. |
36
37 | 9341 | Fix depclean breakage so that it doesn't clean some packages |
38 | zmedico | that shouldn't be cleaned. |
39
40 | 9342 | Add missing % x (bug #208946, comment #2). |
41 | zmedico | |
42
43 | 9343 | Fix reversed order of parent/child parameders to |
44 | zmedico | digraph.add(). |
45
46 | 9344 | Remove IUSE.invalid from qawarnings since there's no reason |
47 | zmedico | for it not to be fatal. Thanks to Betelgeuse. |
48
49 | 9345 | In the action_depclean() topological sort, only add packages |
50 | zmedico | to the graph if they are being removed. |
51
52 | 9346 | Bug #201045 - Make unmerge() preserve the unmerge order of |
53 | zmedico | packages given to it by the user or depclean. |
54
55 | 9347 | Make sure all packages to be pruned or depcleaned are added |
56 | zmedico | to the graph, even when they don't have any dependencies. |
57
58 | 9348 | Now that unmerge() preserves the order that it's given, if |
59 | zmedico | two different slots of the same package are being unmerged |
60 | | then they are not necessarily unmerged consecutively. To |
61 | | make the display less confusing, never display packages as |
62 | | "protected" or "omitted" when they actually belong to the |
63 | | overall set of "selected" packages to be unmerged. |
64
65 | 9349 | Fix unmerge() breakage from due to pkgmap being changed from |
66 | zmedico | a dict to a list. |
67
68 | 9350 | Fix the --depclean/--prune code to use visible() for |
69 | zmedico | visibility checks instead of the old portdbapi hack. |
70
71 | 9351 | Make LibraryConsumerSet.mapPathsToAtoms() produce slot atoms |
72 | zmedico | so that atoms aren't restricted to the currently installed |
73 | | version, making upgrades possible. |
74
75
76 Modified: main/branches/prefix/bin/repoman
77 ===================================================================
78 --- main/branches/prefix/bin/repoman 2008-02-23 23:33:46 UTC (rev 9373)
79 +++ main/branches/prefix/bin/repoman 2008-02-23 23:37:49 UTC (rev 9374)
80 @@ -320,7 +320,6 @@
81 "DEPEND.badindev","RDEPEND.badindev","PDEPEND.badindev",
82 "DEPEND.badmaskedindev","RDEPEND.badmaskedindev","PDEPEND.badmaskedindev",
83 "DESCRIPTION.toolong",
84 -"IUSE.invalid",
85 "KEYWORDS.stupid",
86 "KEYWORDS.missing",
87 "RESTRICT.invalid",
88
89 Modified: main/branches/prefix/pym/_emerge/__init__.py
90 ===================================================================
91 --- main/branches/prefix/pym/_emerge/__init__.py 2008-02-23 23:33:46 UTC (rev 9373)
92 +++ main/branches/prefix/pym/_emerge/__init__.py 2008-02-23 23:37:49 UTC (rev 9374)
93 @@ -840,7 +840,38 @@
94 else:
95 yield flag
96
97 -class DepPriority(object):
98 +class AbstractDepPriority(object):
99 + __slots__ = ("__weakref__", "buildtime", "runtime", "runtime_post")
100 + def __init__(self, **kwargs):
101 + for myattr in chain(self.__slots__, AbstractDepPriority.__slots__):
102 + if myattr == "__weakref__":
103 + continue
104 + myvalue = kwargs.get(myattr, False)
105 + setattr(self, myattr, myvalue)
106 +
107 + def __lt__(self, other):
108 + return self.__int__() < other
109 +
110 + def __le__(self, other):
111 + return self.__int__() <= other
112 +
113 + def __eq__(self, other):
114 + return self.__int__() == other
115 +
116 + def __ne__(self, other):
117 + return self.__int__() != other
118 +
119 + def __gt__(self, other):
120 + return self.__int__() > other
121 +
122 + def __ge__(self, other):
123 + return self.__int__() >= other
124 +
125 + def copy(self):
126 + import copy
127 + return copy.copy(self)
128 +
129 +class DepPriority(AbstractDepPriority):
130 """
131 This class generates an integer priority level based of various
132 attributes of the dependency relationship. Attributes can be assigned
133 @@ -851,13 +882,16 @@
134 "buildtime", "runtime", and "system". Various combinations of
135 attributes lead to the following priority levels:
136
137 - Combination of properties Priority level
138 + Combination of properties Priority Category
139
140 - not satisfied and buildtime 0
141 - not satisfied and runtime -1
142 - satisfied and buildtime -2
143 - satisfied and runtime -3
144 - (none of the above) -4
145 + not satisfied and buildtime 0 HARD
146 + not satisfied and runtime -1 MEDIUM
147 + not satisfied and runtime_post -2 MEDIUM_SOFT
148 + satisfied and buildtime and rebuild -3 SOFT
149 + satisfied and buildtime -4 SOFT
150 + satisfied and runtime -5 SOFT
151 + satisfied and runtime_post -6 SOFT
152 + (none of the above) -6 SOFT
153
154 Several integer constants are defined for categorization of priority
155 levels:
156 @@ -867,17 +901,12 @@
157 SOFT The upper boundary for soft dependencies.
158 MIN The lower boundary for soft dependencies.
159 """
160 - __slots__ = ("__weakref__", "satisfied", "buildtime", "runtime", "runtime_post", "rebuild")
161 + __slots__ = ("satisfied", "rebuild")
162 MEDIUM = -1
163 MEDIUM_SOFT = -2
164 SOFT = -3
165 MIN = -6
166 - def __init__(self, **kwargs):
167 - for myattr in self.__slots__:
168 - if myattr == "__weakref__":
169 - continue
170 - myvalue = kwargs.get(myattr, False)
171 - setattr(self, myattr, myvalue)
172 +
173 def __int__(self):
174 if not self.satisfied:
175 if self.buildtime:
176 @@ -895,21 +924,7 @@
177 if self.runtime_post:
178 return -6
179 return -6
180 - def __lt__(self, other):
181 - return self.__int__() < other
182 - def __le__(self, other):
183 - return self.__int__() <= other
184 - def __eq__(self, other):
185 - return self.__int__() == other
186 - def __ne__(self, other):
187 - return self.__int__() != other
188 - def __gt__(self, other):
189 - return self.__int__() > other
190 - def __ge__(self, other):
191 - return self.__int__() >= other
192 - def copy(self):
193 - import copy
194 - return copy.copy(self)
195 +
196 def __str__(self):
197 myvalue = self.__int__()
198 if myvalue > self.MEDIUM:
199 @@ -920,6 +935,35 @@
200 return "medium-soft"
201 return "soft"
202
203 +class UnmergeDepPriority(AbstractDepPriority):
204 + """
205 + Combination of properties Priority Category
206 +
207 + runtime 0 HARD
208 + runtime_post -1 HARD
209 + buildtime -2 SOFT
210 + (none of the above) -2 SOFT
211 + """
212 +
213 + MAX = 0
214 + SOFT = -2
215 + MIN = -2
216 +
217 + def __int__(self):
218 + if self.runtime:
219 + return 0
220 + if self.runtime_post:
221 + return -1
222 + if self.buildtime:
223 + return -2
224 + return -2
225 +
226 + def __str__(self):
227 + myvalue = self.__int__()
228 + if myvalue > self.SOFT:
229 + return "hard"
230 + return "soft"
231 +
232 class FakeVartree(portage.vartree):
233 """This is implements an in-memory copy of a vartree instance that provides
234 all the interfaces required for use by the depgraph. The vardb is locked
235 @@ -2527,6 +2571,7 @@
236 usepkgonly = "--usepkgonly" in self.myopts
237 empty = "empty" in self.myparams
238 selective = "selective" in self.myparams
239 + reinstall = False
240 # Behavior of the "selective" parameter depends on
241 # whether or not a package matches an argument atom.
242 # If an installed package provides an old-style
243 @@ -2546,9 +2591,12 @@
244 if existing_node:
245 break
246 if installed and not find_existing_node and \
247 + (reinstall or not selective) and \
248 (matched_packages or empty):
249 - # We only need to select an installed package here
250 - # if there is no other choice.
251 + # We only need to select an installed package in the
252 + # following cases:
253 + # 1) there is no other choice
254 + # 2) selective is True
255 continue
256 if hasattr(db, "xmatch"):
257 cpv_list = db.xmatch("match-all", atom)
258 @@ -2656,6 +2704,8 @@
259 self._reinstall_for_flags(
260 forced_flags, old_use, old_iuse,
261 cur_use, cur_iuse)
262 + if reinstall_for_flags:
263 + reinstall = True
264 if not installed:
265 must_reinstall = empty or \
266 (myarg and not selective)
267 @@ -4944,7 +4994,7 @@
268 print darkgreen(newline+\
269 ">>> These are the packages that would be unmerged:")
270
271 - pkgmap={}
272 + pkgmap = []
273 numselected=0
274 for x in candidate_catpkgs:
275 # cycle through all our candidate deps and determine
276 @@ -4970,11 +5020,8 @@
277 portage.writemsg("\n--- Couldn't find '%s' to %s.\n" % \
278 (x, unmerge_action), noiselevel=-1)
279 continue
280 - mykey = portage.key_expand(
281 - portage.dep_getkey(
282 - mymatch[0]), mydb=vartree.dbapi, settings=settings)
283 - if not pkgmap.has_key(mykey):
284 - pkgmap[mykey]={"protected":[], "selected":[], "omitted":[] }
285 + pkgmap.append({"protected":[], "selected":[], "omitted":[] })
286 + mykey = len(pkgmap) - 1
287 if unmerge_action=="unmerge":
288 for y in mymatch:
289 if y not in pkgmap[mykey]["selected"]:
290 @@ -5044,25 +5091,38 @@
291 finally:
292 if vdb_lock:
293 portage.locks.unlockdir(vdb_lock)
294 + all_selected = set()
295 for x in pkgmap:
296 - for y in localtree.dep_match(x):
297 + all_selected.update(x["selected"])
298 + for x in xrange(len(pkgmap)):
299 + selected = pkgmap[x]["selected"]
300 + if not selected:
301 + continue
302 + for mytype, mylist in pkgmap[x].iteritems():
303 + if mytype == "selected":
304 + continue
305 + pkgmap[x][mytype] = \
306 + [cpv for cpv in mylist if cpv not in all_selected]
307 + cp = portage.cpv_getkey(selected[0])
308 + for y in localtree.dep_match(cp):
309 if y not in pkgmap[x]["omitted"] and \
310 y not in pkgmap[x]["selected"] and \
311 - y not in pkgmap[x]["protected"]:
312 + y not in pkgmap[x]["protected"] and \
313 + y not in all_selected:
314 pkgmap[x]["omitted"].append(y)
315 if global_unmerge and not pkgmap[x]["selected"]:
316 #avoid cluttering the preview printout with stuff that isn't getting unmerged
317 continue
318 - if not (pkgmap[x]["protected"] or pkgmap[x]["omitted"]) and (x in syslist):
319 - print colorize("BAD","\a\n\n!!! '%s' is part of your system profile." % x)
320 + if not (pkgmap[x]["protected"] or pkgmap[x]["omitted"]) and cp in syslist:
321 + print colorize("BAD","\a\n\n!!! '%s' is part of your system profile." % cp)
322 print colorize("WARN","\a!!! Unmerging it may be damaging to your system.\n")
323 if "--pretend" not in myopts and "--ask" not in myopts:
324 countdown(int(settings["EMERGE_WARNING_DELAY"]),
325 colorize("UNMERGE_WARN", "Press Ctrl-C to Stop"))
326 if "--quiet" not in myopts:
327 - print "\n "+white(x)
328 + print "\n "+bold(cp)
329 else:
330 - print white(x)+": ",
331 + print bold(cp)+": ",
332 for mytype in ["selected","protected","omitted"]:
333 if "--quiet" not in myopts:
334 portage.writemsg_stdout((mytype + ": ").rjust(14), noiselevel=-1)
335 @@ -5109,7 +5169,7 @@
336 if not autoclean:
337 countdown(int(settings["CLEAN_DELAY"]), ">>> Unmerging")
338
339 - for x in pkgmap:
340 + for x in xrange(len(pkgmap)):
341 for y in pkgmap[x]["selected"]:
342 print ">>> Unmerging "+y+"..."
343 emergelog(xterm_titles, "=== Unmerging... ("+y+")")
344 @@ -6413,23 +6473,32 @@
345 if "--quiet" not in myopts:
346 print "\nCalculating dependencies ",
347
348 - soft = 0
349 - hard = 1
350 + runtime = UnmergeDepPriority(runtime=True)
351 + runtime_post = UnmergeDepPriority(runtime_post=True)
352 + buildtime = UnmergeDepPriority(buildtime=True)
353 +
354 + priority_map = {
355 + "RDEPEND": runtime,
356 + "PDEPEND": runtime_post,
357 + "DEPEND": buildtime,
358 + }
359 +
360 remaining_atoms = []
361 if action == "depclean":
362 for atom in worldlist:
363 if vardb.match(atom):
364 - remaining_atoms.append((atom, 'world', hard))
365 + remaining_atoms.append((atom, 'world', runtime))
366 for atom in syslist:
367 if vardb.match(atom):
368 - remaining_atoms.append((atom, 'system', hard))
369 + remaining_atoms.append((atom, 'system', runtime))
370 elif action == "prune":
371 for atom in syslist:
372 if vardb.match(atom):
373 - remaining_atoms.append((atom, 'system', hard))
374 + remaining_atoms.append((atom, 'system', runtime))
375 # Pull in everything that's installed since we don't want to prune a
376 # package if something depends on it.
377 - remaining_atoms.extend((atom, 'world', hard) for atom in vardb.cp_all())
378 + remaining_atoms.extend(
379 + (atom, 'world', runtime) for atom in vardb.cp_all())
380 if not myfiles:
381 # Try to prune everything that's slotted.
382 for cp in vardb.cp_all():
383 @@ -6438,14 +6507,15 @@
384
385 unresolveable = {}
386 aux_keys = ["DEPEND", "RDEPEND", "PDEPEND"]
387 - metadata_keys = ["PROVIDE", "SLOT", "USE"]
388 + metadata_keys = depgraph._mydbapi_keys
389 graph = digraph()
390 + with_bdeps = myopts.get("--with-bdeps", "y") == "y"
391
392 while remaining_atoms:
393 atom, parent, priority = remaining_atoms.pop()
394 pkgs = vardb.match(atom)
395 if not pkgs:
396 - if not atom.startswith("!") and priority == hard:
397 + if priority > UnmergeDepPriority.SOFT:
398 unresolveable.setdefault(atom, []).append(parent)
399 continue
400 if action == "depclean" and parent == "world" and myfiles:
401 @@ -6470,44 +6540,42 @@
402 filtered_pkgs.append(pkg)
403 pkgs = filtered_pkgs
404 if len(pkgs) > 1:
405 - # Prune all but the best matching slot, since that's all that a
406 - # deep world update would pull in. Don't prune if this atom comes
407 - # directly from world though, since world atoms are greedy when
408 - # they don't specify a slot.
409 - visible_in_portdb = [cpv for cpv in pkgs if portdb.match("="+cpv)]
410 - if visible_in_portdb:
411 - # For consistency with the update algorithm, keep the highest
412 - # visible version and prune any versions that are either masked
413 - # or no longer exist in the portage tree.
414 - pkgs = visible_in_portdb
415 - pkgs = [portage.best(pkgs)]
416 + # For consistency with the update algorithm, keep the highest
417 + # visible version and prune any versions that are old or masked.
418 + for cpv in reversed(pkgs):
419 + metadata = dict(izip(metadata_keys,
420 + vardb.aux_get(cpv, metadata_keys)))
421 + if visible(settings, cpv, metadata,
422 + built=True, installed=True):
423 + pkgs = [cpv]
424 + break
425 + if len(pkgs) > 1:
426 + # They're all masked, so just keep the highest version.
427 + pkgs = [pkgs[-1]]
428 for pkg in pkgs:
429 - graph.add(pkg, parent)
430 + graph.add(pkg, parent, priority=priority)
431 if fakedb.cpv_exists(pkg):
432 continue
433 spinner.update()
434 fakedb.cpv_inject(pkg)
435 myaux = dict(izip(aux_keys, vardb.aux_get(pkg, aux_keys)))
436 mydeps = []
437 - if myopts.get("--with-bdeps", "y") == "y":
438 - mydeps.append((myaux["DEPEND"], soft))
439 - del myaux["DEPEND"]
440 - mydeps.append((" ".join(myaux.values()), hard))
441 +
442 usedef = vardb.aux_get(pkg, ["USE"])[0].split()
443 - for depstr, priority in mydeps:
444 + for dep_type, depstr in myaux.iteritems():
445
446 if not depstr:
447 continue
448
449 + if not with_bdeps and dep_type == "DEPEND":
450 + continue
451 +
452 + priority = priority_map[dep_type]
453 if "--debug" in myopts:
454 print
455 print "Parent: ", pkg
456 print "Depstring:", depstr
457 - print "Priority:",
458 - if priority == soft:
459 - print "soft"
460 - else:
461 - print "hard"
462 + print "Priority:", priority
463
464 try:
465 portage.dep._dep_check_strict = False
466 @@ -6525,6 +6593,8 @@
467 print "Candidates:", atoms
468
469 for atom in atoms:
470 + if atom.startswith("!"):
471 + continue
472 remaining_atoms.append((atom, pkg, priority))
473
474 if "--quiet" not in myopts:
475 @@ -6612,6 +6682,75 @@
476 good("--nodeps"))
477
478 if len(cleanlist):
479 + # Use a topological sort to create an unmerge order such that
480 + # each package is unmerged before it's dependencies. This is
481 + # necessary to avoid breaking things that may need to run
482 + # during pkg_prerm or pkg_postrm phases.
483 +
484 + # Create a new graph to account for dependencies between the
485 + # packages being unmerged.
486 + graph = digraph()
487 + clean_set = set(cleanlist)
488 + del cleanlist[:]
489 + for node in clean_set:
490 + graph.add(node, None)
491 + myaux = dict(izip(aux_keys, vardb.aux_get(node, aux_keys)))
492 + mydeps = []
493 + usedef = vardb.aux_get(pkg, ["USE"])[0].split()
494 + for dep_type, depstr in myaux.iteritems():
495 + if not depstr:
496 + continue
497 + try:
498 + portage.dep._dep_check_strict = False
499 + success, atoms = portage.dep_check(depstr, None, settings,
500 + myuse=usedef, trees=dep_check_trees, myroot=myroot)
501 + finally:
502 + portage.dep._dep_check_strict = True
503 + if not success:
504 + show_invalid_depstring_notice(
505 + ("installed", myroot, node, "nomerge"),
506 + depstr, atoms)
507 + return
508 +
509 + priority = priority_map[dep_type]
510 + for atom in atoms:
511 + if atom.startswith("!"):
512 + continue
513 + matches = vardb.match(atom)
514 + if not matches:
515 + continue
516 + for cpv in matches:
517 + if cpv in clean_set:
518 + graph.add(cpv, node, priority=priority)
519 +
520 + # Order nodes from lowest to highest overall reference count for
521 + # optimal root node selection.
522 + node_refcounts = {}
523 + for node in graph.order:
524 + node_refcounts[node] = len(graph.parent_nodes(node))
525 + def cmp_reference_count(node1, node2):
526 + return node_refcounts[node1] - node_refcounts[node2]
527 + graph.order.sort(cmp_reference_count)
528 +
529 + ignore_priority_range = [None]
530 + ignore_priority_range.extend(
531 + xrange(UnmergeDepPriority.MIN, UnmergeDepPriority.MAX + 1))
532 + while not graph.empty():
533 + for ignore_priority in ignore_priority_range:
534 + nodes = graph.root_nodes(ignore_priority=ignore_priority)
535 + if nodes:
536 + break
537 + if not nodes:
538 + raise AssertionError("no root nodes")
539 + if ignore_priority is not None:
540 + # Some deps have been dropped due to circular dependencies,
541 + # so only pop one node in order do minimize the number that
542 + # are dropped.
543 + del nodes[1:]
544 + for node in nodes:
545 + graph.remove(node)
546 + cleanlist.append(node)
547 +
548 unmerge(root_config, myopts,
549 "unmerge", cleanlist, ldpath_mtimes)
550
551
552 Modified: main/branches/prefix/pym/portage/dbapi/vartree.py
553 ===================================================================
554 --- main/branches/prefix/pym/portage/dbapi/vartree.py 2008-02-23 23:33:46 UTC (rev 9373)
555 +++ main/branches/prefix/pym/portage/dbapi/vartree.py 2008-02-23 23:37:49 UTC (rev 9374)
556 @@ -1601,7 +1601,7 @@
557 for x in preserve_paths:
558 print "injecting %s into %s" % (x, srcroot)
559 if not os.path.exists(os.path.join(destroot, x.lstrip(os.sep))):
560 - print "%s does not exist so can't be preserved"
561 + print "%s does not exist so can't be preserved" % x
562 missing_paths.append(x)
563 continue
564 mydir = os.path.join(srcroot, os.path.dirname(x).lstrip(os.sep))
565
566 Modified: main/branches/prefix/pym/portage/sets/dbapi.py
567 ===================================================================
568 --- main/branches/prefix/pym/portage/sets/dbapi.py 2008-02-23 23:33:46 UTC (rev 9373)
569 +++ main/branches/prefix/pym/portage/sets/dbapi.py 2008-02-23 23:37:49 UTC (rev 9374)
570 @@ -126,8 +126,10 @@
571 link = dblink(mysplit[0], mysplit[1], myroot=self.dbapi.root, \
572 mysettings=self.dbapi.settings, treetype='vartree', \
573 vartree=self.dbapi.vartree)
574 - if paths.intersection(link.getcontents().keys()):
575 - rValue.add("/".join(catpkgsplit(cpv)[:2]))
576 + if paths.intersection(link.getcontents()):
577 + cat, pn = catpkgsplit(cpv)[:2]
578 + slot = self.dbapi.aux_get(cpv, ["SLOT"])[0]
579 + rValue.add("%s/%s:%s" % (cat, pn, slot))
580 return rValue
581
582
583
584 --
585 gentoo-commits@l.g.o mailing list