Merged from trunk -r12583:12593
authorFabian Groffen <grobian@gentoo.org>
Sat, 14 Feb 2009 10:57:35 +0000 (10:57 -0000)
committerFabian Groffen <grobian@gentoo.org>
Sat, 14 Feb 2009 10:57:35 +0000 (10:57 -0000)
   | 12584    | For python-3.0 compatibility, make dict-like classes modify |
   | zmedico  | their keys(), items(), and values() methods appropriatly    |
   |          | for the current python version.                             |

   | 12585    | Inside depgraph._serialize_tasks(), simplify the logic      |
   | zmedico  | which delays selection of root nodes.                       |

   | 12586    | Make DepPriority.__str__() indicate optional deps.          |
   | zmedico  |                                                             |

   | 12587    | Fix digraph.clone() to properly clone priority lists.       |
   | zmedico  |                                                             |

   | 12588    | fix --libdir detection when econf is passed                 |
   | SpankMan | whitespace/empty arguments ... those break the plain string |
   |          | expansion comparison                                        |

   | 12589    | fix previous commit -- hasq isnt as cool as i thought and   |
   | SpankMan | doesnt accept globs, so define a new hasg() func that does  |
   |          | and use that                                                |

   | 12590    | cleanup econf() code -- use hasg* funcs in multilib code to |
   | SpankMan | avoid wrong/duplicate parsing methods, move all handling to |
   |          | "$@" to avoid duplication, and make sure we prepend         |
   |          | arguments coming from the ebuild rather than append -- only |
   |          | EXTRA_ECONF from user should override things                |

   | 12591    | Escape globs in hasgq arguments in order to prevent bash    |
   | zmedico  | from trying to perform filename expansion.                  |

   | 12592    | Filter the new hasg and hasgq functions inside              |
   | zmedico  | save_ebuild_env().                                          |

   | 12593    | add support for .xz compressed files like .lzma             |
   | SpankMan |                                                             |

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

bin/ebuild.sh
bin/isolated-functions.sh
pym/_emerge/__init__.py
pym/portage/__init__.py
pym/portage/cache/anydbm.py
pym/portage/cache/mappings.py
pym/portage/cache/sql_template.py
pym/portage/cache/template.py

index 0ce6f896e7238bbce8e685f5ed3d6614217724ac..e5df919bca1c7d81803e16b661b8ead7b6586eab 100755 (executable)
@@ -434,6 +434,14 @@ unpack() {
                                        lzma -dc "${srcdir}${x}" > ${x%.*} || die "$myfail"
                                fi
                                ;;
+                       xz)
+                               if [ "${y}" == "tar" ]; then
+                                       xz -dc "${srcdir}${x}" | tar xof - ${tar_opts}
+                                       assert "$myfail"
+                               else
+                                       xz -dc "${srcdir}${x}" > ${x%.*} || die "$myfail"
+                               fi
+                               ;;
                        *)
                                vecho "unpack ${x}: file format not recognized. Ignoring."
                                ;;
@@ -455,17 +463,21 @@ strip_duplicate_slashes() {
        fi
 }
 
