From: Fabian Groffen Date: Wed, 23 Jul 2008 06:54:24 +0000 (-0000) Subject: Merged from trunk 11157:11169 X-Git-Url: http://git.tremily.us/gitweb.cgi?a=commitdiff_plain;h=a4fc2fe9dfaa97799e6030ce1c8261ab1d8f1d28;p=portage.git Merged from trunk 11157:11169 | 11158 | Fix --depclean/--prune to add lib providers and their | | zmedico | dependencies to the graph and create a new clean list when | | | necessary. This completes the fix for bug #230053. | | 11159 | Adjust --fetchonly failure messages to work better with | | zmedico | background mode. | | 11160 | Adjust status messages for --fetchonly mode. | | zmedico | | | 11161 | Redirect dblink._preserve_libs() messages to the log when in | | zmedico | background mode. | | 11162 | Make --pretend disable background mode and imply --jobs=1. | | zmedico | | | 11163 | Disable "Installing" status messages when in --pretend or | | zmedico | --buildpkgonly mode. | | 11164 | Redirect build log eqawarn messages to the log file when in | | zmedico | background mode. | | 11165 | Show the number of failed packages in the status display. | | zmedico | | | 11166 | Fix resume_depgraph() so that it doesn't raise an | | zmedico | AssertionError due to unsatisfied PDEPEND. | | 11167 | In dblink.unmerge(), redirect preserve-libs "!needed" | | zmedico | messages to the log file when in background mode. | | 11168 | Update --depclean and --prune, removing warnings about | | zmedico | libraries since those are now automatically accounted for. | | 11169 | Handle UnsatisfiedResumeDep in | | zmedico | Scheduler._calc_resume_list(). | svn path=/main/branches/prefix/; revision=11172 --- diff --git a/NEWS b/NEWS index 1f9f308e7..2fb033c0b 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,8 @@ News (mainly features/major bug fixes) portage-2.2 ------------- +* Add link level dependency awareness to emerge --depclean and --prune actions + in order to protect against uninstallation of required libraries. * Add emerge --jobs and --load-average options which specify behavior for building packages in parallel or for generating metadata in parallel with emerge --regen. diff --git a/man/emerge.1 b/man/emerge.1 index bc9a7efc8..59d335f62 100644 --- a/man/emerge.1 +++ b/man/emerge.1 @@ -103,19 +103,22 @@ setups that the user may wish to run. .BR \-\-depclean Cleans the system by removing packages that are not associated with explicitly merged packages. Depclean works by creating the -full dependency tree from the system and world sets, +full dependency tree from the @system and @world sets, then comparing it to installed packages. Packages installed, but not part of the dependency tree, will be uninstalled by depclean. -Inexperienced users are advised to use \fB\-\-pretend\fR -with this option in order to see a preview of which packages -will be uninstalled. +See \fB\-\-with\-bdeps\fR for behavior with respect to build time dependencies +that are not strictly required. Packages that are part of the world set will +always be kept. They can be manually added to this set with \fIemerge +\-\-noreplace \fR. As a safety measure, depclean will not remove any +packages unless *all* required dependencies have been resolved. As a +consequence, it is often necessary to run \fIemerge \-\-update \-\-newuse +\-\-deep \-\-oneshot @system @world\fR prior to depclean. -\fBWARNING: Removing some -packages may cause packages which link to the removed package -to stop working and complain about missing libraries.\fR -Rebuild the complaining package to fix this issue. Also see -\fB\-\-with\-bdeps\fR for behavior with respect to build time dependencies that -are not strictly required. Note that packages listed in +\fBWARNING:\fR +Inexperienced users are advised to use \fB\-\-pretend\fR with this +option in order to see a preview of which packages +will be uninstalled. Always study the list of packages +to be cleaned for any obvious mistakes. Note that packages listed in package.provided (see \fBportage\fR(5)) may be removed by depclean, even if they are part of the world set. @@ -150,11 +153,9 @@ unless the user has enabled FEATURES="metadata-transfer" in \fBmake.conf\fR(5). .TP .BR "\-\-prune " (\fB\-P\fR) \fBWARNING: This action can remove important packages!\fR Removes all but the -highest installed version of a package from your system. This action doesn't -verify the possible binary compatibility between versions and can thus remove -essential dependencies from your system. Use \fB\-\-prune\fR together with -\fB\-\-verbose\fR to show reverse dependencies or with \fB\-\-nodeps\fR to -ignore all dependencies. +highest installed version of a package from your system. Use \fB\-\-prune\fR +together with \fB\-\-verbose\fR to show reverse dependencies or with +\fB\-\-nodeps\fR to ignore all dependencies. .TP .BR \-\-regen Causes portage to check and update the dependency cache of all ebuilds in the diff --git a/pym/_emerge/__init__.py b/pym/_emerge/__init__.py index 932824055..fc9b9588d 100644 --- a/pym/_emerge/__init__.py +++ b/pym/_emerge/__init__.py @@ -29,6 +29,7 @@ import logging import select import shlex import shutil +import textwrap import urlparse import weakref import gc @@ -2429,8 +2430,9 @@ class EbuildBuild(CompositeTask): if opts.fetchonly: if self._final_exit(fetcher) != os.EX_OK: - eerror("!!! Fetch for %s failed, continuing..." % pkg.cpv, - phase="unpack", key=pkg.cpv) + if not self.background: + eerror("Fetch for %s failed, continuing..." % pkg.cpv, + phase="unpack", key=pkg.cpv) self.wait() return @@ -2761,7 +2763,17 @@ class EbuildPhase(CompositeTask): def _ebuild_exit(self, ebuild_process): if self.phase == "install": - portage._check_build_log(self.settings) + out = None + log_path = self.settings.get("PORTAGE_LOG_FILE") + log_file = None + if self.background and log_path is not None: + log_file = open(log_path, 'a') + out = log_file + try: + portage._check_build_log(self.settings, out=out) + finally: + if log_file is not None: + log_file.close() if self._default_exit(ebuild_process) != os.EX_OK: self.wait() @@ -3391,6 +3403,9 @@ class MergeListItem(CompositeTask): if pkg.type_name == "binary": action_desc = "Extracting" + if build_opts.fetchonly: + action_desc = "Fetching" + if not build_opts.pretend: self.statusMessage("%s (%s of %s) %s %s %s" % \ @@ -3499,9 +3514,12 @@ class PackageMerge(AsynchronousTask): action_desc = "Installing" preposition = "to" - self.merge.statusMessage("%s %s %s %s" % \ - (action_desc, colorize("GOOD", pkg.cpv), - preposition, pkg.root)) + if not self.merge.build_opts.fetchonly and \ + not self.merge.build_opts.pretend and \ + not self.merge.build_opts.buildpkgonly: + self.merge.statusMessage("%s %s %s %s" % \ + (action_desc, colorize("GOOD", pkg.cpv), + preposition, pkg.root)) self.returncode = self.merge.merge() self.wait() @@ -8448,8 +8466,8 @@ class TaskScheduler(object): class JobStatusDisplay(object): - _bound_properties = ("curval", "running") - _jobs_column_width = 42 + _bound_properties = ("curval", "failed", "running") + _jobs_column_width = 48 # Don't update the display unless at least this much # time has passed, in units of seconds. @@ -8577,6 +8595,7 @@ class JobStatusDisplay(object): def _property_change(self, name, old_value, new_value): self._changed = True + self.display() def _load_avg_str(self, digits=2): try: @@ -8613,7 +8632,7 @@ class JobStatusDisplay(object): curval_str = str(self.curval) maxval_str = str(self.maxval) running_str = str(self.running) - merges_str = str(self.merges) + failed_str = str(self.failed) load_avg_str = self._load_avg_str() color_output = StringIO.StringIO() @@ -8642,21 +8661,18 @@ class JobStatusDisplay(object): f.pop_style() f.add_literal_data(" running") - #if self.merges: - if False: + if self.failed: f.add_literal_data(", ") f.push_style(number_style) - f.add_literal_data(merges_str) + f.add_literal_data(failed_str) f.pop_style() - f.add_literal_data(" merge") - if self.merges != 1: - f.add_literal_data("s") + f.add_literal_data(" failed") padding = self._jobs_column_width - len(plain_output.getvalue()) if padding > 0: f.add_literal_data(padding * " ") - f.add_literal_data("Load average: ") + f.add_literal_data("Load avg: ") f.add_literal_data(load_avg_str) self._update(color_output.getvalue()) @@ -8843,7 +8859,8 @@ class Scheduler(PollScheduler): @rtype: bool @returns: True if background mode is enabled, False otherwise. """ - background = self._max_jobs > 1 or "--quiet" in self.myopts + background = (self._max_jobs > 1 or "--quiet" in self.myopts) and \ + "--pretend" not in self.myopts self._status_display.quiet = \ not background or \ @@ -9116,15 +9133,26 @@ class Scheduler(PollScheduler): "--fetch-all-uri" in self.myopts): return - sys.stderr.write("\n\n!!! Some fetch errors were " + \ - "encountered. Please see above for details.\n\n") + if self._background: + msg = "Some fetch errors were " + \ + "encountered. Please see %s for details." % \ + self._fetch_log + else: + msg = "Some fetch errors were " + \ + "encountered. Please see above for details." - for cpv in failed_fetches: - sys.stderr.write(" ") - sys.stderr.write(cpv) - sys.stderr.write("\n") + prefix = bad(" * ") + msg = "".join("%s%s\n" % (prefix, line) \ + for line in textwrap.wrap(msg, 70)) + writemsg_level(msg, level=logging.ERROR, noiselevel=-1) - sys.stderr.write("\n") + msg = [] + msg.append("") + for cpv in failed_fetches: + msg.append(" %s" % cpv) + msg.append("") + writemsg_level("".join("%s%s\n" % (prefix, line) \ + for line in msg), level=logging.ERROR, noiselevel=-1) def _is_restart_scheduled(self): """ @@ -9254,6 +9282,9 @@ class Scheduler(PollScheduler): break dropped_tasks = self._calc_resume_list() + if dropped_tasks is None: + break + clear_caches(self.trees) if not self._mergelist: break @@ -9349,6 +9380,7 @@ class Scheduler(PollScheduler): pkg = merge.merge.pkg if merge.returncode != os.EX_OK: self._failed_pkgs.append((pkg, merge.returncode)) + self._status_display.failed = len(self._failed_pkgs) return self._task_complete(pkg) @@ -9383,10 +9415,10 @@ class Scheduler(PollScheduler): self._status_display.merges = len(self._task_queues.merge) else: self._failed_pkgs.append((build.pkg, build.returncode)) + self._status_display.failed = len(self._failed_pkgs) self._deallocate_config(build.settings) self._jobs -= 1 self._status_display.running = self._jobs - self._status_display.display() self._schedule() def _extract_exit(self, build): @@ -9498,7 +9530,8 @@ class Scheduler(PollScheduler): # Only allow 1 job max if a restart is scheduled # due to portage update. - if self._is_restart_scheduled(): + if self._is_restart_scheduled() or \ + "--pretend" in self.myopts: self._set_max_jobs(1) merge_queue = self._task_queues.merge @@ -9620,6 +9653,9 @@ class Scheduler(PollScheduler): """ Use the current resume list to calculate a new one, dropping any packages with unsatisfied deps. + @rtype: set + @returns: a possibly empty set of dropped tasks, or + None if an error occurs. """ print colorize("GOOD", "*** Resuming merge...") @@ -9641,13 +9677,47 @@ class Scheduler(PollScheduler): print "Calculating dependencies ", myparams = create_depgraph_params(self.myopts, None) - success, mydepgraph, dropped_tasks = resume_depgraph( - self.settings, self.trees, self._mtimedb, self.myopts, - myparams, self._spinner, skip_unsatisfied=True) + success = False + e = None + try: + success, mydepgraph, dropped_tasks = resume_depgraph( + self.settings, self.trees, self._mtimedb, self.myopts, + myparams, self._spinner, skip_unsatisfied=True) + except depgraph.UnsatisfiedResumeDep, e: + mydepgraph = e.depgraph + dropped_tasks = set() if show_spinner: print "\b\b... done!" + if e is not None: + mydepgraph.display_problems() + out = portage.output.EOutput() + out.eerror("One or packages are either masked or " + \ + "have missing dependencies:") + out.eerror("") + indent = " " + for dep in e.value: + if dep.atom is None: + out.eerror(indent + "Masked package:") + out.eerror(2 * indent + str(dep.parent)) + out.eerror("") + else: + out.eerror(indent + str(dep.atom) + " pulled in by:") + out.eerror(2 * indent + str(dep.parent)) + out.eerror("") + msg = "The resume list contains packages " + \ + "that are either masked or have " + \ + "unsatisfied dependencies. " + \ + "Please restart/continue " + \ + "the operation manually, or use --skipfirst " + \ + "to skip the first package in the list and " + \ + "any other packages that may be " + \ + "masked or have missing dependencies." + for line in textwrap.wrap(msg, 72): + out.eerror(line) + return None + if self._show_list(): mylist = mydepgraph.altlist() if "--tree" in self.myopts: @@ -9656,7 +9726,7 @@ class Scheduler(PollScheduler): mydepgraph.display_problems() if not success: - return (None, None) + return None mylist = mydepgraph.altlist() mydepgraph.break_refs(mylist) @@ -11515,8 +11585,10 @@ def action_depclean(settings, trees, ldpath_mtimes, msg.append("\n") msg.append("As a safety measure, depclean will not remove any packages\n") msg.append("unless *all* required dependencies have been resolved. As a\n") - msg.append("consequence, it is often necessary to run\n") - msg.append(good("`emerge --update --newuse --deep world`") + " prior to depclean.\n") + msg.append("consequence, it is often necessary to run %s\n" % \ + good("`emerge --update")) + msg.append(good("--newuse --deep --oneshot @system @world`") + \ + " prior to depclean.\n") if action == "depclean" and "--quiet" not in myopts and not myfiles: portage.writemsg_stdout("\n") @@ -11691,29 +11763,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)) + def unresolved_deps(): - 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 + 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 @@ -11739,49 +11827,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) @@ -11933,8 +12032,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 @@ -12093,13 +12220,11 @@ def resume_depgraph(settings, trees, mtimedb, myopts, myparams, spinner, if isinstance(x, list) and \ tuple(x) not in unsatisfied_parents] - # It shouldn't happen, but if the size of mergelist - # does not decrease for some reason then the loop - # will be infinite. Therefore, if that case ever - # occurs for some reason, raise the exception to - # break out of the loop. + # If the mergelist doesn't shrink then this loop is infinite. if len(pruned_mergelist) == len(mergelist): - raise AssertionError("tight loop") + # This happens if a package can't be dropped because + # it's already installed, but it has unsatisfied PDEPEND. + raise mergelist[:] = pruned_mergelist dropped_tasks.update(unsatisfied_parents) del e, graph, traversed_nodes, \ diff --git a/pym/_emerge/help.py b/pym/_emerge/help.py index bf6a13834..b2c032b21 100644 --- a/pym/_emerge/help.py +++ b/pym/_emerge/help.py @@ -66,35 +66,42 @@ def help(myaction,myopts,havecolor=1): print " file setup or other similar setups that the user may wish to run." print print " "+green("--depclean") - paragraph = "Cleans the system by removing packages that are not associated " + \ - "with explicitly merged packages. Depclean works by creating the " + \ - "full dependency tree from the system and world sets, " + \ - "then comparing it to installed packages. Packages installed, but " + \ - "not part of the dependency tree, will be uninstalled by depclean. " + \ - "Inexperienced users are advised to use --pretend " + \ - "with this option in order to see a preview of which packages " + \ - "will be uninstalled." + + paragraph = "Cleans the system by removing packages that are " + \ + "not associated with explicitly merged packages. Depclean works " + \ + "by creating the full dependency tree from the @system and " + \ + "@world sets, then comparing it to installed packages. Packages " + \ + "installed, but not part of the dependency tree, will be " + \ + "uninstalled by depclean. See --with-bdeps for behavior with " + \ + "respect to build time dependencies that are not strictly " + \ + "required. Packages that are part of the world set will " + \ + "always be kept. They can be manually added to this set with " + \ + "emerge --noreplace . As a safety measure, depclean " + \ + "will not remove any packages unless *all* required dependencies " + \ + "have been resolved. As a consequence, it is often necessary to " + \ + "run emerge --update --newuse --deep --oneshot @system @world " + \ + "prior to depclean." + for line in wrap(paragraph, desc_width): print desc_indent + line print - paragraph = "WARNING: Removing some " + \ - "packages may cause packages which link to the removed package " + \ - "to stop working and complain about missing libraries. " + \ - "Rebuild the complaining package to fix this issue. Also see " + \ - "--with-bdeps for behavior with respect to build time dependencies that " + \ - "are not strictly required. Note that packages listed in " + \ - "package.provided (see portage(5)) may be removed by " + \ - "depclean, even if they are part of the world set." + paragraph = "WARNING: Inexperienced users are advised to use " + \ + "--pretend with this option in order to see a preview of which " + \ + "packages will be uninstalled. Always study the list of packages " + \ + "to be cleaned for any obvious mistakes. Note that packages " + \ + "listed in package.provided (see portage(5)) may be removed by " + \ + "depclean, even if they are part of the world set." + for line in wrap(paragraph, desc_width): print desc_indent + line print - paragraph = "Depclean serves as a dependency aware " + \ - "version of --unmerge. When given one or more atoms, it will " + \ - "unmerge matched packages that have no reverse dependencies. Use " + \ - "--depclean together with --verbose to show reverse " + \ - "dependencies." + paragraph = "Depclean serves as a dependency aware version of " + \ + "--unmerge. When given one or more atoms, it will unmerge " + \ + "matched packages that have no reverse dependencies. Use " + \ + "--depclean together with --verbose to show reverse dependencies." + for line in wrap(paragraph, desc_width): print desc_indent + line print @@ -116,12 +123,13 @@ def help(myaction,myopts,havecolor=1): print print " "+green("--prune")+" ("+green("-P")+" short option)" print " "+turquoise("WARNING: This action can remove important packages!") - print " Removes all but the highest installed version of a package" - print " from your system. This action doesn't verify the possible binary" - print " compatibility between versions and can thus remove essential" - print " dependencies from your system. Use --prune together with" - print " --verbose to show reverse dependencies or with --nodeps to" - print " ignore all dependencies." + paragraph = "Removes all but the highest installed version of a " + \ + "package from your system. Use --prune together with " + \ + "--verbose to show reverse dependencies or with --nodeps " + \ + "to ignore all dependencies. " + + for line in wrap(paragraph, desc_width): + print desc_indent + line print print " "+green("--regen") print " Causes portage to check and update the dependency cache of all" diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py index b40041ffa..e9651184f 100644 --- a/pym/portage/__init__.py +++ b/pym/portage/__init__.py @@ -4312,7 +4312,7 @@ def _post_src_install_checks(mysettings): noiselevel=-1) return retval -def _check_build_log(mysettings): +def _check_build_log(mysettings, out=None): """ Search the content of $PORTAGE_LOG_FILE if it exists and generate the following QA Notices when appropriate: @@ -4357,7 +4357,7 @@ def _check_build_log(mysettings): from portage.elog.messages import eqawarn def _eqawarn(lines): for line in lines: - eqawarn(line, phase="install", key=mysettings.mycpv) + eqawarn(line, phase="install", key=mysettings.mycpv, out=out) from textwrap import wrap wrap_width = 70 diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py index bfd972684..7321a3a8a 100644 --- a/pym/portage/dbapi/vartree.py +++ b/pym/portage/dbapi/vartree.py @@ -1680,6 +1680,7 @@ class dblink(object): The caller must ensure that lockdb() and unlockdb() are called before and after this method. """ + showMessage = self._display_merge if self.vartree.dbapi._categories is not None: self.vartree.dbapi._categories = None # When others_in_slot is supplied, the security check has already been @@ -1835,7 +1836,7 @@ class dblink(object): else: obj_type = "obj" os.unlink(obj) - writemsg_stdout("<<< !needed %s %s\n" % (obj_type, obj)) + showMessage("<<< !needed %s %s\n" % (obj_type, obj)) except OSError, e: if e.errno == errno.ENOENT: pass @@ -2264,6 +2265,7 @@ class dblink(object): return False def _preserve_libs(self, srcroot, destroot, mycontents, counter, inforoot): + showMessage = self._display_merge # read global reverse NEEDED map linkmap = self.vartree.dbapi.linkmap if ostype == "Darwin": @@ -2360,9 +2362,11 @@ class dblink(object): # skip existing files so the 'new' libs aren't overwritten if os.path.exists(os.path.join(srcroot, x.lstrip(os.sep))): continue - print "injecting %s into %s" % (x, srcroot) + showMessage("injecting %s into %s\n" % (x, srcroot), + noiselevel=-1) if not os.path.exists(os.path.join(destroot, x.lstrip(os.sep))): - print "%s does not exist so can't be preserved" % x + showMessage("%s does not exist so can't be preserved\n" % x, + noiselevel=-1) continue mydir = os.path.join(srcroot, os.path.dirname(x).lstrip(os.sep)) if not os.path.exists(mydir):