Merged from trunk 7984:7994
authorFabian Groffen <grobian@gentoo.org>
Mon, 8 Oct 2007 17:23:10 +0000 (17:23 -0000)
committerFabian Groffen <grobian@gentoo.org>
Mon, 8 Oct 2007 17:23:10 +0000 (17:23 -0000)
   | 7985     | Fix package.license support so that SLOT atoms will work.   |
   | zmedico  |                                                             |

   | 7986     | Bug #194552 - Include EAPI in the binary package metadata   |
   | zmedico  | index.                                                      |

   | 7987     | In PackageIndex.readBody(), make each package entry inherit |
   | zmedico  | CHOST from the header.                                      |

   | 7988     | In PackageIndex.write(), skip writing the CHOST for a       |
   | zmedico  | package entry if it's CHOST matches the header.             |

   | 7989     | Fix binarytree.populate() so that it properly caches all    |
   | zmedico  | the metadata necessary for visibility filtering.            |

   | 7990     | add QA check for .pyc/.pyo files in /usr/share              |
   | SpankMan |                                                             |

   | 7991     | add support for .lzma / .tar.lzma to unpack                 |
   | SpankMan |                                                             |

   | 7992     | unify diff_command handling                                 |
   | SpankMan |                                                             |

   | 7993     | add standard --help/--version options                       |
   | SpankMan |                                                             |

   | 7994     | add --debug option and display a message about skipping     |
   | SpankMan | non-files so we dont get confusing loops where portage      |
   |          | claims there are things to update but etc-update claims     |
   |          | there are not                                               |

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

bin/ebuild.sh
bin/etc-update
bin/misc-functions.sh
pym/emerge/__init__.py
pym/portage/__init__.py
pym/portage/dbapi/bintree.py
pym/portage/dbapi/porttree.py
pym/portage/getbinpkg.py

index 644a2d7e0854c5834a1c1717893f503133f07683..24714aa480241e962807ec80310aa6133d67e153 100755 (executable)
@@ -396,6 +396,14 @@ unpack() {
                        a)
                                ar x "${srcdir}/${x}" || die "$myfail"
                                ;;
+                       lzma)
+                               if [ "${y}" == "tar" ]; then
+                                       lzma -dc "${srcdir}${x}" | tar xof - ${tar_opts}
+                                       assert "$myfail"
+                               else
+                                       lzma -dc "${srcdir}${x}" > ${x%.*} || die "$myfail"
+                               fi
+                               ;;
                        *)
                                vecho "unpack ${x}: file format not recognized. Ignoring."
                                ;;
index 4ca47a510d46e684a8e7a8598bc3966b3d80f0d3..8121ddbc3a54536edadb432896d698016cd488ba 100755 (executable)
@@ -34,8 +34,12 @@ get_config() {
                "${PORTAGE_CONFIGROOT}"etc/etc-update.conf)
 }
 
