From: Fabian Groffen Date: Thu, 5 Mar 2009 19:01:49 +0000 (-0000) Subject: Merged from trunk -r12744:12760 X-Git-Url: http://git.tremily.us/gitweb.cgi?a=commitdiff_plain;h=87b75156fc77b85039d03d8ce32908c16e81cd6b;p=portage.git Merged from trunk -r12744:12760 | 12745 | Fix vdb entry writting code in dyn_install() to avoid | | zmedico | generating empty entries in some cases. Thanks to Ned Ludd | | | for reporting. | | 12746 | Bug #256289 - When displaying an unsatisfied USE dep and all | | zmedico | packages with the required IUSE are masked, show a normal | | | "masked package" message for the package(s) that have the | | | required IUSE (instead of showing the unmasked packages with | | | missing IUSE). | | 12747 | Bug #261082 - Fix --getbinpkgonly code in | | zmedico | binarytree._populate() to update the aux_get cache when it's | | | appropriate for a remote package to override a local | | | package. | | 12748 | Make glsa-check executable. | | zmedico | | | 12749 | Bug #261082 - Prefer remote package instances whenever | | zmedico | --getbinpkg is enabled (previously local instances were | | | preferred unless --getbinpkgonly was enabled). | | 12750 | Remove unnecessary creation of lists when iterating over | | zmedico | digraphs for --buildpkgonly hasallzeros check. | | 12751 | Set Unpickler.find_global = None when possible and handle | | zmedico | AttributeError for py3k. | | 12752 | Make --version and action. | | zmedico | | | 12753 | Only generate PORTAGE_COUNTER_HASH for actions that can | | zmedico | involve vdb modification. | | 12754 | Make --searchdesc imply --search inside parse_opts(). | | zmedico | | | 12755 | Make the first argument of update() methods be an optional | | zmedico | positional argument instead of a keyword argument. | | 12756 | Remove unnecessary setting of default values to empty | | zmedico | strings inside database._getitem(). | | 12757 | Use basestring instead of str for isinstance check inside | | zmedico | use_reduce() so that it works with unicode and remove | | | related unicode to str workaround code from the sqlite cache | | | module. | | 12758 | Use enumerate() inside use_reduce() validation code. | | zmedico | | | 12759 | Add tests for use_reduce() and paren_reduce(). | | zmedico | | | 12760 | Make config.categories a sorted tuple so that portdbapi can | | zmedico | reuse it. | svn path=/main/branches/prefix/; revision=12764 --- diff --git a/bin/ebuild.sh b/bin/ebuild.sh index 69cf87c5d..60453d592 100755 --- a/bin/ebuild.sh +++ b/bin/ebuild.sh @@ -1012,14 +1012,15 @@ dyn_install() { cd "${PORTAGE_BUILDDIR}"/build-info set -f - local f + local f x + IFS=$' \t\n\r' for f in ASFLAGS CATEGORY CBUILD CC CFLAGS CHOST CTARGET CXX \ CXXFLAGS DEPEND EXTRA_ECONF EXTRA_EINSTALL EXTRA_MAKE \ FEATURES INHERITED IUSE LDFLAGS LIBCFLAGS LIBCXXFLAGS \ LICENSE PDEPEND PF PKGUSE PROPERTIES PROVIDE RDEPEND RESTRICT SLOT \ KEYWORDS HOMEPAGE SRC_URI DESCRIPTION; do - [ -n "${!f}" ] && echo $(echo "${!f}" | \ - tr '\n,\r,\t' ' , , ' | sed s/' \+'/' '/g) > ${f} + x=$(echo -n ${!f}) + [[ -n $x ]] && echo "$x" > $f done echo "${EPREFIX}" > EPREFIX echo "${USE}" > USE diff --git a/bin/glsa-check b/bin/glsa-check old mode 100644 new mode 100755 diff --git a/pym/_emerge/__init__.py b/pym/_emerge/__init__.py index aaa8fd8bb..b8d31a09e 100644 --- a/pym/_emerge/__init__.py +++ b/pym/_emerge/__init__.py @@ -201,7 +201,7 @@ actions = frozenset([ "clean", "config", "depclean", "info", "list-sets", "metadata", "prune", "regen", "search", -"sync", "unmerge", +"sync", "unmerge", "version", ]) options=[ "--ask", "--alphabetical", @@ -226,7 +226,7 @@ options=[ "--tree", "--update", "--usepkg", "--usepkgonly", -"--verbose", "--version" +"--verbose", ] shortmapping={ @@ -4132,6 +4132,11 @@ class BlockerCache(portage.cache.mappings.MutableMapping): try: f = open(self._cache_filename, mode='rb') mypickle = pickle.Unpickler(f) + try: + mypickle.find_global = None + except AttributeError: + # TODO: If py3k, override Unpickler.find_class(). + pass self._cache_data = mypickle.load() f.close() del f @@ -5961,6 +5966,7 @@ class depgraph(object): xinfo = xinfo.replace("null/", "") masked_packages = [] missing_use = [] + masked_pkg_instances = set() missing_licenses = [] have_eapi_mask = False pkgsettings = self.pkgsettings[root] @@ -5992,9 +5998,12 @@ class depgraph(object): # Filter out any such false matches here. if not atom_set.findAtomForPackage(pkg): continue - if atom.use and not mreasons: + if mreasons: + masked_pkg_instances.add(pkg) + if atom.use: missing_use.append(pkg) - continue + if not mreasons: + continue masked_packages.append( (root_config, pkgsettings, cpv, metadata, mreasons)) @@ -6024,16 +6033,28 @@ class depgraph(object): mreasons.append("Change USE: %s" % " ".join(changes)) missing_use_reasons.append((pkg, mreasons)) - if missing_iuse_reasons and not missing_use_reasons: - missing_use_reasons = missing_iuse_reasons - elif missing_use_reasons: + unmasked_use_reasons = [(pkg, mreasons) for (pkg, mreasons) \ + in missing_use_reasons if pkg not in masked_pkg_instances] + + unmasked_iuse_reasons = [(pkg, mreasons) for (pkg, mreasons) \ + in missing_iuse_reasons if pkg not in masked_pkg_instances] + + show_missing_use = False + if unmasked_use_reasons: # Only show the latest version. - del missing_use_reasons[1:] + show_missing_use = unmasked_use_reasons[:1] + elif unmasked_iuse_reasons: + if missing_use_reasons: + # All packages with required IUSE are masked, + # so display a normal masking message. + pass + else: + show_missing_use = unmasked_iuse_reasons - if missing_use_reasons: + if show_missing_use: print "\nemerge: there are no ebuilds built with USE flags to satisfy "+green(xinfo)+"." print "!!! One of the following packages is required to complete your request:" - for pkg, mreasons in missing_use_reasons: + for pkg, mreasons in show_missing_use: print "- "+pkg.cpv+" ("+", ".join(mreasons)+")" elif masked_packages: @@ -14584,7 +14605,7 @@ def action_build(settings, trees, mtimedb, if "--buildpkgonly" in myopts: graph_copy = mydepgraph.digraph.clone() removed_nodes = set() - for node in list(graph_copy.order): + for node in graph_copy: if not isinstance(node, Package) or \ node.operation == "nomerge": removed_nodes.add(node) @@ -14598,7 +14619,7 @@ def action_build(settings, trees, mtimedb, if "--buildpkgonly" in myopts: graph_copy = mydepgraph.digraph.clone() removed_nodes = set() - for node in list(graph_copy.order): + for node in graph_copy: if not isinstance(node, Package) or \ node.operation == "nomerge": removed_nodes.add(node) @@ -14854,6 +14875,9 @@ def parse_opts(tmpcmdline, silent=False): if v is not None: myopts[myopt] = v + if myoptions.searchdesc: + myoptions.search = True + for action_opt in actions: v = getattr(myoptions, action_opt.replace("-", "_")) if v: @@ -15339,7 +15363,8 @@ def emerge_main(): mysettings = trees[myroot]["vartree"].settings mysettings.unlock() adjust_config(myopts, mysettings) - if "--pretend" not in myopts: + if '--pretend' not in myopts and myaction in \ + (None, 'clean', 'depclean', 'prune', 'unmerge'): mysettings["PORTAGE_COUNTER_HASH"] = \ trees[myroot]["vartree"].dbapi._counter_hash() mysettings.backup_changes("PORTAGE_COUNTER_HASH") @@ -15447,14 +15472,6 @@ def emerge_main(): if "--buildpkg" not in myopts: myopts["--buildpkg"] = True - # Also allow -S to invoke search action (-sS) - if ("--searchdesc" in myopts): - if myaction and myaction != "search": - myfiles.append(myaction) - if "--search" not in myopts: - myopts["--search"] = True - myaction = "search" - # Always try and fetch binary packages if FEATURES=getbinpkg if ("getbinpkg" in settings.features): myopts["--getbinpkg"] = True @@ -15508,7 +15525,7 @@ def emerge_main(): if not sys.stdout.isatty() or ("--nospinner" in myopts): spinner.update = spinner.update_basic - if "--version" in myopts: + if myaction == 'version': print getportageversion(settings["PORTDIR"], settings["ROOT"], settings.profile_path, settings["CHOST"], trees[settings["ROOT"]]["vartree"].dbapi) diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py index 5d3be97b0..8d676b241 100644 --- a/pym/portage/__init__.py +++ b/pym/portage/__init__.py @@ -1618,7 +1618,8 @@ class config(object): #getting categories from an external file now categories = [grabfile(os.path.join(x, "categories")) for x in locations] - self.categories = stack_lists(categories, incremental=1) + self.categories = tuple(sorted( + stack_lists(categories, incremental=1))) del categories archlist = [grabfile(os.path.join(x, "arch.list")) for x in locations] @@ -7900,6 +7901,11 @@ class MtimeDB(dict): try: f = open(filename, 'rb') mypickle = pickle.Unpickler(f) + try: + mypickle.find_global = None + except AttributeError: + # TODO: If py3k, override Unpickler.find_class(). + pass d = mypickle.load() f.close() del f diff --git a/pym/portage/cache/mappings.py b/pym/portage/cache/mappings.py index 1117b855b..77923b462 100644 --- a/pym/portage/cache/mappings.py +++ b/pym/portage/cache/mappings.py @@ -111,7 +111,14 @@ class MutableMapping(Mapping): del self[k] return (k, v) - def update(self, other=None, **kwargs): + def update(self, *args, **kwargs): + if len(args) > 1: + raise TypeError( + "expected at most 1 positional argument, got " + \ + repr(len(args))) + other = None + if args: + other = args[0] if other is None: pass elif hasattr(other, 'iteritems'): @@ -369,7 +376,14 @@ def slot_dict_class(keys, prefix="_val_"): self[key] = default return default - def update(self, other=None, **kwargs): + def update(self, *args, **kwargs): + if len(args) > 1: + raise TypeError( + "expected at most 1 positional argument, got " + \ + repr(len(args))) + other = None + if args: + other = args[0] if other is None: pass elif hasattr(other, 'iteritems'): diff --git a/pym/portage/cache/metadata.py b/pym/portage/cache/metadata.py index 8f7992472..22cf51e56 100644 --- a/pym/portage/cache/metadata.py +++ b/pym/portage/cache/metadata.py @@ -69,9 +69,6 @@ class database(flat_hash.database): # because it calls reconstruct_eclasses() internally. d["_eclasses_"] = reconstruct_eclasses(None, d["_eclasses_"]) - for x in self._known_keys: - d.setdefault(x, '') - return d def _setitem(self, cpv, values): diff --git a/pym/portage/cache/sqlite.py b/pym/portage/cache/sqlite.py index 5a7bcf1f5..aa5c30468 100644 --- a/pym/portage/cache/sqlite.py +++ b/pym/portage/cache/sqlite.py @@ -163,14 +163,7 @@ class database(fs_template.FsBased): column_index +=1 if k not in internal_columns: d[k] = result[0][column_index] - # XXX: The resolver chokes on unicode strings so we convert them here. - for k in d.keys(): - try: - d[k]=str(d[k]) # convert unicode strings to normal - except UnicodeEncodeError, e: - pass #writemsg("%s: %s\n" % (cpv, str(e))) - for x in self._known_keys: - d.setdefault(x,'') + return d def _setitem(self, cpv, values): diff --git a/pym/portage/dbapi/bintree.py b/pym/portage/dbapi/bintree.py index c7a05cecc..f97c2f9bc 100644 --- a/pym/portage/dbapi/bintree.py +++ b/pym/portage/dbapi/bintree.py @@ -713,7 +713,7 @@ class binarytree(object): for cpv in self._remotepkgs: self.dbapi.cpv_inject(cpv) self.populated = 1 - if getbinpkgsonly: + if True: # Remote package instances override local package # if they are not identical. hash_names = ["SIZE"] + self._pkgindex_hashes @@ -735,6 +735,9 @@ class binarytree(object): break if identical: del self._remotepkgs[cpv] + else: + # Override the local package in the aux_get cache. + self.dbapi._aux_cache[cpv] = remote_metadata else: # Local package instances override remote instances. for cpv in metadata: diff --git a/pym/portage/dbapi/porttree.py b/pym/portage/dbapi/porttree.py index 7ac281e8b..57bdd9984 100644 --- a/pym/portage/dbapi/porttree.py +++ b/pym/portage/dbapi/porttree.py @@ -100,7 +100,7 @@ class portdbapi(dbapi): from portage import settings self.mysettings = config(clone=settings) self._iuse_implicit = self.mysettings._get_implicit_iuse() - self._categories = tuple(sorted(set(self.mysettings.categories))) + self._categories = self.mysettings.categories # This is strictly for use in aux_get() doebuild calls when metadata # is generated by the depend phase. It's safest to use a clone for # this purpose because doebuild makes many changes to the config diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py index 6de100d96..68cbd3572 100644 --- a/pym/portage/dbapi/vartree.py +++ b/pym/portage/dbapi/vartree.py @@ -1585,6 +1585,11 @@ class vardbapi(dbapi): try: f = open(self._aux_cache_filename, mode='rb', **open_kwargs) mypickle = pickle.Unpickler(f) + try: + mypickle.find_global = None + except AttributeError: + # TODO: If py3k, override Unpickler.find_class(). + pass aux_cache = mypickle.load() f.close() del f diff --git a/pym/portage/dep.py b/pym/portage/dep.py index 4a9d85e3c..0bff1104c 100644 --- a/pym/portage/dep.py +++ b/pym/portage/dep.py @@ -216,8 +216,8 @@ def use_reduce(deparray, uselist=[], masklist=[], matchall=0, excludeall=[]): @return: The use reduced depend array """ # Quick validity checks - for x in range(len(deparray)): - if deparray[x] in ["||","&&"]: + for x, y in enumerate(deparray): + if y == '||': if len(deparray) - 1 == x or not isinstance(deparray[x+1], list): raise portage.exception.InvalidDependString(deparray[x]+" missing atom list in \""+paren_enclose(deparray)+"\"") if deparray and deparray[-1] and deparray[-1][-1] == "?": @@ -243,7 +243,8 @@ def use_reduce(deparray, uselist=[], masklist=[], matchall=0, excludeall=[]): if head[-1:] == "?": # Use reduce next group on fail. # Pull any other use conditions and the following atom or list into a separate array newdeparray = [head] - while isinstance(newdeparray[-1], str) and newdeparray[-1][-1] == "?": + while isinstance(newdeparray[-1], basestring) and \ + newdeparray[-1][-1:] == "?": if mydeparray: newdeparray.append(mydeparray.pop(0)) else: diff --git a/pym/portage/getbinpkg.py b/pym/portage/getbinpkg.py index db2b6580a..d02207609 100644 --- a/pym/portage/getbinpkg.py +++ b/pym/portage/getbinpkg.py @@ -487,7 +487,13 @@ def dir_get_metadata(baseurl, conn=None, chunk_size=3000, verbose=1, usingcache= out = sys.stdout try: metadatafile = open(metadatafilename, 'rb') - metadata = pickle.load(metadatafile) + mypickle = pickle.Unpickler(metadatafile) + try: + mypickle.find_global = None + except AttributeError: + # TODO: If py3k, override Unpickler.find_class(). + pass + metadata = mypickle.load() out.write("Loaded metadata pickle.\n") out.flush() metadatafile.close() diff --git a/pym/portage/tests/dep/test_use_reduce.py b/pym/portage/tests/dep/test_use_reduce.py new file mode 100644 index 000000000..07b9ddbb9 --- /dev/null +++ b/pym/portage/tests/dep/test_use_reduce.py @@ -0,0 +1,29 @@ +# Copyright 2009 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Id$ + +from portage.tests import TestCase +from portage.exception import InvalidDependString +from portage.dep import paren_reduce, use_reduce +import portage.dep +portage.dep._dep_check_strict = True + +class UseReduce(TestCase): + + def testUseReduce(self): + + tests = ( + ('|| ( x y )', True ), + ('|| x', False ), + ('foo? ( x y )', True ), + ('foo? ( bar? x y )', False ), + ('foo? x', False ), + ) + + for dep_str, valid in tests: + try: + use_reduce(paren_reduce(dep_str), matchall=True) + except InvalidDependString: + self.assertEqual(valid, False) + else: + self.assertEqual(valid, True)