+hasg() {
+    local x s=$1
+    shift
+    for x ; do [[ ${x} == ${s} ]] && echo "${x}" && return 0 ; done
+    return 1
+}
+hasgq() { hasg "$@" >/dev/null ; }
 econf() {
        local x
-       local LOCAL_EXTRA_ECONF="${EXTRA_ECONF}"
 
        ! hasq "$EAPI" 0 1 && [[ $EBUILD_PHASE = compile && \
                $(type -t src_configure) = function ]] && \
                eqawarn "econf called in src_compile instead of src_configure"
 
-       if [ -z "${ECONF_SOURCE}" ]; then
-               ECONF_SOURCE="."
-       fi
+       : ${ECONF_SOURCE:=.}
        if [ -x "${ECONF_SOURCE}/configure" ]; then
                if [ -e "${EPREFIX}"/usr/share/gnuconfig/ ]; then
                        find "${WORKDIR}" -type f '(' \
@@ -476,64 +488,37 @@ econf() {
                        done
                fi
 
-               if [ ! -z "${CBUILD}" ]; then
-                       LOCAL_EXTRA_ECONF="--build=${CBUILD} ${LOCAL_EXTRA_ECONF}"
-               fi
-
-               if [ ! -z "${CTARGET}" ]; then
-                       LOCAL_EXTRA_ECONF="--target=${CTARGET} ${LOCAL_EXTRA_ECONF}"
-               fi
-
                # if the profile defines a location to install libs to aside from default, pass it on.
                # if the ebuild passes in --libdir, they're responsible for the conf_libdir fun.
-               LIBDIR_VAR="LIBDIR_${ABI}"
-               if [ -n "${ABI}" -a -n "${!LIBDIR_VAR}" ]; then
-                       CONF_LIBDIR="${!LIBDIR_VAR}"
+               local CONF_LIBDIR LIBDIR_VAR="LIBDIR_${ABI}"
+               if [[ -n ${ABI} && -n ${!LIBDIR_VAR} ]] ; then
+                       CONF_LIBDIR=${!LIBDIR_VAR}
                fi
-               unset LIBDIR_VAR
-               if [ -n "${CONF_LIBDIR}" ] && [ "${*/--libdir}" == "$*" ]; then
-                       if [ "${*/--exec-prefix}" != "$*" ]; then
-                               local args="$(echo $*)"
-                               local -a pref=($(echo ${args/*--exec-prefix[= ]}))
-                               CONF_PREFIX=${pref}
-                               [ "${CONF_PREFIX:0:1}" != "/" ] && CONF_PREFIX="/${CONF_PREFIX}"
-                       elif [ "${*/--prefix}" != "$*" ]; then
-                               local args="$(echo $*)"
-                               local -a pref=($(echo ${args/*--prefix[= ]}))
-                               CONF_PREFIX=${pref}
-                               [ "${CONF_PREFIX:0:1}" != "/" ] && CONF_PREFIX="/${CONF_PREFIX}"
-                       else
-                               CONF_PREFIX="${EPREFIX}/usr"
-                       fi
-                       export CONF_PREFIX
-                       [ "${CONF_LIBDIR:0:1}" != "/" ] && CONF_LIBDIR="/${CONF_LIBDIR}"
-
-                       CONF_LIBDIR_RESULT="$(strip_duplicate_slashes ${CONF_PREFIX}${CONF_LIBDIR})"
-
-                       LOCAL_EXTRA_ECONF="--libdir=${CONF_LIBDIR_RESULT} ${LOCAL_EXTRA_ECONF}"
+               if [[ -n ${CONF_LIBDIR} ]] && ! hasgq --libdir=\* "$@" ; then
+                       export CONF_PREFIX=$(hasg --exec-prefix=\* "$@")
+                       [[ -z ${CONF_PREFIX} ]] && CONF_PREFIX=$(hasg --prefix=\* "$@")
+                       : ${CONF_PREFIX:=${EPREFIX}/usr}
+                       CONF_PREFIX=${CONF_PREFIX#*=}
+                       [[ ${CONF_PREFIX} != /* ]] && CONF_PREFIX="/${CONF_PREFIX}"
+                       [[ ${CONF_LIBDIR} != /* ]] && CONF_LIBDIR="/${CONF_LIBDIR}"
+                       set -- --libdir="$(strip_duplicate_slashes ${CONF_PREFIX}${CONF_LIBDIR})" "$@"
                fi
 
-               vecho "${ECONF_SOURCE}/configure" \
+               set -- \
                        --prefix="${EPREFIX}"/usr \
+                       ${CBUILD:+--build=${CBUILD}} \
                        --host=${CHOST} \
+                       ${CTARGET:+--target=${CTARGET}} \
                        --mandir="${EPREFIX}"/usr/share/man \
                        --infodir="${EPREFIX}"/usr/share/info \
                        --datadir="${EPREFIX}"/usr/share \
                        --sysconfdir="${EPREFIX}"/etc \
                        --localstatedir="${EPREFIX}"/var/lib \
                        "$@" \
-                       ${LOCAL_EXTRA_ECONF}
+                       ${EXTRA_ECONF}
+               vecho "${ECONF_SOURCE}/configure" "$@"
 
-               if ! "${ECONF_SOURCE}/configure" \
-                       --prefix="${EPREFIX}"/usr \
-                       --host=${CHOST} \
-                       --mandir="${EPREFIX}"/usr/share/man \
-                       --infodir="${EPREFIX}"/usr/share/info \
-                       --datadir="${EPREFIX}"/usr/share \
-                       --sysconfdir="${EPREFIX}"/etc \
-                       --localstatedir="${EPREFIX}"/var/lib \
-                       "$@"  \
-                       ${LOCAL_EXTRA_ECONF}; then
+               if ! "${ECONF_SOURCE}/configure" "$@" ; then
 
                        if [ -s config.log ]; then
                                echo
@@ -542,7 +527,7 @@ econf() {
                        fi
                        die "econf failed"
                fi
-       elif [ -f "${ECONF_SOURCE:-.}/configure" ]; then
+       elif [ -f "${ECONF_SOURCE}/configure" ]; then
                die "configure is not executable"
        else
                die "no configure script found"
index e85e094dcc07e62b8c4162d6138941596577c6ce..1eead1a2cbb02d70110977c2f9fe97611753ac5e 100755 (executable)
@@ -502,7 +502,8 @@ save_ebuild_env() {
                unset -f dump_trace die diefunc quiet_mode vecho elog_base eqawarn elog \
                        esyslog einfo einfon ewarn eerror ebegin _eend eend KV_major \
                        KV_minor KV_micro KV_to_int get_KV unset_colors set_colors has \
-                       hasv hasq qa_source qa_call addread addwrite adddeny addpredict \
+                       hasg hasgq hasv hasq qa_source qa_call \
+                       addread addwrite adddeny addpredict \
                        lchown lchgrp esyslog use usev useq has_version portageq \
                        best_version use_with use_enable register_die_hook check_KV \
                        keepdir unpack strip_duplicate_slashes econf einstall \
index cf34dcb006f6abda7b8052bd84194cbd11f5c42c..6526194b96959686bdd0f2d34d5d28c5f1ef5ee1 100644 (file)
@@ -1000,6 +1000,8 @@ class DepPriority(AbstractDepPriority):
                return -7
 
        def __str__(self):
+               if self.optional:
+                       return "optional"
                myvalue = self.__int__()
                if myvalue > self.MEDIUM:
                        return "hard"
@@ -6895,23 +6897,14 @@ class depgraph(object):
                # successfully selected.
                prefer_asap = True
 
-               # By default, try to avoid selecting root nodes whenever possible. This
-               # helps ensure that the maximimum possible number of soft dependencies
-               # have been removed from the graph before their parent nodes have
-               # selected. This is especially important when those dependencies are
-               # going to be rebuilt by revdep-rebuild or `emerge -e system` after the
-               # CHOST has been changed (like when building a stage3 from a stage2).
-               accept_root_node = False
-
-               # State of prefer_asap and accept_root_node flags for successive
-               # iterations that loosen the criteria for node selection.
+               # State of variables for successive iterations that loosen the
+               # criteria for node selection.
                #
-               # iteration   prefer_asap   accept_root_node
-               # 1           True          False
-               # 2           False         False
-               # 3           False         True
+               # iteration   prefer_asap
+               # 1           True
+               # 2           False
                #
-               # If no nodes are selected on the 3rd iteration, it is due to
+               # If no nodes are selected on the last iteration, it is due to
                # unresolved blockers or circular dependencies.
 
                while not mygraph.empty():
@@ -6919,7 +6912,9 @@ class depgraph(object):
                        selected_nodes = None
                        ignore_priority = None
                        if prefer_asap and asap_nodes:
-                               """ASAP nodes are merged before their soft deps."""
+                               # ASAP nodes are merged before their soft deps. Go ahead and
+                               # select root nodes here if necessary, since it's typical for
+                               # the parent to have been removed from the graph already.
                                asap_nodes = [node for node in asap_nodes \
                                        if mygraph.contains(node)]
                                for node in asap_nodes:
@@ -6963,10 +6958,7 @@ class depgraph(object):
                                                                        # found a non-root node
                                                                        selected_nodes = [node]
                                                                        break
-                                                       if not selected_nodes and \
-                                                               (accept_root_node or ignore_priority is None):
-                                                               # settle for a root node
-                                                               selected_nodes = [nodes[0]]
+
                                                if selected_nodes:
                                                        break
 
@@ -7001,9 +6993,7 @@ class depgraph(object):
                                        for ignore_priority in xrange(DepPriority.SOFT,
                                                DepPriority.MEDIUM_SOFT + 1):
                                                for node in nodes:
-                                                       if nodes is not asap_nodes and \
-                                                               not accept_root_node and \
-                                                               not mygraph.parent_nodes(node):
+                                                       if not mygraph.parent_nodes(node):
                                                                continue
                                                        selected_nodes = set()
                                                        if gather_deps(ignore_priority,
@@ -7028,12 +7018,6 @@ class depgraph(object):
                                                prefer_asap = False
                                                continue
 
-                                       if not selected_nodes and not accept_root_node:
-                                               # Maybe there are only root nodes left, so accept them
-                                               # for the next iteration.
-                                               accept_root_node = True
-                                               continue
-
                        if selected_nodes and ignore_priority > DepPriority.SOFT:
                                # Try to merge ignored medium deps as soon as possible.
                                for node in selected_nodes:
@@ -7214,29 +7198,37 @@ class depgraph(object):
                                                scheduler_graph.add(blocked_pkg, uninst_task,
                                                        priority=BlockerDepPriority.instance)
 
-                               else:
-                                       # None of the Uninstall tasks are acceptable, so
-                                       # the corresponding blockers are unresolvable.
-                                       # We need to drop an Uninstall task here in order
-                                       # to avoid the circular deps code path, but the
-                                       # blocker will still be counted as an unresolved
-                                       # conflict.
-                                       for node in myblocker_uninstalls.leaf_nodes():
-                                               try:
-                                                       mygraph.remove(node)
-                                               except KeyError:
-                                                       pass
-                                               else:
-                                                       uninst_task = node
-                                                       ignored_uninstall_tasks.add(node)
-                                                       break
+                                       # Reset the state variables for leaf node selection and
+                                       # continue trying to select leaf nodes.
+                                       prefer_asap = True
+                                       continue
+
+                       if not selected_nodes:
+                               # Only select root nodes as a last resort. This case should
+                               # only trigger when the graph is nearly empty and the only
+                               # remaining nodes are isolated (no parents or children). Since
+                               # the nodes must be isolated, ignore_priority is not needed.
+                               selected_nodes = get_nodes()
+
+                       if not selected_nodes and not myblocker_uninstalls.is_empty():
+                               # If possible, drop an uninstall task here in order to avoid
+                               # the circular deps code path. The corresponding blocker will
+                               # still be counted as an unresolved conflict.
+                               uninst_task = None
+                               for node in myblocker_uninstalls.leaf_nodes():
+                                       try:
+                                               mygraph.remove(node)
+                                       except KeyError:
+                                               pass
+                                       else:
+                                               uninst_task = node
+                                               ignored_uninstall_tasks.add(node)
+                                               break
 
                                if uninst_task is not None:
-                                       # After dropping an Uninstall task, reset
-                                       # the state variables for leaf node selection and
+                                       # Reset the state variables for leaf node selection and
                                        # continue trying to select leaf nodes.
                                        prefer_asap = True
-                                       accept_root_node = False
                                        continue
 
                        if not selected_nodes:
@@ -7244,10 +7236,8 @@ class depgraph(object):
                                raise self._unknown_internal_error()
 
                        # At this point, we've succeeded in selecting one or more nodes, so
-                       # it's now safe to reset the prefer_asap and accept_root_node flags
-                       # to their default states.
+                       # reset state variables for leaf node selection.
                        prefer_asap = True
-                       accept_root_node = False
 
                        mygraph.difference_update(selected_nodes)
 
index 4ea43517169da464c161df97ac9fac192e0b63c0..60fe960d557a735371914d1bee61735d7d4b1e0d 100644 (file)
@@ -562,8 +562,14 @@ class digraph(object):
        def clone(self):
                clone = digraph()
                clone.nodes = {}
-               for k, v in self.nodes.iteritems():
-                       clone.nodes[k] = (v[0].copy(), v[1].copy(), v[2])
+               for children, parents, node in self.nodes.itervalues():
+                       children_clone = {}
+                       for child, priorities in children.iteritems():
+                               children_clone[child] = priorities[:]
+                       parents_clone = {}
+                       for parent, priorities in parents.iteritems():
+                               parents_clone[parent] = priorities[:]
+                       clone.nodes[node] = (children_clone, parents_clone, node)
                clone.order = self.order[:]
                return clone
 
@@ -3002,6 +3008,10 @@ class config(object):
                                        pass
                return self._selinux_enabled
 
+       if sys.hexversion >= 0x3000000:
+               keys = __iter__
+               items = iteritems
+
 def _shell_quote(s):
        """
        Quote a string in double-quotes and use backslashes to
index 47b8ac1bd4740305bd25788b0a18ff4931469227..9007a1a5679d34cba3a1f5b7142a3c8948d0a9b0 100644 (file)
@@ -9,6 +9,7 @@ try:
 except ImportError:
        import pickle
 import os
+import sys
 from portage.cache import fs_template
 from portage.cache import cache_errors
 
@@ -70,3 +71,6 @@ class database(fs_template.FsBased):
                if "__db" in self.__dict__ and self.__db != None:
                        self.__db.sync()
                        self.__db.close()
+
+       if sys.hexversion >= 0x3000000:
+               items = iteritems
index 112301476fcc55c31fcddce0d48d3d0357ed6ab2..010eb7f8e8d8b19bad1477acf365ecdcebeb693e 100644 (file)
@@ -3,6 +3,7 @@
 # License: GPL2
 # $Id$
 
+import sys
 import UserDict
 import warnings
 import weakref
@@ -65,6 +66,10 @@ class ProtectedDict(UserDict.DictMixin):
                        DeprecationWarning)
                return key in self
 
+       if sys.hexversion >= 0x3000000:
+               keys = __iter__
+               items = iteritems
+
 class LazyLoad(UserDict.DictMixin):
        """
        Lazy loading of values for a dict
@@ -111,6 +116,10 @@ class LazyLoad(UserDict.DictMixin):
                        self.pull = None
                return key in self.d
 
+       if sys.hexversion >= 0x3000000:
+               keys = __iter__
+               items = iteritems
+
 _slot_dict_classes = weakref.WeakValueDictionary()
 
 def slot_dict_class(keys, prefix="_val_"):
@@ -265,6 +274,11 @@ def slot_dict_class(keys, prefix="_val_"):
                        def __str__(self):
                                return str(dict(self.iteritems()))
 
+                       if sys.hexversion >= 0x3000000:
+                               items = iteritems
+                               keys = __iter__
+                               values = itervalues
+
                v = SlotDict
                _slot_dict_classes[v.allowed_keys] = v
        return v
index fe873c3eab4dad2def53b3d6a4cae2b6157e2a94..e5903cd67382ace9be3e2b6167d0a5f3ef3c5c6c 100644 (file)
@@ -3,6 +3,7 @@
 # License: GPL2
 # $Id$
 
+import sys
 from portage.cache import template, cache_errors
 from portage.cache.template import reconstruct_eclasses
 
@@ -277,3 +278,5 @@ class SQLDatabase(template.database):
 
                return [ row[0] for row in self.con.fetchall() ]
 
+       if sys.hexversion >= 0x3000000:
+               items = iteritems
index 238f9dc40c40f7c7003b7251b12b05283aa4b577..35b9efeffbd976b7eaddb908433e8fb0126af4df 100644 (file)
@@ -6,6 +6,7 @@
 from portage.cache import cache_errors
 from portage.cache.cache_errors import InvalidRestriction
 from portage.cache.mappings import ProtectedDict
+import sys
 import warnings
 
 class database(object):
@@ -177,6 +178,9 @@ class database(object):
                        if cont:
                                yield cpv
 
+       if sys.hexversion >= 0x3000000:
+               keys = __iter__
+               items = iteritems
 
 def serialize_eclasses(eclass_dict):
        """takes a dict, returns a string representing said dict"""