-scan() {
+diff_command() {
+       local cmd=${diff_command//%file1/$1}
+       ${cmd//%file2/$2}
+}
 
+scan() {
        echo "Scanning Configuration files..."
        rm -rf ${TMP}/files > /dev/null 2>&1
        mkdir ${TMP}/files || die "Failed mkdir command!" 1
@@ -44,12 +48,6 @@ scan() {
        local find_opts
        local my_basename
 
-       # Sanity check to make sure diff exists and works
-       if ! diff -v &>/dev/null ; then
-               echo "ERROR: 'diff' does not seem to work, aborting"
-               exit 1
-       fi
-
        for path in ${CONFIG_PROTECT} ; do
                path="${EROOT}${path}"
                find_opts="-iname ._cfg????_*"
@@ -65,6 +63,7 @@ scan() {
                for file in $(set -f; find ${path}/ ${find_opts} ! -iname '.*~' ! -iname '.*.bak' |
                           sed -e "s:\(^.*/\)\(\._cfg[0-9]*_\)\(.*$\):\1\2\3\%\2\%\3:" |
                           sort -t'%' -k3 -k2 | LANG=POSIX LC_ALL=POSIX cut -f1 -d'%'); do
+
                        rpath=$(echo "${file/\/\///}" | sed -e "s:/[^/]*$::")
                        rfile=$(echo "${file/\/\///}" | sed -e "s:^.*/::")
                        for mpath in ${CONFIG_PROTECT_MASK}; do
@@ -75,8 +74,10 @@ scan() {
                                        break
                                fi
                        done
-                       [ ! -f ${file} ] && continue
-
+                       if [[ ! -f ${file} ]] ; then
+                               echo "Skipping non-file ${file} ..."
+                               continue
+                       fi
 
                        if [[ "${ofile:10}" != "${rfile:10}" ]] ||
                           [[ ${opath} != ${rpath} ]]; then
@@ -312,17 +313,14 @@ do_cfg() {
                elif [[ "${DELETE_ALL}" == "yes" ]] && ! user_special "${ofile}"; then
                        my_input=2
                else
-                       showdiffcmd=$(echo "${diff_command}" |
-                               sed -e "s:%file1:${ofile}:" -e "s:%file2:${file}:")
-
                        if [ "${using_editor}" == 0 ]; then
                                (
                                        echo "Showing differences between ${ofile} and ${file}"
-                                       ${showdiffcmd}
+                                       diff_command "${ofile}" "${file}"
                                ) | ${pager}
                        else
                                echo "Beginning of differences between ${ofile} and ${file}"
-                               ${showdiffcmd}
+                               diff_command "${ofile}" "${file}"
                                echo "End of differences between ${ofile} and ${file}"
                        fi
                        if [ -L "${file}" ]; then
@@ -415,9 +413,7 @@ Please select from the menu above (-1 to exit, losing this merge): "
                                   return 255
                                   ;;
                                2) ( echo "Showing differences between ${ofile} and ${mfile}"
-                                        $(echo "${diff_command}" | \
-                                         sed -e "s:%file1:${ofile}:" \
-                                                 -e "s:%file2:${mfile}:") ) | ${pager}
+                                        diff_command "${ofile}" "${mfile}" ) | ${pager}
                                   continue
                                   ;;
                                3) break
@@ -451,10 +447,38 @@ die() {
        exit ${2}
 }
 
+usage() {
+       cat <<-EOF
+       etc-update: Handle configuration file updates
+
+       Usage: etc-update [options]
+
+       Options:
+         -d, --debug    Enable shell debugging
+         -h, --help     Show help and run away
+         -V, --version  Show version and trundle away
+       EOF
+
+       [[ -n ${*:2} ]] && printf "\nError: %s\n" "${*:2}" 1>&2
+
+       exit ${1:-0}
+}
+
 #
 # Run the script
 #
-scriptname=$(basename $0)
+
+SET_X=false
+while [[ -n $1 ]] ; do
+       case $1 in
+               -d|--debug)   SET_X=true;;
+               -h|--help)    usage;;
+               -V|--version) echo '$Id$'; exit 0;;
+               *)            usage 1 "Invalid option '$1'";;
+       esac
+       shift
+done
+${SET_X} && set -x
 
 type portageq > /dev/null || exit $?
 eval $(portageq envvar -v CONFIG_PROTECT \
@@ -493,8 +517,17 @@ diff_command=$(get_config diff_command)
 using_editor=$(get_config using_editor)
 merge_command=$(get_config merge_command)
 declare -i mode=$(get_config mode)
-[ -z ${mode} ] && mode=0
-[ -z "${pager}" ] && pager="cat"
+[[ -z ${mode} ]] && mode=0
+[[ -z ${pager} ]] && pager="cat"
+
+# Sanity check to make sure diff exists and works
+echo > "${TMP}"/.diff-test-1
+echo > "${TMP}"/.diff-test-2
+
+if ! diff_command "${TMP}"/.diff-test-1 "${TMP}"/.diff-test-2 &> /dev/null ; then
+       echo "ERROR: '${diff_command}' does not seem to work, aborting"
+       exit 1
+fi
 
 #echo "rm_opts: $rm_opts, mv_opts: $mv_opts, cp_opts: $cp_opts"
 #echo "pager: $pager, diff_command: $diff_command, merge_command: $merge_command"
index b62d0bd039557b240e9de274bef1b47372532b38..9aa0e512ddfaa3e2f3fe7390e9e7f23f78eb68d0 100644 (file)
@@ -401,6 +401,16 @@ install_qa_check() {
                [[ ${abort} == "yes" ]] && hasq stricter ${FEATURES} && die "poor code kills airplanes"
        fi
 
+       # Compiled python objects do not belong in /usr/share (FHS violation)
+       # and can be a pain when upgrading python
+       f=$(find "${ED}"/usr/share -name '*.py[co]')
+       if [[ -n ${f} ]] ; then
+               vecho -ne '\a\n'
+               eqawarn "QA Notice: Precompiled python object files do not belong in /usr/share"
+               eqawarn "${f}"
+               vecho -ne '\a\n'
+       fi
+
        # Portage regenerates this on the installed system.
        rm -f "${ED}"/usr/share/info/dir{,.gz,.bz2}
 
index d7aca4850d71267bfe16b8f077089d62daac52be..062f87c5b2ff367e6b96893a43801356c30669f0 100644 (file)
@@ -1914,6 +1914,7 @@ class depgraph(object):
                                                        print "!!! One of the following masked packages is required to complete your request:"
                                                        oldcomment = ""
                                                        shown_licenses = []
+                                                       portdb_keys = ["LICENSE","SLOT"]
                                                        for p in alleb:
                                                                mreasons = portage.getmaskingstatus(p,
                                                                        settings=pkgsettings, portdb=portdb)
@@ -1928,19 +1929,20 @@ class depgraph(object):
                                                                                print comment
                                                                                oldcomment = comment
                                                                try:
-                                                                       licenses = portdb.aux_get(p, ["LICENSE"])[0]
+                                                                       metadata = dict(izip(portdb_keys,
+                                                                               portdb.aux_get(p, portdb_keys)))
                                                                except KeyError:
                                                                        # Corruption will have been reported above.
                                                                        continue
-                                                               uselist = []
-                                                               if "?" in licenses:
+                                                               metadata["USE"] = ""
+                                                               if "?" in metadata["LICENSE"]:
                                                                        pkgsettings.setcpv(p, mydb=portdb)
-                                                                       uselist = pkgsettings.get("USE", "").split()
+                                                                       metadata["USE"] = pkgsettings.get("USE", "")
                                                                missing_licenses = []
                                                                try:
                                                                        missing_licenses = \
                                                                                pkgsettings.getMissingLicenses(
-                                                                                       licenses, p, uselist)
+                                                                                       p, metadata)
                                                                except portage.exception.InvalidDependString:
                                                                        # This will have already been reported
                                                                        # above via mreasons.
index 88662b704723d09c76d0b8bed82897c0968b7fc4..e29e15338efa00a3f5bbb7a0ca1cc1a29e1e3198 100644 (file)
@@ -1843,19 +1843,17 @@ class config(object):
                if has_changed:
                        self.reset(keeping_pkg=1,use_cache=use_cache)
 
-       def getMissingLicenses(self, licenses, cpv, uselist):
+       def getMissingLicenses(self, cpv, metadata):
                """
                Take a LICENSE string and return a list any licenses that the user may
                may need to accept for the given package.  The returned list will not
                contain any licenses that have already been accepted.  This method
                can throw an InvalidDependString exception.
 
-               @param licenses: A raw LICENSE string as returned form dbapi.aux_get()
-               @type licenses: String
                @param cpv: The package name (for package.license support)
                @type cpv: String
-               @param uselist: A list of flags for evaluation of USE conditionals
-               @type uselist: List
+               @param metadata: A dictionary of raw package metadata
+               @type metadata: dict
                @rtype: List
                @return: A list of licenses that have not been accepted.
                """
@@ -1865,11 +1863,12 @@ class config(object):
                cpdict = self._plicensedict.get(dep_getkey(cpv), None)
                if cpdict:
                        acceptable_licenses = self._accept_license.copy()
-                       for atom in match_to_list(cpv, cpdict.keys()):
+                       cpv_slot = "%s:%s" % (cpv, metadata["SLOT"])
+                       for atom in match_to_list(cpv_slot, cpdict.keys()):
                                acceptable_licenses.update(cpdict[atom])
-               license_struct = portage.dep.paren_reduce(licenses)
+               license_struct = portage.dep.paren_reduce(metadata["LICENSE"])
                license_struct = portage.dep.use_reduce(
-                       license_struct, uselist=uselist)
+                       license_struct, uselist=metadata["USE"].split())
                license_struct = portage.dep.dep_opconvert(license_struct)
                return self._getMissingLicenses(license_struct, acceptable_licenses)
 
@@ -5032,8 +5031,8 @@ def getmaskingstatus(mycpv, settings=None, portdb=None):
 
        # keywords checking
        try:
-               mygroups, licenses, eapi = portdb.aux_get(
-                       mycpv, ["KEYWORDS", "LICENSE", "EAPI"])
+               eapi, mygroups, licenses, slot = portdb.aux_get(
+                       mycpv, ["EAPI", "KEYWORDS", "LICENSE", "SLOT"])
        except KeyError:
                # The "depend" phase apparently failed for some reason.  An associated
                # error message will have already been printed to stderr.
@@ -5093,13 +5092,13 @@ def getmaskingstatus(mycpv, settings=None, portdb=None):
        if kmask:
                rValue.append(kmask+" keyword")
 
-       uselist = []
+       use = ""
        if "?" in licenses:
                settings.setcpv(mycpv, mydb=portdb)
-               uselist = settings.get("USE", "").split()
+               use = settings.get("USE", "")
        try:
                missing_licenses = settings.getMissingLicenses(
-                       licenses, mycpv, uselist)
+                       mycpv, {"LICENSE":licenses, "SLOT":slot, "USE":use})
                if missing_licenses:
                        allowed_tokens = set(["||", "(", ")"])
                        allowed_tokens.update(missing_licenses)
