Merged from trunk 9351:9372
authorFabian Groffen <grobian@gentoo.org>
Sat, 23 Feb 2008 23:46:25 +0000 (23:46 -0000)
committerFabian Groffen <grobian@gentoo.org>
Sat, 23 Feb 2008 23:46:25 +0000 (23:46 -0000)
   | 9352     | Revert back to some known working code from the 2.1.2       |
   | zmedico  | branch.                                                     |

   | 9353     | Use parse_use_local_desc() from the repoman.utilities       |
   | zmedico  | module.                                                     |

   | 9354     | Make PreservedLibsRegistry.store() use atomic_ofstream so   |
   | zmedico  | that we don't lose the whole registry if an error such as   |
   |          | 'out of space' occurs.                                      |

   | 9355     | Bug #210372 - Fix suidctl.conf parser to look for paths     |
   | zmedico  | with a leading slash.                                       |

   | 9357     | Bug #210449 - Reset exeinto(), docinto(), insinto(), and    |
   | zmedico  | into() state variables in case the user is running the      |
   |          | install phase multiple times consecutively via the ebuild   |
   |          | command.                                                    |

   | 9358     | - outsource logic for boolean options into a central        |
   | genone   | function - enable support for greedy behavior in            |
   |          | StaticFileSet                                               |

   | 9359     | For greedy slot behavior, in addition to any installed      |
   | zmedico  | slots also try to pull in the latest new slot that may be   |
   |          | available.                                                  |

   | 9360     | When showing an unsatisfied dep, never include installed    |
   | zmedico  | packages.                                                   |

   | 9361     | Make stack_dicts() treat an empty variable assignment just  |
   | zmedico  | like a non-empty assignment. This allows the profile to set |
   |          | and empty variable in make.defaults and have it override a  |
   |          | non-empty value as one would expect.                        |

   | 9362     | In the circular dependency display, drop PDEPEND (aka       |
   | zmedico  | MEDIUM_SOFT) from the graph so there's less noise.          |

   | 9363     | Optimize dblink.isowner() to use fewer stat calls by doing  |
   | zmedico  | a basename comparison to try and eliminate the file before  |
   |          | resorting to inode comparison. This speeds up the `portageq |
   |          | owners` command as well as the search that is done when     |
   |          | collision-protect finds a collision.                        |

   | 9364     | Make LibraryPackageMap.update() sort the contents of the    |
   | zmedico  | library_consumers cache so that it's nice and orderly.      |

   | 9365     | Bug #211067 - Make the "portdir_overlay" and "mydir"        |
   | zmedico  | variables contain paths that are consistent wrt eachother   |
   |          | regardless of any path irregularities that can be induced   |
   |          | by symlinks. Consistency is achieved by regenerating one of |
   |          | the paths to ensure that both paths have the exact same     |
   |          | mapping between inodes and paths. This consistency ensures  |
   |          | that the path manipulations used to calculate "repolevel"   |
   |          | will work as intended.                                      |

   | 9367     | Add support for file paths as arguments to emerge. If an    |
   | zmedico  | argument starts with / and it's not recognized as a tbz2 or |
   |          | ebuild then we try to find and owner in the vdb and         |
   |          | generate a slot atom from it. Thanks to solar for the       |
   |          | suggestion.                                                 |

   | 9368     | Revert portdbapi category auto-detection code since it's    |
   | zmedico  | not really needed and can cause problems if we need to add  |
   |          | new non-category directories in the future. We only really  |
   |          | need the category auto-detection for bindbapi and vardbapi  |
   |          | anyway.                                                     |

   | 9369     | cleanup main option parsing                                 |
   | SpankMan |                                                             |

   | 9370     | tighten up output from script                               |
   | SpankMan |                                                             |

   | 9371     | add support for lzma/gz snapshots                           |
   | SpankMan |                                                             |

   | 9372     | only try to fetch compression schemes which the host        |
   | SpankMan | supports                                                    |

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

13 files changed:
bin/ebuild.sh
bin/emerge-webrsync
bin/misc-functions.sh
bin/repoman
pym/_emerge/__init__.py
pym/portage/dbapi/porttree.py
pym/portage/dbapi/vartree.py
pym/portage/sets/__init__.py
pym/portage/sets/dbapi.py
pym/portage/sets/files.py
pym/portage/sets/security.py
pym/portage/util.py
pym/repoman/utilities.py

