Merged from trunk 7054:7078
authorFabian Groffen <grobian@gentoo.org>
Thu, 28 Jun 2007 09:28:07 +0000 (09:28 -0000)
committerFabian Groffen <grobian@gentoo.org>
Thu, 28 Jun 2007 09:28:07 +0000 (09:28 -0000)
   +------------------------------------------------------------------------+
   | 7055    | Format $EBUILD_OVERLAY_ECLASSES output more like it was      |
   | zmedico | before.                                                      |
   |---------+--------------------------------------------------------------|
   | 7057    | Fix quoting.                                                 |
   | zmedico |                                                              |
   |---------+--------------------------------------------------------------|
   | 7059    | For bug #142473, account for $ROOT when deciding if a        |
   | zmedico | package is part of world or not.                             |
   |---------+--------------------------------------------------------------|
   | 7061    | Instead of just a list, use a cat/pkg dict for matching      |
   | zmedico | packages against args in the depgraph.                       |
   |---------+--------------------------------------------------------------|
   | 7063    | Improve tracking of correspondence between arguments and     |
   | zmedico | packages in the depgraph.                                    |
   |---------+--------------------------------------------------------------|
   | 7064    | Cache aux_get() metadata in depgraph.create() and use        |
   | zmedico | PROVIDE for matching packages to arguments.                  |
   |---------+--------------------------------------------------------------|
   | 7065    | Just use a containment test for matching pprovided args      |
   | zmedico | since it works correctly and match_to_list() isn't           |
   |         | appropriate for this.                                        |
   |---------+--------------------------------------------------------------|
   | 7067    | Discard "nomerge" nodes to speed up depgraph.altlist() since |
   | zmedico | those nodes aren't used and the --tree algorithm does a good |
   |         | job of regenerating them when appropriate.                   |
   |---------+--------------------------------------------------------------|
   | 7069    | For bug #144333, make the --reinstall option a single choice |
   | zmedico | type.                                                        |
   |---------+--------------------------------------------------------------|
   | 7071    | When filling in "nomerge" nodes for --tree display, stop at  |
   | zmedico | a node that is an argument or a direct member of a set that  |
   |         | has been specified as an argument (system or world).         |
   |---------+--------------------------------------------------------------|
   | 7073    | For bug #183431, catch a ParseError caused by a corrupt      |
   | zmedico | profile and dump an error message. This allows emerge to     |
   |         | continue with actions that don't require a valid profile,    |
   |         | such as --sync.                                              |
   |---------+--------------------------------------------------------------|
   | 7075    | For bug #142473, add 2 additional color classes for system   |
   | zmedico | packages and packages matched by arguments.                  |
   |---------+--------------------------------------------------------------|
   | 7076    | Don't colorize system package when in "world" mode.          |
   | zmedico |                                                              |
   |---------+--------------------------------------------------------------|
   | 7078    | Remove unused worldlist variable.                            |
   | zmedico |                                                              |
   +------------------------------------------------------------------------+

svn path=/main/branches/prefix/; revision=7080

bin/isolated-functions.sh
pym/emerge/__init__.py
pym/portage/__init__.py
pym/portage/output.py

