From: Fabian Groffen Date: Sat, 1 Nov 2008 16:01:40 +0000 (-0000) Subject: Merged from trunk -r11755:11768 X-Git-Url: http://git.tremily.us/gitweb.cgi?a=commitdiff_plain;h=bdb3bd1106aaa50fd764f764b1c1932cf821335b;p=portage.git Merged from trunk -r11755:11768 | 11756 | Bug #244975 - Don't allow the user to make portage unmerge | | zmedico | itself since there's never any valid reason to do so. | | 11758 | Use portage.const.PORTAGE_PACKAGE_ATOM where appropriate. | | zmedico | | | 11759 | Pass a Package instance into the config.setcpv() call. | | zmedico | | | 11760 | Fix broken stuff to avoid tracebacks when running in commit | | zmedico | mode with --pretend and no vcs. | | 11761 | Remove unused conditional_disabled and conditional_enabled | | zmedico | attributes from _use_dep.__slots__. | | 11762 | Bug #244947 - Add repoman support for checking masked and | | zmedico | forced flags when verifying USE deps. Thanks to Brian | | | Harring for reporting. | | 11763 | Revert previous commit since it doesn't properly calculate | | zmedico | masked and forced flags for the package being matched (it | | | erroneously uses the masked and forced flags from the parent | | | package). | | 11764 | Bug #236609 - Fix columns calculation for TERM="dumb". | | zmedico | Thanks to Ulrich Müller for the patch. | | 11765 | In dblink._collision_protect(), remove redundant | | zmedico | self.isowner() calls since self hasn't yet been merged and | | | therefore has no CONTENTS file for ownership checks. Also, | | | remove redundant isprotected() calls. | | 11766 | Bug #243178 - Handle file collisions with preserved libs by | | zmedico | allowing the current package to assume ownership and | | | unregistering the preserved libraries. | | 11767 | Eliminate duplicate code by calling equivalent | | zmedico | dblink._clear_contents_cache(). | | 11768 | Bug #244947 - Add basic repoman support for checking masked | | zmedico | and forced flags when verifying USE deps. TODO: Add repoman | | | support in dep_check() for evaluation of conditional USE | | | deps based on forced/masked flags. masked flags, so that | | | repoman can also | Merged from trunk -r11768:11776 | 11769 | Bug #244947 - Add repoman support for checking masked and | | zmedico | forced flags on conditional USE deps. | | 11770 | Bug #244792 - Remove confcache support. | | zmedico | | | 11771 | Bug #241906 - Handle InvalidAtom exception raised from | | zmedico | vardbapi.match(). | | 11772 | Bug #240295 - When emake is called, echo the make command | | zmedico | similar to the way that econf echoes the configure command. | | 11773 | Filter PORTAGE_VERBOSE in save_ebuild_env(). | | zmedico | | | 11774 | Remove unused imports. | | zmedico | | | 11775 | Define __all__ and remove unused import. | | zmedico | | | 11776 | Define __all__ and remove unused imports. | | zmedico | | svn path=/main/branches/prefix/; revision=11785 --- diff --git a/bin/ebuild.sh b/bin/ebuild.sh index 6a935f829..fff81dc4d 100755 --- a/bin/ebuild.sh +++ b/bin/ebuild.sh @@ -495,32 +495,7 @@ econf() { LOCAL_EXTRA_ECONF="--libdir=${CONF_LIBDIR_RESULT} ${LOCAL_EXTRA_ECONF}" fi - local TMP_CONFCACHE_DIR CONFCACHE_ARG - if hasq confcache $FEATURES && ! hasq confcache $RESTRICT; then - CONFCACHE="$(type -P confcache)" - if [ -z "${CONFCACHE}" ]; then - ewarn "disabling confcache, binary cannot be found" - else - CONFCACHE="${CONFCACHE/ /\ }" - TMP_CONFCACHE_DIR="${CONFCACHE:+${CONFCACHE_DIR:-${PORTAGE_TMPDIR}/confcache}}" - TMP_CONFCACHE_DIR="${TMP_CONFCACHE_DIR/ /\ }" - CONFCACHE_ARG="--confcache-dir" - local s - if [ -n "$CCACHE_DIR" ]; then - s="$CCACHE_DIR" - fi - if [ -n "$DISTCC_DIR" ]; then - s="${s:+${s}:}$DISTCC_DIR" - fi - if [ -n "$s" ]; then - CONFCACHE_ARG="--confcache-ignore $s $CONFCACHE_ARG" - fi - fi - else - CONFCACHE= - fi - - vecho ${CONFCACHE} ${CONFCACHE_ARG} ${TMP_CONFCACHE_DIR} "${ECONF_SOURCE}/configure" \ + vecho "${ECONF_SOURCE}/configure" \ --prefix="${EPREFIX}"/usr \ --host=${CHOST} \ --mandir="${EPREFIX}"/usr/share/man \ @@ -531,7 +506,7 @@ econf() { "$@" \ ${LOCAL_EXTRA_ECONF} - if ! ${CONFCACHE} ${CONFCACHE_ARG} ${TMP_CONFCACHE_DIR} "${ECONF_SOURCE}/configure" \ + if ! "${ECONF_SOURCE}/configure" \ --prefix="${EPREFIX}"/usr \ --host=${CHOST} \ --mandir="${EPREFIX}"/usr/share/man \ diff --git a/bin/emake b/bin/emake index a5abf9c10..83bc87c42 100755 --- a/bin/emake +++ b/bin/emake @@ -11,4 +11,6 @@ # /etc/make.globals here because emake is only called from an # ebuild. +[[ $PORTAGE_QUIET = 1 ]] || echo ${MAKE:-make} ${MAKEOPTS} ${EXTRA_EMAKE} "$@" + exec ${MAKE:-make} ${MAKEOPTS} ${EXTRA_EMAKE} "$@" diff --git a/bin/isolated-functions.sh b/bin/isolated-functions.sh index 7b8a5c935..61bc6b698 100755 --- a/bin/isolated-functions.sh +++ b/bin/isolated-functions.sh @@ -380,7 +380,7 @@ set_colors() { (( COLS > 0 )) || (( COLS = 80 )) COLS=$((${COLS} - 8)) # width of [ ok ] == 7 # Adjust COLS so that eend works properly on a standard BSD console. - [ "${TERM}" = "cons25" ] && COLS=$((${COLS} - 1)) + [[ $TERM = cons25 || $TERM = dumb ]] && ((COLS--)) # Now, ${ENDCOL} will move us to the end of the # column; irregardless of character width @@ -537,7 +537,7 @@ save_ebuild_env() { PORTAGE_INST_UID PORTAGE_LOG_FILE PORTAGE_MASTER_PID \ PORTAGE_QUIET \ PORTAGE_REPO_NAME PORTAGE_RESTRICT PORTAGE_UPDATE_ENV \ - PORTAGE_WORKDIR_MODE PORTDIR \ + PORTAGE_VERBOSE PORTAGE_WORKDIR_MODE PORTDIR \ PORTDIR_OVERLAY ${!PORTAGE_SANDBOX_*} PREROOTPATH \ PROFILE_PATHS PWORKDIR QA_INTERCEPTORS \ RC_DEFAULT_INDENT RC_DOT_PATTERN RC_ENDCOL \ diff --git a/bin/regenworld b/bin/regenworld index 7d9fccf4b..2c251c25b 100755 --- a/bin/regenworld +++ b/bin/regenworld @@ -4,6 +4,7 @@ # $Id$ import sys, os +import portage.exception # for an explanation on this logic, see pym/_emerge/__init__.py import os @@ -85,7 +86,7 @@ for mykey in biglist: #print "checking:",mykey try: mylist=portage.db["/"]["vartree"].dbapi.match(mykey) - except KeyError: + except (portage.exception.InvalidAtom, KeyError): if "--debug" in sys.argv: print "* ignoring broken log entry for %s (likely injected)" % mykey except ValueError, e: diff --git a/bin/repoman b/bin/repoman index 553099b93..b78443076 100755 --- a/bin/repoman +++ b/bin/repoman @@ -750,6 +750,8 @@ new_ebuilds = set() modified_changelogs = set() mychanged = [] mynew = [] +myremoved = [] + if vcs == "cvs": mycvstree = cvstree.getentries("./", recursive=1) mychanged = cvstree.findchanged(mycvstree, recursive=1, basedir="./") @@ -1468,7 +1470,7 @@ for x in scanlist: portdb.mysettings = dep_settings portdb.xcache = xcache # for package.use.mask support inside dep_check - dep_settings.setcpv("/".join((catdir, y))) + dep_settings.setcpv(pkg) dep_settings["ACCEPT_KEYWORDS"] = " ".join(groups) # just in case, prevent config.reset() from nuking these. dep_settings.backup_changes("ACCEPT_KEYWORDS") @@ -1815,7 +1817,8 @@ else: unameout += platform.processor() else: unameout += platform.machine() - commitmessage+="\n(Portage version: "+str(portage_version)+"/"+vcs+"/"+unameout + commitmessage += "\n(Portage version: %s/%s/%s" % \ + (portage_version, vcs, unameout) if options.force: commitmessage += ", RepoMan options: --force" commitmessage += ")" diff --git a/pym/_emerge/__init__.py b/pym/_emerge/__init__.py index 8122cb76a..12308d828 100644 --- a/pym/_emerge/__init__.py +++ b/pym/_emerge/__init__.py @@ -56,13 +56,13 @@ else: import portage -from portage import digraph, portdbapi -from portage.const import NEWS_LIB_PATH, CACHE_PATH, PRIVATE_PATH, USER_CONFIG_PATH, GLOBAL_CONFIG_PATH +from portage import digraph +from portage.const import NEWS_LIB_PATH import _emerge.help import portage.xpak, commands, errno, re, socket, time, types from portage.output import blue, bold, colorize, darkblue, darkgreen, darkred, green, \ - havecolor, nc_len, nocolor, red, teal, turquoise, white, xtermTitle, \ + nc_len, red, teal, turquoise, xtermTitle, \ xtermTitleReset, yellow from portage.output import create_color_func good = create_color_func("GOOD") @@ -10531,7 +10531,7 @@ def unmerge(root_config, myopts, unmerge_action, candidate_catpkgs=[] global_unmerge=0 xterm_titles = "notitles" not in settings.features - + out = portage.output.EOutput() pkg_cache = {} db_keys = list(vartree.dbapi._aux_cache_keys) @@ -10796,6 +10796,21 @@ def unmerge(root_config, myopts, unmerge_action, # It could have been uninstalled # by a concurrent process. continue + + if unmerge_action != "clean" and \ + root_config.root == "/" and \ + portage.match_from_list( + portage.const.PORTAGE_PACKAGE_ATOM, [pkg]): + msg = ("Not unmerging package %s since there is no valid " + \ + "reason for portage to unmerge itself.") % (pkg.cpv,) + for line in textwrap.wrap(msg, 75): + out.eerror(line) + # adjust pkgmap so the display output is correct + pkgmap[cp]["selected"].remove(cpv) + all_selected.remove(cpv) + pkgmap[cp]["protected"].add(cpv) + continue + parents = [] for s in installed_sets: # skip sets that the user requested to unmerge, and skip world @@ -10854,10 +10869,18 @@ def unmerge(root_config, myopts, unmerge_action, print " %s\n" % ", ".join(parents) # adjust pkgmap so the display output is correct pkgmap[cp]["selected"].remove(cpv) + all_selected.remove(cpv) pkgmap[cp]["protected"].add(cpv) del installed_sets + numselected = len(all_selected) + if not numselected: + writemsg_level( + "\n>>> No packages selected for removal by " + \ + unmerge_action + "\n") + return 0 + # Unmerge order only matters in some cases if not ordered: unordered = {} @@ -11819,9 +11842,11 @@ def action_sync(settings, trees, mtimedb, myopts, myaction): portdb = trees[settings["ROOT"]]["porttree"].dbapi root_config = trees[settings["ROOT"]]["root_config"] - mybestpv = portdb.xmatch("bestmatch-visible", "sys-apps/portage") + mybestpv = portdb.xmatch("bestmatch-visible", + portage.const.PORTAGE_PACKAGE_ATOM) mypvs = portage.best( - trees[settings["ROOT"]]["vartree"].dbapi.match("sys-apps/portage")) + trees[settings["ROOT"]]["vartree"].dbapi.match( + portage.const.PORTAGE_PACKAGE_ATOM)) chk_updated_cfg_files(EPREFIX, settings.get("CONFIG_PROTECT","").split()) diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py index 35b57250d..71f8b444a 100644 --- a/pym/portage/__init__.py +++ b/pym/portage/__init__.py @@ -2017,45 +2017,13 @@ class config(object): if defaults != self.configdict["defaults"].get("USE",""): self.configdict["defaults"]["USE"] = defaults has_changed = True - useforce = [] - pos = 0 - for i in xrange(len(self.profiles)): - cpdict = self.puseforce_list[i].get(cp, None) - if cpdict: - keys = cpdict.keys() - while keys: - best_match = best_match_to_list(cpv_slot, keys) - if best_match: - keys.remove(best_match) - useforce.insert(pos, cpdict[best_match]) - else: - break - del keys - if self.useforce_list[i]: - useforce.insert(pos, self.useforce_list[i]) - pos = len(useforce) - useforce = set(stack_lists(useforce, incremental=True)) + + useforce = self._getUseForce(cpv_slot) if useforce != self.useforce: self.useforce = useforce has_changed = True - usemask = [] - pos = 0 - for i in xrange(len(self.profiles)): - cpdict = self.pusemask_list[i].get(cp, None) - if cpdict: - keys = cpdict.keys() - while keys: - best_match = best_match_to_list(cpv_slot, keys) - if best_match: - keys.remove(best_match) - usemask.insert(pos, cpdict[best_match]) - else: - break - del keys - if self.usemask_list[i]: - usemask.insert(pos, self.usemask_list[i]) - pos = len(usemask) - usemask = set(stack_lists(usemask, incremental=True)) + + usemask = self._getUseMask(cpv_slot) if usemask != self.usemask: self.usemask = usemask has_changed = True @@ -2227,6 +2195,52 @@ class config(object): return iuse_implicit + def _getUseMask(self, pkg): + cp = getattr(pkg, "cp", None) + if cp is None: + cp = dep_getkey(pkg) + usemask = [] + pos = 0 + for i in xrange(len(self.profiles)): + cpdict = self.pusemask_list[i].get(cp, None) + if cpdict: + keys = cpdict.keys() + while keys: + best_match = best_match_to_list(pkg, keys) + if best_match: + keys.remove(best_match) + usemask.insert(pos, cpdict[best_match]) + else: + break + del keys + if self.usemask_list[i]: + usemask.insert(pos, self.usemask_list[i]) + pos = len(usemask) + return set(stack_lists(usemask, incremental=True)) + + def _getUseForce(self, pkg): + cp = getattr(pkg, "cp", None) + if cp is None: + cp = dep_getkey(pkg) + useforce = [] + pos = 0 + for i in xrange(len(self.profiles)): + cpdict = self.puseforce_list[i].get(cp, None) + if cpdict: + keys = cpdict.keys() + while keys: + best_match = best_match_to_list(pkg, keys) + if best_match: + keys.remove(best_match) + useforce.insert(pos, cpdict[best_match]) + else: + break + del keys + if self.useforce_list[i]: + useforce.insert(pos, self.useforce_list[i]) + pos = len(useforce) + return set(stack_lists(useforce, incremental=True)) + def _getMaskAtom(self, cpv, metadata): """ Take a package and return a matching package.mask atom, or None if no @@ -4956,10 +4970,6 @@ def _prepare_features_dirs(mysettings): "basedir_var":"CCACHE_DIR", "default_dir":os.path.join(mysettings["PORTAGE_TMPDIR"], "ccache"), "always_recurse":False}, - "confcache":{ - "basedir_var":"CONFCACHE_DIR", - "default_dir":os.path.join(mysettings["PORTAGE_TMPDIR"], "confcache"), - "always_recurse":False}, "distcc":{ "basedir_var":"DISTCC_DIR", "default_dir":os.path.join(mysettings["BUILD_PREFIX"], ".distcc"), @@ -6144,7 +6154,7 @@ def dep_virtual(mysplit, mysettings): return newsplit def _expand_new_virtuals(mysplit, edebug, mydbapi, mysettings, myroot="/", - trees=None, **kwargs): + trees=None, use_mask=None, use_force=None, **kwargs): """Recursively expand new-style virtuals so as to collapse one or more levels of indirection. In dep_zapdeps, new-style virtuals will be assigned zero cost regardless of whether or not they are currently installed. Virtual @@ -6180,8 +6190,14 @@ def _expand_new_virtuals(mysplit, edebug, mydbapi, mysettings, myroot="/", raise portage.exception.ParseError( "invalid atom: '%s'" % x) - # Repoman only checks IUSE for USE deps, so there's - # no need to evaluate conditionals. + if repoman and x.use and x.use.conditional: + evaluated_atom = portage.dep.remove_slot(x) + if x.slot: + evaluated_atom += ":%s" % x.slot + evaluated_atom += str(x.use._eval_qa_conditionals( + use_mask, use_force)) + x = portage.dep.Atom(evaluated_atom) + if not repoman and \ myuse is not None and isinstance(x, portage.dep.Atom) and x.use: if x.use.conditional: @@ -6572,7 +6588,8 @@ def dep_check(depstring, mydbapi, mysettings, use="yes", mode=None, myuse=None, # collapse one or more levels of indirection. try: mysplit = _expand_new_virtuals(mysplit, edebug, mydbapi, mysettings, - use=use, mode=mode, myuse=myuse, use_cache=use_cache, + use=use, mode=mode, myuse=myuse, + use_force=useforce, use_mask=mymasks, use_cache=use_cache, use_binaries=use_binaries, myroot=myroot, trees=trees) except portage.exception.ParseError, e: return [0, str(e)] diff --git a/pym/portage/dbapi/__init__.py b/pym/portage/dbapi/__init__.py index 0900fcfa8..2bdb3e7cd 100644 --- a/pym/portage/dbapi/__init__.py +++ b/pym/portage/dbapi/__init__.py @@ -2,15 +2,16 @@ # Distributed under the terms of the GNU General Public License v2 # $Id$ +__all__ = ["dbapi"] + import os import re -from portage.dep import Atom, dep_getslot, dep_getkey, \ - dep_getusedeps, match_from_list +from portage.dep import match_from_list from portage.locks import unlockfile from portage.output import red from portage.util import writemsg from portage import auxdbkeys, dep_expand -from portage.versions import catpkgsplit, catsplit, pkgcmp +from portage.versions import catpkgsplit, pkgcmp class dbapi(object): @@ -150,7 +151,7 @@ class dbapi(object): self._iuse_implicit = self.settings._get_implicit_iuse() for cpv in cpv_iter: try: - iuse, use = self.aux_get(cpv, ["IUSE", "USE"]) + iuse, slot, use = self.aux_get(cpv, ["IUSE", "SLOT", "USE"]) except KeyError: continue use = use.split() @@ -169,6 +170,20 @@ class dbapi(object): continue if atom.use.disabled.intersection(use): continue + else: + # Check masked and forced flags for repoman. + mysettings = getattr(self, "mysettings", None) + if mysettings is not None and not mysettings.local_config: + + pkg = "%s:%s" % (cpv, slot) + usemask = mysettings._getUseMask(pkg) + if usemask.intersection(atom.use.enabled): + continue + + useforce = mysettings._getUseForce(pkg).difference(usemask) + if useforce.intersection(atom.use.disabled): + continue + yield cpv def invalidentry(self, mypath): diff --git a/pym/portage/dbapi/bintree.py b/pym/portage/dbapi/bintree.py index d4d4508e2..c46ba7e76 100644 --- a/pym/portage/dbapi/bintree.py +++ b/pym/portage/dbapi/bintree.py @@ -2,10 +2,12 @@ # Distributed under the terms of the GNU General Public License v2 # $Id$ +__all__ = ["bindbapi", "binarytree"] + from portage.cache.mappings import slot_dict_class from portage.dep import isvalidatom, isjustname, dep_getkey, match_from_list from portage.dbapi.virtual import fakedbapi -from portage.exception import InvalidPackageName, InvalidAtom, \ +from portage.exception import InvalidPackageName, \ PermissionDenied, PortageException from portage.output import green, EOutput from portage.util import ensure_dirs, normalize_path, writemsg, writemsg_stdout diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py index e200a36c5..6fb04895a 100644 --- a/pym/portage/dbapi/vartree.py +++ b/pym/portage/dbapi/vartree.py @@ -8,11 +8,11 @@ __all__ = ["PreservedLibsRegistry", "LinkageMap", from portage.checksum import perform_md5 from portage.const import CACHE_PATH, CONFIG_MEMORY_FILE, \ - PRIVATE_PATH, VDB_PATH, EPREFIX, EPREFIX_LSTRIP -from portage.data import portage_gid, portage_uid, secpass, ostype + PORTAGE_PACKAGE_ATOM, PRIVATE_PATH, VDB_PATH, EPREFIX, EPREFIX_LSTRIP +from portage.data import portage_gid, portage_uid, secpass from portage.dbapi import dbapi from portage.dep import use_reduce, paren_reduce, isvalidatom, \ - isjustname, dep_getkey + isjustname, dep_getkey, match_from_list from portage.exception import InvalidData, InvalidPackageName, \ FileNotFound, PermissionDenied, UnsupportedAPIException from portage.locks import lockdir, unlockdir @@ -3135,6 +3135,18 @@ class dblink(object): collision_ignore = set([normalize_path(myignore) for myignore in \ shlex.split(self.settings.get("COLLISION_IGNORE", ""))]) + # For collisions with preserved libraries, the current package + # will assume ownership and the libraries will be unregistered. + plib_dict = self.vartree.dbapi.plib_registry.getPreservedLibs() + plib_cpv_map = {} + plib_paths = set() + for cpv, paths in plib_dict.iteritems(): + plib_paths.update(paths) + for f in paths: + plib_cpv_map[f] = cpv + plib_inodes = self._lstat_inode_map(plib_paths) + plib_collisions = {} + showMessage = self._display_merge scheduler = self._scheduler stopmerge = False @@ -3186,12 +3198,29 @@ class dblink(object): raise if f[0] != "/": f="/"+f + + plibs = plib_inodes.get((dest_lstat.st_dev, dest_lstat.st_ino)) + if plibs: + for path in plibs: + cpv = plib_cpv_map[path] + paths = plib_collisions.get(cpv) + if paths is None: + paths = set() + plib_collisions[cpv] = paths + paths.add(path) + # The current package will assume ownership and the + # libraries will be unregistered, so exclude this + # path from the normal collisions. + continue + isowned = False full_path = os.path.join(destroot, f.lstrip(os.path.sep)) - for ver in [self] + mypkglist: - if (ver.isowner(f, destroot) or ver.isprotected(full_path)): + for ver in mypkglist: + if ver.isowner(f, destroot): isowned = True break + if not isowned and self.isprotected(full_path): + isowned = True if not isowned: stopmerge = True if collision_ignore: @@ -3204,7 +3233,33 @@ class dblink(object): break if stopmerge: collisions.append(f) - return collisions + return collisions, plib_collisions + + def _lstat_inode_map(self, path_iter): + """ + Use lstat to create a map of the form: + {(st_dev, st_ino) : set([path1, path2, ...])} + Multiple paths may reference the same inode due to hardlinks. + All lstat() calls are relative to self.myroot. + """ + root = self.myroot + inode_map = {} + for f in path_iter: + path = os.path.join(root, f.lstrip(os.sep)) + try: + st = os.lstat(path) + except OSError, e: + if e.errno not in (errno.ENOENT, errno.ENOTDIR): + raise + del e + continue + key = (st.st_dev, st.st_ino) + paths = inode_map.get(key) + if paths is None: + paths = set() + inode_map[key] = paths + paths.add(f) + return inode_map def _security_check(self, installed_instances): if not installed_instances: @@ -3463,7 +3518,8 @@ class dblink(object): blockers = self._blockers() if blockers is None: blockers = [] - collisions = self._collision_protect(srcroot, destroot, + collisions, plib_collisions = \ + self._collision_protect(srcroot, destroot, others_in_slot + blockers, myfilelist + mylinklist) # Make sure the ebuild environment is initialized and that ${T}/elog @@ -3697,17 +3753,14 @@ class dblink(object): # just been merged. others_in_slot.append(self) # self has just been merged for dblnk in others_in_slot: - dblnk.contentscache = None - dblnk._contents_inodes = None - dblnk._contents_basenames = None + dblnk._clear_contents_cache() # If portage is reinstalling itself, remove the old # version now since we want to use the temporary # PORTAGE_BIN_PATH that will be removed when we return. reinstall_self = False if self.myroot == "/" and \ - "sys-apps" == self.cat and \ - "portage" == pkgsplit(self.pkg)[0]: + match_from_list(PORTAGE_PACKAGE_ATOM, [self.mycpv]): reinstall_self = True autoclean = self.settings.get("AUTOCLEAN", "yes") == "yes" @@ -3746,6 +3799,24 @@ class dblink(object): self.vartree.dbapi.removeFromContents(blocker, iter(contents), relative_paths=False) + # Unregister any preserved libs that this package has overwritten + # and update the contents of the packages that owned them. + plib_registry = self.vartree.dbapi.plib_registry + plib_dict = plib_registry.getPreservedLibs() + for cpv, paths in plib_collisions.iteritems(): + if cpv not in plib_dict: + continue + if cpv == self.mycpv: + continue + try: + slot, counter = self.vartree.dbapi.aux_get( + cpv, ["SLOT", "COUNTER"]) + except KeyError: + continue + remaining = [f for f in plib_dict[cpv] if f not in paths] + plib_registry.register(cpv, slot, counter, remaining) + self.vartree.dbapi.removeFromContents(cpv, paths) + self.vartree.dbapi._add(self) contents = self.getcontents() @@ -4094,8 +4165,7 @@ class dblink(object): if self.vartree.dbapi._categories is not None: self.vartree.dbapi._categories = None if self.myroot == "/" and \ - "sys-apps" == self.cat and \ - "portage" == pkgsplit(self.pkg)[0]: + match_from_list(PORTAGE_PACKAGE_ATOM, [self.mycpv]): settings = self.settings base_path_orig = os.path.dirname(settings["PORTAGE_BIN_PATH"]) from tempfile import mkdtemp diff --git a/pym/portage/dep.py b/pym/portage/dep.py index b36a6bf5a..fc6a8b10e 100644 --- a/pym/portage/dep.py +++ b/pym/portage/dep.py @@ -341,8 +341,8 @@ def dep_opconvert(deplist): class _use_dep(object): - __slots__ = ("__weakref__", "conditional", "conditional_disabled", - "conditional_enabled", "disabled", "enabled", "tokens", "required") + __slots__ = ("__weakref__", "conditional", + "disabled", "enabled", "tokens", "required") _conditionals_class = portage.cache.mappings.slot_dict_class( ("disabled", "enabled", "equal", "not_equal"), prefix="") @@ -459,6 +459,31 @@ class _use_dep(object): return _use_dep(tokens) + def _eval_qa_conditionals(self, use_mask, use_force): + """ + For repoman, evaluate all possible combinations within the constraints + of the given use.force and use.mask settings. The result may seem + ambiguous in the sense that the same flag can be in both the enabled + and disabled sets, but this is useful within the context of how its + intended to be used by repoman. It is assumed that the caller has + already ensured that there is no intersection between the given + use_mask and use_force sets when necessary. + """ + tokens = [] + + conditional = self.conditional + tokens.extend(self.enabled) + tokens.extend("-" + x for x in self.disabled) + tokens.extend(x for x in conditional.enabled if x not in use_mask) + tokens.extend("-" + x for x in conditional.disabled if x not in use_force) + + tokens.extend(x for x in conditional.equal if x not in use_mask) + tokens.extend("-" + x for x in conditional.equal if x not in use_force) + tokens.extend("-" + x for x in conditional.not_equal if x not in use_mask) + tokens.extend(x for x in conditional.not_equal if x not in use_force) + + return _use_dep(tokens) + class _AtomCache(type): """ Cache Atom instances from constructor calls and reuse