index 9e32971a097c3d9f38817bfc9ddcded21aad20d2..d2d645e86dea3ccafb2355eaf40c0459e7434f83 100644 (file)
@@ -15,6 +15,7 @@ from portage import dep_expand, listdir, _movefile
 import portage.xpak, portage.getbinpkg
 
 import os, errno, stat
+from itertools import izip
 
 class bindbapi(fakedbapi):
        def __init__(self, mybintree=None, settings=None):
@@ -27,7 +28,8 @@ class bindbapi(fakedbapi):
                self.settings = settings
                self._match_cache = {}
                # Selectively cache metadata in order to optimize dep matching.
-               self._aux_cache_keys = set(["CHOST","EAPI","SLOT","EPREFIX"])
+               self._aux_cache_keys = set(
+                       ["CHOST", "EAPI", "KEYWORDS", "LICENSE", "SLOT", "EPREFIX"])
                self._aux_cache = {}
 
        def match(self, *pargs, **kwargs):
@@ -136,12 +138,14 @@ class binarytree(object):
                        self.invalids = []
                        self.settings = settings
                        self._pkg_paths = {}
+                       self._populating = False
                        self._all_directory = os.path.isdir(
                                os.path.join(self.pkgdir, "All"))
                        self._pkgindex_version = 0
                        self._pkgindex_hashes = ["MD5","SHA1"]
                        self._pkgindex_file = os.path.join(self.pkgdir, "Packages")