index 594c4e8ec41160e6d9b01a9f4ec09ecc2a82b4d6..15fc1758057f9acf835cb65ac1bc4287a40722f3 100755 (executable)
@@ -54,9 +54,13 @@ diefunc() {
         [ -n "${PORTAGE_LOG_FILE}" ] && \
             eerror "A complete build log is located at '${PORTAGE_LOG_FILE}'."
         if [ -n "${EBUILD_OVERLAY_ECLASSES}" ] ; then
-                eerror "This ebuild used eclasses from overlays: ${EBUILD_OVERLAY_ECLASSES}"
+            eerror "This ebuild used the following eclasses from overlays:"
+            local x
+            for x in ${EBUILD_OVERLAY_ECLASSES} ; do
+                 eerror "  ${x}"
+            done
         fi
-        if [ ${EBUILD#${PORTDIR}/} == ${EBUILD} ] ; then
+        if [ "${EBUILD#${PORTDIR}/}" == "${EBUILD}" ] ; then
             local overlay=${EBUILD%/*}
             overlay=${overlay%/*}
             overlay=${overlay%/*}
index 4e03f60ae81caea0db4b59dca63d26cc5baf66a9..0495c3a41cc28ec5593cf19bab60e929aa645e96 100644 (file)
@@ -936,7 +936,8 @@ class depgraph(object):
                # Maps slot atom to digraph node for all nodes added to the graph.
                self._slot_node_map = {}
                self.mydbapi = {}
-               self._mydbapi_keys = ["SLOT", "DEPEND", "RDEPEND", "PDEPEND"]
+               self._mydbapi_keys = ["SLOT", "DEPEND", "RDEPEND", "PDEPEND",
+                       "USE", "IUSE", "PROVIDE"]
                self.useFlags = {}
                self.trees = {}
                for myroot in trees:
@@ -979,7 +980,10 @@ class depgraph(object):
                self._parent_child_digraph = digraph()
                self.orderedkeys=[]
                self.outdatedpackages=[]
-               self.args_keys = []
+               self._args_atoms = {}
+               self._args_nodes = set()
+               self._sets = {}
+               self._sets_nodes = {}
                self.blocker_digraph = digraph()
                self.blocker_parents = {}
                self._unresolved_blocker_parents = {}
@@ -1052,7 +1056,7 @@ class depgraph(object):
                        elif org_iuse.intersection(orig_use) != \
                                cur_iuse.intersection(cur_use):
                                return True
-               elif "changed-use" in self.myopts.get("--reinstall","").split(","):
+               elif "changed-use" == self.myopts.get("--reinstall"):
                        if org_iuse.intersection(orig_use) != \
                                cur_iuse.intersection(cur_use):
                                return True
@@ -1110,14 +1114,22 @@ class depgraph(object):
                # directive, otherwise we add a "merge" directive.
 
                mydbapi = self.trees[myroot][self.pkg_tree_map[mytype]].dbapi
+               metadata = dict(izip(self._mydbapi_keys,
+                       mydbapi.aux_get(mykey, self._mydbapi_keys)))
+               if mytype == "ebuild":
+                       pkgsettings.setcpv(mykey, mydb=portdb)
+                       metadata["USE"] = pkgsettings["USE"]
+                       myuse = pkgsettings["USE"].split()
 
                if not arg and myroot == self.target_root:
-                       cpv_slot = "%s:%s" % (mykey, mydbapi.aux_get(mykey, ["SLOT"])[0])
-                       arg = portage.best_match_to_list(cpv_slot, self.args_keys)
-
-               if myuse is None:
-                       self.pkgsettings[myroot].setcpv(mykey, mydb=portdb)
-                       myuse = self.pkgsettings[myroot]["USE"].split()
+                       try:
+                               arg = self._find_atom_for_pkg(self._args_atoms, mykey, metadata)
+                       except portage.exception.InvalidDependString, e:
+                               if mytype != "installed":
+                                       show_invalid_depstring_notice(tuple(mybigkey+["merge"]),
+                                               metadata["PROVIDE"], str(e))
+                                       return 0
+                               del e
 
                merging=1
                if mytype == "installed":
@@ -1140,8 +1152,7 @@ class depgraph(object):
                                forced_flags.update(pkgsettings.useforce)
                                forced_flags.update(pkgsettings.usemask)
                                old_use = vardbapi.aux_get(mykey, ["USE"])[0].split()
-                               iuses = set(filter_iuse_defaults(
-                                       mydbapi.aux_get(mykey, ["IUSE"])[0].split()))
+                               iuses = set(filter_iuse_defaults(metadata["IUSE"].split()))
                                old_iuse = set(filter_iuse_defaults(
                                        vardbapi.aux_get(mykey, ["IUSE"])[0].split()))
                                if self._reinstall_for_flags(
@@ -1155,16 +1166,15 @@ class depgraph(object):
                jbigkey = tuple(mybigkey)
 
                if addme:
-                       metadata = dict(izip(self._mydbapi_keys,
-                               mydbapi.aux_get(mykey, self._mydbapi_keys)))
                        if merging == 0 and vardbapi.cpv_exists(mykey) and \
                                mytype != "installed":
+                               mytype = "installed"
                                mybigkey[0] = "installed"
                                mydbapi = vardbapi
                                jbigkey = tuple(mybigkey)
                                metadata = dict(izip(self._mydbapi_keys,
                                        mydbapi.aux_get(mykey, self._mydbapi_keys)))
-                               myuse = mydbapi.aux_get(mykey, ["USE"])[0].split()
+                               myuse = metadata["USE"].split()
                        slot_atom = "%s:%s" % (portage.dep_getkey(mykey), metadata["SLOT"])
                        existing_node = self._slot_node_map[myroot].get(
                                slot_atom, None)
@@ -1222,6 +1232,20 @@ class depgraph(object):
                                self.digraph.addnode(jbigkey, myparent,
                                        priority=priority)
 
+               if arg:
+                       self._args_nodes.add(jbigkey)
+                       try:
+                               for set_name, pkg_set in self._sets.iteritems():
+                                       atom = self._find_atom_for_pkg(pkg_set, mykey, metadata)
+                                       if atom:
+                                               self._sets_nodes[set_name].add(jbigkey)
+                       except portage.exception.InvalidDependString, e:
+                               if mytype != "installed":
+                                       show_invalid_depstring_notice(jbigkey,
+                                               metadata["PROVIDE"], str(e))
+                                       return 0
+                               del e
+
                # Do this even when addme is False (--onlydeps) so that the
                # parent/child relationship is always known in case
                # self._show_slot_collision_notice() needs to be called later.
@@ -1245,9 +1269,8 @@ class depgraph(object):
 
                edepend={}
                depkeys = ["DEPEND","RDEPEND","PDEPEND"]
-               depvalues = mydbapi.aux_get(mykey, depkeys)
-               for i in xrange(len(depkeys)):
-                       edepend[depkeys[i]] = depvalues[i]
+               for k in depkeys:
+                       edepend[k] = metadata[k]
 
                if mytype == "ebuild":
                        if "--buildpkgonly" in self.myopts:
@@ -1444,7 +1467,9 @@ class depgraph(object):
 
                """ These are used inside self.create() in order to ensure packages
                that happen to match arguments are not incorrectly marked as nomerge."""
-               self.args_keys = [x[1] for x in arg_atoms]
+               for myarg, myatom in arg_atoms:
+                       self._args_atoms.setdefault(
+                               portage.dep_getkey(myatom), []).append(myatom)
                for myarg, myatom in arg_atoms:
                                try:
                                        self.mysd = self.select_dep(myroot, myatom, arg=myarg)
@@ -1548,11 +1573,12 @@ class depgraph(object):
                                return 0
                        mymerge = mycheck[1]
 
-               if not mymerge and arg and \
-                       portage.best_match_to_list(depstring, self.args_keys):
+               if not mymerge and arg:
                        # A provided package has been specified on the command line.  The
                        # package will not be merged and a warning will be displayed.
-                       self._pprovided_args.append(arg)
+                       cp = portage.dep_getkey(depstring)
+                       if cp in self._args_atoms and depstring in self._args_atoms[cp]:
+                               self._pprovided_args.append(arg)
 
                if myparent:
                        # The parent is added after it's own dep_check call so that it
@@ -2044,6 +2070,9 @@ class depgraph(object):
                        self._altlist_cache[reversed] = retlist[:]
                        return retlist
                mygraph=self.digraph.copy()
+               for node in mygraph.order[:]:
+                       if node[-1] == "nomerge":
+                               mygraph.remove(node)
                self._merge_order_bias(mygraph)
                myblockers = self.blocker_digraph.copy()
                retlist=[]
@@ -2222,13 +2251,24 @@ class depgraph(object):
                        matches = portdb.gvisible(portdb.visible(mylist))
                        return [x for x in mylist \
                                if x in matches or not portdb.cpv_exists(x)]
+               def create_cp_dict(atom_list):
+                       cp_dict = {}
+                       for atom in atom_list:
+                               cp_dict.setdefault(portage.dep_getkey(atom), []).append(atom)
+                       return cp_dict
                world_problems = False
                if mode=="system":
                        mylist = getlist(self.settings, "system")
+                       self._sets["system"] = create_cp_dict(mylist)
+                       self._sets_nodes["system"] = set()
                else:
                        #world mode
                        worldlist = getlist(self.settings, "world")
+                       self._sets["world"] = create_cp_dict(worldlist)
+                       self._sets_nodes["world"] = set()
                        mylist = getlist(self.settings, "system")
+                       self._sets["system"] = create_cp_dict(mylist)
+                       self._sets_nodes["system"] = set()
                        worlddict=genericdict(worldlist)
 
                        for x in worlddict:
@@ -2299,7 +2339,11 @@ class depgraph(object):
                                                if available:
                                                        newlist.append(myslot_atom)
                mylist = newlist
-               
+
+               for myatom in mylist:
+                       self._args_atoms.setdefault(
+                               portage.dep_getkey(myatom), []).append(myatom)
+
                missing_atoms = []
                for mydep in mylist:
                        try:
@@ -2325,6 +2369,31 @@ class depgraph(object):
 
                return 1
 
+       def _find_atom_for_pkg(self, pkg_set, cpv, metadata):
+               """Return the best match for a given package from the arguments, or
+               None if there are no matches.  This matches virtual arguments against
+               the PROVIDE metadata.  This can raise an InvalidDependString exception
+               if an error occurs while parsing PROVIDE."""
+               cpv_slot = "%s:%s" % (cpv, metadata["SLOT"])
+               cp = portage.dep_getkey(cpv)
+               atoms = pkg_set.get(cp)
+               if atoms:
+                       best_match = portage.best_match_to_list(cpv_slot, atoms)
+                       if best_match:
+                               return best_match
+               provides = portage.flatten(portage.dep.use_reduce(
+                       portage.dep.paren_reduce(metadata["PROVIDE"]),
+                       uselist=metadata["USE"].split()))
+               for provide in provides:
+                       provided_cp = portage.dep_getkey(provide)
+                       atoms = pkg_set.get(provided_cp)
+                       if atoms:
+                               transformed_atoms = [atom.replace(provided_cp, cp) for atom in atoms]
+                               best_match = portage.best_match_to_list(cpv_slot, transformed_atoms)
+                               if best_match:
+                                       return atoms[transformed_atoms.index(best_match)]
+               return None
+
        def display(self,mylist,verbosity=None):
                if verbosity is None:
                        verbosity = ("--quiet" in self.myopts and 1 or \
@@ -2432,7 +2501,12 @@ class depgraph(object):
                                        traversed_nodes = set() # prevent endless circles
                                        traversed_nodes.add(graph_key)
                                        def add_parents(current_node, ordered):
-                                               parent_nodes = mygraph.parent_nodes(current_node)
+                                               parent_nodes = None
+                                               # Do not traverse to parents if this node is an
+                                               # an argument or a direct member of a set that has
+                                               # been specified as an argument (system or world).
+                                               if current_node not in self._args_nodes:
+                                                       parent_nodes = mygraph.parent_nodes(current_node)
                                                if parent_nodes:
                                                        child_nodes = set(mygraph.child_nodes(current_node))
                                                        selected_parent = None
@@ -2493,7 +2567,6 @@ class depgraph(object):
                # files to fetch list - avoids counting a same file twice
                # in size display (verbose mode)
                myfetchlist=[]
-               worldlist = set(getlist(self.settings, "world"))
 
                for mylist_index in xrange(len(mylist)):
                        x, depth, ordered = mylist[mylist_index]
@@ -2765,17 +2838,40 @@ class depgraph(object):
                                        myoldbest=blue("["+myoldbest+"]")
 
                                pkg_cp = xs[0]
-                               pkg_world = pkg_cp in worldlist
+                               pkg_arg    = False
+                               pkg_world  = False
+                               pkg_system = False
+                               pkg_node = tuple(x)
+                               if pkg_node in self._args_nodes:
+                                       pkg_arg = True
+                                       world_nodes = self._sets_nodes.get("world")
+                                       if world_nodes and pkg_node in world_nodes:
+                                               pkg_world = True
+                                       if world_nodes is None:
+                                               # Don't colorize system package when in "world" mode.
+                                               system_nodes = self._sets_nodes.get("system")
+                                               if system_nodes and pkg_node in system_nodes:
+                                                       pkg_system = True
 
                                def pkgprint(pkg):
                                        if pkg_merge:
-                                               if pkg_world:
-                                                       return colorize("PKG_MERGE_WORLD", pkg)
+                                               if pkg_arg:
+                                                       if pkg_world:
+                                                               return colorize("PKG_MERGE_WORLD", pkg)
+                                                       elif pkg_system:
+                                                               return colorize("PKG_MERGE_SYSTEM", pkg)
+                                                       else:
+                                                               return colorize("PKG_MERGE_ARG", pkg)
                                                else:
                                                        return colorize("PKG_MERGE", pkg)
                                        else:
-                                               if pkg_world:
-                                                       return colorize("PKG_NOMERGE_WORLD", pkg)
+                                               if pkg_arg:
+                                                       if pkg_world:
+                                                               return colorize("PKG_NOMERGE_WORLD", pkg)
+                                                       elif pkg_system:
+                                                               return colorize("PKG_NOMERGE_SYSTEM", pkg)
+                                                       else:
+                                                               return colorize("PKG_NOMERGE_ARG", pkg)
                                                else:
                                                        return colorize("PKG_NOMERGE", pkg)
 
@@ -5335,7 +5431,9 @@ def parse_opts(tmpcmdline, silent=False):
                        "choices":("y", "n")
                },
                "--reinstall": {
-                       "help":"specify conditions to trigger package reinstallation"
+                       "help":"specify conditions to trigger package reinstallation",
+                       "type":"choice",
+                       "choices":["changed-use"]
                }
        }
 
index c5cb97f64aa256bea833f50829344500a2a038c4..79f3d6124ba86f687e077eaf4e28d86c21fbff46 100644 (file)
@@ -1021,7 +1021,14 @@ class config(object):
                                                                        "Parent '%s' not found: '%s'" %  \
                                                                        (parentPath, parentsFile))
                                        self.profiles.append(currentPath)
-                               addProfile(os.path.realpath(self.profile_path))
+                               try:
+                                       addProfile(os.path.realpath(self.profile_path))
+                               except portage.exception.ParseError, e:
+                                       writemsg("!!! Unable to parse profile: '%s'\n" % \
+                                               self.profile_path, noiselevel=-1)
+                                       writemsg("!!! ParseError: %s\n" % str(e), noiselevel=-1)
+                                       del e
+                                       self.profiles = []
                        if local_config:
                                custom_prof = os.path.join(
                                        config_root, CUSTOM_PROFILE_PATH.lstrip(os.path.sep))
index 008a10fc7f072942891b1a2d28ffc299084a08d0..49a2fd995b2917fd4ac88e4ecc6a10bfd00c03d2 100644 (file)
@@ -130,8 +130,12 @@ codes["UNMERGE_WARN"] = codes["red"]
 codes["SECURITY_WARN"] = codes["red"]
 codes["MERGE_LIST_PROGRESS"] = codes["yellow"]
 codes["PKG_MERGE"]           = codes["darkgreen"]
+codes["PKG_MERGE_ARG"]       = codes["darkgreen"]
+codes["PKG_MERGE_SYSTEM"]    = codes["green"]
 codes["PKG_MERGE_WORLD"]     = codes["green"]
 codes["PKG_NOMERGE"]         = codes["darkblue"]
+codes["PKG_NOMERGE_ARG"]     = codes["darkblue"]
+codes["PKG_NOMERGE_SYSTEM"]  = codes["blue"]
 codes["PKG_NOMERGE_WORLD"]   = codes["blue"]
 
 def parse_color_map():