summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAli Polatel <hawking@gentoo.org>2008-06-20 17:46:02 +0000
committerAli Polatel <hawking@gentoo.org>2008-06-20 17:46:02 +0000
commitce0e380e3a91d437277fdd03336eeb56a6e73491 (patch)
treea9150ceaea946577817fddb1547e5e2efc33a23c
parentAdded ChangeLog (diff)
downloadpython-updater-ce0e380e3a91d437277fdd03336eeb56a6e73491.tar.gz
python-updater-ce0e380e3a91d437277fdd03336eeb56a6e73491.tar.bz2
python-updater-ce0e380e3a91d437277fdd03336eeb56a6e73491.zip
Splitted checks. Respect PYUPDATER_OPTIONS. Bashified tests. Added man page.
-rw-r--r--ChangeLog26
-rw-r--r--Makefile25
-rw-r--r--man.include60
-rwxr-xr-xpython-updater340
4 files changed, 355 insertions, 96 deletions
diff --git a/ChangeLog b/ChangeLog
index d83e6f5..d209dc3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,32 +3,40 @@ ChangeLog for python-updater
This file lists all changes except typo and formatting fixes.
-2008-01-04 Ali Polatel <hawking@gentoo.org>
+2008-06-20 Ali Polatel
- * ChangeLog: Added ChangeLog
+ * python-updater, +man.include, +Makefile: Splitted checks and added
+ command line options for them. Added new tests eclass and soname.
+ Respect PYUPDATER_OPTIONS environment variable for default command
+ line options. Bashified tests. Added man page and Makefile to do
+ common tasks. Fixed ChangeLog.
-2008-01-04 Ali Polatel <hawking@gentoo.org>
+2008-01-04 Ali Polatel
- * AUTHORS: Added AUTHORS
+ * +ChangeLog: Added ChangeLog
-2007-12-13 Ali Polatel <hawking@gentoo.org>
+2008-01-04 Ali Polatel
+
+ * +AUTHORS: Added AUTHORS
+
+2007-12-13 Ali Polatel
* python-updater: Don't ignore versions when SLOT doesn't exist,
bug 201848
-2007-11-04 Ali Polatel <hawking@gentoo.org>
+2007-11-04 Ali Polatel
* python-updater: be more specific when searching for package name
-2007-10-29 Ali Polatel <hawking@gentoo.org>
+2007-10-29 Ali Polatel
* python-updater: added dev-libs/boost to PKGS_MANUAL
-2007-10-29 Ali Polatel <hawking@gentoo.org>
+2007-10-29 Ali Polatel
* python-updater: imported python-updater from gentoo-python
-2007-10-29 Ali Polatel <hawking@gentoo.org>
+2007-10-29 Ali Polatel
* .: added projects/python-updater
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..885ae36
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,25 @@
+# Makefile for python-updater
+MAN_INCLUDE=man.include
+VERSION=$(shell ./python-updater -V)
+FILES=AUTHORS ChangeLog python-updater python-updater.1
+PKGDIR=python-updater-$(VERSION)
+TARBALL=$(PKGDIR)-tar.bz2
+
+all: python-updater.1 tarball
+
+python-updater.1: python-updater $(MAN_INCLUDE)
+ help2man -L en_GB.UTF-8 -Ni $(MAN_INCLUDE) ./python-updater -o $@
+ sed -i -e 's/ in the manpage//' $@
+
+.PHONY: all clean tarball upload
+clean:
+ rm -fr python-updater.1 *.bz2 $(PKGDIR) || true
+tarball:
+ mkdir $(PKGDIR)
+ cp $(FILES) $(PKGDIR)
+ tar cjf $(TARBALL) $(PKGDIR)
+ rm -fr $(PKGDIR)
+upload:
+ scp $(TARBALL) dev.gentoo.org:/space/distfiles-local
+ ssh dev.gentoo.org chmod ug+rw dev.gentoo.org:/space/distfiles-local/$(TARBALL)
+
diff --git a/man.include b/man.include
new file mode 100644
index 0000000..33d52c7
--- /dev/null
+++ b/man.include
@@ -0,0 +1,60 @@
+[CHECKS]
+pylibdir
+ Find packages that installed files under old python library dir,
+ /usr/lib/python$old/site-packages where $old is old python version
+ Enabled by default.
+
+soname
+ Find packages that have files linked to old libpython (requires pax-utils)
+ Enabled by default.
+
+eclass
+ Find packages that inherited python.eclass and set PYVER to old
+ python version. The packages found by this check may not be
+ broken.
+ Disabled by default.
+
+manual
+ python-updater has a list of packages that are known to break
+ by python upgrades but can't be determined by methods specified
+ above. This check can be disabled if you're sure you've rebuilt
+ the package once and it's OK now.
+ Enabled by default.
+
+Checks can be enabled/disabled on command line with -e/--enable and -d/--disable
+switches.
+
+See EXAMPLES for a list examples.
+
+See ENVIRONMENT on how to set default options to override
+[COPYRIGHT]
+Copyright (c) 2007-2008 Gentoo Foundation
+Distributed under the terms of the GNU General Public License v2
+[REPORTING BUGS]
+Submit bug reports to https://bugs.gentoo.org/
+[AUTHORS]
+Bryan Østergaard "kloeri" <bryan.ostergaard@gmail.com>
+ Wrote main code
+
+Ali Polatel "hawking" <hawking@gentoo.org>
+ Current maintainer
+[EXAMPLES]
+
+* Rebuild packages after a python upgrade. Default options are just fine ;)
+
+ $> python-updater
+
+* Rebuild packages omitting manually added ones:
+
+ $> python-updater -dmanual
+ $> python-updater -disable-manual
+
+* You can use unique substrings instead of names for checks:
+
+ $> python-updater -dm -ep
+ $> python-updater --disable-m --enable-pylib
+
+[ENVIRONMENT]
+
+PYUPDATER_OPTIONS
+ Default command line options
diff --git a/python-updater b/python-updater
index 1c9d247..4fd5559 100755
--- a/python-updater
+++ b/python-updater
@@ -1,5 +1,8 @@
#!/bin/bash
-# vim: set et sw=4 sts=4 :
+# vim: set et sw=4 sts=4 tw=80:
+# Copyright 2007-2008 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
# A bit of hackery to update everything that is humanly possible
# that maybe related to an older version of python. This script can
# be run as many times as you like.
@@ -20,19 +23,15 @@
# PKGS_MASKED = list of packages that are installed, but masked.
#
+VERSION="0.5"
NEW_PY_VER=$(python -V 2>&1 | sed 's:Python ::' | cut -d. -f1-2)
PKGS_EXCEPTIONS="dev-lang/python sys-apps/portage"
PKGS_MANUAL="app-office/gnumeric app-office/dia dev-libs/boost x11-libs/vte"
-# portage variables
-PKG_DBDIR=/var/db/pkg
-PORTDIR=`portageq portdir`
-PORTDIR_OVERLAYS=`portageq portdir_overlay`
-
PRETEND=0
-DIRECT_ONLY=0
IGNORE_VERSIONS=0
+VERBOSE=0
PKGS_TO_REMERGE=""
PKGS_COUNT_REMERGE=0
PORTAGE_PYTHON="/usr/bin/python"
@@ -41,51 +40,146 @@ SUPPORTED_PMS="portage pkgcore paludis"
PMS_COMMAND=( "emerge" "pmerge" "paludis" )
PMS_OPTIONS=( "-vD1" "-Do" "-i1" )
+# Checks
+CHECK_ECLASS=0
+CHECK_MANUAL=1
+CHECK_PYLIBDIR=1
+CHECK_SONAME=1
+
# load the gentoo-style info macros, but hack to get around
# it thinking this is an rc script
EBUILD="1"
source /etc/init.d/functions.sh
+# portage variables
+PKG_DBDIR=/var/db/pkg
+
+# usage()
+# display usage
usage() {
- echo "usage: python-updater [-h|-p|-o X.X]"
- echo " --help, -h help"
- echo " --pretend, -p pretend (don't do anything)"
- echo " --old-version, -o X.X set old python version to upgrade from [default: ${OLD_PY_VER}]"
- echo " --ignore-versions, -i ignore versions when remerging packages (still respects SLOTs)"
- echo " --direct-only don't consider indirect aka manually added packages"
- echo " --package-manager, -P name select between ${SUPPORTED_PMS} [default: portage]"
+ cat <<EOF_USAGE
+${0##*/} -- Find & rebuild packages broken due to a python upgrade
+
+Usage: python-updater [OPTION]
+
+Options:
+ -h, --help Print usage
+ -V, --version Print version
+ -p, --pretend Pretend (don't do anything)
+ -v, --verbose Increase verbosity (may be specified multiple times)
+ -o PYVER, --old-version PYVER
+ Set old python version to upgrade from to PYVER
+ -i, --ignore-versions
+ Ignore versions when remerging packages
+ (still respects SLOTs)
+ -P PM, --package-manager PM
+ Select between ${SUPPORTED_PMS} [default: portage]
+ -c CMD, --command CMD
+ Pipe found packages to command CMD instead of invoking package
+ manager. Only for debug and script use.
+ -eCHECK --enable-CHECK
+ Enable CHECK
+ -dCHECK --disable-CHECK
+ Disable CHECK
+
+See CHECKS section in the manpage for a list of checks and EXAMPLES section to
+learn how to use them.
+EOF_USAGE
}
-#
-# Sanity check
-#
+# veinfo(verbosity, message)
+# einfo message if VERBOSE is bigger than verbosity
+veinfo() {
+ if [[ VERBOSE > $1 ]]; then
+ shift
+ einfo $@
+ fi
+}
-if [ -z "${PORTDIR}" ]; then
- eerror "Unable to proceed. Can not find PORTDIR. Make sure the command:"
- eerror " "
- eerror " portageq portdir"
- eerror " "
- eerror "returns a value. If it doesn't, make sure you have updated to"
- eerror "latest portage version."
- eerror " "
- eerror "Report bugs to http://bugs.gentoo.org/"
- exit 1
-fi
+# get_old_pyver()
+# Find old python version, return non-zero if not found
+get_old_pyver() {
+ for old in 2.5 2.4 2.3 2.2 2.1; do
+ if [[ "${old}" != "${NEW_PY_VER}" ]]; then
+ if [[ -e /usr/bin/python${old} ]]; then
+ echo -n "${old}"
+ return 0
+ fi
+ fi
+ done
+ eerror "Couldn't determine any previous Python version(s)."
+ return 1
+}
+
+# get_portage_python(oldpy=2.4,newpy=2.5)
+# Find where portage is, in python2.2 or somewhere else?
+get_portage_python() {
+ local oldpy newpy
+ if [[ ! -z "$1" ]]; then
+ oldpy="$1"
+ else
+ oldpy=2.4
+ fi
+
+ if [ ! -z "$2" ]; then
+ newpy="$2"
+ else
+ newpy=2.5
+ fi
+
+ pybin=/usr/bin/python
+ for py in ${pybin} ${pybin}${oldpy} ${pybin}${newpy}; do
+ if ${py} -c "import portage" > /dev/null 2>&1; then
+ echo -n "${py}"
+ return 0
+ fi
+ done
+ eerror "Could't determine portage python"
+ return 1
+}
+
+# get_portage_portdir()
+# Check if portage knows about PORTDIR and return it
+get_portage_portdir() {
+ local portdir="$(/usr/bin/portageq portdir)"
+
+ if [[ -z "${portdir}" ]]; then
+ eerror "Unable to proceed. Can not find PORTDIR. Make sure the command:"
+ eerror " "
+ eerror " portageq portdir"
+ eerror "returns a value. If it doesn't, make sure you have updated to"
+ eerror "latest portage version."
+ eerror " "
+ eerror "Report bugs to http://bugs.gentoo.org/"
+ return 1
+ else
+ echo -n "${portdir}"
+ return 0
+ fi
+}
+
+# Respect PYUPDATER_OPTIONS
+if [[ -n "${PYUPDATER_OPTIONS}" ]]; then
+ set -- ${PYUPDATER_OPTIONS} $@
+fi
-#
-#
# Command Line Parsing
-#
-#
-while [ -n "$1" ]; do
+while [[ -n "$1" ]]; do
case "$1" in
-h|--help)
usage
exit 0
;;
+ -V|--version)
+ echo "${VERSION}"
+ exit 0
+ ;;
-p|--pretend)
PRETEND=1
;;
+ -v|--verbose)
+ VERBOSE=$(( $VERBOSE + 1 ))
+ ;;
-o|--old-version)
shift
OLD_PY_VER="$1"
@@ -93,9 +187,6 @@ while [ -n "$1" ]; do
-i|--ignore-versions)
IGNORE_VERSIONS=1
;;
- --direct-only)
- DIRECT_ONLY=1
- ;;
-P|--package-manager)
shift
PACKAGE_MANAGER="$1"
@@ -107,7 +198,7 @@ while [ -n "$1" ]; do
exit
;;
esac
-
+
# PMS_INDEX is used to select the right commands and options for the selected package manager
PMS_INDEX=0
for PM in ${SUPPORTED_PMS}; do
@@ -115,7 +206,35 @@ while [ -n "$1" ]; do
PMS_INDEX=$((${PMS_INDEX} + 1))
done
;;
- *)
+ -c|--command)
+ shift
+ PIPE_COMMAND="$1"
+ ;;
+ -ee*|--enable-e*)
+ CHECK_ECLASS=1
+ ;;
+ -de*|--disable-e*)
+ CHECK_ECLASS=0
+ ;;
+ -em*|--enable-m*)
+ CHECK_MANUAL=1
+ ;;
+ -dm*|--disable-m*)
+ CHECK_MANUAL=0
+ ;;
+ -ep*|--enable-p*)
+ CHECK_PYLIBDIR=1
+ ;;
+ -dp*|--disable-p*)
+ CHECK_PYLIBDIR=0
+ ;;
+ -es*|--enable-s*)
+ CHECK_SONAME=1
+ ;;
+ -ds*|--disable-s*)
+ CHECK_SONAME=0
+ ;;
+ *)
usage
echo "unrecognised option: $1"
exit 0
@@ -124,67 +243,72 @@ while [ -n "$1" ]; do
shift
done
+# Sanity check
+PORTDIR="$(get_portage_portdir)"
+[[ $? != 0 ]] && exit 1
+
# Determine old python version
if [[ -z "${OLD_PY_VER}" ]]; then
- for old in 2.5 2.4 2.3 2.2 2.1; do
- if [ "${old}" != "${NEW_PY_VER}" ]; then
- if [ -e /usr/bin/python${old} ] ; then
- OLD_PY_VER=${old}
- break;
- fi
- fi
- done
-fi
-
-
-if [ -z "${OLD_PY_VER}" ] ; then
- eerror "Can't determine any previous Python version(s)."
- exit 1
+ OLD_PY_VER="$(get_old_pyver)"
+ if [[ $? -ne 0 ]]; then
+ exit 1
+ fi
fi
-#
-# Test where portage is, in python2.2 or somewhere else?
-#
-for py in /usr/bin/python /usr/bin/python${OLD_PY_VER} /usr/bin/python${NEW_PY_VER}; do
- if ${py} -c "import portage" > /dev/null 2>&1; then
- PORTAGE_PYTHON=${py}
- break;
- fi
-done
+# Get portage python
+PORTAGE_PYTHON="$(get_portage_python ${OLD_PY_VER} ${NEW_PY_VER})"
+[[ $? != 0 ]] && exit 1
-#
-#
-# Find all packages that have installed something in
-# /usr/lib/python${OLD_PY_VER}
-#
-#
-OLD_MODULES_DIRS="/usr/lib/python${OLD_PY_VER} /usr/lib32/python${OLD_PY_VER} /usr/lib64/python${OLD_PY_VER}"
-OLD_INCLUDE_DIR=/usr/include/python${OLD_PY_VER}
einfo "Starting Python Updater from ${OLD_PY_VER} to ${NEW_PY_VER} :"
-einfo "Searching for packages with files in ${OLD_MODULES_DIRS} .."
+if [[ CHECK_SONAME -ne 0 ]]; then
+ if ! type -P scanelf >/dev/null 2>&1; then
+ ewarn "scanelf not found!"
+ ewarn "check soname is disabled."
+ CHECK_SONAME=0
+ else
+ veinfo 1 'check "soname" enabled.'
+ OLD_SONAME="$(readlink -n /usr/lib/libpython${OLD_PY_VER}.so)"
+ if [[ -z "${OLD_SONAME}" ]]; then
+ ewarn "Couldn't find old libpython soname"
+ ewarn "Disabling soname check."
+ CHECK_SONAME=0
+ fi
+ fi
+else
+ veinfo 1 'check "soname" disabled.'
+fi
+[[ CHECK_PYLIBDIR -ne 0 ]] \
+ && veinfo 1 'check "pylibdir" enabled.' \
+ || veinfo 1 'check "pylibdir" disabled.'
+[[ CHECK_ECLASS -ne 0 ]] \
+ && veinfo 1 'check "eclass" enabled.' \
+ || veinfo 1 'check "eclass" disabled.'
+[[ CHECK_MANUAL -ne 0 ]] \
+ && veinfo 1 'check "manual" enabled.' \
+ || veinfo 1 'check "manual" disabled.'
# iterate thru all the installed package's contents
for content in `find ${PKG_DBDIR} -name CONTENTS`; do
# extract the category, package name and package version
CATPKGVER=$(echo ${content} | sed "s:${PKG_DBDIR}/\(.*\)/CONTENTS:\1:")
CATPKG="${CATPKGVER%%-[0-9]*}"
+ veinfo 2 "Checking ${CATPKGVER}"
# exclude packages that are an exception, like portage and python itself.
exception=0
for exp in ${PKGS_EXCEPTIONS}; do
- if [ -z "${CATPKG##${exp}}" ]; then
+ if [[ -z "${CATPKG##${exp}}" ]]; then
+ veinfo 2 "Skipping ${CATPKG}, reason: exception"
exception=1
break;
fi
done
-
- if [ ${exception} = 1 ]; then
- continue;
- fi
-
+
+ [[ ${exception} == 1 ]] && continue
+
# Check if package is in PKGS_MANUAL
- if [[ DIRECT_ONLY -ne 1 ]]; then
+ if [[ CHECK_MANUAL -ne 0 ]]; then
for pkg in ${PKGS_MANUAL}; do
if [ -z "${CATPKG##${pkg}}" ]; then
exception=2
@@ -192,7 +316,7 @@ for content in `find ${PKG_DBDIR} -name CONTENTS`; do
fi
done
fi
-
+
# replace version number by SLOT if IGNORE_VERSIONS != 0
# Don't ignore versions when SLOT doesn't exist, bug 201848
if [[ IGNORE_VERSIONS -ne 0 && -f "${content/CONTENTS/SLOT}" ]]; then
@@ -201,23 +325,65 @@ for content in `find ${PKG_DBDIR} -name CONTENTS`; do
else
CATPKGVER="=${CATPKGVER}"
fi
-
- if [ ${exception} = 2 ]; then
+
+ if [[ ${exception} = 2 ]]; then
PKGS_TO_REMERGE="${PKGS_TO_REMERGE} ${CATPKGVER}"
- einfo "Adding to list (manually): ${CATPKGVER}"
- continue;
+ eindent
+ einfo "Adding to list: ${CATPKGVER}"
+ veinfo 1 "check: manual [Added to list manually]"
+ eoutdent
+ continue
fi
-
- for OLD_MODULES_DIR in ${OLD_MODULES_DIRS}; do
- if fgrep "${OLD_MODULES_DIR}" ${content} > /dev/null; then
+
+ if [[ CHECK_PYLIBDIR -ne 0 ]]; then
+ # Search for possible old python dirs in CONTENTS
+ # /usr/include/python$old
+ # /usr/lib/python$old
+ # /usr/lib32/python$old
+ # /usr/lib64/python$old
+ if grep -qe "/usr/\(include\|lib\(32\|64\)\?\)/python${OLD_PY_VER}" ${content}; then
PKGS_TO_REMERGE="${PKGS_TO_REMERGE} ${CATPKGVER}"
+ eindent
einfo "Adding to list: ${CATPKGVER}"
- elif fgrep "${OLD_INCLUDE_DIR}" ${content} > /dev/null; then
+ veinfo 1 "check: pylibdir [ Installed file under old python library directory ]"
+ eoutdent
+ continue
+ fi
+ fi
+
+ if [[ CHECK_SONAME -ne 0 ]]; then
+ broken_libs="$(scanelf -qBN ${OLD_SONAME} < <(
+ grep -e '^obj' ${content} | cut -d' ' -f2))"
+ if [[ -n "${broken_libs}" ]]; then
PKGS_TO_REMERGE="${PKGS_TO_REMERGE} ${CATPKGVER}"
+ eindent
+ einfo "Adding to list: ${CATPKGVER}"
+ veinfo 1 "check: soname [ Libraries linked to old libpython found:"
+ veinfo 1 "${broken_libs}"
+ veinfo 1 "]"
+ eoutdent
fi
- done
+ fi
+
+ if [[ CHECK_ECLASS -ne 0 ]]; then
+ ENVIRON="${content/CONTENTS/environment.bz2}"
+ if bzip2 -dc ${ENVIRON} | grep -qe "^\(export \)\?PYVER=${OLD_PY_VER}"; then
+ PKGS_TO_REMERGE="${PKGS_TO_REMERGE} ${CATPKGVER}"
+ eindent
+ einfo "Adding to list: ${CATPKGVER}"
+ veinfo 1 "check: environ [ Ebuild set PYVER=${OLD_PY_VER} ]"
+ eoutdent
+ continue
+ fi
+ fi
done
+# Pipe to command if we have one
+if [[ -n "${PIPE_COMMAND}" ]]; then
+ echo "${PKGS_TO_REMERGE}" | ${PIPE_COMMAND}
+ exit $?
+fi
+
# only pretending?
[[ PRETEND -eq 1 ]] && PMS_OPTIONS[${PMS_INDEX}]="${PMS_OPTIONS[${PMS_INDEX}]}p"