summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2008-07-21 23:15:37 +0000
committerZac Medico <zmedico@gentoo.org>2008-07-21 23:15:37 +0000
commit26d6a4f30c30d395ab661eaff11aec846f6170f3 (patch)
treee59ff5e36244fb2592a2836ca94c843cf95d47bd
parentbf878c2fb4ae1d98ff0059d62530e87aa775d871 (diff)
downloadportage-26d6a4f30c30d395ab661eaff11aec846f6170f3.tar.gz
portage-26d6a4f30c30d395ab661eaff11aec846f6170f3.tar.bz2
portage-26d6a4f30c30d395ab661eaff11aec846f6170f3.zip
Fix --depclean/--prune to add lib providers and their dependencies to the
graph and create a new clean list when necessary. This completes the fix for bug #230053. svn path=/main/trunk/; revision=11158
-rw-r--r--pym/_emerge/__init__.py185
1 files changed, 120 insertions, 65 deletions
diff --git a/pym/_emerge/__init__.py b/pym/_emerge/__init__.py
index 10869765e..3ddb7be5f 100644
--- a/pym/_emerge/__init__.py
+++ b/pym/_emerge/__init__.py
@@ -11601,29 +11601,45 @@ def action_depclean(settings, trees, ldpath_mtimes,
if not success:
return 1
- unresolveable = set()
- for dep in resolver._initially_unsatisfied_deps:
- if isinstance(dep.parent, Package):
- unresolveable.add((dep.atom, dep.parent.cpv))
-
- if unresolveable and not allow_missing_deps:
- print "Dependencies could not be completely resolved due to"
- print "the following required packages not being installed:"
- print
- for atom, parent in unresolveable:
- print atom, "required by", str(parent)
- if unresolveable and not allow_missing_deps:
- print
- print "Have you forgotten to run " + good("`emerge --update --newuse --deep world`") + " prior to"
- print "%s? It may be necessary to manually uninstall packages that no longer" % action
- print "exist in the portage tree since it may not be possible to satisfy their"
- print "dependencies. Also, be aware of the --with-bdeps option that is documented"
- print "in " + good("`man emerge`") + "."
- print
- if action == "prune":
- print "If you would like to ignore dependencies then use %s." % \
- good("--nodeps")
- return
+ def unresolved_deps():
+
+ unresolvable = set()
+ for dep in resolver._initially_unsatisfied_deps:
+ if isinstance(dep.parent, Package):
+ unresolvable.add((dep.atom, dep.parent.cpv))
+ if not unresolvable:
+ return False
+
+ if unresolvable and not allow_missing_deps:
+ prefix = bad(" * ")
+ msg = []
+ msg.append("Dependencies could not be completely resolved due to")
+ msg.append("the following required packages not being installed:")
+ msg.append("")
+ for atom, parent in unresolvable:
+ msg.append(" %s pulled in by:" % (atom,))
+ msg.append(" %s" % (parent,))
+ msg.append("")
+ msg.append("Have you forgotten to run " + \
+ good("`emerge --update --newuse --deep world`") + " prior to")
+ msg.append(("%s? It may be necessary to manually " + \
+ "uninstall packages that no longer") % action)
+ msg.append("exist in the portage tree since " + \
+ "it may not be possible to satisfy their")
+ msg.append("dependencies. Also, be aware of " + \
+ "the --with-bdeps option that is documented")
+ msg.append("in " + good("`man emerge`") + ".")
+ if action == "prune":
+ msg.append("")
+ msg.append("If you would like to ignore " + \
+ "dependencies then use %s." % good("--nodeps"))
+ writemsg_level("".join("%s%s\n" % (prefix, line) for line in msg),
+ level=logging.ERROR, noiselevel=-1)
+ return True
+ return False
+
+ if unresolved_deps():
+ return 1
graph = resolver.digraph.copy()
required_pkgs_total = 0
@@ -11649,49 +11665,60 @@ def action_depclean(settings, trees, ldpath_mtimes,
msg.append("\n")
portage.writemsg_stdout("".join(msg), noiselevel=-1)
- cleanlist = []
- if action == "depclean":
- if args_set:
- for pkg in vardb:
- arg_atom = None
- try:
- arg_atom = args_set.findAtomForPackage(pkg)
- except portage.exception.InvalidDependString:
- # this error has already been displayed by now
- continue
- if arg_atom:
+ def create_cleanlist():
+ pkgs_to_remove = []
+
+ if action == "depclean":
+ if args_set:
+
+ for pkg in vardb:
+ arg_atom = None
+ try:
+ arg_atom = args_set.findAtomForPackage(pkg)
+ except portage.exception.InvalidDependString:
+ # this error has already been displayed by now
+ continue
+
+ if arg_atom:
+ if pkg not in graph:
+ pkgs_to_remove.append(pkg)
+ elif "--verbose" in myopts:
+ show_parents(pkg)
+
+ else:
+ for pkg in vardb:
if pkg not in graph:
- cleanlist.append(pkg)
+ pkgs_to_remove.append(pkg)
elif "--verbose" in myopts:
show_parents(pkg)
- else:
- for pkg in vardb:
- if pkg not in graph:
- cleanlist.append(pkg)
- elif "--verbose" in myopts:
- show_parents(pkg)
- elif action == "prune":
- # Prune really uses all installed instead of world. It's not a real
- # reverse dependency so don't display it as such.
- graph.remove(set_args["world"])
- for atom in args_set:
- for pkg in vardb.match_pkgs(atom):
- if pkg not in graph:
- cleanlist.append(pkg)
- elif "--verbose" in myopts:
- show_parents(pkg)
-
- if not cleanlist:
- portage.writemsg_stdout(
- ">>> No packages selected for removal by %s\n" % action)
- if "--verbose" not in myopts:
- portage.writemsg_stdout(
- ">>> To see reverse dependencies, use %s\n" % \
- good("--verbose"))
- if action == "prune":
- portage.writemsg_stdout(
- ">>> To ignore dependencies, use %s\n" % \
- good("--nodeps"))
+
+ elif action == "prune":
+ # Prune really uses all installed instead of world. It's not
+ # a real reverse dependency so don't display it as such.
+ graph.remove(set_args["world"])
+
+ for atom in args_set:
+ for pkg in vardb.match_pkgs(atom):
+ if pkg not in graph:
+ pkgs_to_remove.append(pkg)
+ elif "--verbose" in myopts:
+ show_parents(pkg)
+
+ if not pkgs_to_remove:
+ writemsg_level(
+ ">>> No packages selected for removal by %s\n" % action)
+ if "--verbose" not in myopts:
+ writemsg_level(
+ ">>> To see reverse dependencies, use %s\n" % \
+ good("--verbose"))
+ if action == "prune":
+ writemsg_level(
+ ">>> To ignore dependencies, use %s\n" % \
+ good("--nodeps"))
+
+ return pkgs_to_remove
+
+ cleanlist = create_cleanlist()
if len(cleanlist):
clean_set = set(cleanlist)
@@ -11843,8 +11870,36 @@ def action_depclean(settings, trees, ldpath_mtimes,
msg.append("")
writemsg_level("".join(prefix + "%s\n" % line for line in msg),
level=logging.WARNING, noiselevel=-1)
- # TODO: Add packages + deps to graph, and calculate new clean list.
- return 1
+
+ # Add lib providers to the graph as children of lib consumers,
+ # and also add any dependencies pulled in by the provider.
+ writemsg_level(">>> Adding lib providers to graph...\n")
+
+ for pkg, consumers in consumer_map.iteritems():
+ for consumer_dblink in set(chain(*consumers.values())):
+ consumer_pkg = vardb.get(("installed", myroot,
+ consumer_dblink.mycpv, "nomerge"))
+ resolver._add_pkg(pkg, consumer_pkg,
+ priority=UnmergeDepPriority(runtime=True))
+
+ writemsg_level("\nCalculating dependencies ")
+ success = resolver._complete_graph()
+ writemsg_level("\b\b... done!\n")
+ resolver.display_problems()
+ if not success:
+ return 1
+ if unresolved_deps():
+ return 1
+
+ graph = resolver.digraph.copy()
+ required_pkgs_total = 0
+ for node in graph:
+ if isinstance(node, Package):
+ required_pkgs_total += 1
+ cleanlist = create_cleanlist()
+ if not cleanlist:
+ return 0
+ clean_set = set(cleanlist)
# Use a topological sort to create an unmerge order such that
# each package is unmerged before it's dependencies. This is