diff options
| -rw-r--r-- | bin/eclean | 54 | ||||
| -rwxr-xr-x | bin/euse | 7 | ||||
| -rw-r--r-- | bin/glsa-check | 45 | ||||
| -rwxr-xr-x | bin/revdep-rebuild | 46 | ||||
| -rw-r--r-- | pym/gentoolkit/helpers2.py | 8 | ||||
| -rw-r--r-- | pym/gentoolkit/package.py | 2 |
6 files changed, 115 insertions, 47 deletions
@@ -1,8 +1,9 @@ -#!/usr/bin/env python +#!/usr/bin/python # Copyright 2003-2005 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Header: $ +from __future__ import with_statement ############################################################################### # Meta: @@ -15,6 +16,7 @@ __description__ = "A cleaning tool for Gentoo distfiles and binaries." ############################################################################### # Python imports: + import sys import os, stat import re @@ -502,12 +504,13 @@ def exclDictMatch(excl_dict,pkg): # findDistfiles: find all obsolete distfiles. # XXX: what about cvs ebuilds? i should install some to see where it goes... def findDistfiles( \ + myoptions, \ exclude_dict={}, \ destructive=False,\ fetch_restricted=False, \ package_names=False, \ time_limit=0, \ - size_limit=0): + size_limit=0,): # this regexp extracts files names from SRC_URI. It is not very precise, # but we don't care (may return empty strings, etc.), since it is fast. file_regexp = re.compile('([a-zA-Z0-9_,\.\-\+\~]*)[\s\)]') @@ -548,7 +551,12 @@ def findDistfiles( \ except KeyError: continue del pkg_list - # create a dictionary of files which should be deleted + # create a dictionary of files which should be deleted + if not (os.path.isdir(distdir)): + eerror("%s does not appear to be a directory." % distdir, myoptions['nocolor']) + eerror("Please set DISTDIR to a sane value.", myoptions['nocolor']) + eerror("(Check your /etc/make.conf and environment).", myoptions['nocolor']) + exit(1) for file in os.listdir(distdir): filepath = os.path.join(distdir, file) try: file_stat = os.stat(filepath) @@ -589,12 +597,19 @@ def findDistfiles( \ # XXX: packages are found only by symlinks. Maybe i should also return .tbz2 # files from All/ that have no corresponding symlinks. def findPackages( \ + myoptions, \ exclude_dict={}, \ destructive=False, \ time_limit=0, \ package_names=False): clean_dict = {} - # create a full package dictionnary + # create a full package dictionary + + if not (os.path.isdir(pkgdir)): + eerror("%s does not appear to be a directory." % pkgdir, myoptions['nocolor']) + eerror("Please set PKGDIR to a sane value.", myoptions['nocolor']) + eerror("(Check your /etc/make.conf and environment).", myoptions['nocolor']) + exit(1) for root, dirs, files in os.walk(pkgdir): if root[-3:] == 'All': continue for file in files: @@ -631,7 +646,7 @@ def findPackages( \ del clean_dict[mycpv] continue if portage.cpv_getkey(mycpv) in cp_all: - # exlusion because of --package-names + # exlusion because of --package-names del clean_dict[mycpv] return clean_dict @@ -673,7 +688,12 @@ def doCleanup(clean_dict,action,myoptions): "Do you want to delete this " \ + file_type+"?"): # non-interactive mode or positive answer. - # For each file,... + # For each file, try to delete the file and clean it out + # of Packages metadata file + if action == 'packages': + metadata = portage.getbinpkg.PackageIndex() + with open(os.path.join(pkgdir, 'Packages')) as metadata_file: + metadata.read(metadata_file) for file in clean_dict[mykey]: # ...get its size... filesize = 0 @@ -683,11 +703,21 @@ def doCleanup(clean_dict,action,myoptions): except: eerror("Could not read size of "\ +file, myoptions['nocolor']) # ...and try to delete it. - try: os.unlink(file) - except: eerror("Could not delete "+file, \ - myoptions['nocolor']) + try: + os.unlink(file) + except: + eerror("Could not delete "+file, \ + myoptions['nocolor']) # only count size if successfully deleted - else: clean_size += filesize + else: + clean_size += filesize + if action == 'packages': + metadata.packages[:] = [p for p in metadata.packages if 'CPV' in p and p['CPV'] != file] + + if action == 'packages': + with open(os.path.join(pkgdir, 'Packages'), 'w') as metadata_file: + metadata.write(metadata_file) + # return total size of deleted or to delete files return clean_size @@ -704,13 +734,15 @@ def doAction(action,myoptions,exclude_dict={}): einfo("Building file list for "+action+" cleaning...", \ myoptions['nocolor']) if action == 'packages': - clean_dict = findPackages( \ + clean_dict = findPackages( + myoptions, \ exclude_dict=exclude_dict, \ destructive=myoptions['destructive'], \ package_names=myoptions['package-names'], \ time_limit=myoptions['time-limit']) else: clean_dict = findDistfiles( \ + myoptions, \ exclude_dict=exclude_dict, \ destructive=myoptions['destructive'], \ fetch_restricted=myoptions['fetch-restricted'], \ @@ -346,7 +346,7 @@ showinstdesc() { local current_desc local args local -i foundone=0 - local IFS + local OIFS="$IFS" args=("${@:-*}") @@ -376,7 +376,7 @@ showinstdesc() { echo "$desc" # get list of installed packages matching this USE flag. IFS=$'\n' - packages=($(equery -q -C hasuse -i "${1}" | awk '{ print $(NF-1) }')) + packages=($(equery -q -C hasuse -i "${1}" | awk '{ print $(NF-1) }' | sort)) foundone+=${#packages[@]} printf "\nInstalled packages matching this USE flag: " if [ ${foundone} -gt 0 ]; then @@ -396,7 +396,9 @@ showinstdesc() { # exit status of equery instead of a subshell and pipe to wc -l if [ $(equery -q -C list -i -e "${pkg}" | wc -l) -gt 0 ]; then foundone=1 + IFS="$OIFS" get_flagstatus "${flag}" + IFS=': ' printf "%s (%s):\n%s\n\n" "${flag}" "${pkg}" "${desc#- }" fi done < <(grep ":${1} *-" "${descdir}/use.local.desc") @@ -408,6 +410,7 @@ showinstdesc() { if [ ${foundone} -lt 1 ]; then echo "no matching entries found" fi + IFS="$OIFS" } # show a list of all currently active flags and where they are activated diff --git a/bin/glsa-check b/bin/glsa-check index 1fb577d..0ce133e 100644 --- a/bin/glsa-check +++ b/bin/glsa-check @@ -16,7 +16,7 @@ try: except ImportError: from output import * -from getopt import getopt,GetoptError +from getopt import getopt, GetoptError __program__ = "glsa-check" __author__ = "Marius Mauch <genone@gentoo.org>" @@ -81,10 +81,10 @@ try: # sanity checking if len(args) <= 0: sys.stderr.write("no option given: what should I do ?\n") - mode="help" + mode = "HELP" elif len(args) > 1: sys.stderr.write("please use only one command per call\n") - mode = "help" + mode = "HELP" else: # in what mode are we ? args = args[0] @@ -95,32 +95,37 @@ try: except GetoptError, e: sys.stderr.write("unknown option given: ") sys.stderr.write(str(e)+"\n") - mode = "help" + mode = "HELP" # we need a set of glsa for most operation modes if len(params) <= 0 and mode in ["fix", "test", "pretend", "dump", "inject", "mail"]: sys.stderr.write("\nno GLSA given, so we'll do nothing for now. \n") sys.stderr.write("If you want to run on all GLSA please tell me so \n") sys.stderr.write("(specify \"all\" as parameter)\n\n") - mode = "help" + mode = "HELP" elif len(params) <= 0 and mode == "list": params.append("new") # show help message -if mode == "help": - sys.stderr.write("\nSyntax: glsa-check <option> [glsa-list]\n\n") +if mode == "help" or mode == "HELP": + msg = "Syntax: glsa-check <option> [glsa-list]\n\n" for m in optionmap: - sys.stderr.write(m[0] + "\t" + m[1] + " \t: " + m[-1] + "\n") + msg += m[0] + "\t" + m[1] + " \t: " + m[-1] + "\n" for o in m[2:-1]: - sys.stderr.write("\t" + o + "\n") - sys.stderr.write("\nglsa-list can contain an arbitrary number of GLSA ids, \n") - sys.stderr.write("filenames containing GLSAs or the special identifiers \n") - sys.stderr.write("'all', 'new' and 'affected'\n") - sys.exit(1) + msg += "\t" + o + "\n" + msg += "\nglsa-list can contain an arbitrary number of GLSA ids, \n" + msg += "filenames containing GLSAs or the special identifiers \n" + msg += "'all', 'new' and 'affected'\n" + if mode == "help": + sys.stdout.write(msg) + sys.exit(0) + else: + sys.stderr.write("\n" + msg) + sys.exit(1) # we need root priviledges for write access if mode in ["fix", "inject"] and os.geteuid() != 0: - sys.stderr.write("\nThis tool needs root access to "+mode+" this GLSA\n\n") + sys.stderr.write(__program__ + ": root access is needed for \""+mode+"\" mode\n") sys.exit(2) # show version and copyright information @@ -219,7 +224,7 @@ def summarylist(myglsalist, fd1=sys.stdout, fd2=sys.stderr): fd1.write("... ") else: for pkg in myglsa.packages.keys(): - mylist = vardb.match(portage.dep_getkey(pkg)) + mylist = vardb.match(portage.dep_getkey(str(pkg))) if len(mylist) > 0: pkg = color(" ".join(mylist)) fd1.write(" " + pkg + " ") @@ -227,7 +232,7 @@ def summarylist(myglsalist, fd1=sys.stdout, fd2=sys.stderr): fd1.write(")") if list_cve: fd1.write(" "+(",".join([r[:13] for r in myglsa.references if r[:4] in ["CAN-", "CVE-"]]))) - fd1.write("\n") + fd1.write("\n") return 0 if mode == "list": @@ -261,6 +266,8 @@ if mode in ["dump", "fix", "inject", "pretend"]: exitcode >>= 8 if exitcode: sys.exit(exitcode) + if len(mergelist): + sys.stdout.write("\n") myglsa.inject() elif mode == "pretend": sys.stdout.write("Checking GLSA "+myid+"\n") @@ -278,10 +285,10 @@ if mode in ["dump", "fix", "inject", "pretend"]: sys.stdout.write(" " + pkg + " (" + oldver + ")\n") else: sys.stdout.write("Nothing to do for this GLSA\n") + sys.stdout.write("\n") elif mode == "inject": sys.stdout.write("injecting " + myid + "\n") myglsa.inject() - sys.stdout.write("\n") sys.exit(0) # test is a bit different as Glsa.test() produces no output @@ -323,12 +330,12 @@ if mode == "mail": # color doesn't make any sense for mail nocolor() - if glsaconfig.has_key("PORTAGE_ELOG_MAILURI"): + if "PORTAGE_ELOG_MAILURI" in glsaconfig: myrecipient = glsaconfig["PORTAGE_ELOG_MAILURI"].split()[0] else: myrecipient = "root@localhost" - if glsaconfig.has_key("PORTAGE_ELOG_MAILFROM"): + if "PORTAGE_ELOG_MAILFROM" in glsaconfig: myfrom = glsaconfig["PORTAGE_ELOG_MAILFROM"] else: myfrom = "glsa-check" diff --git a/bin/revdep-rebuild b/bin/revdep-rebuild index fac03d8..72efba0 100755 --- a/bin/revdep-rebuild +++ b/bin/revdep-rebuild @@ -123,6 +123,7 @@ rm() { eerror "I was instructed to rm '$@'" die 1 "Refusing to delete anything before changing to temporary directory." } +: <<'EW' ## # GNU find has -executable, but if our users' finds do not have that flag # we emulate it with this function. Also emulates -writable and -readable. @@ -158,6 +159,7 @@ find() { fi find "$@" } +EW print_usage() { cat << EOF @@ -222,7 +224,7 @@ countdown() { # Replace whitespace with linebreaks, normalize repeated '/' chars, and sort -u # (If any libs have whitespace in their filenames, someone needs punishment.) clean_var() { - awk 'BEGIN {RS="[[:space:]]"} + gawk 'BEGIN {RS="[[:space:]]"} /-\*/ {exit} /[^[:space:]]/ {gsub(/\/\/+/, "/"); print}' | sort -u } @@ -633,8 +635,8 @@ get_files() { findMask="${findMask[@]/#/-o -path }" findMask="( ${findMask#-o } ) -prune -o" fi - # TODO: Check this - find ${SEARCH_DIRS[@]} $findMask -type f \( -executable -o \ + # TODO: Check this -- afaict SEARCH_DIRS isn't an array, so this should just be $SEARCH_DIRS? + find ${SEARCH_DIRS[@]} $findMask -type f \( -perm -u+x -o -perm -g+x -o -perm -o+x -o \ -name '*.so' -o -name '*.so.*' -o -name '*.la' \) -print 2> /dev/null | sort -u > "$FILES_FILE" || die $? "find failed to list binary files (This is a bug.)" @@ -735,18 +737,39 @@ main_checks() { fi elif [[ $SEARCH_BROKEN ]]; then # Look for broken .la files + la_SEARCH_DIRS="$SEARCH_DIRS" + la_search_dir="" + la_broken="" + la_lib="" for depend in $( - awk -F"[=']" '/^dependency_libs/{ - gsub("^-[^[:space:]]*", "", $3); - gsub("[[:space:]]-[^[:space:]]*", "", $3); + gawk -F"[=']" '/^dependency_libs/{ print $3 }' "$target_file" ); do if [[ $depend = /* && ! -e $depend ]]; then echo "obj $target_file" >> "$BROKEN_FILE" echo_v " broken $target_file (requires $depend)" + elif [[ $depend = -[LR]/* ]]; then + if ! [[ $'\n'${la_SEARCH_DIRS}$'\n' == *$'\n'${depend#-?}$'\n'* ]]; then + la_SEARCH_DIRS+=$'\n'"${depend#-?}" + fi + elif [[ $depend = "-l"* ]]; then + la_lib="lib${depend#-l}" + la_broken="yes" + IFS=$'\n' + for la_search_dir in $la_SEARCH_DIRS; do + if [[ -e ${la_search_dir}/${la_lib}.so || -e ${la_search_dir}/${la_lib}.a ]]; then + la_broken="no" + fi + done + IFS="$OIFS" + if [[ $la_broken = yes ]]; then + echo "obj $target_file" >> "$BROKEN_FILE" + echo_v " broken $target_file (requires $depend)" + fi fi done + unset la_SEARCH_DIRS la_search_dir la_broken la_lib fi [[ $VERBOSE ]] && progress $((++i)) $numFiles $target_file || @@ -760,7 +783,7 @@ main_checks() { done < <( # Regexify LD_LIBRARY_MASK. Exclude it from the search. LD_LIBRARY_MASK="${LD_LIBRARY_MASK//$'\n'/|}" - awk -v ldmask="(${LD_LIBRARY_MASK//./\\\.})" ' + gawk -v ldmask="(${LD_LIBRARY_MASK//./\\\.})" ' /no version information available/ && $0 !~ ldmask { gsub(/[()]/, "", $NF) if (seen[$NF]++) next @@ -945,7 +968,7 @@ show_unowned_files() { ewarn "The broken files are:" while read filename junk; do [[ $junk = *none* ]] && ewarn " $filename" - done < "$OWNERS_FILE" | awk '!s[$0]++' # (omit dupes) + done < "$OWNERS_FILE" | gawk '!s[$0]++' # (omit dupes) fi } ## @@ -1080,8 +1103,11 @@ cleanup() { einfo 'Build finished correctly. Removing temporary files...' einfo einfo 'You can re-run revdep-rebuild to verify that all libraries and binaries' - einfo 'are fixed. If some inconsistency remains, it can be orphaned file, deep' - einfo 'dependency, binary package or specially evaluated library.' + einfo 'are fixed. Possible reasons for remaining inconsistencies include:' + einfo ' orphaned files' + einfo ' deep dependencies' + einfo " packages installed outside of portage's control" + einfo ' specially-evaluated libraries' if [[ -r "$OWNERS_FILE" && -s "$OWNERS_FILE" ]]; then show_unowned_files fi diff --git a/pym/gentoolkit/helpers2.py b/pym/gentoolkit/helpers2.py index 20d1de0..1a2530a 100644 --- a/pym/gentoolkit/helpers2.py +++ b/pym/gentoolkit/helpers2.py @@ -132,6 +132,8 @@ def uses_globbing(query): def _do_complex_lookup(query, query_opts): """Find matches for a query which is a regex or includes globbing.""" + # pylint: Too many branches (18/12) + # pylint: disable-message=R0912 result = [] if query_opts["includeInstalled"]: @@ -240,8 +242,6 @@ def _do_simple_lookup(query, query_opts): def do_lookup(query, query_opts): """A high-level wrapper around gentoolkit package-finder functions. - @todo: equery modules to move to do_lookup: c,m,u,w - @type query: str @param query: pkg, cat/pkg, pkg-ver, cat/pkg-ver, atom or regex @type query_opts: dict @@ -401,9 +401,9 @@ def prepare_categories(category_filter): def split_query(query): - """Split a query, using either. + """Split a query into category, name, version and revision. - @see: split_atom, gentoolkit.split_package_name + @type query: str @param query: pkg, cat/pkg, pkg-ver, cat/pkg-ver, atom or regex @rtype: tuple @return: (category, pkg_name, version, revision) diff --git a/pym/gentoolkit/package.py b/pym/gentoolkit/package.py index 65cdb9a..340a512 100644 --- a/pym/gentoolkit/package.py +++ b/pym/gentoolkit/package.py @@ -465,7 +465,7 @@ class Package(object): """ if not self._db: self._db = portage.dblink( - category, + self.category, "%s-%s" % (self.name, self.fullversion), settings["ROOT"], settings |
