From: Fabian Groffen Date: Sat, 23 Feb 2008 23:33:46 +0000 (-0000) Subject: Merged from trunk 9300:9333 X-Git-Url: http://git.tremily.us/gitweb.cgi?a=commitdiff_plain;h=44499711e5d842d68b6f2e389acbdaadbc67c41c;p=portage.git Merged from trunk 9300:9333 | 9301 | Bug #208708 - Show informative warning messages for | | zmedico | installed packages that are masked. | | 9307 | removing obsolete cruft | | genone | | | 9308 | new script for creating release tarballs | | genone | (Deleted in Prefix as we have a working tarball.sh) | | 9309 | minor documentation updates | | genone | | | 9310 | more minor doc updates regarding package sets | | genone | | | 9311 | add preserve-libs info to make.conf.example | | genone | | | 9312 | add tagging capabilities and cli options | | genone | | | 9313 | Bug #208743 - Update dosed docs to indicate that | | zmedico | "s:${D}::g" is used as the default expression if none | | | other is given. | | 9316 | fix nasty typo | | genone | (Prefix already had most of this fix) | | 9318 | Fix get_mask_info() to properly pass the "installed" | | zmedico | attribute into the Package constructor. | | 9320 | Fix the exitcode logic for bug #209144 so that when the | | zmedico | server is out of date it's not interpreted like an actual | | | rsync exitcode (to avoid a misleading exitcode | | | interpretation message). | | 9321 | Bug #209144 - For emerge --sync, show an informative error | | zmedico | and don't return 1 when PORTAGE_RSYNC_RETRIES is exceeded. | | 9324 | Fix CHOST masking logic wrt installed packages so that | | zmedico | it's consistent between visible() and | | | get_masking_status(). | | 9326 | Fix rejects. | | zmedico | | | 9327 | Remove the killparent() function and associated SIGINT | | zmedico | trap since this should already be handled on the python | | | side and it won't work with dropped privileges anyway. | | 9328 | fix more trivial issues breaking repoman | | genone | | | 9330 | Bug #209538 - Disable annoying "masked by keyword" | | zmedico | warnings for installed packages. We can assume that if the | | | user accepted the keywords at merge time then they never | | | want to be bothered again. | | 9332 | Add bits about namespace pollution, add whitespacing | | WarnerBro | comments after looking at some new code I wrote and | | | realizing I was not following the current style. Fix typos | | 9333 | Bug #209768 - Fix --search "Size of files:" handling so | | zmedico | that it properly shows the "Unknown (missing digest)" | | | message instead of a traceback. | svn path=/main/branches/prefix/; revision=9373 --- diff --git a/DEVELOPING b/DEVELOPING index 725f1ae1e..cd9f78f94 100644 --- a/DEVELOPING +++ b/DEVELOPING @@ -1,11 +1,39 @@ Code Guidelines --------------- -A few code guidelines to try to stick to, please comment of none of these make +A few code guidelines to try to stick to, please comment if none of these make sense, they are pretty basic and mostly apply to old code. However for people who are looking at current code, they make take up bad habits that exist in the current codebase. -Strings +Tabs +---- + +The current code uses tabs, not spaces. Keep whitespace usage consistent +between files. New files should use tabs. + +Line-Wrapping +------------- + +Lines should typically not be longer than 80 characters; if they are an attempt +should be made to wrap them. Move code to the line below and indent once (\t). + +errors.append(MalformedMetadata( + errors.DESCRIPTION_TOO_LONG_ERROR % \ + (length, max_desc_len), + attr='DESCRIPTION.toolong') + +Do not do this: + +errors.append(MalformedMetadata( + errors.DESCRIPTION_TOO_LONG_ERROR % \ + (length, max_desc_len), + attr='DESCRIPTION.toolong') + +The mixing of tabs and spaces means other developers can't read what you did. +This is why the python peps state spaces over tabs; because with spaces the line +wrapping is always clear (but you cannot convert spaces as easily as tabwidth). + +String ------- Try not to use the functions in the string module, they are deprecated. @@ -21,7 +49,7 @@ string.split(string, delimeter) should be replaced with: -string.split(delimeter) +"somestring".split(delimeter) Nearly all other methods in string work on string objects and have similar calling conventions. @@ -102,3 +130,36 @@ NO: import portage.util import time import sys + +Try not to import large numbers of things into the namespace of a module. +I realize this is done all over the place in current code but it really makes it +a pain to do code reflection when the namespace is cluttered with identifiers +from other modules. + +YES: + +from portage import output + +NO: + +from portage.output import bold, create_color_func, darkgreen, \ + green, nocolor, red, turquoise, yellow + +The YES example imports the 'output' module into the current namespace. +The negative here is having to use output.COLOR all over the place instead of +just COLOR. However it means during introspection of the current namespace +'green','red', 'yellow', etc. will not show up. + +The NO example just imports a set of functions from the output module. It is +somewhat annoying because the import line needs to be modified when functions +are needed and often unused functions are left in the import line until someone +comes along with a linter to clean up (does not happen often). The color is a +bit clearer as + + print red('blar') + +is shorter than: + + print output.red('blar') + +Rationale: python -c 'import portage; dir(portage)' (circa 02/2008) diff --git a/NEWS b/NEWS index 86c9d5489..243ef7ecc 100644 --- a/NEWS +++ b/NEWS @@ -10,7 +10,7 @@ portage-2.2 * Fix -* handling in package.keywords to work as intended (reset the accepted keywords list), also see RELEASE-NOTES. * Experimental support for preserving old library files on package upgrades - based on FEATURES=preserve-libs, USE AT YOUR OWN RISK!!! + based on FEATURES=preserve-libs * Make elog functionality available to python code * Add support for news items (GLEP 42) * Add support for generic package sets (also see RELEASE-NOTES) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index e68670f77..49f316f96 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -24,9 +24,13 @@ portage-2.2 conditionals or any-of constructs aren't possible yet - emerge makes no difference atm wether you pass a setname or all atoms contained in the set to it, this means that without options packages will be remerged if - already installed and added to the worldfile, or in the case of --unmerge all - atoms in a set will be unmerged even if they are depended upon by other - packages + already installed, or in the case of --unmerge all atoms in a set will be + unmerged even if they are depended upon by other packages. This may change in + future versions. + - sets can be referenced either in other file-based sets or as argument to emerge, but + not in ebuilds, config files or other tools at this time. +* "world" does no longer include "system" unconditionally, but you can add + "@system" to the worldfile to restore the old state. portage-2.1.4.1 ================================== diff --git a/bin/ebuild.sh b/bin/ebuild.sh index 1704103de..60f5d760b 100755 --- a/bin/ebuild.sh +++ b/bin/ebuild.sh @@ -1586,14 +1586,6 @@ if [ -n "${EBUILD_SH_ARGS}" ] && \ # source ${X} || die "Failed to source ${X}" # done -else - -killparent() { - trap INT - kill ${PORTAGE_MASTER_PID} -} -trap "killparent" INT - fi # "$*"!="depend" && "$*"!="clean" && "$*" != "setup" export SANDBOX_ON="1" diff --git a/bin/isolated-functions.sh b/bin/isolated-functions.sh index 93774dc54..239524ce5 100755 --- a/bin/isolated-functions.sh +++ b/bin/isolated-functions.sh @@ -467,7 +467,7 @@ save_ebuild_env() { abort_test abort_install dyn_compile dyn_test dyn_install \ dyn_preinst dyn_help debug-print debug-print-function \ debug-print-section inherit EXPORT_FUNCTIONS newdepend newrdepend \ - newpdepend do_newdepend remove_path_entry killparent \ + newpdepend do_newdepend remove_path_entry \ save_ebuild_env filter_readonly_variables preprocess_ebuild_env \ source_all_bashrcs ebuild_phase ebuild_phase_with_hooks \ ${QA_INTERCEPTORS} diff --git a/bin/repoman b/bin/repoman index 6ea9f9684..ba8f27b31 100755 --- a/bin/repoman +++ b/bin/repoman @@ -1680,10 +1680,10 @@ else: try: editor = os.environ.get("EDITOR") if editor and utilities.editor_is_executable(editor): - commitmessage = utilties.get_commit_message_with_editor( + commitmessage = utilities.get_commit_message_with_editor( editor, message=qa_output) else: - commitmessage = utilties.get_commit_message_with_stdin() + commitmessage = utilities.get_commit_message_with_stdin() except KeyboardInterrupt: exithandler() if not commitmessage or not commitmessage.strip(): diff --git a/cnf/make.conf b/cnf/make.conf index 1077d28ea..d1adefbd2 100644 --- a/cnf/make.conf +++ b/cnf/make.conf @@ -278,6 +278,9 @@ # 'notitles' disables xterm titlebar updates (which contain status info). # 'parallel-fetch' # do fetching in parallel to compilation +# 'preserve-libs' +# keep libraries around that would normally removed by an upgrade, +# but are still needed by other packages # 'sandbox' enables sandboxing when running emerge and ebuild. # 'splitdebug' Prior to stripping ELF etdyn and etexec files, the debugging # info is stored for later use by various debuggers. This diff --git a/cnf/make.conf.sparc-fbsd.diff b/cnf/make.conf.sparc-fbsd.diff index d71178abb..4ca3a50cd 100644 --- a/cnf/make.conf.sparc-fbsd.diff +++ b/cnf/make.conf.sparc-fbsd.diff @@ -23,10 +23,10 @@ # Portage Directories # =================== -@@ -279,7 +286,8 @@ - # 'notitles' disables xterm titlebar updates (which contain status info). - # 'parallel-fetch' - # do fetching in parallel to compilation +@@ -272,7 +286,8 @@ + # 'preserve-libs' + # keep libraries around that would normally removed by an upgrade, + # but are still needed by other packages -# 'sandbox' enables sandboxing when running emerge and ebuild. +# 'sandbox' enables sandboxing when running emerge and ebuild. Doesn't +# work on *BSD-based systems. diff --git a/cnf/make.conf.x86-fbsd.diff b/cnf/make.conf.x86-fbsd.diff index c2cf7cb71..a71e54032 100644 --- a/cnf/make.conf.x86-fbsd.diff +++ b/cnf/make.conf.x86-fbsd.diff @@ -63,10 +63,10 @@ # Portage Directories # =================== -@@ -279,7 +313,8 @@ - # 'notitles' disables xterm titlebar updates (which contain status info). - # 'parallel-fetch' - # do fetching in parallel to compilation +@@ -272,7 +313,8 @@ + # 'preserve-libs' + # keep libraries around that would normally removed by an upgrade, + # but are still needed by other packages -# 'sandbox' enables sandboxing when running emerge and ebuild. +# 'sandbox' enables sandboxing when running emerge and ebuild. Doesn't +# work on *BSD-based systems. diff --git a/make-man-tarball.sh b/make-man-tarball.sh deleted file mode 100755 index 0f1f3ed4d..000000000 --- a/make-man-tarball.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -if [ -z "$1" ] ; then - echo "Usage: $0 " - exit 1 -fi - -find man -name '*.eclass.5' > man-page-list -tar -jcf portage-manpages-${1}.tar.bz2 --files-from man-page-list -echo "Packed away $(wc -l man-page-list | cut -f1 -d' ') manpages" -rm -f man-page-list - -ls -l portage-manpages-${1}.tar.bz2 diff --git a/man/ebuild.5 b/man/ebuild.5 index 6f6403738..44bbc45aa 100644 --- a/man/ebuild.5 +++ b/man/ebuild.5 @@ -727,7 +727,8 @@ multiple directories. .PD 1 .TP \fBdosed\fR \fI"s:orig:change:g" \fR -Performs sed in place on \fIfilename\fR inside ${D}. +Performs sed in place on \fIfilename\fR inside ${D}. If no expression is +given then \fI"s:${D}::g"\fR is used as the default expression. .br .BR 'dosed\ "s:/usr/local:/usr:g"\ /usr/bin/some\-script' runs sed on ${D}/usr/bin/some\-script diff --git a/man/emerge.1 b/man/emerge.1 index bf664e0c5..d019eb54a 100644 --- a/man/emerge.1 +++ b/man/emerge.1 @@ -4,7 +4,7 @@ emerge \- Command\-line interface to the Portage system .SH "SYNOPSIS" .TP .BR emerge -[\fIoptions\fR] [\fIaction\fR] [\fIebuild\fR | \fItbz2file\fR | \fIset\fR | \fIatom\fR] ... +[\fIoptions\fR] [\fIaction\fR] [\fIebuild\fR | \fItbz2file\fR | \fI@set\fR | \fIatom\fR] ... .TP .BR emerge \fB\-\-sync\fR | \fB\-\-version\fR @@ -52,13 +52,15 @@ A \fItbz2file\fR must be a valid .tbz2 created with \fBebuild .TP .BR set A \fIset\fR is a convenient shorthand for a large group of -packages. Two sets are currently supported: \fBsystem\fR +packages. Two sets are currently always available: \fBsystem\fR and \fBworld\fR. \fBsystem\fR refers to a set of packages -deemed necessary for your system to run properly. \fBworld\fR -contains all the packages in \fBsystem\fR, plus any -other packages listed in \fB/var/lib/portage/world\fR. [See -\fBFILES\fR below for more information.] Note that a \fIset\fR -is generally used in conjunction with \fB\-\-update\fR. +deemed necessary for your system to run properly. \fBworld\fR +contains all the packages listed in \fB/var/lib/portage/world\fR. [See +\fBFILES\fR below for more information.] Other sets can exist depending +on the current configuration. Note that a \fIset\fR +is generally used in conjunction with \fB\-\-update\fR. When used as +arguments to \fBemerge\fR sets have to be prefixed with \fB@\fR to be +recognized. .TP .BR atom An \fIatom\fR describes bounds on a package that you wish to install. diff --git a/pym/_emerge/__init__.py b/pym/_emerge/__init__.py index 4e5dbb93e..f6c57ec2f 100644 --- a/pym/_emerge/__init__.py +++ b/pym/_emerge/__init__.py @@ -665,6 +665,7 @@ class search(object): myversion = self.getVersion(full_package, search.VERSION_RELEASE) mysum = [0,0] + file_size_str = None mycat = match.split("/")[0] mypkg = match.split("/")[1] mycpv = match + "-" + myversion @@ -679,7 +680,7 @@ class search(object): try: mysum[0] = mf.getDistfilesSize(fetchlist) except KeyError, e: - mysum[0] = "Unknown (missing digest for %s)" % \ + file_size_str = "Unknown (missing digest for %s)" % \ str(e) available = False @@ -695,13 +696,13 @@ class search(object): myebuild = None break - if myebuild: + if myebuild and file_size_str is None: mystr = str(mysum[0] / 1024) mycount = len(mystr) while (mycount > 3): mycount -= 3 mystr = mystr[:mycount] + "," + mystr[mycount:] - mysum[0] = mystr + " kB" + file_size_str = mystr + " kB" if self.verbose: if available: @@ -709,7 +710,7 @@ class search(object): print " ", self.getInstallationStatus(mycat+'/'+mypkg) if myebuild: print " %s %s" % \ - (darkgreen("Size of files:"), mysum[0]) + (darkgreen("Size of files:"), file_size_str) print " ", darkgreen("Homepage:")+" ",homepage print " ", darkgreen("Description:")+" ",desc print " ", darkgreen("License:")+" ",license @@ -1043,7 +1044,7 @@ def visible(pkgsettings, cpv, metadata, built=False, installed=False): return False if not portage.eapi_is_supported(metadata["EAPI"]): return False - if pkgsettings.getMissingKeywords(cpv, metadata): + if not installed and pkgsettings.getMissingKeywords(cpv, metadata): return False if pkgsettings.getMaskAtom(cpv, metadata): return False @@ -1053,6 +1054,97 @@ def visible(pkgsettings, cpv, metadata, built=False, installed=False): return False return True +def get_masking_status(pkg, pkgsettings, root_config): + + mreasons = portage.getmaskingstatus( + pkg, settings=pkgsettings, + portdb=root_config.trees["porttree"].dbapi) + + if pkg.built and not pkg.installed and \ + pkg.metadata["CHOST"] != root_config.settings["CHOST"]: + mreasons.append("CHOST: %s" % \ + pkg.metadata["CHOST"]) + + if pkg.built and not pkg.installed: + if not "EPREFIX" in metadata or not metadata["EPREFIX"]: + mreasons.append("missing EPREFIX") + elif len(metadata["EPREFIX"].strip()) < len(pkgsettings["EPREFIX"]): + mreasons.append("EPREFIX: '%s' too small" % metadata["EPREFIX"]) + + if not pkg.metadata["SLOT"]: + mreasons.append("invalid: SLOT is undefined") + + return mreasons + +def get_mask_info(root_config, cpv, pkgsettings, + db, pkg_type, built, installed, db_keys): + eapi_masked = False + try: + metadata = dict(izip(db_keys, + db.aux_get(cpv, db_keys))) + except KeyError: + metadata = None + if metadata and not built: + pkgsettings.setcpv(cpv, mydb=metadata) + metadata["USE"] = pkgsettings.get("USE", "") + if metadata is None: + mreasons = ["corruption"] + else: + pkg = Package(type_name=pkg_type, root=root_config.root, + cpv=cpv, built=built, installed=installed, metadata=metadata) + mreasons = get_masking_status(pkg, pkgsettings, root_config) + return metadata, mreasons + +def show_masked_packages(masked_packages): + shown_licenses = set() + shown_comments = set() + # Maybe there is both an ebuild and a binary. Only + # show one of them to avoid redundant appearance. + shown_cpvs = set() + have_eapi_mask = False + for (root_config, pkgsettings, cpv, + metadata, mreasons) in masked_packages: + if cpv in shown_cpvs: + continue + shown_cpvs.add(cpv) + comment, filename = None, None + if "package.mask" in mreasons: + comment, filename = \ + portage.getmaskingreason( + cpv, metadata=metadata, + settings=pkgsettings, + portdb=root_config.trees["porttree"].dbapi, + return_location=True) + missing_licenses = [] + if metadata: + if not portage.eapi_is_supported(metadata["EAPI"]): + have_eapi_mask = True + try: + missing_licenses = \ + pkgsettings.getMissingLicenses( + cpv, metadata) + except portage.exception.InvalidDependString: + # This will have already been reported + # above via mreasons. + pass + + print "- "+cpv+" (masked by: "+", ".join(mreasons)+")" + if comment and comment not in shown_comments: + print filename+":" + print comment + shown_comments.add(comment) + portdb = root_config.trees["porttree"].dbapi + for l in missing_licenses: + l_path = portdb.findLicensePath(l) + if l in shown_licenses: + continue + msg = ("A copy of the '%s' license" + \ + " is located at '%s'.") % (l, l_path) + print msg + print + shown_licenses.add(l) + return have_eapi_mask + def iter_atoms(deps): """Take a dependency structure as returned by paren_reduce or use_reduce and iterate over all the atoms.""" @@ -1415,6 +1507,7 @@ class depgraph(object): self._altlist_cache = {} self._pprovided_args = [] self._missing_args = [] + self._masked_installed = [] self._dep_stack = [] self._unsatisfied_deps = [] self._ignored_deps = [] @@ -1610,15 +1703,18 @@ class depgraph(object): pkgsettings = self.pkgsettings[pkg.root] args = None + arg_atoms = None if True: try: - args = list(self._iter_args_for_pkg(pkg)) + arg_atoms = list(self._iter_atoms_for_pkg(pkg)) except portage.exception.InvalidDependString, e: if not pkg.installed: show_invalid_depstring_notice( pkg, pkg.metadata["PROVIDE"], str(e)) return 0 del e + else: + args = [arg for arg, atom in arg_atoms] if not pkg.onlydeps: if not pkg.installed and \ @@ -1698,6 +1794,32 @@ class depgraph(object): del e return 0 + if pkg.installed: + # Warn if all matching ebuilds are masked or + # the installed package itself is masked. Do + # not warn if there are simply no matching + # ebuilds since that would be annoying in some + # cases: + # + # - binary packages installed from an overlay + # that is not listed in PORTDIR_OVERLAY + # + # - multi-slot atoms listed in the world file + # to prevent depclean from removing them + + if arg_atoms: + portdb = self.trees[pkg.root]["porttree"].dbapi + for arg, atom in arg_atoms: + all_ebuilds_masked = bool( + portdb.xmatch("match-all", atom) and + not portdb.xmatch("bestmatch-visible", atom)) + if all_ebuilds_masked: + self._missing_args.append((arg, atom)) + + if not visible(pkgsettings, pkg.cpv, pkg.metadata, + built=pkg.built, installed=pkg.installed): + self._masked_installed.append((pkg, pkgsettings)) + if args: self._set_nodes.add(pkg) @@ -1874,6 +1996,18 @@ class depgraph(object): continue yield arg + def _iter_atoms_for_pkg(self, pkg): + # TODO: add multiple $ROOT support + if pkg.root != self.target_root: + return + atom_arg_map = self._atom_arg_map + for atom in self._set_atoms.iterAtomsForPackage(pkg): + for arg in atom_arg_map[(atom, pkg.root)]: + if isinstance(arg, PackageArg) and \ + arg.package != pkg: + continue + yield arg, atom + def _get_arg_for_pkg(self, pkg): """ Return a matching DependencyArg instance for the given Package if @@ -2110,33 +2244,9 @@ class depgraph(object): return 0, myfavorites self._missing_args.append((arg, atom)) continue - if pkg.installed: - # Warn if all matching ebuilds are masked or - # the installed package itself is masked. Do - # not warn if there are simply no matching - # ebuilds since that would be annoying in some - # cases: - # - # - binary packages installed from an overlay - # that is not listed in PORTDIR_OVERLAY - # - # - multi-slot atoms listed in the world file - # to prevent depclean from removing them - - installed_masked = not visible( - pkgsettings, pkg.cpv, pkg.metadata, - built=pkg.built, installed=pkg.installed) - - all_ebuilds_masked = bool( - portdb.xmatch("match-all", atom) and - not portdb.xmatch("bestmatch-visible", atom)) - - if installed_masked or all_ebuilds_masked: - self._missing_args.append((arg, atom)) - - if "selective" not in self.myparams: - self._show_unsatisfied_dep(myroot, atom) - return 0, myfavorites + if pkg.installed and "selective" not in self.myparams: + self._show_unsatisfied_dep(myroot, atom) + return 0, myfavorites self._dep_stack.append( Dependency(atom=atom, root=myroot, parent=arg)) @@ -2360,9 +2470,9 @@ class depgraph(object): red(' [%s]' % myparent[0]) + ')' masked_packages = [] missing_licenses = [] - from textwrap import wrap have_eapi_mask = False pkgsettings = self.pkgsettings[root] + root_config = self.roots[root] portdb = self.roots[root].trees["porttree"].dbapi dbs = self._filtered_trees[root]["dbs"] for db, pkg_type, built, installed, db_keys in dbs: @@ -2374,81 +2484,15 @@ class depgraph(object): # descending order cpv_list.reverse() for cpv in cpv_list: - try: - metadata = dict(izip(db_keys, - db.aux_get(cpv, db_keys))) - except KeyError: - mreasons = ["corruption"] - metadata = None - if metadata and not built: - if "?" in metadata["LICENSE"]: - pkgsettings.setcpv(cpv, mydb=portdb) - metadata["USE"] = pkgsettings.get("USE", "") - else: - metadata["USE"] = "" - mreasons = portage.getmaskingstatus( - cpv, metadata=metadata, - settings=pkgsettings, portdb=portdb) - comment, filename = None, None - if "package.mask" in mreasons: - comment, filename = \ - portage.getmaskingreason( - cpv, metadata=metadata, - settings=pkgsettings, portdb=portdb, - return_location=True) - if built and \ - metadata["CHOST"] != pkgsettings["CHOST"]: - mreasons.append("CHOST: %s" % \ - metadata["CHOST"]) - if built: - if not "EPREFIX" in metadata or not metadata["EPREFIX"]: - mreasons.append("missing EPREFIX") - elif len(metadata["EPREFIX"].strip()) < len(pkgsettings["EPREFIX"]): - mreasons.append("EPREFIX: '%s' too small" % metadata["EPREFIX"]) - missing_licenses = [] - if metadata: - if not metadata["SLOT"]: - mreasons.append("invalid: SLOT is undefined") - if not portage.eapi_is_supported(metadata["EAPI"]): - have_eapi_mask = True - try: - missing_licenses = \ - pkgsettings.getMissingLicenses( - cpv, metadata) - except portage.exception.InvalidDependString: - # This will have already been reported - # above via mreasons. - pass - if not mreasons: - continue - masked_packages.append((cpv, mreasons, - comment, filename, missing_licenses)) + metadata, mreasons = get_mask_info(root_config, cpv, + pkgsettings, db, pkg_type, built, installed, db_keys) + masked_packages.append( + (root_config, pkgsettings, cpv, metadata, mreasons)) + if masked_packages: print "\n!!! "+red("All ebuilds that could satisfy ")+green(xinfo)+red(" have been masked.") print "!!! One of the following masked packages is required to complete your request:" - shown_licenses = set() - shown_comments = set() - # Maybe there is both an ebuild and a binary. Only - # show one of them to avoid redundant appearance. - shown_cpvs = set() - for cpv, mreasons, comment, filename, missing_licenses in masked_packages: - if cpv in shown_cpvs: - continue - shown_cpvs.add(cpv) - print "- "+cpv+" (masked by: "+", ".join(mreasons)+")" - if comment and comment not in shown_comments: - print filename+":" - print comment - shown_comments.add(comment) - for l in missing_licenses: - l_path = portdb.findLicensePath(l) - if l in shown_licenses: - continue - msg = ("A copy of the '%s' license" + \ - " is located at '%s'.") % (l, l_path) - print msg - print - shown_licenses.add(l) + have_eapi_mask = show_masked_packages(masked_packages) if have_eapi_mask: if portage.const.EAPIPREFIX: p = portage.const.EAPIPREFIX + " " @@ -2459,6 +2503,7 @@ class depgraph(object): "EAPI '%s%s'. You must upgrade to a newer version" + \ " of portage before EAPI masked packages can" + \ " be installed.") % (p, portage.const.EAPI) + from textwrap import wrap for line in wrap(msg, 75): print line print @@ -3947,6 +3992,18 @@ class depgraph(object): # TODO: Add generic support for "set problem" handlers so that # the below warnings aren't special cases for world only. + + masked_packages = [] + for pkg, pkgsettings in self._masked_installed: + root_config = self.roots[pkg.root] + mreasons = get_masking_status(pkg, pkgsettings, root_config) + masked_packages.append((root_config, pkgsettings, + pkg.cpv, pkg.metadata, mreasons)) + if masked_packages: + sys.stderr.write("\n" + colorize("BAD", "!!!") + \ + " The following installed packages are masked:\n") + show_masked_packages(masked_packages) + if self._missing_args: world_problems = False if "world" in self._sets: @@ -3961,6 +4018,7 @@ class depgraph(object): sys.stderr.write("!!! Please run " + \ green("emaint --check world")+"\n\n") + if self._missing_args: sys.stderr.write("\n" + colorize("BAD", "!!!") + \ " Ebuilds for the following packages are either all\n") sys.stderr.write(colorize("BAD", "!!!") + \ @@ -5556,6 +5614,8 @@ def action_sync(settings, trees, mtimedb, myopts, myaction): ("-6" in all_rsync_opts or "--ipv6" in all_rsync_opts): family = socket.AF_INET6 ips=[] + SERVER_OUT_OF_DATE = -1 + EXCEEDED_MAX_RETRIES = -2 while (1): if ips: del ips[0] @@ -5697,7 +5757,7 @@ def action_sync(settings, trees, mtimedb, myopts, myaction): print ">>> In order to force sync, remove '%s'." % servertimestampfile print ">>>" print - exitcode = 1 + exitcode = SERVER_OUT_OF_DATE elif (servertimestamp == 0) or (servertimestamp > mytimestamp): # actual sync mycommand = rsynccommand + [dosyncuri+"/", myportdir] @@ -5723,10 +5783,17 @@ def action_sync(settings, trees, mtimedb, myopts, myaction): # over retries # exit loop updatecache_flg=False + exitcode = EXCEEDED_MAX_RETRIES break if (exitcode==0): emergelog(xterm_titles, "=== Sync completed with %s" % dosyncuri) + elif exitcode == SERVER_OUT_OF_DATE: + sys.exit(1) + elif exitcode == EXCEEDED_MAX_RETRIES: + sys.stderr.write( + ">>> Exceeded PORTAGE_RSYNC_RETRIES: %s\n" % maxretries) + sys.exit(1) elif (exitcode>0): print if exitcode==1: diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py index 584ae40ae..c92adedb2 100644 --- a/pym/portage/__init__.py +++ b/pym/portage/__init__.py @@ -5741,11 +5741,21 @@ def getmaskingreason(mycpv, metadata=None, settings=None, portdb=None, return_lo else: return None -def getmaskingstatus(mycpv, metadata=None, settings=None, portdb=None): +def getmaskingstatus(mycpv, settings=None, portdb=None): if settings is None: settings = config(clone=globals()["settings"]) if portdb is None: portdb = globals()["portdb"] + + metadata = None + installed = False + if not isinstance(mycpv, basestring): + # emerge passed in a Package instance + pkg = mycpv + mycpv = pkg.cpv + metadata = pkg.metadata + installed = pkg.installed + mysplit = catpkgsplit(mycpv) if not mysplit: raise ValueError("invalid CPV: %s" % mycpv) @@ -5835,7 +5845,9 @@ def getmaskingstatus(mycpv, metadata=None, settings=None, portdb=None): kmask="~"+myarch break - if kmask: + # Assume that the user doesn't want to be bothered about + # KEYWORDS of packages that are already installed. + if kmask and not installed: rValue.append(kmask+" keyword") try: diff --git a/pym/repoman/utilities.py b/pym/repoman/utilities.py index d22afb299..4282f2a9a 100644 --- a/pym/repoman/utilities.py +++ b/pym/repoman/utilities.py @@ -13,13 +13,14 @@ import os import sys from portage import output +from portage.output import red, green from portage import exception from portage import util normalize_path = util.normalize_path util.initialize_logger() -def detect_vcs_conflicts(vcs, options): +def detect_vcs_conflicts(options, vcs): """Determine if the checkout has problems like cvs conflicts. If you want more vcs support here just keep adding if blocks... diff --git a/tarball.sh b/tarball.sh index 114bc56eb..c87d5e33e 100755 --- a/tarball.sh +++ b/tarball.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# $Id: $ +# $Id$ if [ -z "$1" ]; then echo