-                       self._pkgindex_keys = set(["CPV", "SLOT", "MTIME", "SIZE"])
+                       self._pkgindex_keys = self.dbapi._aux_cache_keys.copy()
+                       self._pkgindex_keys.update(["CPV", "MTIME", "SIZE"])
                        self._pkgindex_header_keys = set(["ACCEPT_KEYWORDS", "CBUILD",
                                "CHOST", "CONFIG_PROTECT", "CONFIG_PROTECT_MASK", "FEATURES",
                                "GENTOO_MIRRORS", "INSTALL_MASK", "SYNC", "USE"])
@@ -324,16 +328,20 @@ class binarytree(object):
 
        def populate(self, getbinpkgs=0, getbinpkgsonly=0):
                "populates the binarytree"
+               if self._populating:
+                       return
                from portage.locks import lockfile, unlockfile
                pkgindex_lock = None
                try:
                        if os.access(self.pkgdir, os.W_OK):
                                pkgindex_lock = lockfile(self._pkgindex_file,
                                        wantnewlockfile=1)
+                       self._populating = True
                        self._populate(getbinpkgs, getbinpkgsonly)
                finally:
                        if pkgindex_lock:
                                unlockfile(pkgindex_lock)
+                       self._populating = False
 
        def _populate(self, getbinpkgs=0, getbinpkgsonly=0):
                if (not os.path.isdir(self.pkgdir) and not getbinpkgs):
@@ -343,6 +351,7 @@ class binarytree(object):
 
                if not getbinpkgsonly:
                        pkg_paths = {}
+                       self._pkg_paths = pkg_paths
                        dirs = listdir(self.pkgdir, dirsonly=True, EmptyOnError=True)
                        if "All" in dirs:
                                dirs.remove("All")
