From 64851c5e6bf06bd97e96bb0f950529c387f9b48b Mon Sep 17 00:00:00 2001 From: Fabian Groffen Date: Thu, 10 Apr 2008 16:50:06 +0000 Subject: [PATCH] Merged from trunk 9725:9741 | 9726 | preserve order of ebuild messages even between different | | genone | message types (bug #197905) | | 9727 | * Use type -P which does not produce messages to stderr. | | zmedico | another option is to redirect both stderr and out. * Avoid | | | &> replace with > ... 2>&1 Thanks to Alon Bar-Lev for this | | | patch. | | 9728 | only preserve libraries if no copy exists in the libary | | genone | search path (bug #215242) | | 9729 | Fix the CompositDbapi.match() logic wrt "selective" behavior | | zmedico | and installed packages so that it correctly handles false | | | argument matches due to PROVIDE when a corresponding | | | new-style virtual exists. | | 9731 | Rename the CompositDbapi class to DepcheckCompositeDB since | | zmedico | it's really a special pupose class just for dep_check() and | | | it doesn't implement the full dbapi interface. | | 9732 | Fix java.eclassesnotused logic. Thanks to Betelgeuse. | | zmedico | | | 9733 | In dump_trace(), fix BASH_ARGV and BASH_ARGC offsets so that | | zmedico | they are always correct wrt eachother. Thanks to Betelgeuse | | | for reporting. | | 9734 | Fix BASH_ARGC and BASH_ARGV offsets some more. | | zmedico | | | 9735 | Fix DepcheckCompositeDB.match() so that it doesn't assume | | zmedico | that every DependencyArg instance has an "atom" attribute. | | 9736 | Fix variable name collision in DepcheckCompositeDB.match(). | | zmedico | | | 9737 | Move virtuals logic from DepcheckCompositeDB.match() to | | zmedico | depgraph._iter_atoms_for_pkg() since it's more generally | | | useful there. | | 9738 | Move all the --update greedy slot logic to | | zmedico | depgraph.select_files(). | | 9739 | Fix broken IUSE defaults handling when filtering USE for the | | zmedico | Packages file. | | 9740 | Handle empty KEYWORDS in the Packages file. | | zmedico | | | 9741 | * Optimize metadata caching in pordbapi and bindbapi so that | | zmedico | cache is never pulled for the same package twice. * Cache a | | | Package instances constructed during package selection and | | | reuse them during later package selections. | svn path=/main/branches/prefix/; revision=9805 --- bin/emerge-webrsync | 15 ++-- bin/isolated-functions.sh | 14 +++- bin/repoman | 3 +- pym/_emerge/__init__.py | 136 ++++++++++++++++------------------ pym/portage/dbapi/__init__.py | 4 +- pym/portage/dbapi/bintree.py | 29 ++++++-- pym/portage/dbapi/porttree.py | 15 +++- pym/portage/dbapi/vartree.py | 7 +- pym/portage/elog/messages.py | 19 ++++- pym/portage/getbinpkg.py | 9 ++- 10 files changed, 147 insertions(+), 104 deletions(-) diff --git a/bin/emerge-webrsync b/bin/emerge-webrsync index 324837d39..6b08f8b40 100755 --- a/bin/emerge-webrsync +++ b/bin/emerge-webrsync @@ -28,7 +28,7 @@ wecho() { echo "${argv0}: warning: $*" 1>&2 ; } eecho() { echo "${argv0}: error: $*" 1>&2 ; } argv0=$0 -if ! type portageq > /dev/null ; then +if ! type -P portageq > /dev/null ; then eecho "could not find 'portageq'; aborting" exit 1 fi @@ -150,7 +150,7 @@ check_file_signature() { vecho "Checking signature ..." - if type -p gpg > /dev/null; then + if type -P gpg > /dev/null; then gpg --homedir "${PORTAGE_GPG_DIR}" --verify "$signature" "$file" && r=0 else eecho "cannot check signature: gpg binary not found" @@ -174,7 +174,7 @@ sync_local() { vecho "Syncing local tree ..." # tarsync-0.2.1 doesn't seem to support lzma compression. - if [ "${file##*.}" != "lzma" ] && type -P tarsync &> /dev/null; then + if [ "${file##*.}" != "lzma" ] && type -P tarsync > /dev/null; then if ! tarsync $(vvecho -v) -s 1 -o portage -g portage -e /distfiles -e /packages -e /local "${file}" "${PORTDIR}"; then eecho "tarsync failed; tarball is corrupt? (${file})" return 1 @@ -189,9 +189,8 @@ sync_local() { # Free disk space rm -f "${file}" - chown ${PORTAGE_USER:-portage}:${PORTAGE_GROUP:-portage} portage &> /dev/null && \ + chown ${PORTAGE_USER:-portage}:${PORTAGE_GROUP:-portage} portage > /dev/null 2>&1 && \ chown -R ${PORTAGE_USER:-portage}:${PORTAGE_GROUP:-portage} portage - cd portage rsync -av --progress --stats --delete --delete-after \ --exclude='/distfiles' --exclude='/packages' \ @@ -222,9 +221,9 @@ do_snapshot() { local mirror local compressions="" - type lzcat > /dev/null && compressions="${compressions} lzma" - type bzcat > /dev/null && compressions="${compressions} bz2" - type zcat > /dev/null && compressions="${compressions} gz" + type -P lzcat > /dev/null && compressions="${compressions} lzma" + type -P bzcat > /dev/null && compressions="${compressions} bz2" + type -P zcat > /dev/null && compressions="${compressions} gz" if [[ -z ${compressions} ]] ; then eecho "unable to locate any decompressors (lzcat or bzcat or zcat)" exit 1 diff --git a/bin/isolated-functions.sh b/bin/isolated-functions.sh index e525e5f87..aa5d73d72 100755 --- a/bin/isolated-functions.sh +++ b/bin/isolated-functions.sh @@ -15,7 +15,7 @@ shopt -s extdebug # [whitespacing for filenames], # [whitespacing for line numbers]) dump_trace() { - local funcname="" sourcefile="" lineno="" n e s="yes" + local funcname="" sourcefile="" lineno="" s="yes" n p declare -i strip=${1:-1} local filespacing=$2 linespacing=$3 @@ -23,14 +23,19 @@ dump_trace() { # that the user will not be interested in. Therefore, the stack trace # should only show calls that come after qa_call(). (( n = ${#FUNCNAME[@]} - 1 )) + (( p = ${#BASH_ARGV[@]} )) while (( n > 0 )) ; do [ "${FUNCNAME[${n}]}" == "qa_call" ] && break + (( p -= ${BASH_ARGC[${n}]} )) (( n-- )) done - (( n == 0 )) && (( n = ${#FUNCNAME[@]} - 1 )) + if (( n == 0 )) ; then + (( n = ${#FUNCNAME[@]} - 1 )) + (( p = ${#BASH_ARGV[@]} )) + fi eerror "Call stack:" - for (( p = ${#BASH_ARGV[@]} ; n > ${strip} ; n-- )) ; do + while (( n > ${strip} )) ; do funcname=${FUNCNAME[${n} - 1]} sourcefile=$(basename ${BASH_SOURCE[${n}]}) lineno=${BASH_LINENO[${n} - 1]} @@ -44,6 +49,7 @@ dump_trace() { (( p -= ${BASH_ARGC[${n} - 1]} )) fi eerror " $(printf "%${filespacing}s" "${sourcefile}"):$(printf "%${linespacing}s" "${lineno}"): " + (( n-- )) done } @@ -171,7 +177,7 @@ elog_base() { return 1 ;; esac - echo -e "$*" >> "${T}/logging/${EBUILD_PHASE:-other}.${messagetype}" + echo -e "${messagetype} $*" >> "${T}/logging/${EBUILD_PHASE:-other}" return 0 } diff --git a/bin/repoman b/bin/repoman index 2e2a87e1c..74adcca75 100755 --- a/bin/repoman +++ b/bin/repoman @@ -1165,7 +1165,8 @@ for x in scanlist: myflag = myflag[1:] myiuse.add(myflag) - inherited_java_eclass = "java-pkg" in inherited + inherited_java_eclass = "java-pkg-2" in inherited or \ + "java-pkg-opt-2" in inherited operator_tokens = set(["||", "(", ")"]) type_list, badsyntax = [], [] for mytype in ("DEPEND", "RDEPEND", "PDEPEND", "LICENSE", "PROVIDE"): diff --git a/pym/_emerge/__init__.py b/pym/_emerge/__init__.py index c50cf24c9..7a8a802c8 100644 --- a/pym/_emerge/__init__.py +++ b/pym/_emerge/__init__.py @@ -1447,7 +1447,7 @@ def show_invalid_depstring_notice(parent_node, depstring, error_msg): f.add_flowing_data(x) f.end_paragraph(1) -class CompositeDbapi(object): +class DepcheckCompositeDB(object): def __init__(self, depgraph, root): self._depgraph = depgraph self._root = root @@ -1464,12 +1464,10 @@ class CompositeDbapi(object): else: if pkg.installed and "selective" not in self._depgraph.myparams: try: - self._depgraph._iter_args_for_pkg(pkg).next() - except StopIteration: - pass - except portage.exception.InvalidDependString: - pass - else: + arg = self._depgraph._iter_atoms_for_pkg(pkg).next() + except (StopIteration, portage.exception.InvalidDependString): + arg = None + if arg: ret = [] if ret is None: self._cpv_tree_map[pkg.cpv] = \ @@ -1560,7 +1558,7 @@ class depgraph(object): self._filtered_trees[myroot]["vartree"] = self.trees[myroot]["vartree"] def filtered_tree(): pass - filtered_tree.dbapi = CompositeDbapi(self, myroot) + filtered_tree.dbapi = DepcheckCompositeDB(self, myroot) self._filtered_trees[myroot]["porttree"] = filtered_tree dbs = [] portdb = self.trees[myroot]["porttree"].dbapi @@ -1613,6 +1611,8 @@ class depgraph(object): self._select_package = self._select_pkg_highest_available self._highest_pkg_cache = {} self._installed_pkg_cache = {} + # All Package instances + self._pkg_cache = {} def _show_slot_collision_notice(self): """Show an informational message advising the user to mask one of the @@ -2040,35 +2040,22 @@ class depgraph(object): return 0 return 1 - def _greedy_slot_atoms(self, root, atom): - """Generate SLOT atoms for the highest available match and - any matching installed SLOTs that are also available.""" - vardb = self.roots[root].trees["vartree"].dbapi - mykey = portage.dep_getkey(atom) - myslots = set() - for cpv in vardb.match(mykey): - myslots.add(vardb.aux_get(cpv, ["SLOT"])[0]) - for myslot in myslots: - yield "%s:%s" % (mykey, myslot) - - def _iter_args_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 - 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): + atom_cp = portage.dep_getkey(atom) + if atom_cp != pkg.cp: + have_new_virt = False + for db, pkg_type, built, installed, db_keys in \ + self._filtered_trees[pkg.root]["dbs"]: + if db.cp_list(atom_cp): + have_new_virt = True + break + if have_new_virt: + continue for arg in atom_arg_map[(atom, pkg.root)]: if isinstance(arg, PackageArg) and \ arg.package != pkg: @@ -2084,7 +2071,7 @@ class depgraph(object): This will raise an InvalidDependString exception if PROVIDE is invalid. """ any_arg = None - for arg in self._iter_args_for_pkg(pkg): + for arg, atom in self._iter_atoms_for_pkg(pkg): if isinstance(arg, PackageArg): return arg any_arg = arg @@ -2282,9 +2269,13 @@ class depgraph(object): greedy_atoms.append(arg) if not isinstance(arg, (AtomArg, PackageArg)): continue - for greedy_atom in self._greedy_slot_atoms(myroot, arg.atom): + atom_cp = portage.dep_getkey(arg.atom) + slots = set() + for cpv in vardb.match(atom_cp): + slots.add(vardb.aux_get(cpv, ["SLOT"])[0]) + for slot in slots: greedy_atoms.append( - AtomArg(arg=arg.arg, atom=greedy_atom, + AtomArg(arg=arg.arg, atom="%s:%s" % (atom_cp, slot), root_config=root_config)) args = greedy_atoms del greedy_atoms @@ -2567,6 +2558,11 @@ class depgraph(object): cpv_list = db.xmatch("match-all", atom) else: cpv_list = db.match(atom) + if not cpv_list: + continue + pkg_status = "merge" + if installed or onlydeps: + pkg_status = "nomerge" # descending order cpv_list.reverse() for cpv in cpv_list: @@ -2575,36 +2571,48 @@ class depgraph(object): cpv in vardb.match(atom): break reinstall_for_flags = None - try: - metadata = dict(izip(db_keys, - db.aux_get(cpv, db_keys))) - except KeyError: - continue - if not built: - if "?" in metadata["LICENSE"]: + cache_key = (pkg_type, root, cpv, pkg_status) + calculated_use = True + pkg = self._pkg_cache.get(cache_key) + if pkg is None: + calculated_use = False + try: + metadata = dict(izip(self._mydbapi_keys, + db.aux_get(cpv, self._mydbapi_keys))) + except KeyError: + continue + if not built and ("?" in metadata["LICENSE"] or \ + "?" in metadata["PROVIDE"]): + # This is avoided whenever possible because + # it's expensive. It only needs to be done here + # if it has an effect on visibility. pkgsettings.setcpv(cpv, mydb=metadata) metadata["USE"] = pkgsettings["PORTAGE_USE"] - else: - metadata["USE"] = "" + calculated_use = True + pkg = Package(built=built, cpv=cpv, + installed=installed, metadata=metadata, + onlydeps=onlydeps, root=root, type_name=pkg_type) + self._pkg_cache[pkg] = pkg myarg = None if root == self.target_root: try: - myarg = self._get_arg_for_pkg( - Package(type_name=pkg_type, root=root, - cpv=cpv, metadata=metadata, - built=built, installed=installed, - onlydeps=onlydeps)) + myarg = self._iter_atoms_for_pkg(pkg).next() + except StopIteration: + pass except portage.exception.InvalidDependString: if not installed: # masked by corruption continue - pkg = Package(built=built, cpv=cpv, installed=installed, - metadata=metadata, type_name=pkg_type) if not installed: if myarg: found_available_arg = True if not visible(pkgsettings, pkg): continue + if not built and not calculated_use: + # This is avoided whenever possible because + # it's expensive. + pkgsettings.setcpv(cpv, mydb=pkg.metadata) + pkg.metadata["USE"] = pkgsettings["PORTAGE_USE"] if pkg.cp == atom_cp: if highest_version is None: highest_version = pkg @@ -2616,9 +2624,7 @@ class depgraph(object): # will always end with a break statement below # this point. if find_existing_node: - slot_atom = "%s:%s" % ( - portage.cpv_getkey(cpv), metadata["SLOT"]) - e_pkg = self._slot_pkg_map[root].get(slot_atom) + e_pkg = self._slot_pkg_map[root].get(pkg.slot_atom) if not e_pkg: break cpv_slot = "%s:%s" % \ @@ -2642,9 +2648,9 @@ class depgraph(object): ("--newuse" in self.myopts or \ "--reinstall" in self.myopts): iuses = set(filter_iuse_defaults( - metadata["IUSE"].split())) - old_use = metadata["USE"].split() - mydb = metadata + pkg.metadata["IUSE"].split())) + old_use = pkg.metadata["USE"].split() + mydb = pkg.metadata if myeb and not usepkgonly: mydb = portdb if myeb: @@ -2670,7 +2676,7 @@ class depgraph(object): ("--newuse" in self.myopts or \ "--reinstall" in self.myopts) and \ cpv in vardb.match(atom): - pkgsettings.setcpv(cpv, mydb=metadata) + pkgsettings.setcpv(cpv, mydb=pkg.metadata) forced_flags = set() forced_flags.update(pkgsettings.useforce) forced_flags.update(pkgsettings.usemask) @@ -2679,7 +2685,7 @@ class depgraph(object): vardb.aux_get(cpv, ["IUSE"])[0].split())) cur_use = pkgsettings["PORTAGE_USE"].split() cur_iuse = set(filter_iuse_defaults( - metadata["IUSE"].split())) + pkg.metadata["IUSE"].split())) reinstall_for_flags = \ self._reinstall_for_flags( forced_flags, old_use, old_iuse, @@ -2693,22 +2699,8 @@ class depgraph(object): not must_reinstall and \ cpv in vardb.match(atom): break - # Metadata accessed above is cached internally by - # each db in order to optimize visibility checks. - # Now that all possible checks visibility checks - # are complete, it's time to pull the rest of the - # metadata (including *DEPEND). This part is more - # expensive, so avoid it whenever possible. - metadata.update(izip(self._mydbapi_keys, - db.aux_get(cpv, self._mydbapi_keys))) if not built: - pkgsettings.setcpv(cpv, mydb=metadata) - metadata["USE"] = pkgsettings["PORTAGE_USE"] myeb = cpv - pkg = Package(type_name=pkg_type, root=root, - cpv=cpv, metadata=metadata, - built=built, installed=installed, - onlydeps=onlydeps) matched_packages.append(pkg) if reinstall_for_flags: self._reinstall_nodes[pkg] = \ diff --git a/pym/portage/dbapi/__init__.py b/pym/portage/dbapi/__init__.py index cd3208d50..1431c1074 100644 --- a/pym/portage/dbapi/__init__.py +++ b/pym/portage/dbapi/__init__.py @@ -8,7 +8,7 @@ from portage.dep import dep_getslot, dep_getkey, match_from_list from portage.locks import unlockfile from portage.output import red from portage.util import writemsg -from portage import dep_expand +from portage import auxdbkeys, dep_expand from portage.versions import catpkgsplit, catsplit, pkgcmp @@ -16,6 +16,8 @@ class dbapi(object): _category_re = re.compile(r'^\w[-.+\w]*$') _pkg_dir_name_re = re.compile(r'^\w[-+\w]*$') _categories = None + _known_keys = frozenset(x for x in auxdbkeys + if not x.startswith("UNUSED_0")) def __init__(self): pass diff --git a/pym/portage/dbapi/bintree.py b/pym/portage/dbapi/bintree.py index 9efca10a3..b2421c98d 100644 --- a/pym/portage/dbapi/bintree.py +++ b/pym/portage/dbapi/bintree.py @@ -20,6 +20,8 @@ import re from itertools import izip class bindbapi(fakedbapi): + _known_keys = frozenset(list(fakedbapi._known_keys) + \ + ["CHOST", "repository", "USE"]) def __init__(self, mybintree=None, **kwargs): fakedbapi.__init__(self, **kwargs) self.bintree = mybintree @@ -28,8 +30,10 @@ class bindbapi(fakedbapi): self.cpdict={} # Selectively cache metadata in order to optimize dep matching. self._aux_cache_keys = set( - ["CHOST", "EAPI", "IUSE", "KEYWORDS", - "LICENSE", "PROVIDE", "SLOT", "USE", "EPREFIX"]) + ["CHOST", "DEPEND", "EAPI", "IUSE", "KEYWORDS", + "LICENSE", "PDEPEND", "PROVIDE", + "RDEPEND", "repository", "RESTRICT", "SLOT", "USE", + "EPREFIX"]) self._aux_cache = {} def match(self, *pargs, **kwargs): @@ -41,10 +45,11 @@ class bindbapi(fakedbapi): if self.bintree and not self.bintree.populated: self.bintree.populate() cache_me = False - if not set(wants).difference(self._aux_cache_keys): + if not self._known_keys.intersection( + wants).difference(self._aux_cache_keys): aux_cache = self._aux_cache.get(mycpv) if aux_cache is not None: - return [aux_cache[x] for x in wants] + return [aux_cache.get(x, "") for x in wants] cache_me = True mysplit = mycpv.split("/") mylist = [] @@ -149,7 +154,8 @@ class binarytree(object): self._pkgindex_aux_keys = \ ["CHOST", "DEPEND", "DESCRIPTION", "EAPI", "IUSE", "KEYWORDS", "LICENSE", "PDEPEND", - "PROVIDE", "RDEPEND", "SLOT", "USE", "EPREFIX"] + "PROVIDE", "RDEPEND", "repository", "SLOT", "USE", + "EPREFIX"] self._pkgindex_aux_keys = list(self._pkgindex_aux_keys) self._pkgindex_header_keys = set(["ACCEPT_KEYWORDS", "CBUILD", "CHOST", "CONFIG_PROTECT", "CONFIG_PROTECT_MASK", "FEATURES", @@ -159,14 +165,22 @@ class binarytree(object): else: eapi = str(EAPI) self._pkgindex_default_pkg_data = { + "DEPEND" : "", "EAPI" : eapi, "IUSE" : "", + "KEYWORDS": "", "LICENSE" : "", + "PDEPEND" : "", "PROVIDE" : "", + "RDEPEND" : "", + "RESTRICT": "", "SLOT" : "0", "USE" : "" } - self._pkgindex_inherited_keys = ["CHOST", "EPREFIX"] + self._pkgindex_inherited_keys = ["CHOST", "repository", "EPREFIX"] + self._pkgindex_default_header_data = { + "repository":"" + } def move_ent(self, mylist): if not self.populated: @@ -805,6 +819,7 @@ class binarytree(object): def _new_pkgindex(self): return portage.getbinpkg.PackageIndex( + default_header_data=self._pkgindex_default_header_data, default_pkg_data=self._pkgindex_default_pkg_data, inherited_keys=self._pkgindex_inherited_keys) @@ -845,7 +860,7 @@ class binarytree(object): del metadata["DESCRIPTION"] use = metadata["USE"].split() raw_use = use - iuse = set(metadata["IUSE"].split()) + iuse = set(f.lstrip("-+") for f in metadata["IUSE"].split()) use = [f for f in use if f in iuse] use.sort() metadata["USE"] = " ".join(use) diff --git a/pym/portage/dbapi/porttree.py b/pym/portage/dbapi/porttree.py index de5a03bfe..532530131 100644 --- a/pym/portage/dbapi/porttree.py +++ b/pym/portage/dbapi/porttree.py @@ -83,11 +83,13 @@ class portdbapi(dbapi): self.porttrees = [self.porttree_root] + \ [os.path.realpath(t) for t in self.mysettings["PORTDIR_OVERLAY"].split()] self.treemap = {} + self._repository_map = {} for path in self.porttrees: repo_name_path = os.path.join(path, REPO_NAME_LOC) try: repo_name = open(repo_name_path, 'r').readline().strip() self.treemap[repo_name] = path + self._repository_map[path] = repo_name except (OSError,IOError): # warn about missing repo_name at some other time, since we # don't want to see a warning every time the portage module is @@ -116,7 +118,9 @@ class portdbapi(dbapi): self.depcachedir, x, filtered_auxdbkeys, gid=portage_gid) # Selectively cache metadata in order to optimize dep matching. self._aux_cache_keys = set( - ["EAPI", "IUSE", "KEYWORDS", "LICENSE", "PROVIDE", "SLOT"]) + ["DEPEND", "EAPI", "IUSE", "KEYWORDS", "LICENSE", + "PDEPEND", "PROVIDE", "RDEPEND", "repository", + "RESTRICT", "SLOT"]) self._aux_cache = {} self._broken_ebuilds = set() @@ -208,10 +212,11 @@ class portdbapi(dbapi): cache_me = False if not mytree: cache_me = True - if not mytree and not set(mylist).difference(self._aux_cache_keys): + if not mytree and not self._known_keys.intersection( + mylist).difference(self._aux_cache_keys): aux_cache = self._aux_cache.get(mycpv) if aux_cache is not None: - return [aux_cache[x] for x in mylist] + return [aux_cache.get(x, "") for x in mylist] cache_me = True global auxdbkeys, auxdbkeylen cat,pkg = mycpv.split("/", 1) @@ -335,6 +340,10 @@ class portdbapi(dbapi): if not mydata.setdefault("EAPI", "0"): mydata["EAPI"] = "0" + # do we have a origin repository name for the current package + mydata["repository"] = self._repository_map.get( + os.path.sep.join(myebuild.split(os.path.sep)[:-3]), "") + #finally, we look at our internal cache entry and return the requested data. returnme = [] for x in mylist: diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py index cc1db12fb..59062eed1 100644 --- a/pym/portage/dbapi/vartree.py +++ b/pym/portage/dbapi/vartree.py @@ -16,7 +16,7 @@ from portage.output import bold, red, green from portage.update import fixdbentries from portage.util import apply_secpass_permissions, ConfigProtect, ensure_dirs, \ writemsg, writemsg_stdout, write_atomic, atomic_ofstream, writedict, \ - grabfile, grabdict, normalize_path, new_protect_filename + grabfile, grabdict, normalize_path, new_protect_filename, getlibpaths from portage.versions import pkgsplit, catpkgsplit, catsplit, best, pkgcmp from portage import listdir, dep_expand, flatten, key_expand, \ @@ -1639,7 +1639,10 @@ class dblink(object): for lib in list(preserve_libs): if not has_external_consumers(lib, old_contents, preserve_libs): - preserve_libs.remove(lib) + preserve_libs.remove(lib) + for path in getlibpaths(): + if os.path.exists(os.path.join(path, lib)): + preserve_libs.remove(lib) # get the real paths for the libs preserve_paths = [x for x in old_contents if os.path.basename(x) in preserve_libs] diff --git a/pym/portage/elog/messages.py b/pym/portage/elog/messages.py index 0c3aa999e..63f9a69c5 100644 --- a/pym/portage/elog/messages.py +++ b/pym/portage/elog/messages.py @@ -24,16 +24,27 @@ def collect_ebuild_messages(path): # exploit listdir() file order so we process log entries in chronological order mylogfiles.reverse() logentries = {} - for f in mylogfiles: - msgfunction, msgtype = f.split(".") + for msgfunction in mylogfiles: if msgfunction not in EBUILD_PHASES: writemsg("!!! can't process invalid log file: %s\n" % f, noiselevel=-1) continue if not msgfunction in logentries: logentries[msgfunction] = [] - msgcontent = open(os.path.join(path, f), "r").readlines() - logentries[msgfunction].append((msgtype, msgcontent)) + lastmsgtype = None + msgcontent = [] + for l in open(os.path.join(path, msgfunction), "r").readlines(): + msgtype, msg = l.split(" ", 1) + if lastmsgtype is None: + lastmsgtype = msgtype + if msgtype == lastmsgtype: + msgcontent.append(msg) + else: + if msgcontent: + logentries[msgfunction].append((lastmsgtype, msgcontent)) + msgcontent = [msg] + lastmsgtype = msgtype + # clean logfiles to avoid repetitions for f in mylogfiles: try: diff --git a/pym/portage/getbinpkg.py b/pym/portage/getbinpkg.py index c2fb48d03..64cd74699 100644 --- a/pym/portage/getbinpkg.py +++ b/pym/portage/getbinpkg.py @@ -668,10 +668,14 @@ def _cmp_cpv(d1, d2): class PackageIndex(object): - def __init__(self, default_pkg_data=None, inherited_keys=None): + def __init__(self, default_header_data=None, default_pkg_data=None, + inherited_keys=None): + self._default_header_data = default_header_data self._default_pkg_data = default_pkg_data self._inherited_keys = inherited_keys self.header = {} + if self._default_header_data: + self.header.update(self._default_header_data) self.packages = [] self.modified = True @@ -726,7 +730,8 @@ class PackageIndex(object): self.header["PACKAGES"] = str(len(self.packages)) keys = self.header.keys() keys.sort() - self._writepkgindex(pkgfile, [(k, self.header[k]) for k in keys]) + self._writepkgindex(pkgfile, [(k, self.header[k]) \ + for k in keys if self.header[k]]) for metadata in sorted(self.packages, _cmp_cpv): metadata = metadata.copy() cpv = metadata["CPV"] -- 2.26.2