|
|
#!/bin/sh |
#!/bin/bash |
# Copyright 1999-2005 Gentoo Foundation |
# Copyright 1999-2007 Gentoo Foundation |
# $Header$ |
|
| |
# revdep-rebuild: Reverse dependency rebuilder. | # revdep-rebuild: Reverse dependency rebuilder. |
# Original Author: Stanislav Brabec | # Original Author: Stanislav Brabec |
# Current Maintainer: Paul Varner <fuzzyray@gentoo.org> | # Current Maintainer: Paul Varner <fuzzyray@gentoo.org> |
| |
# Known problems: |
# TODO: |
# |
# - Implement /etc/init.d/functions.sh |
# In exact ebuild mode revdep-rebuild can fail to properly order packages, |
# - These problems seem to have been fixed. Test. |
# which are not up to date. |
# - http://bugs.gentoo.org/show_bug.cgi?id=23018 |
# http://bugs.gentoo.org/show_bug.cgi?id=23018 |
# - http://bugs.gentoo.org/show_bug.cgi?id=4698 |
# |
|
# Rebuilding using --package-names mode should be default, but emerge has no |
|
# feature to update to latest version of defined SLOT. |
|
# http://bugs.gentoo.org/show_bug.cgi?id=4698 |
|
| |
# Customizable variables: | # Customizable variables: |
# | # |
|
|
| |
-h, --help Print this usage | -h, --help Print this usage |
-k, --keep-temp Do not delete temporary files on exit | -k, --keep-temp Do not delete temporary files on exit |
-X, --package-names Emerge based on package names, not exact versions |
-e, --exact Emerge based on exact package version |
-L, --library NAME Emerge existing packages that use the library with NAME |
|
--library=NAME NAME can be a full path to the library or a basic |
|
regular expression (man grep) |
|
-l, --no-ld-path Do not set LD_LIBRARY_PATH | -l, --no-ld-path Do not set LD_LIBRARY_PATH |
-C, --nocolor Turn off colored output | -C, --nocolor Turn off colored output |
-i, --ignore Ignore temporary files from previous runs | -i, --ignore Ignore temporary files from previous runs |
|
-o, --no-order Do not check the build order |
|
(Saves time, but may cause breakage.) |
-q, --quiet Be less verbose (also passed to emerge command) | -q, --quiet Be less verbose (also passed to emerge command) |
-v, --verbose Be more verbose | -v, --verbose Be more verbose |
|
-u, --no-util UTIL Do not use features provided by UTIL |
|
--no-util=UTIL UTIL can be one of portage-utils, pkgcore, or equery |
|
or it can be a *quoted* space-delimited list. |
|
-L, --library NAME Emerge existing packages that use the library with NAME |
|
--library=NAME NAME can be a full path to the library or a basic |
|
regular expression (man grep) |
| |
Calls emerge, all other options are used for it (e. g. -p, --pretend). | Calls emerge, all other options are used for it (e. g. -p, --pretend). |
| |
|
|
echo "$@" >&2 | echo "$@" >&2 |
exit $status | exit $status |
} | } |
|
# What to do when dynamic linking is consistent |
|
clean_exit() { |
|
[[ $KEEP_TEMP ]] || rm $LIST.?_* |
|
set_color green |
|
die 0 $'\n'"$OK_TEXT... All done. " |
|
} |
# Set the output color | # Set the output color |
set_color() { | set_color() { |
# sets itself the first time it's called, so we don't have to check $NOCOLOR | # sets itself the first time it's called, so we don't have to check $NOCOLOR |
|
|
} | } |
get_args() { | get_args() { |
appname="${0##*/}" | appname="${0##*/}" |
# Check if various utils are installed |
|
# TODO: give the user the option to turn off detection of various utils? |
|
if hash q 2> /dev/null; then |
|
PORTAGE_UTILS=1 |
|
elif hash pquery 2> /dev/null; then |
|
PKGCORE=1 |
|
elif hash equery 2> /dev/null; then |
|
# Well... if equery doesn't work something's definitely broken ;) |
|
EQUERY=1 |
|
fi |
|
echo_v() { echo "$@"; } | echo_v() { echo "$@"; } |
unset PACKAGE_NAMES VERBOSE KEEP_TEMP EMERGE_OPTIONS CALLED_OPTIONS |
unset VERBOSE KEEP_TEMP EMERGE_OPTIONS remove_old_tempfiles |
|
order_packages=1 |
|
PACKAGE_NAMES=1 |
SONAME="not found" | SONAME="not found" |
SEARCH_BROKEN=1 | SEARCH_BROKEN=1 |
FULL_LD_PATH=1 | FULL_LD_PATH=1 |
|
local avoid_utils |
while [[ $1 ]]; do | while [[ $1 ]]; do |
case $1 in | case $1 in |
-h|--help) | -h|--help) |
print_usage | print_usage |
exit 0 | exit 0 |
;; | ;; |
-X|--package-names) |
-e|--exact) |
PACKAGE_NAMES=1 |
unset PACKAGE_NAMES |
CALLED_OPTIONS+=" --package_names" # TODO: inconsistency _ versus - ? |
;; |
|
-o|--no-order) |
|
unset order_packages |
;; | ;; |
-q|--quiet) | -q|--quiet) |
echo_v() { : ; } | echo_v() { : ; } |
|
|
-L=*|--library=*|--soname=*|--soname-regexp=*) | -L=*|--library=*|--soname=*|--soname-regexp=*) |
SONAME="${1#*=}" | SONAME="${1#*=}" |
unset SEARCH_BROKEN | unset SEARCH_BROKEN |
CALLED_OPTIONS+=" --library=$SONAME" |
|
;; | ;; |
-L|--library|--soname|--soname-regexp) | -L|--library|--soname|--soname-regexp) |
[[ $2 = -* ]] && die 1 "Missing expected argument to $1" |
[[ ! $2 || $2 = -* ]] && die 1 "Missing expected argument to $1" |
shift | shift |
SONAME="$1" | SONAME="$1" |
unset SEARCH_BROKEN | unset SEARCH_BROKEN |
CALLED_OPTIONS+=" --library=$SONAME" |
;; |
|
-u=*|--no-util=*) |
|
# TODO: check for invalid values |
|
avoid_utils="${1#*=}" |
|
;; |
|
-u|--no-util) |
|
[[ ! $2 || $2 = -* ]] && die 1 "Missing expected argument to $1" |
|
shift |
|
avoid_utils="$1" |
;; | ;; |
-nc|-C|--no-color|--nocolor) | -nc|-C|--no-color|--nocolor) |
NOCOLOR=1 |
export NOCOLOR=1 |
;; | ;; |
-l|-np|--no-ld-path) | -l|-np|--no-ld-path) |
unset FULL_LD_PATH | unset FULL_LD_PATH |
CALLED_OPTIONS+=" --no-ld-path" |
|
;; | ;; |
-i|--ignore) | -i|--ignore) |
rm -f $LIST* |
remove_old_tempfiles=1 |
;; | ;; |
-k|--keep-temp) | -k|--keep-temp) |
KEEPTEMP=1 |
KEEP_TEMP=1 |
;; | ;; |
-vv|--extra-verbose|-v|--verbose) | -vv|--extra-verbose|-v|--verbose) |
VERBOSE=1 | VERBOSE=1 |
|
EMERGE_OPTIONS+=" $1" |
;; | ;; |
--) | --) |
;; | ;; |
|
|
esac | esac |
shift | shift |
done | done |
|
# Check if various utils are allowed and installed |
|
if [[ $avoid_utils != *portage-utils* ]] && hash q 2> /dev/null; then |
|
PORTAGE_UTILS=1 |
|
elif [[ $avoid_utils != *pkgcore* ]] && hash pquery 2> /dev/null; then |
|
PKGCORE=1 |
|
elif [[ $avoid_utils != *equery* ]] && hash equery 2> /dev/null; then |
|
EQUERY=1 |
|
fi |
} | } |
get_args "$@" | get_args "$@" |
| |
|
|
if [[ $LIST = .$appname ]]; then | if [[ $LIST = .$appname ]]; then |
die 1 "!!! Unable to find a satisfactory location for temporary files !!!" | die 1 "!!! Unable to find a satisfactory location for temporary files !!!" |
fi | fi |
|
[[ $remove_old_tempfiles ]] && rm -f $LIST.* |
| |
CALLED_OPTIONS=$(clean_var "$CALLED_OPTIONS") |
|
function set_trap () { | function set_trap () { |
trap "rm_temp $1" SIGHUP SIGINT SIGQUIT SIGABRT SIGTERM | trap "rm_temp $1" SIGHUP SIGINT SIGQUIT SIGABRT SIGTERM |
} | } |
|
|
$( | $( |
find -L "$LIST" -type f -mmin +1440 -print | | find -L "$LIST" -type f -mmin +1440 -print | |
while read; do echo 1; break; done | while read; do echo 1; break; done |
) ]] && rm -f $LIST* |
) ]] && rm -f $LIST.* |
|
|
# Don't use our previous files if environment doesn't match |
|
if [[ -r $LIST.0_env ]]; then |
|
oIFS="$IFS"; IFS=$'\a' |
|
PREVS=( $( |
|
source "$LIST.0_env" |
|
echo "$SEARCH_DIRS"$'\a'"$SEARCH_DIRS_MASK"$'\a'"$LD_LIBRARY_MASK"$'\a'"$PORTAGE_ROOT"$'\a'"$CALLED_OPTIONS" |
|
) ) |
|
IFS="$oIFS" |
|
if [[ ${PREVS[0]} != $SEARCH_DIRS || |
|
${PREVS[1]} != $SEARCH_DIRS_MASK || |
|
${PREVS[2]} != $LD_LIBRARY_MASK || |
|
${PREVS[3]} != $PORTAGE_ROOT || |
|
${PREVS[4]} != $CALLED_OPTIONS ]]; then |
|
echo 'Environment mismatch from previous run, deleting temporary files...' |
|
rm -f $LIST* |
|
fi |
|
unset PREVS |
|
fi |
|
| |
# Log the current environment | # Log the current environment |
cat > "$LIST.0_env" <<- EOF |
new_env=$( |
|
cat <<- EOF |
SEARCH_DIRS="$SEARCH_DIRS" | SEARCH_DIRS="$SEARCH_DIRS" |
SEARCH_DIRS_MASK="$SEARCH_DIRS_MASK" | SEARCH_DIRS_MASK="$SEARCH_DIRS_MASK" |
LD_LIBRARY_MASK="$LD_LIBRARY_MASK" | LD_LIBRARY_MASK="$LD_LIBRARY_MASK" |
PORTAGE_ROOT="$PORTAGE_ROOT" | PORTAGE_ROOT="$PORTAGE_ROOT" |
CALLED_OPTIONS="$CALLED_OPTIONS" |
|
EMERGE_OPTIONS="$EMERGE_OPTIONS" | EMERGE_OPTIONS="$EMERGE_OPTIONS" |
EOF |
order_packages="$order_packages" |
|
FULL_LD_PATH="$FULL_LD_PATH" |
|
EOF |
|
) |
| |
if [[ $VERBOSE ]]; then |
# Don't use our previous files if environment doesn't match |
echo |
if [[ -r $LIST.0_env ]] && |
echo "$appname environment:" |
! diff -b "$LIST.0_env" <(echo "$new_env") &> /dev/null; then |
cat $LIST.0_env |
|
|
echo 'Environment mismatch from previous run, deleting temporary files...' |
|
rm -f $LIST* |
|
else |
|
# No 0_env file found, silently delete any other tempfiles that may exist |
|
rm -f $LIST* |
fi | fi |
| |
|
# Save the environment in a file for next time |
|
echo "$new_env" > "$LIST.0_env" |
|
|
|
[[ $VERBOSE ]] && echo $'\n'"$appname environment:"$'\n'"$new_env" |
|
unset new_env |
|
|
cat <<- EOF | cat <<- EOF |
| |
Checking reverse dependencies... | Checking reverse dependencies... |
|
|
| |
echo | echo |
color_echo green -n "Checking dynamic linking$WORKING_TEXT..." | color_echo green -n "Checking dynamic linking$WORKING_TEXT..." |
if [[ -f $LIST.3_rebuild ]]; then |
if [[ -s $LIST.3_rebuild ]]; then |
echo " using existing $LIST.3_rebuild." | echo " using existing $LIST.3_rebuild." |
else | else |
[[ $LIST ]] || die 1 "$LIST" 'is undefined! (This is a bug.)' | [[ $LIST ]] || die 1 "$LIST" 'is undefined! (This is a bug.)' |
|
|
echo_v " broken $FILE (no version information available)" | echo_v " broken $FILE (no version information available)" |
done | done |
fi | fi |
|
[[ -s $LIST.3_rebuild ]] || clean_exit |
echo -e " done.\n ($LIST.3_rebuild)" | echo -e " done.\n ($LIST.3_rebuild)" |
fi | fi |
| |
|
|
if [[ $PORTAGE_UTILS ]]; then | if [[ $PORTAGE_UTILS ]]; then |
EXACT_PKG=$(qfile -qvC $FILE) | EXACT_PKG=$(qfile -qvC $FILE) |
elif [[ $PKGCORE ]]; then | elif [[ $PKGCORE ]]; then |
EXACT_PKG=$(pquery --nocolor --early-out --vdb --owns="$FILE") |
EXACT_PKG=$(pquery --nocolor --owns="$FILE") |
elif [[ $EQUERY ]]; then | elif [[ $EQUERY ]]; then |
EXACT_PKG=$(equery -q -C b $FILE) | EXACT_PKG=$(equery -q -C b $FILE) |
else | else |
|
|
echo -e " done.\n ($LIST.4_ebuilds)" | echo -e " done.\n ($LIST.4_ebuilds)" |
else | else |
echo " Nothing to rebuild" | echo " Nothing to rebuild" |
rm "$LIST.4_ebuilds" |
rm -f "$LIST.4_ebuilds" |
fi | fi |
fi | fi |
else | else |
|
|
echo " using existing $LIST.4_ebuilds." | echo " using existing $LIST.4_ebuilds." |
else | else |
if [[ -s $LIST.3_rebuild ]]; then | if [[ -s $LIST.3_rebuild ]]; then |
rebuildList=$(awk '{print $2}' "$LIST.3_rebuild") |
rebuildList=" $(<"$LIST.3_rebuild") " |
|
rebuildList="${rebuildList//[[:space:]]obj[[:space:]]/ }" |
if [[ $PORTAGE_UTILS ]]; then | if [[ $PORTAGE_UTILS ]]; then |
qfile -qvC $rebuildList # Don't put quotes around $rebuildList | qfile -qvC $rebuildList # Don't put quotes around $rebuildList |
# elif [[ $PKGCORE ]]; then | # elif [[ $PKGCORE ]]; then |
|
|
echo -e " done.\n ($LIST.4_ebuilds)" | echo -e " done.\n ($LIST.4_ebuilds)" |
else | else |
echo " Nothing to rebuild" | echo " Nothing to rebuild" |
rm > $LIST.4_ebuilds |
rm -f $LIST.4_ebuilds |
fi | fi |
fi | fi |
fi | fi |
| |
# TODO: let the user skip this step |
if [[ $order_packages ]]; then |
color_echo green -n $'\nEvaluating package order...' |
color_echo green -n $'\nEvaluating package order...' |
if [[ -r $LIST.5_order ]]; then |
if [[ -r $LIST.5_order ]]; then |
echo " using existing $LIST.5_order." | echo " using existing $LIST.5_order." |
else |
else |
set_trap "$LIST.5_order" | set_trap "$LIST.5_order" |
RAW_REBUILD_LIST=$(<"$LIST.4_ebuilds") | RAW_REBUILD_LIST=$(<"$LIST.4_ebuilds") |
if [[ $RAW_REBUILD_LIST ]]; then | if [[ $RAW_REBUILD_LIST ]]; then |
|
|
fi | fi |
[[ -f $LIST.5_order ]] && echo -e " done.\n ($LIST.5_order)" || | [[ -f $LIST.5_order ]] && echo -e " done.\n ($LIST.5_order)" || |
echo -e " done.\n ($LIST.4_ebuilds)" | echo -e " done.\n ($LIST.4_ebuilds)" |
|
fi |
|
else |
|
color_echo green "Skipping package ordering" |
fi | fi |
| |
# Clean up no longer needed environment variables | # Clean up no longer needed environment variables |
unset COMPLETE_LD_LIBRARY_PATH SEARCH_DIRS SEARCH_DIRS_MASK LD_LIBRARY_MASK PORTAGE_ROOT CALLED_OPTIONS |
unset COMPLETE_LD_LIBRARY_PATH SEARCH_DIRS SEARCH_DIRS_MASK LD_LIBRARY_MASK PORTAGE_ROOT |
| |
[[ -f $LIST.5_order ]] && REBUILD_LIST=$(<"$LIST.5_order") || | [[ -f $LIST.5_order ]] && REBUILD_LIST=$(<"$LIST.5_order") || |
REBUILD_LIST=$(<"$LIST.4_ebuilds") | REBUILD_LIST=$(<"$LIST.4_ebuilds") |
REBUILD_LIST="=${REBUILD_LIST//[[:space:]]/ =}" |
|
| |
trap - SIGHUP SIGINT SIGQUIT SIGABRT SIGTERM | trap - SIGHUP SIGINT SIGQUIT SIGABRT SIGTERM |
| |
if [[ ! $REBUILD_LIST ]]; then |
REBUILD_LIST="=${REBUILD_LIST//[[:space:]]/ =}" |
[[ $KEEPTEMP ]] || rm $LIST.?_* |
|
set_color green |
|
die 0 $'\n'"$OK_TEXT... All done. " |
|
fi |
|
| |
IS_REAL_MERGE=1 | IS_REAL_MERGE=1 |
for option in $EMERGE_OPTIONS; do | for option in $EMERGE_OPTIONS; do |