@@ -491,6 +500,11 @@ class binarytree(object):
                                        d["SLOT"] = slot
                                        d["MTIME"] = str(long(s.st_mtime))
                                        d["SIZE"] = str(s.st_size)
+
+                                       aux_keys = list(self.dbapi._aux_cache_keys)
+                                       d.update(izip(aux_keys,
+                                               self.dbapi.aux_get(mycpv, aux_keys)))
+
                                        # record location if it's non-default
                                        if mypath != mycpv + ".tbz2":
                                                d["PATH"] = mypath
@@ -503,7 +517,6 @@ class binarytree(object):
                                                        aux_cache[k] = d[k]
                                                self.dbapi._aux_cache[mycpv] = aux_cache
 
-                       self._pkg_paths = pkg_paths
                        # Do not bother to write the Packages index if $PKGDIR/All/ exists
                        # since it will provide no benefit due to the need to read CATEGORY
                        # from xpak.
@@ -511,6 +524,8 @@ class binarytree(object):
                                stale = [cpv for cpv in metadata if cpv not in self._pkg_paths]
                                for cpv in stale:
                                        del metadata[cpv]
+                               #
+                               self._update_pkgindex_header(pkgindex.header)
                                from portage.util import atomic_ofstream
                                f = atomic_ofstream(self._pkgindex_file)
                                try:
@@ -709,7 +724,7 @@ class binarytree(object):
                        # record location if it's non-default
                        if rel_path != cpv + ".tbz2":
                                d["PATH"] = rel_path
-                       keys = ["USE", "IUSE", "DESCRIPTION", "LICENSE", "PROVIDE", \
+                       keys = ["USE", "IUSE", "DESCRIPTION", "EAPI", "LICENSE", "PROVIDE", \
                                "RDEPEND", "DEPEND", "PDEPEND"]
                        from itertools import izip
                        d.update(izip(keys, self.dbapi.aux_get(cpv, keys)))
index 03550033ab2d09b198c3439e7db76568c5920d34..3990a827e986bff5ff50cd3c8e5ce80ed999c057 100644 (file)
@@ -728,13 +728,13 @@ class portdbapi(dbapi):
                                        hasstable = True
                        if not match and ((hastesting and "~*" in pgroups) or (hasstable and "*" in pgroups) or "**" in pgroups):
                                match=1
-                       uselist = []
+                       use = ""
                        if "?" in licenses:
                                self.doebuild_settings.setcpv(mycpv, mydb=self)
-                               uselist = self.doebuild_settings.get("USE", "").split()
+                               use = self.doebuild_settings.get("USE", "")
                        try:
-                               if self.mysettings.getMissingLicenses(
-                                       licenses, mycpv, uselist):
+                               if self.mysettings.getMissingLicenses(mycpv,
+                                       {"LICENSE":licenses, "SLOT":slot, "USE":use}):
                                        match = 0
                        except InvalidDependString:
                                match = 0
index 1362b1707d2328e1bd80aac441e747313f30656e..79820256a4ebcf00ac9edcda79ce8707b8cf031a 100644 (file)
@@ -678,6 +678,7 @@ class PackageIndex(object):
                self.header.update(readpkgindex(pkgfile))
 
        def readBody(self, pkgfile):
+               header_chost = self.header.get("CHOST")
                while True:
                        d = readpkgindex(pkgfile)
                        if not d:
@@ -685,7 +686,10 @@ class PackageIndex(object):
                        mycpv = d.get("CPV")
                        if not mycpv:
                                continue
+                       d.setdefault("EAPI", "0")
                        d.setdefault("SLOT", "0")
+                       if header_chost:
+                               d.setdefault("CHOST", header_chost)
                        self.packages[mycpv] = d
 
        def write(self, pkgfile):
@@ -697,8 +701,13 @@ class PackageIndex(object):
                keys = self.header.keys()
                keys.sort()
                writepkgindex(pkgfile, [(k, self.header[k]) for k in keys])
+               header_chost = self.header.get("CHOST")
                for cpv in cpv_all:
                        metadata = self.packages[cpv].copy()
+                       if metadata.get("CHOST") == header_chost:
+                               del metadata["CHOST"]
+                       if metadata.get("EAPI") == "0":
+                               del metadata["EAPI"]
                        if metadata.get("SLOT") == "0":
                                del metadata["SLOT"]
                        if metadata.get("USE") == "":