index 60f5d760b34e62063a74f44dd4b10610ea4fb3df..2498554818ee7b8626f22fd4d34533f44f33688c 100755 (executable)
@@ -263,10 +263,6 @@ register_die_hook() {
 #if no perms are specified, dirs/files will have decent defaults
 #(not secretive, but not stupid)
 umask 022
-export DESTTREE=/usr
-export INSDESTTREE=""
-export _E_EXEDESTTREE_=""
-export _E_DOCDESTTREE_=""
 export INSOPTIONS="-m0644"
 export EXEOPTIONS="-m0755"
 export LIBOPTIONS="-m0644"
@@ -986,6 +982,15 @@ dyn_install() {
        #some packages uses an alternative to $S to build in, cause
        #our libtool to create problematic .la files
        export PWORKDIR="$WORKDIR"
+
+       # Reset exeinto(), docinto(), insinto(), and into() state variables
+       # in case the user is running the install phase multiple times
+       # consecutively via the ebuild command.
+       export DESTTREE=/usr
+       export INSDESTTREE=""
+       export _E_EXEDESTTREE_=""
+       export _E_DOCDESTTREE_=""
+
        ebuild_phase src_install
        touch "${PORTAGE_BUILDDIR}/.installed"
        vecho ">>> Completed installing ${PF} into ${ED}"
index 37c727260ba72e5ce622a3524b3ca86b9e86dc9b..0910bd939e9fdfa6bef8aa2f4533d1b4a2ef13c9 100755 (executable)
@@ -1,5 +1,5 @@
 #!@BASH@
-# Copyright 1999-2006 Gentoo Foundation
+# Copyright 1999-2008 Gentoo Foundation
 # Distributed under the terms of the GNU General Public License v2
 # $Id$
 # Author: Karl Trygve Kalleberg <karltk@gentoo.org>
@@ -7,6 +7,10 @@
 # Author: Alon Bar-Lev <alon.barlev@gmail.com>
 # Major rewrite from Karl's scripts.
 
+# TODO:
+#  - all output should prob be converted to e* funcs
+#  - add support for ROOT
+
 #
 # gpg key import
 # KEY_ID=0x7DDAD20D
 # gpg --homedir /etc/portage/gnupg --edit-key $KEY_ID trust
 #
 
-type portageq > /dev/null || exit $?
+# Only echo if in verbose mode
+vvecho() { [[ ${do_verbose} -eq 1 ]] && echo "$@" ; }
+# Only echo if not in verbose mode
+nvecho() { [[ ${do_verbose} -eq 0 ]] && echo "$@" ; }
+# warning echos
+wecho() { echo "${argv0}: warning: $*" 1>&2 ; }
+# error echos
+eecho() { echo "${argv0}: error: $*" 1>&2 ; }
+
+argv0=$0
+if ! type portageq > /dev/null ; then
+       eecho "could not find 'portageq'; aborting"
+       exit 1
+fi
 eval $(portageq envvar -v FEATURES FETCHCOMMAND GENTOO_MIRRORS \
        PORTAGE_BIN_PATH PORTAGE_GPG_DIR PORTAGE_INST_UID PORTAGE_INST_GID \
        PORTAGE_NICENESS PORTAGE_RSYNC_EXTRA_OPTS PORTAGE_TMPDIR PORTDIR \
@@ -31,6 +48,7 @@ fi
 source "${PORTAGE_BIN_PATH}"/isolated-functions.sh || exit 1
 
 do_verbose=0
+do_debug=0
 
 if hasq webrsync-gpg ${FEATURES} ; then
        WEBSYNC_VERIFY_SIGNATURE=1
@@ -38,10 +56,24 @@ else
        WEBSYNC_VERIFY_SIGNATURE=0
 fi
 if [ ${WEBSYNC_VERIFY_SIGNATURE} != 0 -a -z "${PORTAGE_GPG_DIR}" ]; then
-       echo "Error: Please set PORTAGE_GPG_DIR in make.conf"
+       eecho "please set PORTAGE_GPG_DIR in make.conf"
        exit 1
 fi
 
+do_tar() {
+       local file=$1; shift
+       local decompressor
+       case ${file} in
+               *.lzma) decompressor="lzcat" ;;
+               *.bz2)  decompressor="bzcat" ;;
+               *.gz)   decompressor="zcat"  ;;
+               *)      decompressor="cat"   ;;
+       esac
+       ${decompressor} "${file}" | tar "$@"
+       _pipestatus=${PIPESTATUS[*]}
+       [[ ${_pipestatus// /} -eq 0 ]]
+}
+
 get_utc_date_in_seconds() {
        date -u +"%s"
 }
@@ -78,25 +110,17 @@ fetch_file() {
        local opts
 
        if [ "${FETCHCOMMAND/wget/}" != "${FETCHCOMMAND}" ]; then
-               opts="--continue"
-
-               [ "${do_verbose}" == 0 ] && opts="$opts -q" 
+               opts="--continue $(nvecho -q)"
        elif [ "${FETCHCOMMAND/curl/}" != "${FETCHCOMMAND}" ]; then
-               opts="--continue-at -"
-
-               [ "${do_verbose}" == 0 ] && opts="$opts -s -f" 
+               opts="--continue-at - $(nvecho -s -f)"
        else
                rm -f "${FILE}"
        fi
 
-       echo "Fetching file ${FILE}..."
-
-       #already set DISTDIR=
-       if [ "${do_verbose}" == 0 ] ; then
-               eval "${FETCHCOMMAND}" ${opts} > /dev/null && [ -s "${FILE}" ]
-       else
-               eval "${FETCHCOMMAND}" ${opts} && [ -s "${FILE}" ]
-       fi
+       vecho "Fetching file ${FILE} ..."
+       # already set DISTDIR=
+       eval "${FETCHCOMMAND}" ${opts}
+       [ -s "${FILE}" ]
 }
 
 check_file_digest() {
@@ -104,15 +128,14 @@ check_file_digest() {
        local file="$2"
        local r=1
 
-       echo "Checking digest..."
+       vecho "Checking digest ..."
 
        if type -P md5sum > /dev/null; then
                md5sum -c $digest && r=0
        elif type -P md5 > /dev/null; then
                [ "$(md5 -q $file)" == "$(cut -d \ -f 1 \"$digest\")" ] && r=0
        else
-               echo "Error: Cannot check digest"
-               echo "No suitable md5/md5sum binaries found"
+               eecho "cannot check digest: no suitable md5/md5sum binaries found"
        fi
 
        return "${r}"
@@ -125,13 +148,12 @@ check_file_signature() {
 
        if [ ${WEBSYNC_VERIFY_SIGNATURE} != 0 ]; then
 
-               echo "Checking signature..."
+               vecho "Checking signature ..."
 
                if type -p gpg > /dev/null; then
                        gpg --homedir "${PORTAGE_GPG_DIR}" --verify "$signature" "$file" && r=0
                else
-                       echo "Error: Cannot check signature"
-                       echo "gpg binary not found"
+                       eecho "cannot check signature: gpg binary not found"
                fi
        else
                r=0
@@ -143,27 +165,22 @@ check_file_signature() {
 get_snapshot_timestamp() {
        local file="$1"
 
-       tar --to-stdout -xf "${file}" portage/metadata/timestamp.x | cut -f 1 -d " "
+       do_tar "${file}" --to-stdout -xf - portage/metadata/timestamp.x | cut -f 1 -d " "
 }
 
 sync_local() {
        local file="$1"
 
-       echo "Syncing local tree..."
+       vecho "Syncing local tree ..."
 
        if type -P tarsync &> /dev/null; then
-               if [ "${do_verbose}" != 0 ] ; then
-                       tarsync_verbose=-v
-               fi
-               if ! tarsync $tarsync_verbose -s 1 -o portage -g portage -e /distfiles -e /packages -e /local "${file}" "${PORTDIR}"; then
-                       echo "Error: tarsync failed; tarball is corrupt? (${file})"
+               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
                fi
        else
-               echo "Note: tarsync was not found, you may consider emerge it..."
-
-               if ! tar jxf "${file}"; then
-                       echo "Error: tar failed to extract the image. tarball is corrupt? (${file})"
+               if ! do_tar "${file}" xf -; then
+                       eecho "tar failed to extract the image. tarball is corrupt? (${file})"
                        rm -fr portage
                        return 1
                fi
@@ -179,12 +196,12 @@ sync_local() {
                        --exclude='/local' ${PORTAGE_RSYNC_EXTRA_OPTS} . "${PORTDIR%%/}"
                cd ..
 
-               echo "Cleaning up..."
+               vecho "Cleaning up ..."
                rm -fr portage 
        fi
 
        if hasq metadata-transfer ${FEATURES} ; then
-               echo "Updating cache..."
+               vecho "Updating cache ..."
                emerge --metadata
        fi
        [ -x "${EPREFIX}"/etc/portage/bin/post_sync ] && "${EPREFIX}"/etc/portage/bin/post_sync
@@ -197,76 +214,92 @@ do_snapshot() {
 
        local r=1
 
-       local file="portage-${date}.tar.bz2"
-       local digest="${file}.md5sum"
-       local signature="${file}.gpgsig"
+       local base_file="portage-${date}.tar"
 
        local have_files=0
        local mirror
 
-       echo "Trying to retrieve ${date} snapshot..."
+       local compressions=""
+       type lzcat > /dev/null && compressions="${compressions} lzma"
+       type bzcat > /dev/null && compressions="${compressions} bz2"
+       type  zcat > /dev/null && compressions="${compressions} gz"
+       if [[ -z ${compressions} ]] ; then
+               eecho "unable to locate any decompressors (lzcat or bzcat or zcat)"
+               exit 1
+       fi
 
        for mirror in ${GENTOO_MIRRORS} ; do 
 
-               [ -s "${file}" -a -s "${digest}" -a -s "${signature}" ] && \
-                       check_file_digest "${digest}" "${file}" && \
-                       check_file_signature "${signature}" "${file}" && \
-                       have_files=1
-
-               [ ${have_files} == 0 ] && \
-                       fetch_file "${mirror}/snapshots/${digest}" "${digest}" && \
-                       fetch_file "${mirror}/snapshots/${signature}" "${signature}" && \
-                       fetch_file "${mirror}/snapshots/${file}" "${file}" && \
-                       check_file_digest "${digest}" "${file}" && \
-                       check_file_signature "${signature}" "${file}" && \
-                       have_files=1
-
-               #
-               # If timestamp is invalid
-               # we want to try and retieve
-               # from a different mirror
-               #
-               if [ ${have_files} != 0 ]; then
-
-                       echo "Getting snapshot timetasmp..."
-                       local snapshot_timestamp=$(get_snapshot_timestamp "${file}")
-
-                       if [ ${ignore_timestamp} == 0 ]; then
-                               if [ ${snapshot_timestamp} -lt $(get_portage_timestamp) ]; then
-                                       echo "Warning: Portage is newer than snapshot"
-                                       have_files=0
-                               fi
-                       else
-                               local utc_seconds=$(get_utc_second_from_string "${date}")
+               vecho "Trying to retrieve ${date} snapshot from ${mirror} ..."
 
-                               #
-                               # Check that this snapshot
-                               # is what it claims to be...
-                               #
-                               if [ ${snapshot_timestamp} -lt ${utc_seconds} ] || \
-                                       [ ${snapshot_timestamp} -gt $((${utc_seconds}+ 2*86400)) ]; then
+               for compression in ${compressions} ; do
+                       local file="portage-${date}.tar.${compression}"
+                       local digest="${file}.md5sum"
+                       local signature="${file}.gpgsig"
 
-                                       echo "Warning: Snapshot timestamp is not in acceptable period."
-                                       have_files=0
-                               fi
+                       if [ -s "${file}" -a -s "${digest}" -a -s "${signature}" ] ; then
+                               check_file_digest "${digest}" "${file}" && \
+                               check_file_signature "${signature}" "${file}" && \
+                               have_files=1
+                       fi
+
+                       if [ ${have_files} -eq 0 ] ; then
+                               fetch_file "${mirror}/snapshots/${digest}" "${digest}" && \
+                               fetch_file "${mirror}/snapshots/${signature}" "${signature}" && \
+                               fetch_file "${mirror}/snapshots/${file}" "${file}" && \
+                               check_file_digest "${digest}" "${file}" && \
+                               check_file_signature "${signature}" "${file}" && \
+                               have_files=1
                        fi
-               fi
 
-               if [ ${have_files} != 0 ]; then
-                       break;
-               else
                        #
-                       # Remove files and use
-                       # a diffeernt mirror
+                       # If timestamp is invalid
+                       # we want to try and retrieve
+                       # from a different mirror
                        #
-                       rm -f "${file}" "${digest}" "${signature}"
-               fi
+                       if [ ${have_files} -eq 1 ]; then
+
+                               vecho "Getting snapshot timetasmp ..."
+                               local snapshot_timestamp=$(get_snapshot_timestamp "${file}")
+
+                               if [ ${ignore_timestamp} == 0 ]; then
+                                       if [ ${snapshot_timestamp} -lt $(get_portage_timestamp) ]; then
+                                               wecho "portage is newer than snapshot"
+                                               have_files=0
+                                       fi
+                               else
+                                       local utc_seconds=$(get_utc_second_from_string "${date}")
+
+                                       #
+                                       # Check that this snapshot
+                                       # is what it claims to be ...
+                                       #
+                                       if [ ${snapshot_timestamp} -lt ${utc_seconds} ] || \
+                                               [ ${snapshot_timestamp} -gt $((${utc_seconds}+ 2*86400)) ]; then
+
+                                               wecho "snapshot timestamp is not in acceptable period"
+                                               have_files=0
+                                       fi
+                               fi
+                       fi
+
+                       if [ ${have_files} -eq 1 ]; then
+                               break
+                       else
+                               #
+                               # Remove files and use a different mirror
+                               #
+                               rm -f "${file}" "${digest}" "${signature}"
+                       fi
+               done
+
+               [ ${have_files} -eq 1 ] && break
        done
 
-       if [ ${have_files} != 0 ]; then
+       if [ ${have_files} -eq 1 ]; then
                sync_local "${file}" && r=0
        else
-               echo "Warning: ${date} snapshot was not found."
+               vecho "${date} snapshot was not found"
        fi
        
        rm -f "${file}" "${digest}" "${signature}"
@@ -277,7 +310,7 @@ do_latest_snapshot() {
        local attempts=-1
        local r=1
 
-       echo "Fetching most recent snapshot..."
+       vecho "Fetching most recent snapshot ..."
 
        while (( ${attempts} <  40 )) ; do
                local day
@@ -295,10 +328,9 @@ do_latest_snapshot() {
                utc_midnight=$(get_date_part $(expr ${utc_attempt} - ${utc_attempt} % 86400) "%s")
 
                if [ ${utc_midnight} -lt $(($(get_portage_timestamp)-86400)) ]; then
-                       echo "Note: Portage content is newer than available snapshots"
-                       echo "use --revert option to overide."
+                       wecho "portage content is newer than available snapshots (use --revert option to overide)"
                        r=0
-                       break;
+                       break
                fi
 
                if do_snapshot 0 "${year}${month}${day}"; then
@@ -310,42 +342,50 @@ do_latest_snapshot() {
        return "${r}"
 }
 
+usage() {
+       cat <<-EOF
+       Usage: $0 [options]
+       
+       Options:
+         --revert=yyyymmdd   Revert to snapshot
+         -q, --quiet         Only output errors
+         -v, --verbose       Enable verbose output
+         -x, --debug         Enable debug output
+         -h, --help          This help screen (duh!)
+       EOF
+       if [[ -n $* ]] ; then
+               printf "\nError: %s\n" "$*" 1>&2
+               exit 1
+       else
+               exit 0
+       fi
+}
+
 main() {
        local arg
-       local do_revert=0
        local revert_date
        
        [ ! -d "${DISTDIR}" ] && mkdir -p "${DISTDIR}"
        cd "${DISTDIR}"
 
-       for arg in $*; do
+       for arg in "$@" ; do
                local v=${arg#*=}
                case ${arg} in
-                       --help)
-                               echo "usage: $0 [options]"
-                               echo "        --verbose (-v)    - verbose"
-                               echo "        --revert=yyyymmdd - revert to snapshot"
-                               exit 0
-                       ;;
-                       --verbose|-v)
-                               do_verbose=1
-                       ;;
-                       --revert=*)
-                               do_revert=1
-                               revert_date=${v}
-                       ;;
-                       *)
-                               echo "Error: Invalid arguments"
-                               exit 1
-                       ;;
+                       -h|--help)    usage ;;
+                       -q|--quiet)   PORTAGE_QUIET=1 ;;
+                       -v|--verbose) do_verbose=1 ;;
+                       -x|--debug)   do_debug=1 ;;
+                       --revert=*)   revert_date=${v} ;;
+                       *)            usage "Invalid option '${arg}'" ;;
                esac
        done
+       [[ ${do_debug} -eq 1 ]] && set -x
 
-       if [ ${do_revert} != 0 ]; then
+       if [[ -n ${revert_date} ]] ; then
                do_snapshot 1 "${revert_date}"
        else
                do_latest_snapshot
        fi
 }
 
-main $*
+main "$@"
index 197f79be3859bdfc87151bafae5482d9b9a789c0..891d6ef8cbe9122a3a05a50f06f93bbdc049f716 100644 (file)
@@ -592,7 +592,7 @@ preinst_suid_scan() {
 #note not space-safe
                for i in $(find "${ED}" -type f \( -perm -4000 -o -perm -2000 \) ); do
                        if [ -s "${sfconf}" ]; then
-                               suid="$(grep "^${i/${D}}$" "${sfconf}")"
+                               suid="$(grep "^/${i#${D}}$" "${sfconf}")"
                                if [ "${suid}" = "${i/${D}}" ]; then
                                        vecho "- ${i/${D}} is an approved suid file"
                                else
index ae1dc01d3eba243dc67a7b2c2135ebde5624a735..43b118d4f072d7ce30e2aaac5c21a41a6e76cb06 100755 (executable)
@@ -7,6 +7,7 @@
 # Then, check to make sure deps are satisfiable (to avoid "can't find match for" problems)
 # that last one is tricky because multiple profiles need to be checked.
 
+import commands
 import codecs
 import errno
 import formatter
@@ -491,6 +492,9 @@ repodir = startdir
 for x in range(0, repolevel - 1):
        repodir = os.path.dirname(repodir)
 
+def caterror(mycat):
+       err(mycat+" is not an official category.  Skipping QA checks in this directory.\nPlease ensure that you add "+catdir+" to "+repodir+"/profiles/categories\nif it is a new category.")
+
 # retreive local USE list
 luselist={}
 try:
@@ -506,7 +510,7 @@ if portdir_overlay != portdir:
        if os.path.exists(filename):
                try:
                        f = open(filename)
-                       parse_use_local_desc(f, luselist)
+                       utilities.parse_use_local_desc(f, luselist)
                        f.close()
                except (IOError, OSError, ParseError), e:
                        logging.exception("Couldn't read from '%s'" % filename, e)
@@ -546,8 +550,34 @@ if portdir_overlay != portdir:
        kwlist.update(portage.grabfile(
                os.path.join(portdir_overlay, "profiles", "arch.list")))
 
-scanlist = utilities.FindPackagesToScan(repoman_settings, startdir, reposplit)
+scanlist=[]
+if repolevel==2:
+       #we are inside a category directory
+       catdir=reposplit[-1]
+       if catdir not in repoman_settings.categories:
+               caterror(catdir)
+       mydirlist=os.listdir(startdir)
+       for x in mydirlist:
+               if x == "CVS" or x.startswith("."):
+                       continue
+               if os.path.isdir(startdir+"/"+x):
+                       scanlist.append(catdir+"/"+x)
+elif repolevel==1:
+       for x in repoman_settings.categories:
+               if not os.path.isdir(startdir+"/"+x):
+                       continue
+               for y in os.listdir(startdir+"/"+x):
+                       if y == "CVS" or y.startswith("."):
+                               continue
+                       if os.path.isdir(startdir+"/"+x+"/"+y):
+                               scanlist.append(x+"/"+y)
+elif repolevel==3:
+       catdir = reposplit[-2]
+       if catdir not in repoman_settings.categories:
+               caterror(catdir)
+       scanlist.append(catdir+"/"+reposplit[-1])
 scanlist.sort()
+
 logging.debug("Found the following packages to scan:\n%s" % '\n'.join(scanlist))
 
 profiles={}
index f2015dfbfb39d75dc7b93914e19e319bbecbbcec..a87aa4515b85f9942cb8288117906ae11e3c2e22 100644 (file)
@@ -1456,6 +1456,7 @@ class depgraph(object):
                self._reinstall_nodes = {}
                self.mydbapi = {}
                self.trees = {}
+               self._trees_orig = trees
                self.roots = {}
                # Contains a filtered view of preferred packages that are selected
                # from available repositories.
@@ -2150,6 +2151,35 @@ class depgraph(object):
                                        cpv=mykey, metadata=metadata, onlydeps=onlydeps)
                                args.append(PackageArg(arg=x, package=pkg,
                                        root_config=root_config))
+                       elif x.startswith(os.path.sep):
+                               if not x.startswith(myroot):
+                                       portage.writemsg(("\n\n!!! '%s' does not start with" + \
+                                               " $ROOT.\n") % x, noiselevel=-1)
+                                       return 0, []
+                               relative_path = x[len(myroot):]
+                               vartree = self._trees_orig[myroot]["vartree"]
+                               owner_cpv = None
+                               for cpv in vardb.cpv_all():
+                                       self.spinner.update()
+                                       cat, pf = portage.catsplit(cpv)
+                                       if portage.dblink(cat, pf, myroot,
+                                               pkgsettings, vartree=vartree).isowner(
+                                               relative_path, myroot):
+                                               owner_cpv = cpv
+                                               break
+                               if owner_cpv is None:
+                                       portage.writemsg(("\n\n!!! '%s' is not claimed " + \
+                                               "by any package.\n") % x, noiselevel=-1)
+                                       return 0, []
+                               slot = vardb.aux_get(owner_cpv, ["SLOT"])[0]
+                               if not slot:
+                                       # portage now masks packages with missing slot, but it's
+                                       # possible that one was installed by an older version
+                                       atom = portage.cpv_getkey(owner_cpv)
+                               else:
+                                       atom = "%s:%s" % (portage.cpv_getkey(owner_cpv), slot)
+                               args.append(AtomArg(arg=atom, atom=atom,
+                                       root_config=root_config))
                        else:
                                if x in ("system", "world"):
                                        x = SETPREFIX + x
@@ -2520,6 +2550,8 @@ class depgraph(object):
                portdb = self.roots[root].trees["porttree"].dbapi
                dbs = self._filtered_trees[root]["dbs"]
                for db, pkg_type, built, installed, db_keys in dbs:
+                       if installed:
+                               continue
                        match = db.match
                        if hasattr(db, "xmatch"):
                                cpv_list = db.xmatch("match-all", atom)
@@ -3352,7 +3384,7 @@ class depgraph(object):
                                # have no parents and thus can not be part of a cycle.
                                while True:
                                        root_nodes = mygraph.root_nodes(
-                                               ignore_priority=DepPriority.SOFT)
+                                               ignore_priority=DepPriority.MEDIUM_SOFT)
                                        if not root_nodes:
                                                break
                                        for node in root_nodes:
index e9fad09566996d3ea7600f9b42afb1fb3e8d22c4..1937c4e1154cab7e6e4d0e456d1d51cdf32a2cad 100644 (file)
@@ -27,9 +27,6 @@ from itertools import izip
 class portdbapi(dbapi):
        """this tree will scan a portage directory located at root (passed to init)"""
        portdbapi_instances = []
-       _non_category_dirs = ["distfiles", "eclass", "licenses",
-               "local", "metadata", "packages", "profiles", "scripts"]
-       _non_category_dirs = re.compile(r'^(%s)$' % "|".join(_non_category_dirs))
        def __init__(self, porttree_root, mysettings=None):
                portdbapi.portdbapi_instances.append(self)
 
@@ -39,6 +36,7 @@ class portdbapi(dbapi):
                else:
                        from portage import settings
                        self.mysettings = config(clone=settings)
+               self._categories = set(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
@@ -486,11 +484,8 @@ class portdbapi(dbapi):
        def cp_all(self):
                "returns a list of all keys in our tree"
                d = {}
-               for oroot in self.porttrees:
-                       for x in listdir(oroot, EmptyOnError=1, ignorecvs=1, dirsonly=1):
-                               if not self._category_re.match(x) or \
-                                       self._non_category_dirs.match(x):
-                                       continue
+               for x in self.mysettings.categories:
+                       for oroot in self.porttrees:
                                for y in listdir(oroot+"/"+x, EmptyOnError=1, ignorecvs=1, dirsonly=1):
                                        if not self._pkg_dir_name_re.match(y) or \
                                                y == "CVS":
@@ -520,7 +515,7 @@ class portdbapi(dbapi):
                                        self.xcache["match-all"][mycp] = cachelist
                                return cachelist[:]
                mysplit = mycp.split("/")
-               invalid_category = not self._category_re.match(mysplit[0])
+               invalid_category = mysplit[0] not in self._categories
                d={}
                if mytree:
                        mytrees = [mytree]
index d3ecacee04104349bfed69a8eff85126d136ee81..6f5f3c9e0bf645866b25b9f50fdf427f987c9db2 100644 (file)
@@ -63,8 +63,10 @@ class PreservedLibsRegistry(object):
                """ Store the registry data to file. No need to call this if autocommit
                    was enabled.
                """
-               cPickle.dump(self._data, open(self._filename, "w"))
-       
+               f = atomic_ofstream(self._filename)
+               cPickle.dump(self._data, f)
+               f.close()
+
        def register(self, cpv, slot, counter, paths):
                """ Register new objects in the registry. If there is a record with the
                        same packagename (internally derived from cpv) and slot it is 
@@ -160,7 +162,8 @@ class LibraryPackageMap(object):
                                        else:
                                                obj_dict[lib].append(mysplit[0])
                mapfile = open(self._filename, "w")
-               for lib in obj_dict:
+               for lib in sorted(obj_dict):
+                       obj_dict[lib].sort()
                        mapfile.write(lib+" "+",".join(obj_dict[lib])+"\n")
                mapfile.close()
 
@@ -909,6 +912,7 @@ class dblink(object):
                self._installed_instance = None
                self.contentscache = None
                self._contents_inodes = None
+               self._contents_basenames = None
 
        def lockdb(self):
                if self._lock_vdb:
@@ -1510,6 +1514,16 @@ class dblink(object):
                if pkgfiles and destfile in pkgfiles:
                        return True
                if pkgfiles:
+                       basename = os.path.basename(destfile)
+                       if self._contents_basenames is None:
+                               self._contents_basenames = set(
+                                       os.path.basename(x) for x in pkgfiles)
+                       if basename not in self._contents_basenames:
+                               # This is a shortcut that, in most cases, allows us to
+                               # eliminate this package as an owner without the need
+                               # to examine inode numbers of parent directories.
+                               return False
+
                        # Use stat rather than lstat since we want to follow
                        # any symlinks to the real parent directory.
                        parent_path = os.path.dirname(destfile)
@@ -1545,7 +1559,6 @@ class dblink(object):
                        p_path_list = self._contents_inodes.get(
                                (parent_stat.st_dev, parent_stat.st_ino))
                        if p_path_list:
-                               basename = os.path.basename(destfile)
                                for p_path in p_path_list:
                                        x = os.path.join(p_path, basename)
                                        if x in pkgfiles:
@@ -2101,6 +2114,7 @@ class dblink(object):
                for dblnk in others_in_slot:
                        dblnk.contentscache = None
                        dblnk._contents_inodes = None
+                       dblnk._contents_basenames = None
 
                # If portage is reinstalling itself, remove the old
                # version now since we want to use the temporary
index 5f82b69b7492fd12db45526af163211b0c510e07..39cebdf842bd8b9a60784ae6208baecd1edae306 100644 (file)
@@ -9,6 +9,16 @@ from portage.const import USER_CONFIG_PATH, GLOBAL_CONFIG_PATH
 
 SETPREFIX = "@"
 
+def get_boolean(options, name, default):
+       if not name in options:
+               return default
+       elif options[name].lower() in ("1", "yes", "on", "true"):
+               return True
+       elif options[name].lower() in ("0", "no", "off", "false"):
+               return False
+       else:
+               raise SetConfigError("invalid value '%s' for option '%s'" % (options[name], name))
+
 class SetConfigError(Exception):
        pass
 
index 220ff2283498a44fc5c27d7c5b2b9178b3fad581..c4f974aa9fcfe0bb3ff47c9fac70b00b1ecd0865 100644 (file)
@@ -4,7 +4,7 @@
 
 from portage.versions import catsplit, catpkgsplit
 from portage.sets.base import PackageSet
-from portage.sets import SetConfigError
+from portage.sets import SetConfigError, get_boolean
 from portage.dbapi.vartree import dblink
 from portage.util import grabfile
 
@@ -65,10 +65,7 @@ class CategorySet(PackageSet):
        _builderGetRepository = classmethod(_builderGetRepository)
 
        def _builderGetVisible(cls, options):
-               visible = options.get("only_visible", "true").lower()
-               if visible not in ["1", "0", "yes", "no", "true", "false", "on", "off"]:
-                       raise SetConfigError("invalid value for only_visible: %s" % visible)
-               return bool(visible in ["1", "yes", "true", "on"])
+               return get_boolean(options, "only_visible", True)
        _builderGetVisible = classmethod(_builderGetVisible)
                
        def singleBuilder(cls, options, settings, trees):
@@ -176,9 +173,6 @@ class MissingLibraryConsumerSet(LibraryConsumerSet):
                self._setAtoms(self.mapPathsToAtoms(consumers))
        
        def singleBuilder(cls, options, settings, trees):
-               if options.get("debug", "true").lower() in ["true", "on", "1", "yes"]:
-                       debug = True
-               else:
-                       debug = False
+               debug = get_boolean(options, "debug", False)
                return MissingLibraryConsumerSet(trees["vartree"].dbapi, debug=debug)
        singleBuilder = classmethod(singleBuilder)
index 655391cc4db75231d0106756d8abec12f175304f..e11a36e4faf16ff1060579d6009984d85e1f5b08 100644 (file)
@@ -10,7 +10,7 @@ from portage.const import PRIVATE_PATH, USER_CONFIG_PATH
 from portage.locks import lockfile, unlockfile
 from portage import portage_gid
 from portage.sets.base import PackageSet, EditablePackageSet
-from portage.sets import SetConfigError, SETPREFIX
+from portage.sets import SetConfigError, SETPREFIX, get_boolean
 from portage.env.loaders import ItemFileLoader, KeyListFileLoader
 from portage.env.validators import ValidAtomValidator
 from portage import dep_getkey, cpv_getkey
@@ -20,12 +20,17 @@ __all__ = ["StaticFileSet", "ConfigFileSet", "WorldSet"]
 class StaticFileSet(EditablePackageSet):
        _operations = ["merge", "unmerge"]
        
-       def __init__(self, filename):
+       def __init__(self, filename, greedy=False, dbapi=None):
                super(StaticFileSet, self).__init__()
                self._filename = filename
                self._mtime = None
                self.description = "Package set loaded from file %s" % self._filename
                self.loader = ItemFileLoader(self._filename, self._validate)
+               if greedy and not dbapi:
+                       self.errors.append("%s configured as greedy set, but no dbapi instance passed in constructor" % self._filename)
+                       greedy = False
+               self.greedy = greedy
+               self.dbapi = dbapi
 
                metadata = grabfile(self._filename + ".metadata")
                key = None
@@ -69,13 +74,26 @@ class StaticFileSet(EditablePackageSet):
                                        raise
                                del e
                                data = {}
-                       self._setAtoms(data.keys())
+                       if self.greedy:
+                               atoms = []
+                               for a in data.keys():
+                                       matches = self.dbapi.match(a)
+                                       for cpv in matches:
+                                               atoms.append("%s:%s" % (cpv_getkey(cpv),
+                                                       self.dbapi.aux_get(cpv, ["SLOT"])[0]))
+                                       # In addition to any installed slots, also try to pull
+                                       # in the latest new slot that may be available.
+                                       atoms.append(a)
+                       else:
+                               atoms = data.keys()
+                       self._setAtoms(atoms)
                        self._mtime = mtime
                
        def singleBuilder(self, options, settings, trees):
                if not "filename" in options:
                        raise SetConfigError("no filename specified")
-               return ConfigFileSet(options[filename])
+               greedy = get_boolean(options, "greedy", True)
+               return StaticFileSet(options["filename"], greedy=greedy, dbapi=trees["vartree"].dbapi)
        singleBuilder = classmethod(singleBuilder)
        
        def multiBuilder(self, options, settings, trees):
@@ -84,13 +102,14 @@ class StaticFileSet(EditablePackageSet):
                name_pattern = options.get("name_pattern", "sets/$name")
                if not "$name" in name_pattern and not "${name}" in name_pattern:
                        raise SetConfigError("name_pattern doesn't include $name placeholder")
+               greedy = get_boolean(options, "greedy", True)
                if os.path.isdir(directory):
                        for filename in os.listdir(directory):
                                if filename.endswith(".metadata"):
                                        continue
                                myname = name_pattern.replace("$name", filename)
                                myname = myname.replace("${name}", filename)
-                               rValue[myname] = StaticFileSet(os.path.join(directory, filename))
+                               rValue[myname] = StaticFileSet(os.path.join(directory, filename), greedy=greedy, dbapi=trees["vartree"].dbapi)
                return rValue
        multiBuilder = classmethod(multiBuilder)
        
@@ -108,7 +127,7 @@ class ConfigFileSet(PackageSet):
        def singleBuilder(self, options, settings, trees):
                if not "filename" in options:
                        raise SetConfigError("no filename specified")
-               return ConfigFileSet(options[filename])
+               return ConfigFileSet(options["filename"])
        singleBuilder = classmethod(singleBuilder)
        
        def multiBuilder(self, options, settings, trees):
index f93b34ef88fc74d4eccc88c0216a8d6eb4f38582..928fecbcfb68f08a0b7dcbba15a00b6ee7582d86 100644 (file)
@@ -7,6 +7,7 @@ import portage.glsa as glsa
 from portage.util import grabfile, write_atomic
 from portage.sets.base import PackageSet
 from portage.versions import catpkgsplit, pkgcmp
+from portage.sets import get_boolean
 
 __all__ = ["SecuritySet", "NewGlsaSet", "NewAffectedSet", "AffectedSet"]
 
@@ -69,11 +70,7 @@ class SecuritySet(PackageSet):
                                myglsa.inject()
        
        def singleBuilder(cls, options, settings, trees):
-               if "use_emerge_resoler" in options \
-                               and options.get("use_emerge_resolver").lower() in ["1", "yes", "true", "on"]:
-                       least_change = False
-               else:
-                       least_change = True
+               least_change = not get_boolean(options, "use_emerge_resolver", False)
                return cls(settings, trees["vartree"].dbapi, trees["porttree"].dbapi, least_change=least_change)
        singleBuilder = classmethod(singleBuilder)
        
index ea16c5cffc92b9dcd7c9873be4163d563dd85a3f..2cbcfb74593eb0cfdeda281a79d7eff09454f598 100644 (file)
@@ -169,7 +169,7 @@ def stack_dicts(dicts, incremental=0, incrementals=[], ignore_none=0):
                if final_dict is None:
                        final_dict = {}
                for y in mydict.keys():
-                       if mydict[y]:
+                       if True:
                                if final_dict.has_key(y) and (incremental or (y in incrementals)):
                                        final_dict[y] += " "+mydict[y][:]
                                else:
index 4282f2a9aa50cc7ca709f0b8594b017dbb6fa762..fc31afc88bf17e211063717a31db61789456c86a 100644 (file)
@@ -317,12 +317,12 @@ def FindPortdir(settings):
 
        location = normalize_path(location)
 
-       path_ids = set()
+       path_ids = {}
        p = location
        s = None
        while True:
                s = os.stat(p)
-               path_ids.add((s.st_dev, s.st_ino))
+               path_ids[(s.st_dev, s.st_ino)] = p
                if p == "/":
                        break
                p = os.path.dirname(p)
@@ -335,10 +335,12 @@ def FindPortdir(settings):
                        s = os.stat(overlay)
                except OSError:
                        continue
-               overlay_id = (s.st_dev, s.st_ino)
+               overlay = path_ids.get((s.st_dev, s.st_ino))
+               if overlay is None:
+                       continue
                if overlay[-1] != "/":
                        overlay += "/"
-               if overlay_id in path_ids:
+               if True:
                        portdir_overlay = overlay
                        subdir = location[len(overlay):]
                        if subdir and subdir[-1] != "/":