Merged from trunk -r12744:12760
authorFabian Groffen <grobian@gentoo.org>
Thu, 5 Mar 2009 19:01:49 +0000 (19:01 -0000)
committerFabian Groffen <grobian@gentoo.org>
Thu, 5 Mar 2009 19:01:49 +0000 (19:01 -0000)
   | 12745   | Fix vdb entry writting code in dyn_install() to avoid        |
   | zmedico | generating empty entries in some cases. Thanks to Ned Ludd   |
   |         | <solar@g.o> 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

13 files changed:
bin/ebuild.sh
bin/glsa-check [changed mode: 0644->0755]
pym/_emerge/__init__.py
pym/portage/__init__.py
pym/portage/cache/mappings.py
pym/portage/cache/metadata.py
pym/portage/cache/sqlite.py
pym/portage/dbapi/bintree.py
pym/portage/dbapi/porttree.py
pym/portage/dbapi/vartree.py
pym/portage/dep.py
pym/portage/getbinpkg.py
pym/portage/tests/dep/test_use_reduce.py [new file with mode: 0644]

index 69cf87c5d25f1bb9437b604d8dbc0489dcc91d2d..60453d59249f0b1978fac85eee6487fa75fd0049 100755 (executable)
@@ -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
old mode 100644 (file)
new mode 100755 (executable)
index aaa8fd8bb3d0bf5673225ec0224c8b32c249487e..b8d31a09ef307a0c0f928ae87be06a91c4bf127f 100644 (file)
@@ -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)
index 5d3be97b0b1f6a609b93e55b8ab9daea155461b1..8d676b2414f86a8e2e75d9cdb86cdde4903daff6 100644 (file)
@@ -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
index 1117b855b288487ef7ac8c036f7489cd367051ad..77923b46230a49bfcb10aaf659458d74216536f9 100644 (file)
@@ -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'):
index 8f7992472c2ac65cbd389addf7acc936b1c35bad..22cf51e56c82e729bb02910354ec8258e6d055a8 100644 (file)
@@ -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):
index 5a7bcf1f5d652fca4b2209e64fd8c3dfa8052f4b..aa5c3046876d4a8c199daaed56a2b95dcb0f22cb 100644 (file)
@@ -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):
index c7a05cecc4914c66d5dc415641a3e3914c9224c1..f97c2f9bc6d37483106749cb929870a42cde9023 100644 (file)
@@ -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:
index 7ac281e8b50b94dae8b6c60b8316bb2b59b8bd8f..57bdd9984ecab080c67217abe3e9a851231aad7c 100644 (file)
@@ -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
index 6de100d96f5dcac3ddb72eade295e21b02337af7..68cbd3572fcfb029dcd356221e8f6210265b072b 100644 (file)
@@ -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
index 4a9d85e3c38d80344f8132cbc10277709f2492bb..0bff1104ccffd46aca84d684bc6e645b55fd32ba 100644 (file)
@@ -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:
index db2b6580a8b7a283e1b616ae250ba314e6265e12..d022076094e846aa2a594243266aafdf7af24063 100644 (file)
@@ -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 (file)
index 0000000..07b9ddb
--- /dev/null
@@ -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)