Gentoo Archives: gentoo-commits

From: "Zac Medico (zmedico)" <zmedico@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] portage r9603 - main/branches/2.1.2/bin
Date: Sat, 29 Mar 2008 10:23:03
Message-Id: E1JfYDC-0002cG-7X@stork.gentoo.org
1 Author: zmedico
2 Date: 2008-03-29 10:22:57 +0000 (Sat, 29 Mar 2008)
3 New Revision: 9603
4
5 Modified:
6 main/branches/2.1.2/bin/emerge
7 Log:
8 Merge part of the package selection code from trunk.
9
10
11 Modified: main/branches/2.1.2/bin/emerge
12 ===================================================================
13 --- main/branches/2.1.2/bin/emerge 2008-03-29 07:55:08 UTC (rev 9602)
14 +++ main/branches/2.1.2/bin/emerge 2008-03-29 10:22:57 UTC (rev 9603)
15 @@ -1461,16 +1461,17 @@
16 self.edebug = 1
17 self.spinner = spinner
18 self.pkgsettings = {}
19 - # Maps cpv to digraph node for all nodes added to the graph.
20 - self.pkg_node_map = {}
21 - # Maps slot atom to digraph node for all nodes added to the graph.
22 - self._slot_node_map = {}
23 + # Maps slot atom to package for each Package added to the graph.
24 + self._slot_pkg_map = {}
25 # Maps nodes to the reasons they were selected for reinstallation.
26 self._reinstall_nodes = {}
27 self.mydbapi = {}
28 self.trees = {}
29 self._trees_orig = trees
30 self.roots = {}
31 + # Contains a filtered view of preferred packages that are selected
32 + # from available repositories.
33 + self._filtered_trees = {}
34 for myroot in trees:
35 self.trees[myroot] = {}
36 for tree in ("porttree", "bintree"):
37 @@ -1481,8 +1482,7 @@
38 self._mydbapi_keys)
39 self.pkgsettings[myroot] = portage.config(
40 clone=self.trees[myroot]["vartree"].settings)
41 - self.pkg_node_map[myroot] = {}
42 - self._slot_node_map[myroot] = {}
43 + self._slot_pkg_map[myroot] = {}
44 vardb = self.trees[myroot]["vartree"].dbapi
45 self.roots[myroot] = RootConfig(self.trees[myroot])
46 # This fakedbapi instance will model the state that the vdb will
47 @@ -1499,7 +1499,22 @@
48 metadata=dict(izip(self._mydbapi_keys,
49 vardb.aux_get(pkg, self._mydbapi_keys))))
50 del vardb, fakedb
51 + self._filtered_trees[myroot] = {}
52 + dbs = []
53 + portdb = self.trees[myroot]["porttree"].dbapi
54 + bindb = self.trees[myroot]["bintree"].dbapi
55 + vardb = self.trees[myroot]["vartree"].dbapi
56 + # (db, pkg_type, built, installed, db_keys)
57 + if "--usepkgonly" not in self.myopts:
58 + db_keys = list(portdb._aux_cache_keys)
59 + dbs.append((portdb, "ebuild", False, False, db_keys))
60 if "--usepkg" in self.myopts:
61 + db_keys = list(bindb._aux_cache_keys)
62 + dbs.append((bindb, "binary", True, False, db_keys))
63 + db_keys = self._mydbapi_keys
64 + dbs.append((vardb, "installed", True, True, db_keys))
65 + self._filtered_trees[myroot]["dbs"] = dbs
66 + if "--usepkg" in self.myopts:
67 self.trees[myroot]["bintree"].populate(
68 "--getbinpkg" in self.myopts,
69 "--getbinpkgonly" in self.myopts)
70 @@ -1531,6 +1546,7 @@
71 self._masked_installed = []
72 self._unsatisfied_deps_for_display = []
73 self._world_problems = False
74 + self._select_package = self._select_pkg_highest_available
75
76 def _show_slot_collision_notice(self):
77 """Show an informational message advising the user to mask one of the
78 @@ -1554,15 +1570,9 @@
79 msg.append("\n\n")
80 slot_nodes = []
81 for node in self._slot_collision_nodes:
82 - type_name, pkg_root, cpv, pkg_status = node
83 - if pkg_root != root:
84 - continue
85 - mydb = self.roots[root].trees[
86 - self.pkg_tree_map[type_name]].dbapi
87 - slot = mydb.aux_get(cpv, ["SLOT"])[0]
88 - if slot_atom == "%s:%s" % (portage.cpv_getkey(cpv), slot):
89 + if node.slot_atom == slot_atom:
90 slot_nodes.append(node)
91 - slot_nodes.append(self._slot_node_map[root][slot_atom])
92 + slot_nodes.append(self._slot_pkg_map[root][slot_atom])
93 for node in slot_nodes:
94 msg.append(indent)
95 msg.append(str(node))
96 @@ -1572,10 +1582,18 @@
97 if len(parents) > max_parents:
98 omitted_parents = len(parents) - max_parents
99 pruned_list = []
100 + # When generating the pruned list, prefer instances
101 + # of DependencyArg over instances of Package.
102 for parent in parents:
103 - pruned_list.append(parent)
104 - if len(pruned_list) == max_parents:
105 - break
106 + if isinstance(parent, DependencyArg):
107 + pruned_list.append(parent)
108 + if len(pruned_list) == max_parents:
109 + break
110 + for parent in parents:
111 + if not isinstance(parent, DependencyArg):
112 + pruned_list.append(parent)
113 + if len(pruned_list) == max_parents:
114 + break
115 parents = pruned_list
116 msg.append(" pulled in by\n")
117 for parent in parents:
118 @@ -1638,8 +1656,9 @@
119 return flags
120 return None
121
122 - def create(self, mybigkey, myparent=None, addme=1, metadata=None,
123 - priority=DepPriority(), rev_dep=False, arg=None):
124 + def create(self, pkg, myparent, priority=None):
125 + if priority is None:
126 + priority = DepPriority()
127 """
128 Fills the digraph with nodes comprised of packages to merge.
129 mybigkey is the package spec of the package to merge.
130 @@ -1652,91 +1671,27 @@
131 #"no downgrade" emerge
132 """
133
134 - # unused parameters
135 - rev_dep = False
136 -
137 - mytype, myroot, mykey = mybigkey
138 -
139 # select the correct /var database that we'll be checking against
140 - vardbapi = self.trees[myroot]["vartree"].dbapi
141 - portdb = self.trees[myroot]["porttree"].dbapi
142 - bindb = self.trees[myroot]["bintree"].dbapi
143 - pkgsettings = self.pkgsettings[myroot]
144 + vardbapi = self.trees[pkg.root]["vartree"].dbapi
145 + portdb = self.trees[pkg.root]["porttree"].dbapi
146 + pkgsettings = self.pkgsettings[pkg.root]
147
148 - # if the package is already on the system, we add a "nomerge"
149 - # directive, otherwise we add a "merge" directive.
150 -
151 - mydbapi = self.trees[myroot][self.pkg_tree_map[mytype]].dbapi
152 - if metadata is None:
153 - metadata = dict(izip(self._mydbapi_keys,
154 - mydbapi.aux_get(mykey, self._mydbapi_keys)))
155 - if mytype == "ebuild":
156 - pkgsettings.setcpv(mykey, mydb=portdb)
157 - metadata["USE"] = pkgsettings["PORTAGE_USE"]
158 - myuse = metadata["USE"].split()
159 -
160 - if not arg and myroot == self.target_root:
161 - try:
162 - arg = self._set_atoms.findAtomForPackage(mykey, metadata)
163 + arg = None
164 + if pkg.root == self.target_root:
165 + try:
166 + arg = self._set_atoms.findAtomForPackage(
167 + pkg.cpv, pkg.metadata)
168 except portage_exception.InvalidDependString, e:
169 - if mytype != "installed":
170 - show_invalid_depstring_notice(tuple(mybigkey+["merge"]),
171 - metadata["PROVIDE"], str(e))
172 - return 0
173 - del e
174 + if not pkg.installed:
175 + show_invalid_depstring_notice(pkg,
176 + pkg.metadata["PROVIDE"], str(e))
177 + return 0
178 + del e
179
180 - noreplace = "--noreplace" in self.myopts
181 - reinstall_for_flags = None
182 - merging=1
183 - if mytype == "installed":
184 - merging = 0
185 - if addme and mytype != "installed":
186 - # this is where we add the node to the list of packages to merge
187 - if "selective" in self.myparams or not arg:
188 - if "empty" not in self.myparams and vardbapi.cpv_exists(mykey):
189 - merging=0
190 -
191 - """ If we aren't merging, perform the --newuse check.
192 - If the package has new iuse flags or different use flags then if
193 - --newuse is specified, we need to merge the package. """
194 - if not noreplace and merging == 0 and \
195 - myroot == self.target_root and \
196 - ("--newuse" in self.myopts or
197 - "--reinstall" in self.myopts) and \
198 - vardbapi.cpv_exists(mykey):
199 - pkgsettings.setcpv(mykey, mydb=mydbapi)
200 - forced_flags = set()
201 - forced_flags.update(pkgsettings.useforce)
202 - forced_flags.update(pkgsettings.usemask)
203 - old_use = vardbapi.aux_get(mykey, ["USE"])[0].split()
204 - iuses = set(filter_iuse_defaults(metadata["IUSE"].split()))
205 - old_iuse = set(filter_iuse_defaults(
206 - vardbapi.aux_get(mykey, ["IUSE"])[0].split()))
207 - reinstall_for_flags = self._reinstall_for_flags(
208 - forced_flags, old_use, old_iuse, myuse, iuses)
209 - if reinstall_for_flags:
210 - merging = 1
211 -
212 - if addme and merging == 1:
213 - mybigkey.append("merge")
214 - else:
215 - mybigkey.append("nomerge")
216 - jbigkey = tuple(mybigkey)
217 -
218 - if addme:
219 - if merging == 0 and vardbapi.cpv_exists(mykey) and \
220 - mytype != "installed":
221 - mytype = "installed"
222 - mybigkey[0] = "installed"
223 - mydbapi = vardbapi
224 - jbigkey = tuple(mybigkey)
225 - metadata = dict(izip(self._mydbapi_keys,
226 - mydbapi.aux_get(mykey, self._mydbapi_keys)))
227 - myuse = metadata["USE"].split()
228 - slot_atom = "%s:%s" % (portage.dep_getkey(mykey), metadata["SLOT"])
229 - if merging and \
230 + if not pkg.onlydeps:
231 + if not pkg.installed and \
232 "empty" not in self.myparams and \
233 - vardbapi.match(slot_atom):
234 + vardbapi.match(pkg.slot_atom):
235 # Increase the priority of dependencies on packages that
236 # are being rebuilt. This optimizes merge order so that
237 # dependencies are rebuilt/updated as soon as possible,
238 @@ -1747,12 +1702,10 @@
239 # are being merged in that case.
240 priority.rebuild = True
241
242 - existing_node = self._slot_node_map[myroot].get(
243 - slot_atom, None)
244 + existing_node = self._slot_pkg_map[pkg.root].get(pkg.slot_atom)
245 slot_collision = False
246 if existing_node:
247 - e_type, myroot, e_cpv, e_status = existing_node
248 - if mykey == e_cpv:
249 + if pkg.cpv == existing_node.cpv:
250 # The existing node can be reused.
251 self._parent_child_digraph.add(existing_node, myparent)
252 # If a direct circular dependency is not an unsatisfied
253 @@ -1765,100 +1718,94 @@
254 priority=priority)
255 return 1
256 else:
257 - if jbigkey in self._slot_collision_nodes:
258 + if pkg in self._slot_collision_nodes:
259 return 1
260 # A slot collision has occurred. Sometimes this coincides
261 # with unresolvable blockers, so the slot collision will be
262 # shown later if there are no unresolvable blockers.
263 - self._slot_collision_info.add((slot_atom, myroot))
264 - self._slot_collision_nodes.add(jbigkey)
265 + self._slot_collision_info.add((pkg.slot_atom, pkg.root))
266 + self._slot_collision_nodes.add(pkg)
267 slot_collision = True
268
269 if slot_collision:
270 # Now add this node to the graph so that self.display()
271 - # can show use flags and --tree output. This node is
272 + # can show use flags and --tree portage.output. This node is
273 # only being partially added to the graph. It must not be
274 # allowed to interfere with the other nodes that have been
275 # added. Do not overwrite data for existing nodes in
276 - # self.pkg_node_map and self.mydbapi since that data will
277 - # be used for blocker validation.
278 - self.pkg_node_map[myroot].setdefault(mykey, jbigkey)
279 + # self.mydbapi since that data will be used for blocker
280 + # validation.
281 # Even though the graph is now invalid, continue to process
282 # dependencies so that things like --fetchonly can still
283 # function despite collisions.
284 + pass
285 else:
286 - self.mydbapi[myroot].cpv_inject(mykey, metadata=metadata)
287 - self._slot_node_map[myroot][slot_atom] = jbigkey
288 - self.pkg_node_map[myroot][mykey] = jbigkey
289 - if reinstall_for_flags:
290 - self._reinstall_nodes[jbigkey] = reinstall_for_flags
291 + self.mydbapi[pkg.root].cpv_inject(
292 + pkg.cpv, metadata=pkg.metadata)
293 + self._slot_pkg_map[pkg.root][pkg.slot_atom] = pkg
294
295 - if rev_dep and myparent:
296 - self.digraph.addnode(myparent, jbigkey,
297 - priority=priority)
298 - else:
299 - self.digraph.addnode(jbigkey, myparent,
300 - priority=priority)
301 + self.digraph.addnode(pkg, myparent, priority=priority)
302
303 - if mytype != "installed":
304 + if not pkg.installed:
305 # Allow this package to satisfy old-style virtuals in case it
306 # doesn't already. Any pre-existing providers will be preferred
307 # over this one.
308 try:
309 - pkgsettings.setinst(mykey, metadata)
310 + pkgsettings.setinst(pkg.cpv, pkg.metadata)
311 # For consistency, also update the global virtuals.
312 - settings = self.roots[myroot].settings
313 + settings = self.roots[pkg.root].settings
314 settings.unlock()
315 - settings.setinst(mykey, metadata)
316 + settings.setinst(pkg.cpv, pkg.metadata)
317 settings.lock()
318 except portage_exception.InvalidDependString, e:
319 - show_invalid_depstring_notice(jbigkey, metadata["PROVIDE"], str(e))
320 + show_invalid_depstring_notice(
321 + pkg, pkg.metadata["PROVIDE"], str(e))
322 del e
323 return 0
324
325 - built = mytype != "ebuild"
326 - installed = mytype == "installed"
327 - if installed:
328 - # Warn if all matching ebuilds are masked or
329 - # the installed package itself is masked. Do
330 - # not warn if there are simply no matching
331 - # ebuilds since that would be annoying in some
332 - # cases:
333 - #
334 - # - binary packages installed from an overlay
335 - # that is not listed in PORTDIR_OVERLAY
336 - #
337 - # - multi-slot atoms listed in the world file
338 - # to prevent depclean from removing them
339 + if pkg.installed:
340 + # Warn if all matching ebuilds are masked or
341 + # the installed package itself is masked. Do
342 + # not warn if there are simply no matching
343 + # ebuilds since that would be annoying in some
344 + # cases:
345 + #
346 + # - binary packages installed from an overlay
347 + # that is not listed in PORTDIR_OVERLAY
348 + #
349 + # - multi-slot atoms listed in the world file
350 + # to prevent depclean from removing them
351
352 - if arg:
353 - all_ebuilds_masked = bool(
354 - portdb.xmatch("match-all", arg) and
355 - not portdb.xmatch("bestmatch-visible", arg))
356 - if all_ebuilds_masked:
357 - self._missing_args.append(arg)
358 + if arg:
359 + all_ebuilds_masked = bool(
360 + portdb.xmatch("match-all", arg) and
361 + not portdb.xmatch("bestmatch-visible", arg))
362 + if all_ebuilds_masked:
363 + self._missing_args.append(arg)
364 + if "selective" not in self.myparams:
365 + self._unsatisfied_deps_for_display.append(
366 + ((pkg.root, arg), {"myparent":myparent}))
367 + return 0
368
369 - if "selective" not in self.myparams:
370 - self._unsatisfied_deps_for_display.append(
371 - ((myroot, arg), {"myparent":myparent}))
372 - return 0
373 + if not visible(pkgsettings, pkg.cpv, pkg.metadata,
374 + built=pkg.built, installed=pkg.installed):
375 + self._masked_installed.append((pkg, pkgsettings))
376
377 - pkg = Package(type_name=mytype, root=myroot,
378 - cpv=mykey, built=built, installed=installed,
379 - metadata=metadata)
380 -
381 - if not visible(pkgsettings, pkg.cpv, pkg.metadata,
382 - built=pkg.built, installed=pkg.installed):
383 - self._masked_installed.append((pkg, pkgsettings))
384 -
385 if arg:
386 - self._set_nodes.add(jbigkey)
387 + self._set_nodes.add(pkg)
388
389 # Do this even when addme is False (--onlydeps) so that the
390 # parent/child relationship is always known in case
391 # self._show_slot_collision_notice() needs to be called later.
392 - self._parent_child_digraph.add(jbigkey, myparent)
393 + self._parent_child_digraph.add(pkg, myparent)
394
395 + merging = not (pkg.installed or pkg.onlydeps)
396 + myuse = pkg.metadata["USE"].split()
397 + mytype = pkg.type_name
398 + myroot = pkg.root
399 + mykey = pkg.cpv
400 + metadata = pkg.metadata
401 +
402 """ This section determines whether we go deeper into dependencies or not.
403 We want to go deeper on a few occasions:
404 Installing package A, we need to make sure package A's deps are met.
405 @@ -1904,7 +1851,7 @@
406 """ We have retrieve the dependency information, now we need to recursively
407 process them. DEPEND gets processed for root = "/", {R,P}DEPEND in myroot. """
408
409 - mp = tuple(mybigkey)
410 + mp = pkg
411
412 try:
413 if not self.select_dep("/", edepend["DEPEND"], myparent=mp,
414 @@ -1958,6 +1905,7 @@
415 bindb_keys = list(bindb._aux_cache_keys)
416 pkgsettings = self.pkgsettings[myroot]
417 arg_atoms = []
418 + onlydeps = "--onlydeps" in self.myopts
419 for x in myfiles:
420 ext = os.path.splitext(x)[1]
421 if ext==".tbz2":
422 @@ -1978,8 +1926,12 @@
423 os.path.realpath(self.trees[myroot]["bintree"].getname(mykey)):
424 print colorize("BAD", "\n*** You need to adjust PKGDIR to emerge this package.\n")
425 return 0, myfavorites
426 - if not self.create(["binary", myroot, mykey],
427 - addme=("--onlydeps" not in self.myopts), arg=x):
428 + metadata = dict(izip(self._mydbapi_keys,
429 + bindb.aux_get(mykey, self._mydbapi_keys)))
430 + pkg = Package(type_name="binary", root=myroot,
431 + cpv=mykey, built=True, metadata=metadata,
432 + onlydeps=onlydeps)
433 + if not self.create(pkg, None):
434 return (0,myfavorites)
435 arg_atoms.append((x, "="+mykey))
436 elif ext==".ebuild":
437 @@ -2012,8 +1964,13 @@
438 else:
439 raise portage_exception.PackageNotFound(
440 "%s is not in a valid portage tree hierarchy or does not exist" % x)
441 - if not self.create(["ebuild", myroot, mykey],
442 - None, "--onlydeps" not in self.myopts, arg=x):
443 + metadata = dict(izip(self._mydbapi_keys,
444 + portdb.aux_get(mykey, self._mydbapi_keys)))
445 + pkgsettings.setcpv(mykey, mydb=metadata)
446 + metadata["USE"] = pkgsettings["PORTAGE_USE"]
447 + pkg = Package(type_name="ebuild", root=myroot,
448 + cpv=mykey, metadata=metadata, onlydeps=onlydeps)
449 + if not self.create(pkg, None):
450 return (0,myfavorites)
451 arg_atoms.append((x, "="+mykey))
452 elif x.startswith(os.path.sep):
453 @@ -2153,8 +2110,14 @@
454 if not oneshot:
455 myfavorites.append(myatom)
456 for myarg, myatom in arg_atoms:
457 + pkg, existing_node = self._select_package(
458 + myroot, myatom, onlydeps=onlydeps)
459 + if not pkg:
460 + self._unsatisfied_deps_for_display.append(
461 + ((myroot, myatom), {"myparent":None}))
462 + return False, myfavorites
463 try:
464 - self.mysd = self.select_dep(myroot, myatom, arg=myarg)
465 + self.mysd = self.create(pkg, None)
466 except portage_exception.MissingSignature, e:
467 portage.writemsg("\n\n!!! A missing gpg signature is preventing portage from calculating the\n")
468 portage.writemsg("!!! required dependencies. This is a security feature enabled by the admin\n")
469 @@ -2261,6 +2224,206 @@
470 print xfrom
471 print
472
473 + def _select_pkg_highest_available(self, root, atom, onlydeps=False):
474 + pkgsettings = self.pkgsettings[root]
475 + dbs = self._filtered_trees[root]["dbs"]
476 + vardb = self.roots[root].trees["vartree"].dbapi
477 + portdb = self.roots[root].trees["porttree"].dbapi
478 + # List of acceptable packages, ordered by type preference.
479 + matched_packages = []
480 + existing_node = None
481 + myeb = None
482 + usepkgonly = "--usepkgonly" in self.myopts
483 + empty = "empty" in self.myparams
484 + selective = "selective" in self.myparams
485 + noreplace = "--noreplace" in self.myopts
486 + reinstall = False
487 + # Behavior of the "selective" parameter depends on
488 + # whether or not a package matches an argument atom.
489 + # If an installed package provides an old-style
490 + # virtual that is no longer provided by an available
491 + # package, the installed package may match an argument
492 + # atom even though none of the available packages do.
493 + # Therefore, "selective" logic does not consider
494 + # whether or not an installed package matches an
495 + # argument atom. It only considers whether or not
496 + # available packages match argument atoms, which is
497 + # represented by the found_available_arg flag.
498 + found_available_arg = False
499 + for find_existing_node in True, False:
500 + if existing_node:
501 + break
502 + for db, pkg_type, built, installed, db_keys in dbs:
503 + if existing_node:
504 + break
505 + if installed and not find_existing_node and \
506 + (reinstall or not selective) and \
507 + (matched_packages or empty):
508 + # We only need to select an installed package in the
509 + # following cases:
510 + # 1) there is no other choice
511 + # 2) selective is True
512 + continue
513 + if hasattr(db, "xmatch"):
514 + cpv_list = db.xmatch("match-all", atom)
515 + else:
516 + cpv_list = db.match(atom)
517 + # descending order
518 + cpv_list.reverse()
519 + for cpv in cpv_list:
520 + # Make --noreplace take precedence over --newuse.
521 + if not installed and noreplace and \
522 + cpv in vardb.match(atom):
523 + break
524 + reinstall_for_flags = None
525 + try:
526 + metadata = dict(izip(db_keys,
527 + db.aux_get(cpv, db_keys)))
528 + except KeyError:
529 + continue
530 + if not built:
531 + if "?" in metadata["LICENSE"]:
532 + pkgsettings.setcpv(cpv, mydb=metadata)
533 + metadata["USE"] = pkgsettings["PORTAGE_USE"]
534 + else:
535 + metadata["USE"] = ""
536 + myarg = None
537 + if root == self.target_root:
538 + try:
539 + myarg = self._set_atoms.findAtomForPackage(
540 + cpv, metadata)
541 + except portage_exception.InvalidDependString:
542 + if not installed:
543 + # masked by corruption
544 + continue
545 + if not installed:
546 + if myarg:
547 + found_available_arg = True
548 + try:
549 + if not visible(pkgsettings, cpv, metadata,
550 + built=built, installed=installed):
551 + continue
552 + except portage_exception.InvalidDependString:
553 + # masked by corruption
554 + continue
555 + # At this point, we've found the highest visible
556 + # match from the current repo. Any lower versions
557 + # from this repo are ignored, so this so the loop
558 + # will always end with a break statement below
559 + # this point.
560 + if find_existing_node:
561 + slot_atom = "%s:%s" % (
562 + portage.cpv_getkey(cpv), metadata["SLOT"])
563 + e_pkg = self._slot_pkg_map[root].get(slot_atom)
564 + if not e_pkg:
565 + break
566 + cpv_slot = "%s:%s" % \
567 + (e_pkg.cpv, e_pkg.metadata["SLOT"])
568 + if portage_dep.match_from_list(atom, [cpv_slot]):
569 + matched_packages.append(e_pkg)
570 + existing_node = e_pkg
571 + break
572 + # Compare built package to current config and
573 + # reject the built package if necessary.
574 + if built and not installed and \
575 + ("--newuse" in self.myopts or \
576 + "--reinstall" in self.myopts):
577 + iuses = set(filter_iuse_defaults(
578 + metadata["IUSE"].split()))
579 + old_use = metadata["USE"].split()
580 + mydb = metadata
581 + if myeb and not usepkgonly:
582 + mydb = portdb
583 + if myeb:
584 + pkgsettings.setcpv(myeb, mydb=mydb)
585 + else:
586 + pkgsettings.setcpv(cpv, mydb=mydb)
587 + now_use = pkgsettings["PORTAGE_USE"].split()
588 + forced_flags = set()
589 + forced_flags.update(pkgsettings.useforce)
590 + forced_flags.update(pkgsettings.usemask)
591 + cur_iuse = iuses
592 + if myeb and not usepkgonly:
593 + cur_iuse = set(filter_iuse_defaults(
594 + portdb.aux_get(myeb,
595 + ["IUSE"])[0].split()))
596 + if self._reinstall_for_flags(forced_flags,
597 + old_use, iuses,
598 + now_use, cur_iuse):
599 + break
600 + # Compare current config to installed package
601 + # and do not reinstall if possible.
602 + if not installed and \
603 + ("--newuse" in self.myopts or \
604 + "--reinstall" in self.myopts) and \
605 + vardb.cpv_exists(cpv):
606 + pkgsettings.setcpv(cpv, mydb=metadata)
607 + forced_flags = set()
608 + forced_flags.update(pkgsettings.useforce)
609 + forced_flags.update(pkgsettings.usemask)
610 + old_use = vardb.aux_get(cpv, ["USE"])[0].split()
611 + old_iuse = set(filter_iuse_defaults(
612 + vardb.aux_get(cpv, ["IUSE"])[0].split()))
613 + cur_use = pkgsettings["PORTAGE_USE"].split()
614 + cur_iuse = set(filter_iuse_defaults(
615 + metadata["IUSE"].split()))
616 + reinstall_for_flags = \
617 + self._reinstall_for_flags(
618 + forced_flags, old_use, old_iuse,
619 + cur_use, cur_iuse)
620 + if reinstall_for_flags:
621 + reinstall = True
622 + if not installed:
623 + must_reinstall = empty or \
624 + (myarg and not selective)
625 + if not reinstall_for_flags and \
626 + not must_reinstall and \
627 + cpv in vardb.match(atom):
628 + break
629 + if installed:
630 + must_reinstall = empty or \
631 + (found_available_arg and not selective)
632 + if must_reinstall:
633 + break
634 + # Metadata accessed above is cached internally by
635 + # each db in order to optimize visibility checks.
636 + # Now that all possible checks visibility checks
637 + # are complete, it's time to pull the rest of the
638 + # metadata (including *DEPEND). This part is more
639 + # expensive, so avoid it whenever possible.
640 + metadata.update(izip(self._mydbapi_keys,
641 + db.aux_get(cpv, self._mydbapi_keys)))
642 + if not built:
643 + pkgsettings.setcpv(cpv, mydb=metadata)
644 + metadata["USE"] = pkgsettings["PORTAGE_USE"]
645 + myeb = cpv
646 + matched_packages.append(
647 + Package(type_name=pkg_type, root=root,
648 + cpv=cpv, metadata=metadata,
649 + built=built, installed=installed,
650 + onlydeps=onlydeps))
651 + if reinstall_for_flags:
652 + pkg_node = (pkg_type, root, cpv, "merge")
653 + self._reinstall_nodes[pkg_node] = \
654 + reinstall_for_flags
655 + break
656 +
657 + if not matched_packages:
658 + return None, None
659 +
660 + if "--debug" in self.myopts:
661 + for pkg in matched_packages:
662 + print (pkg.type_name + ":").rjust(10), pkg.cpv
663 +
664 + if len(matched_packages) > 1:
665 + bestmatch = portage.best(
666 + [pkg.cpv for pkg in matched_packages])
667 + matched_packages = [pkg for pkg in matched_packages \
668 + if pkg.cpv == bestmatch]
669 +
670 + # ordered by type preference ("ebuild" type is the last resort)
671 + return matched_packages[-1], existing_node
672 +
673 def select_dep(self, myroot, depstring, myparent=None, arg=None,
674 myuse=None, raise_on_missing=False, priority=DepPriority(),
675 rev_deps=False, parent_arg=None):
676 @@ -2340,144 +2503,12 @@
677 ("blocks", p_root, x[1:]), set()).add(myparent)
678 continue
679 else:
680 - # List of acceptable packages, ordered by type preference.
681 - matched_packages = []
682 - myeb_matches = portdb.xmatch("match-visible", x)
683 - myeb = None
684 - myeb_pkg = None
685 - metadata = None
686 - existing_node = None
687 - if myeb_matches:
688 - myeb = portage.best(myeb_matches)
689 - # For best performance, try to reuse an exising node
690 - # and it's cached metadata. The portdbapi caches SLOT
691 - # metadata in memory so it's really only pulled once.
692 - slot_atom = "%s:%s" % (portage.dep_getkey(myeb),
693 - portdb.aux_get(myeb, ["SLOT"])[0])
694 - existing_node = self._slot_node_map[myroot].get(slot_atom)
695 - if existing_node:
696 - e_type, myroot, e_cpv, e_status = existing_node
697 - metadata = dict(izip(self._mydbapi_keys,
698 - self.mydbapi[myroot].aux_get(e_cpv, self._mydbapi_keys)))
699 - cpv_slot = "%s:%s" % (e_cpv, metadata["SLOT"])
700 - if portage.match_from_list(x, [cpv_slot]):
701 - matched_packages.append(
702 - ([e_type, myroot, e_cpv], metadata))
703 - else:
704 - existing_node = None
705 -
706 - if not existing_node and \
707 - "--usepkg" in self.myopts:
708 - # The next line assumes the binarytree has been populated.
709 - # XXX: Need to work out how we use the binary tree with roots.
710 - usepkgonly = "--usepkgonly" in self.myopts
711 - chost = pkgsettings["CHOST"]
712 - myeb_pkg_matches = []
713 - bindb_keys = list(bindb._aux_cache_keys)
714 - for pkg in bindb.match(x):
715 - metadata = dict(izip(bindb_keys,
716 - bindb.aux_get(pkg, bindb_keys)))
717 - if not visible(pkgsettings, pkg, metadata, built=True):
718 - continue
719 - myeb_pkg_matches.append(pkg)
720 - if myeb_pkg_matches:
721 - myeb_pkg = portage.best(myeb_pkg_matches)
722 - # For best performance, try to reuse an exising node
723 - # and it's cached metadata. The bindbapi caches SLOT
724 - # metadata in memory so it's really only pulled once.
725 - slot_atom = "%s:%s" % (portage.dep_getkey(myeb_pkg),
726 - bindb.aux_get(myeb_pkg, ["SLOT"])[0])
727 - existing_node = self._slot_node_map[myroot].get(slot_atom)
728 - if existing_node:
729 - e_type, myroot, e_cpv, e_status = existing_node
730 - metadata = dict(izip(self._mydbapi_keys,
731 - self.mydbapi[myroot].aux_get(e_cpv, self._mydbapi_keys)))
732 - cpv_slot = "%s:%s" % (e_cpv, metadata["SLOT"])
733 - if portage.match_from_list(x, [cpv_slot]):
734 - myeb_pkg = None
735 - matched_packages.append(
736 - ([e_type, myroot, e_cpv], metadata))
737 - else:
738 - existing_node = None
739 - if not existing_node:
740 - # For best performance, avoid pulling
741 - # metadata whenever possible.
742 - metadata = dict(izip(self._mydbapi_keys,
743 - bindb.aux_get(myeb_pkg, self._mydbapi_keys)))
744 -
745 - if not existing_node and \
746 - myeb_pkg and \
747 - ("--newuse" in self.myopts or \
748 - "--reinstall" in self.myopts):
749 - iuses = set(filter_iuse_defaults(metadata["IUSE"].split()))
750 - old_use = metadata["USE"].split()
751 - mydb = None
752 - if "--usepkgonly" not in self.myopts and myeb:
753 - mydb = portdb
754 - if myeb:
755 - pkgsettings.setcpv(myeb, mydb=mydb)
756 - else:
757 - pkgsettings.setcpv(myeb_pkg, mydb=mydb)
758 - now_use = pkgsettings["PORTAGE_USE"].split()
759 - forced_flags = set()
760 - forced_flags.update(pkgsettings.useforce)
761 - forced_flags.update(pkgsettings.usemask)
762 - cur_iuse = iuses
763 - if "--usepkgonly" not in self.myopts and myeb:
764 - cur_iuse = set(filter_iuse_defaults(
765 - portdb.aux_get(myeb, ["IUSE"])[0].split()))
766 - if self._reinstall_for_flags(
767 - forced_flags, old_use, iuses, now_use, cur_iuse):
768 - myeb_pkg = None
769 - if myeb_pkg:
770 - matched_packages.append(
771 - (["binary", myroot, myeb_pkg], metadata))
772 -
773 - if not existing_node and \
774 - myeb and \
775 - "--usepkgonly" not in self.myopts:
776 - metadata = dict(izip(self._mydbapi_keys,
777 - portdb.aux_get(myeb, self._mydbapi_keys)))
778 - pkgsettings.setcpv(myeb, mydb=portdb)
779 - metadata["USE"] = pkgsettings["PORTAGE_USE"]
780 - matched_packages.append(
781 - (["ebuild", myroot, myeb], metadata))
782 -
783 - if not matched_packages and \
784 - not (arg and "selective" not in self.myparams):
785 - """Fall back to the installed package database. This is a
786 - last resort because the metadata tends to diverge from that
787 - of the ebuild in the tree."""
788 - myeb_inst_matches = vardb.match(x)
789 - myeb_inst = None
790 - if myeb_inst_matches:
791 - myeb_inst = portage.best(myeb_inst_matches)
792 - if myeb_inst:
793 - metadata = dict(izip(self._mydbapi_keys,
794 - vardb.aux_get(myeb_inst, self._mydbapi_keys)))
795 - matched_packages.append(
796 - (["installed", myroot, myeb_inst], metadata))
797 -
798 - if not matched_packages:
799 - if raise_on_missing:
800 - raise portage_exception.PackageNotFound(x)
801 + pkg, existing_node = self._select_package(myroot, x)
802 + if not pkg:
803 self._unsatisfied_deps_for_display.append(
804 ((myroot, x), {"myparent":myparent}))
805 return 0
806
807 - if "--debug" in self.myopts:
808 - for pkg, metadata in matched_packages:
809 - print (pkg[0] + ":").rjust(10), pkg[2]
810 -
811 - if len(matched_packages) > 1:
812 - bestmatch = portage.best(
813 - [pkg[2] for pkg, metadata in matched_packages])
814 - matched_packages = [pkg for pkg in matched_packages \
815 - if pkg[0][2] == bestmatch]
816 -
817 - # ordered by type preference ("ebuild" type is the last resort)
818 - selected_pkg = matched_packages[0]
819 -
820 # In some cases, dep_check will return deps that shouldn't
821 # be proccessed any further, so they are identified and
822 # discarded here. Try to discard as few as possible since
823 @@ -2488,12 +2519,11 @@
824 "empty" not in self.myparams and \
825 "deep" not in self.myparams and \
826 not ("--update" in self.myopts and parent_arg):
827 - (mytype, myroot, mykey), metadata = selected_pkg
828 myarg = None
829 - if myroot == self.target_root:
830 + if pkg.root == self.target_root:
831 try:
832 myarg = self._set_atoms.findAtomForPackage(
833 - mykey, metadata)
834 + pkg.cpv, pkg.metadata)
835 except portage_exception.InvalidDependString:
836 # This is already handled inside
837 # self.create() when necessary.
838 @@ -2506,16 +2536,12 @@
839 mypriority = priority.copy()
840 if vardb.match(x):
841 mypriority.satisfied = True
842 - if not self.create(selected_pkg[0], myparent=myparent,
843 - metadata=selected_pkg[1], priority=mypriority,
844 - rev_dep=rev_deps, arg=arg):
845 + if not self.create(pkg, myparent, priority=mypriority):
846 return 0
847 else:
848 #if mysource is not set, then we are a command-line dependency and should not be added
849 #if --onlydeps is specified.
850 - if not self.create(selected_pkg[0], myparent=myparent,
851 - addme=("--onlydeps" not in self.myopts),
852 - metadata=selected_pkg[1], rev_dep=rev_deps, arg=arg):
853 + if not self.create(pkg, myparent):
854 return 0
855
856 if "--debug" in self.myopts:
857 @@ -2537,11 +2563,9 @@
858 myslots = {}
859 modified_slots[myroot] = myslots
860 final_db = self.mydbapi[myroot]
861 - slot_node_map = self._slot_node_map[myroot]
862 - for slot_atom, mynode in slot_node_map.iteritems():
863 - mytype, myroot, mycpv, mystatus = mynode
864 - if mystatus == "merge":
865 - myslots[slot_atom] = mycpv
866 + for pkg in self._slot_pkg_map[myroot].itervalues():
867 + if not (pkg.installed or pkg.onlydeps):
868 + myslots[pkg.slot_atom] = pkg.cpv
869
870 #if "deep" in self.myparams:
871 if True:
872 @@ -2564,7 +2588,6 @@
873
874 dep_keys = ["DEPEND","RDEPEND","PDEPEND"]
875 for myroot in self.trees:
876 - pkg_node_map = self.pkg_node_map[myroot]
877 vardb = self.trees[myroot]["vartree"].dbapi
878 portdb = self.trees[myroot]["porttree"].dbapi
879 pkgsettings = self.pkgsettings[myroot]
880 @@ -2573,9 +2596,12 @@
881 blocker_cache = BlockerCache(myroot, vardb)
882 for pkg in cpv_all_installed:
883 blocker_atoms = None
884 - matching_node = pkg_node_map.get(pkg, None)
885 - if matching_node and \
886 - matching_node[3] == "nomerge":
887 + metadata = dict(izip(self._mydbapi_keys,
888 + vardb.aux_get(pkg, self._mydbapi_keys)))
889 + node = Package(cpv=pkg, built=True,
890 + installed=True, metadata=metadata,
891 + type_name="installed", root=myroot)
892 + if self.digraph.contains(node):
893 continue
894 # If this node has any blockers, create a "nomerge"
895 # node for it so that they can be enforced.
896 @@ -2604,8 +2630,7 @@
897 # matches (this can happen if an atom lacks a
898 # category).
899 show_invalid_depstring_notice(
900 - ("installed", myroot, pkg, "nomerge"),
901 - depstr, str(e))
902 + node, depstr, str(e))
903 del e
904 raise
905 finally:
906 @@ -2619,9 +2644,7 @@
907 # annoy the user too much (otherwise they'd be
908 # forced to manually unmerge it first).
909 continue
910 - show_invalid_depstring_notice(
911 - ("installed", myroot, pkg, "nomerge"),
912 - depstr, atoms)
913 + show_invalid_depstring_notice(node, depstr, atoms)
914 return False
915 blocker_atoms = [myatom for myatom in atoms \
916 if myatom.startswith("!")]
917 @@ -2629,10 +2652,6 @@
918 blocker_cache[pkg] = \
919 blocker_cache.BlockerData(counter, blocker_atoms)
920 if blocker_atoms:
921 - # Don't store this parent in pkg_node_map, because it's
922 - # not needed there and it might overwrite a "merge"
923 - # node with the same cpv.
924 - myparent = ("installed", myroot, pkg, "nomerge")
925 for myatom in blocker_atoms:
926 blocker = ("blocks", myroot, myatom[1:])
927 myparents = \
928 @@ -2640,7 +2659,7 @@
929 if not myparents:
930 myparents = set()
931 self.blocker_parents[blocker] = myparents
932 - myparents.add(myparent)
933 + myparents.add(node)
934 blocker_cache.flush()
935 del blocker_cache
936
937 @@ -2674,10 +2693,10 @@
938 for cpv in blocked_initial:
939 slot_atom = blocked_slots_initial[cpv]
940 if slot_atom == pslot_atom:
941 - # The parent blocks an initial package in the same
942 - # slot as itself. The merge/nomerge status of neither
943 - # node matters. In any case, this particular block is
944 - # automatically resolved.
945 + # TODO: Support blocks within slots in cases where it
946 + # might make sense. For example, a new version might
947 + # require that the old version be uninstalled at build
948 + # time.
949 continue
950 if parent_static and \
951 slot_atom not in modified_slots[myroot]:
952 @@ -2686,25 +2705,20 @@
953 continue
954 if pstatus == "merge" and \
955 slot_atom in modified_slots[myroot]:
956 - replacement = final_db.match(slot_atom)
957 - if replacement:
958 - slot = portage_dep.dep_getslot(slot_atom)
959 - if not portage.match_from_list(
960 - mydep, ["%s:%s" % (replacement[0], slot)]):
961 - # Apparently a replacement may be able to
962 - # invalidate this block.
963 - replacement_node = \
964 - self.pkg_node_map[proot][replacement[0]]
965 - depends_on_order.add((replacement_node, parent))
966 - continue
967 + replacement = self._slot_pkg_map[myroot][slot_atom]
968 + if not portage.match_from_list(
969 + mydep, [replacement.cpv_slot]):
970 + # Apparently a replacement may be able to
971 + # invalidate this block.
972 + depends_on_order.add((replacement, parent))
973 + continue
974 # None of the above blocker resolutions techniques apply,
975 # so apparently this one is unresolvable.
976 unresolved_blocks = True
977 for cpv in blocked_final:
978 slot_atom = blocked_slots_final[cpv]
979 if slot_atom == pslot_atom:
980 - # The parent blocks itself, so the merge order does not
981 - # need to be enforced.
982 + # TODO: Support blocks within slots.
983 continue
984 if parent_static and \
985 slot_atom not in modified_slots[myroot]:
986 @@ -2713,18 +2727,16 @@
987 continue
988 if not parent_static and pstatus == "nomerge" and \
989 slot_atom in modified_slots[myroot]:
990 - replacement = final_db.match(pslot_atom)
991 - if replacement:
992 - replacement_node = \
993 - self.pkg_node_map[proot][replacement[0]]
994 - if replacement_node not in \
995 - self.blocker_parents[blocker]:
996 - # Apparently a replacement may be able to
997 - # invalidate this block.
998 - blocked_node = self.pkg_node_map[proot][cpv]
999 - depends_on_order.add(
1000 - (replacement_node, blocked_node))
1001 - continue
1002 + replacement = self._slot_pkg_map[myroot][pslot_atom]
1003 + if replacement not in \
1004 + self.blocker_parents[blocker]:
1005 + # Apparently a replacement may be able to
1006 + # invalidate this block.
1007 + blocked_node = \
1008 + self._slot_pkg_map[myroot][slot_atom]
1009 + depends_on_order.add(
1010 + (replacement, blocked_node))
1011 + continue
1012 # None of the above blocker resolutions techniques apply,
1013 # so apparently this one is unresolvable.
1014 unresolved_blocks = True
1015 @@ -2786,6 +2798,19 @@
1016 self._altlist_cache[reversed] = retlist[:]
1017 return retlist
1018 mygraph=self.digraph.copy()
1019 + # Prune "nomerge" root nodes if nothing depends on them, since
1020 + # otherwise they slow down merge order calculation. Don't remove
1021 + # non-root nodes since they help optimize merge order in some cases
1022 + # such as revdep-rebuild.
1023 + while True:
1024 + removed_something = False
1025 + for node in mygraph.root_nodes():
1026 + if not isinstance(node, Package) or \
1027 + node.installed or node.onlydeps:
1028 + mygraph.remove(node)
1029 + removed_something = True
1030 + if not removed_something:
1031 + break
1032 self._merge_order_bias(mygraph)
1033 def cmp_circular_bias(n1, n2):
1034 """
1035 @@ -2812,8 +2837,10 @@
1036 get_nodes = mygraph.root_nodes
1037 else:
1038 get_nodes = mygraph.leaf_nodes
1039 - for cpv, node in self.pkg_node_map["/"].iteritems():
1040 - if "portage" == portage.catsplit(portage.dep_getkey(cpv))[-1]:
1041 + for node in mygraph.order:
1042 + if node.root == "/" and \
1043 + "portage" == portage.catsplit(
1044 + portage.cpv_getkey(node.cpv))[-1]:
1045 portage_node = node
1046 asap_nodes.append(node)
1047 break
1048 @@ -3106,13 +3133,14 @@
1049 self._set_atoms.add(myatom)
1050
1051 for mydep in mylist:
1052 - try:
1053 - if not self.select_dep(
1054 - self.target_root, mydep, raise_on_missing=True, arg=mydep):
1055 - print >> sys.stderr, "\n\n!!! Problem resolving dependencies for", mydep
1056 - return 0
1057 - except portage_exception.PackageNotFound:
1058 + pkg, existing_node = self._select_package(
1059 + self.target_root, mydep)
1060 + if not pkg:
1061 self._missing_args.append(mydep)
1062 + continue
1063 + if not self.create(pkg, None):
1064 + print >> sys.stderr, "\n\n!!! Problem resolving dependencies for", mydep
1065 + return 0
1066
1067 if not self.validate_blockers():
1068 return False
1069
1070 --
1071 gentoo-commits@l.g.o mailing list