# Original Author: Stanislav Brabec
# Current Maintainer: Paul Varner <fuzzyray@gentoo.org>
-# Known problems:
-#
-# In exact ebuild mode revdep-rebuild can fail to properly order packages,
-# which are not up to date.
-# http://bugs.gentoo.org/show_bug.cgi?id=23018
-#
-# 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
+source /etc/init.d/functions.sh
+# TODO:
+# - Use more /etc/init.d/functions.sh
# Customizable variables:
#
# An entry of "-*" means to clear the variable from that point forward.
# Example: env SEARCH_DIRS="/usr/bin -*" revdep-rebuild will set SEARCH_DIRS
# to contain only /usr/bin
-
-# Print pre-release disclaimer to stderr
-cat 1>&2 << EOF
-
-WARNING
-WARNING *** This is a rewritten version of revdep-rebuild ***
-WARNING
-WARNING
-WARNING Please report any bugs to http://bugs.gentoo.org
-WARNING
-WARNING In the bug report please include the following information:
-WARNING emerge --info
-WARNING A copy of the output from the revdep-rebuild command
-WARNING A copy of the .revdep-rebuild* files as an attachment
-WARNING
-WARNING If the bug is severe, the previous version of revdep-rebuild is located
-WARNING at: /usr/lib/gentoolkit/bin/revdep-rebuild
-WARNING
-WARNING
-WARNING *** This is a rewritten version of revdep-rebuild ***
-WARNING
-
-EOF
-sleep 2
+declare -r oIFS="$IFS"
rm() {
- [[ $LIST && $appname ]] ||
+ [[ $LIST && $appname ]] ||
die 1 '$LIST or $appname is not defined! (This is a bug.)'
for i in $@; do
[[ $i = -* || $i = *.$appname* ]] ||
progress() { :; }
else
progress() {
+ (( $1 == $2 )) && local lb=$'\n'
echo -ne '\r \r'
- echo -n "[ $(( $1 * 100 / $2 ))% ] "
+ echo -n "[ $(( $1 * 100 / $2 ))% ] $lb"
}
progress $@
fi
die() {
local status=$1
shift
- echo "$@" >&2
+ eerror "$@"
exit $status
}
# What to do when dynamic linking is consistent
set_color green
die 0 $'\n'"$OK_TEXT... All done. "
}
-# Set the output color
-set_color() {
- # sets itself the first time it's called, so we don't have to check $NOCOLOR
- # each time
- if [[ $NOCOLOR ]]; then
- set_color() { :; }
- else
- set_color() {
- case $1 in
- black) tput setaf 0;;
- maroon) tput setaf 1;;
- green) tput setaf 2;;
- tan) tput setaf 3;;
- blue) tput setaf 4;;
- magenta) tput setaf 5;;
- aqua) tput setaf 6;;
- gray) tput setaf 7;;
- red) tput setaf 8;;
- *) tput setaf 9;;
- esac
- }
- set_color "$@"
- fi
-}
-# Echo with a particular color
-color_echo() {
- set_color $1
- shift
- echo "$@"
- set_color normal
-}
get_args() {
appname="${0##*/}"
- echo_v() { echo "$@"; }
+ echo_v() { ewarn "$@"; }
unset VERBOSE KEEP_TEMP EMERGE_OPTIONS remove_old_tempfiles
order_packages=1
PACKAGE_NAMES=1
-q|--quiet)
echo_v() { : ; }
quiet=1
- EMERGE_OPTIONS+=" $1"
+ EMERGE_OPTIONS+=($1)
;;
-L=*|--library=*|--soname=*|--soname-regexp=*)
SONAME="${1#*=}"
avoid_utils="$1"
;;
-nc|-C|--no-color|--nocolor)
+ # TODO: Does this variable do anything now that the main color functions are removed?
export NOCOLOR=1
;;
-l|-np|--no-ld-path)
;;
-vv|--extra-verbose|-v|--verbose)
VERBOSE=1
- EMERGE_OPTIONS+=" $1"
+ EMERGE_OPTIONS+=($1)
;;
--)
;;
*)
- EMERGE_OPTIONS+=" $1"
+ EMERGE_OPTIONS+=($1)
;;
esac
shift
done
# Check if various utils are allowed and installed
- if [[ avoid_utils != *portage-utils* ]] && hash q 2> /dev/null; then
+ if [[ $avoid_utils != *portage-utils* ]] && hash q 2> /dev/null; then
PORTAGE_UTILS=1
- elif [[ avoid_utils != *pkgcore* ]] && hash pquery 2> /dev/null; then
+ elif [[ $avoid_utils != *pkgcore* ]] && hash pquery 2> /dev/null; then
PKGCORE=1
- elif [[ avoid_utils != *equery* ]] && hash equery 2> /dev/null; then
+ elif [[ $avoid_utils != *equery* ]] && hash equery 2> /dev/null; then
EQUERY=1
fi
+ # Don't use equery until portage 2.1.3 is stable
+ # Portage 2.1.2 doesn't write all errors to stderr and this
+ # causes equery output to be potentially hosed
+ unset EQUERY
+ EMERGE_OPTIONS=(${EMERGE_OPTIONS[@]/%-p/--pretend})
+ EMERGE_OPTIONS=(${EMERGE_OPTIONS[@]/%-f/--fetchonly})
+ if [[ ${EMERGE_OPTIONS[@]} != *--pretend* && $UID -ne 0 ]]; then
+ ewarn "You are not superuser. Adding --pretend to emerge options."
+ EMERGE_OPTIONS+=(--pretend)
+ fi
}
+is_real_merge() [[
+ ${EMERGE_OPTIONS[@]} != *--pretend* && ${EMERGE_OPTIONS[@]} != *--fetchonly*
+]]
+
get_args "$@"
-echo "Configuring search environment for $appname"
+einfo "Configuring search environment for $appname"
# Obey PORTAGE_NICENESS
PORTAGE_NICENESS=$(portageq envvar PORTAGE_NICENESS)
fi
# Get the ROOTPATH and PATH from /etc/profile.env
-if [[ -r "/etc/profile.env" ]]; then
+if [[ -rs "/etc/profile.env" ]]; then
SEARCH_DIRS+=" "$(. /etc/profile.env; /usr/bin/tr ':' ' ' <<< "$ROOTPATH $PATH")
fi
# Get the directories from /etc/ld.so.conf
-if [[ -r /etc/ld.so.conf ]]; then
+if [[ -rs /etc/ld.so.conf ]]; then
SEARCH_DIRS+=" "$(sed '/^#/d;s/#.*$//' /etc/ld.so.conf)
-fi
+fi
# Set the final variables
+[[ $SEARCH_DIRS ]] || die 1 "No search defined -- this is a bug."
SEARCH_DIRS=$(clean_var "$SEARCH_DIRS")
SEARCH_DIRS_MASK=$(clean_var "$SEARCH_DIRS_MASK")
LD_LIBRARY_MASK=$(clean_var "$LD_LIBRARY_MASK")
}
function rm_temp () {
rm $1
- die 1 $' ...terminated.\nRemoving incomplete '"$1."
+ die 1 $' ...terminated. Removing incomplete '"$1."
}
-if [[ $SEARCH_BROKEN ]]; then
- SONAME_SEARCH="$SONAME"
- HEAD_TEXT="broken by a package update"
- OK_TEXT="Dynamic linking on your system is consistent"
- WORKING_TEXT=" consistency"
-else
- # first case is needed to test against /path/to/foo.so
- if [[ $SONAME = /* ]]; then
- # Set to "<space>$SONAME<space>"
- SONAME_SEARCH=" $SONAME "
+get_search_env() {
+ if [[ $SEARCH_BROKEN ]]; then
+ SONAME_SEARCH="$SONAME"
+ HEAD_TEXT="broken by a package update"
+ OK_TEXT="Dynamic linking on your system is consistent"
+ WORKING_TEXT="consistency"
else
- # Set to "<tab>$SONAME<space>"
- SONAME_SEARCH=$'\t'"$SONAME "
- fi
- # NOTE: Using a redirect instead of echo is good, but it will cause a minor
- # incompatibility with older versions of revdep-rebuild, because the
- # string sent to md5sum will no longer have a newline at the end.
- SOMD5=$(md5sum <<< "$SONAME_SEARCH$SONAME")
- LIST+="_${SOMD5:0:8}"
- HEAD_TEXT="using $SONAME"
- OK_TEXT="There are no dynamic links to $SONAME"
- unset WORKING_TEXT SOMD5
-fi
-
-[[ $LIST ]] || die 1 $LIST IS NOT DEFINED
-
-# If any of our temporary files are older than 1 day, remove them all
-[[ ! $keep_tempfiles && -r $LIST &&
- $(
- find -L "$LIST" -type f -mmin +1440 -print |
- while read; do echo 1; break; done
- ) ]] && 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"
- ) )
- IFS="$oIFS"
- if [[ ${PREVS[0]} != $SEARCH_DIRS ||
- ${PREVS[1]} != $SEARCH_DIRS_MASK ||
- ${PREVS[2]} != $LD_LIBRARY_MASK ||
- ${PREVS[3]} != $PORTAGE_ROOT ]]; then
- echo 'Environment mismatch from previous run, deleting temporary files...'
- rm -f $LIST*
+ # first case is needed to test against /path/to/foo.so
+ if [[ $SONAME = /* ]]; then
+ # Set to "<space>$SONAME<space>"
+ SONAME_SEARCH=" $SONAME "
+ else
+ # Set to "<tab>$SONAME<space>"
+ SONAME_SEARCH=$'\t'"$SONAME "
+ fi
+ # NOTE: Using a redirect instead of echo is good, but it will cause a minor
+ # incompatibility with older versions of revdep-rebuild, because the
+ # string sent to md5sum will no longer have a newline at the end.
+ SOMD5=$(md5sum <<< "$SONAME_SEARCH$SONAME")
+ LIST+="_${SOMD5:0:8}"
+ HEAD_TEXT="using $SONAME"
+ OK_TEXT="There are no dynamic links to $SONAME"
+ unset WORKING_TEXT SOMD5
fi
- unset PREVS
-fi
-# Log the current environment
-cat > "$LIST.0_env" <<- EOF
- SEARCH_DIRS="$SEARCH_DIRS"
- SEARCH_DIRS_MASK="$SEARCH_DIRS_MASK"
- LD_LIBRARY_MASK="$LD_LIBRARY_MASK"
- PORTAGE_ROOT="$PORTAGE_ROOT"
- EMERGE_OPTIONS="$EMERGE_OPTIONS"
-EOF
+ [[ $LIST ]] || die 1 $LIST IS NOT DEFINED
-if [[ $VERBOSE ]]; then
- echo
- echo "$appname environment:"
- cat $LIST.0_env
-fi
+ # If any of our temporary files are older than 1 day, remove them all
+ [[ ! $keep_tempfiles && -r $LIST &&
+ $(
+ find -L "$LIST" -type f -mmin +1440 -print |
+ while read; do echo 1; break; done
+ ) ]] && rm -f $LIST.*
-cat <<- EOF
+ # Compare old and new environments
+ # Don't use our previous files if environment doesn't match
+ new_env=$(
+ cat <<- EOF
+ SEARCH_DIRS="$SEARCH_DIRS"
+ SEARCH_DIRS_MASK="$SEARCH_DIRS_MASK"
+ LD_LIBRARY_MASK="$LD_LIBRARY_MASK"
+ PORTAGE_ROOT="$PORTAGE_ROOT"
+ EMERGE_OPTIONS="${EMERGE_OPTIONS[@]}"
+ order_packages="$order_packages"
+ FULL_LD_PATH="$FULL_LD_PATH"
+ EOF
+ )
+ if [[ -rs $LIST.0_env ]]; then
+ old_env=$(<"$LIST.0_env")
+ if [[ $old_env != $new_env ]]; then
+ ewarn 'Environment mismatch from previous run, deleting temporary files...'
+ rm -f "$LIST"*
+ fi
+ else
+ # No 0_env file found, silently delete any other tempfiles that may exist
+ rm -f "$LIST"*
+ fi
- Checking reverse dependencies...
+ # Save the environment in a file for next time
+ echo "$new_env" > "$LIST.0_env"
- Packages containing binaries and libraries $HEAD_TEXT
- will be emerged.
+ [[ $VERBOSE ]] && echo $'\n'"$appname environment:"$'\n'"$new_env"
+ unset new_env
-EOF
-color_echo green -n "Collecting system binaries and libraries..."
+ echo
+ einfo "Checking reverse dependencies"
+ einfo "Packages containing binaries and libraries $HEAD_TEXT"
+ einfo "will be emerged."
+}
+get_files() {
+ einfo "Collecting system binaries and libraries"
+ if [[ -rs $LIST.1_files ]]; then
+ einfo "Found existing $LIST.1_files"
+ else
+ # Be safe and remove any extraneous temporary files
+ rm -f $LIST.[1-9]_*
-if [[ -r $LIST.1_files ]]; then
- echo " using existing $LIST.1_files."
-else
- # Be safe and remove any extraneous temporary files
- rm -f $LIST.[1-9]_*
-
- set_trap "$LIST.1_*"
-
- findMask=($SEARCH_DIRS_MASK)
- findMask="${findMask[@]/#/-o -path }"
- findMask="${findMask#-o }"
- find ${SEARCH_DIRS[@]} \( $findMask \) -prune -o -type f \( -executable -o \
- -name '*.so' -o -name '*.so.*' -o -name '*.la' \) -print 2> /dev/null |
- sort -u > $LIST.1_files
- echo -e " done.\n ($LIST.1_files)"
-fi
+ set_trap "$LIST.1_*"
-if [[ $SEARCH_BROKEN && $FULL_LD_PATH ]]; then
- echo
- color_echo green -n 'Collecting complete LD_LIBRARY_PATH...'
- if [[ -f $LIST.2_ldpath ]] ; then
- echo " using existing $LIST.2_ldpath."
+ if [[ $SEARCH_DIRS_MASK ]]; then
+ findMask=($SEARCH_DIRS_MASK)
+ findMask="${findMask[@]/#/-o -path }"
+ findMask="( ${findMask#-o } ) -prune -o"
+ fi
+ find ${SEARCH_DIRS[@]} $findMask -type f \( -executable -o \
+ -name '*.so' -o -name '*.so.*' -o -name '*.la' \) -print 2> /dev/null |
+ sort -u > "$LIST.1_files" ||
+ die $? "find failed to list binary files (This is a bug.)"
+ einfo "Generated new $LIST.1_files"
+ fi
+}
+get_ldpath() {
+ [[ $SEARCH_BROKEN && $FULL_LD_PATH ]] || return
+ einfo 'Collecting complete LD_LIBRARY_PATH'
+ if [[ -rs $LIST.2_ldpath ]] ; then
+ einfo "Found existing $LIST.2_ldpath."
COMPLETE_LD_LIBRARY_PATH=$(<"$LIST.2_ldpath")
else
set_trap "$LIST.2_ldpath"
$(sed '/^#/d;s/#.*$//' < /etc/ld.so.conf)
$(sed 's:/[^/]*$::' < "$LIST.1_files" | sort -ru)
)
- oIFS="$IFS"; IFS=':'
+ IFS=':'
COMPLETE_LD_LIBRARY_PATH="${COMPLETE_LD_LIBRARY_PATH[*]}"
IFS="$oIFS"
echo "$COMPLETE_LD_LIBRARY_PATH" > "$LIST.2_ldpath"
- echo -e " done.\n ($LIST.2_ldpath)"
+ einfo "Generated new $LIST.2_ldpath"
fi
-fi
-
-echo
-color_echo green -n "Checking dynamic linking$WORKING_TEXT..."
-if [[ -s $LIST.3_rebuild ]]; then
- echo " using existing $LIST.3_rebuild."
-else
- [[ $LIST ]] || die 1 "$LIST" 'is undefined! (This is a bug.)'
- echo_v
- set_trap "$LIST.3_rebuild"
- rm -f $LIST.3*
- files=($(<"$LIST.1_files"))
- numFiles=${#files[@]}; i=0
-
- for FILE in ${files[@]}; do
- if [[ $FILE != *.la ]]; then
- # Note: double checking seems to be faster than single with complete path
- # (special add ons are rare).
- ldd_output=$(ldd "$FILE" 2>> "$LIST.3_ldd_errors" | sort -u)
- ldd_status=$? # TODO: Check this for problems with sort
- if grep -vF "$LD_LIBRARY_MASK" <<< "$ldd_output" |
- grep -q "$SONAME_SEARCH"; then
- if [[ $SEARCH_BROKEN && $FULL_LD_PATH ]]; then
-
- if LD_LIBRARY_PATH="$COMPLETE_LD_LIBRARY_PATH" ldd "$FILE" 2>/dev/null |
- grep -v "$LD_LIBRARY_MASK" | grep -q "$SONAME_SEARCH"; then
+}
+main_checks() {
+ einfo "Checking dynamic linking $WORKING_TEXT"
+ if [[ -rs $LIST.3_rebuild ]]; then
+ einfo "Found existing $LIST.3_rebuild."
+ else
+ [[ $LIST ]] || die 1 "$LIST" 'is undefined! (This is a bug.)'
+ set_trap "$LIST.3_rebuild"
+ rm -f $LIST.3*
+ files=($(<"$LIST.1_files"))
+ numFiles=${#files[@]}; i=0
+ for FILE in ${files[@]}; do
+ if [[ $FILE != *.la ]]; then
+ # Note: double checking seems to be faster than single with complete path
+ # (special add ons are rare).
+ ldd_output=$(ldd "$FILE" 2>> "$LIST.3_ldd_errors" | sort -u)
+ ldd_status=$? # TODO: Check this for problems with sort
+ # HACK: if LD_LIBRARY_MASK is null or undefined grep -vF doesn't work
+ if grep -vF "${LD_LIBRARY_MASK:=$'\a'}" <<< "$ldd_output" |
+ grep -q "$SONAME_SEARCH"; then
+ if [[ $SEARCH_BROKEN && $FULL_LD_PATH ]]; then
+
+ if LD_LIBRARY_PATH="$COMPLETE_LD_LIBRARY_PATH" ldd "$FILE" 2>/dev/null |
+ grep -vF "$LD_LIBRARY_MASK" | grep -q "$SONAME_SEARCH"; then
+ # FIXME: I hate duplicating code
+ # Only build missing direct dependencies
+ MISSING_LIBS=$(
+ expr='s/[[:space:]]*\([^[:space:]]*\) => not found/\1/p'
+ sed -n "$expr" <<< "$ldd_output"
+ )
+ REQUIRED_LIBS=$(
+ expr='s/^[[:space:]]*NEEDED[[:space:]]*\([^[:space:]]*\).*/\1/p';
+ objdump -x "$FILE" | sed "$expr" | sort -u
+ )
+ MISSING_LIBS=$(grep -F "$REQUIRED_LIBS" <<< "$MISSING_LIBS")
+ if [[ $MISSING_LIBS ]]; then
+ echo "obj $FILE" >> "$LIST.3_rebuild"
+ echo_v " broken $FILE (requires $MISSING_LIBS)"
+ fi
+ fi
+ else
# FIXME: I hate duplicating code
- # Only build missing direct dependencies
+ # Only rebuild for direct dependencies
MISSING_LIBS=$(
- expr='s/[[:space:]]*\([^[:space:]]*\) => not found/\1/p'
- sed -n "$expr" <<< "$ldd_output"
+ expr="/$SONAME_SEARCH/s/^\([^[:space:]]*\).*$/\1/p"
+ sort -u <<< "$ldd_output" | sed -n "$expr"
)
REQUIRED_LIBS=$(
expr='s/^[[:space:]]*NEEDED[[:space:]]*\([^[:space:]]*\).*/\1/p';
objdump -x "$FILE" | sed "$expr" | sort -u
)
- MISSING_LIBS=$(grep -F "$REQUIRED_LIBS" <<< "$MISSING_LIBS")
+ MISSING_LIBS=$(grep -F "$REQUIRED_LIBS")
if [[ $MISSING_LIBS ]]; then
echo "obj $FILE" >> "$LIST.3_rebuild"
- echo_v " broken $FILE (requires $MISSING_LIBS)"
+ if [[ $SEARCH_BROKEN ]]; then
+ echo_v " broken $FILE (requires $MISSING_LIBS)"
+ else
+ echo_v " found $FILE"
+ fi
fi
fi
- else
- # FIXME: I hate duplicating code
- # Only rebuild for direct dependencies
- MISSING_LIBS=$(
- expr="/$SONAME_SEARCH/s/^\([^[:space:]]*\).*$/\1/p"
- sort -u <<< "$ldd_output" | sed -n "$expr"
- )
- REQUIRED_LIBS=$(
- expr='s/^[[:space:]]*NEEDED[[:space:]]*\([^[:space:]]*\).*/\1/p';
- objdump -x "$FILE" | sed "$expr" | sort -u
- )
- MISSING_LIBS=$(grep -F "$REQUIRED_LIBS")
- if [[ $MISSING_LIBS ]]; then
+ fi
+ elif [[ $SEARCH_BROKEN ]]; then
+ # Look for broken .la files
+ for depend in $(
+ awk -F"[=']" '/^dependency_libs/{
+ gsub("^-[^[:space:]]*", "", $2);
+ gsub("[[:space:]]-[^[:space:]]*", "", $2);
+ print $2
+ }' "$FILE"
+ ); do
+ if [[ $depend != /* && ! -e $depend ]]; then
echo "obj $FILE" >> "$LIST.3_rebuild"
- if [[ $SEARCH_BROKEN ]]; then
- echo_v " broken $FILE (requires $MISSING_LIBS)"
- else
- echo_v " found $FILE"
- fi
+ echo_v " broken $FILE (requires $depend)"
fi
- fi
+ done
fi
- elif [[ $SEARCH_BROKEN ]]; then
- # Look for broken .la files
- for depend in $(
- awk -F"[=']" '/^dependency_libs/{
- gsub("^-[^[:space:]]*", "", $2);
- gsub("[[:space:]]-[^[:space:]]*", "", $2);
- print $2
- }' "$FILE"
+ [[ $VERBOSE ]] &&
+ progress $((++i)) $numFiles $FILE ||
+ progress $((++i)) $numFiles
+ done
+ if [[ $SEARCH_BROKEN ]]; then
+ # Look for missing version
+ for FILE in $(
+ awk '/no version information available/{
+ gsub("[()]", "", $NF);
+ print $NF
+ }' "$LIST.3_ldd_errors" | sort -u
); do
- if [[ $depend != /* && ! -e $depend ]]; then
- echo "obj $FILE" >> "$LIST.3_rebuild"
- echo_v " broken $FILE (requires $depend)"
- fi
+ echo "obj $FILE" >> "$LIST.3_rebuild"
+ echo_v " broken $FILE (no version information available)"
done
fi
- [[ $VERBOSE ]] &&
- progress $((++i)) $numFiles $FILE ||
- progress $((++i)) $numFiles
- done
- if [[ $SEARCH_BROKEN ]]; then
- # Look for missing version
- for FILE in $(
- awk '/no version information available/{
- gsub("[()]", "", $NF);
- print $NF
- }' "$LIST.3_ldd_errors" | sort -u
- ); do
- echo "obj $FILE" >> "$LIST.3_rebuild"
- echo_v " broken $FILE (no version information available)"
- done
+ [[ -rs $LIST.3_rebuild ]] || clean_exit
+ einfo "Generated new $LIST.3_rebuild"
fi
- [[ -s $LIST.3_rebuild ]] || clean_exit
- echo -e " done.\n ($LIST.3_rebuild)"
-fi
-
-if [[ $PACKAGE_NAMES ]]; then
- echo
- color_echo green -n 'Assigning files to packages...'
- if [[ -r $LIST.4_packages_raw ]]; then
- echo " using existing $LIST.4_packages_raw."
+}
+get_packages() {
+ einfo 'Assigning files to packages'
+ if [[ -rs $LIST.4_packages_raw ]]; then
+ einfo "Found existing $LIST.4_packages_raw"
else
set_trap "$LIST.4_packages*"
rm -f $LIST.4*
PKG="${PKG%-*}"
echo "$EXACT_PKG" >> $LIST.4_packages_raw
echo "$FILE -> $EXACT_PKG" >> $LIST.4_package_owners
- echo_v -n -e "\n $FILE -> $PKG"
+ echo_v " $FILE -> $PKG"
else
- color_echo -n -e "\n *** $FILE not owned by any package is broken! ***"
+ ewarn " !!! $FILE not owned by any package is broken !!!"
echo "$FILE -> (none)" >> $LIST.4_package_owners
echo_v -n -e "\n $FILE -> (none)"
fi
done < "$LIST.3_rebuild"
- echo_v
- echo -e " done.\n ($LIST.4_packages_raw, $LIST.4_package_owners)"
+ einfo "Generated new $LIST.4_packages_raw and $LIST.4_package_owners"
fi
-
- echo
- color_echo green -n "Cleaning list of packages to rebuild..."
- if [[ -f $LIST.4_packages ]]; then
- echo " using existing $LIST.4_packages."
+}
+clean_packages() {
+ einfo 'Cleaning list of packages to rebuild'
+ if [[ -rs $LIST.4_packages ]]; then
+ einfo "Found existing $LIST.4_packages"
else
sort -u $LIST.4_packages_raw > $LIST.4_packages
- echo -e " done.\n ($LIST.4_packages)"
+ einfo "Generated new $LIST.4_packages"
fi
-
- echo
- color_echo green -n 'Assigning packages to ebuilds...'
- if [[ -f $LIST.4_ebuilds ]]; then
- echo " using existing $LIST.4_ebuilds."
- else
- if [[ -s $LIST.4_packages ]]; then
+}
+assign_packages_to_ebuilds() {
+ einfo 'Assigning packages to ebuilds'
+ if [[ -rs $LIST.4_ebuilds ]]; then
+ einfo "Found existing $LIST.4_ebuilds"
+ elif [[ -rs $LIST.4_packages ]]; then
set_trap "$LIST.4_ebuilds"
while read EXACT_PKG; do
# Get the slot
SLOT=$(</var/db/pkg/$EXACT_PKG/SLOT)
portageq best_visible $PORTAGE_ROOT $PKG:$SLOT
done < "$LIST.4_packages" > "$LIST.4_ebuilds"
- echo -e " done.\n ($LIST.4_ebuilds)"
+ einfo "Generated new $LIST.4_ebuilds"
+ else
+ einfo 'Nothing to rebuild.'
+ die 1 '(The program should have already quit, so this is a minor bug.)'
+ fi
+}
+get_exact_ebuilds() {
+ einfo 'Assigning files to ebuilds'
+ if [[ -rs $LIST.4_ebuilds ]]; then
+ einfo "Found existing $LIST.4_ebuilds"
+ elif [[ -rs $LIST.3_rebuild ]]; then
+ rebuildList=" $(<"$LIST.3_rebuild") "
+ rebuildList=(${rebuildList//[[:space:]]obj[[:space:]]/ })
+ if [[ $PORTAGE_UTILS ]]; then
+ qfile -qvC ${rebuildList[@]}
+ elif [[ $PKGCORE ]]; then
+ IFS=,
+ pquery --nocolor --owns="${rebuildList[*]}"
+ IFS="$oIFS"
+ elif [[ $EQUERY ]]; then
+ equery -q -C b ${rebuildList[@]}
else
- echo " Nothing to rebuild"
- rm -f "$LIST.4_ebuilds"
- fi
+ find /var/db/pkg -name CONTENTS |
+ xargs grep -Fl "$rebuildList" |
+ sed 's:/var/db/pkg/\(.*\)/CONTENTS:=\1:'
+ fi > $LIST.4_ebuilds
+ einfo "Generated new $LIST.4_ebuilds"
+ else
+ einfo 'Nothing to rebuild.'
+ die 1 '(The program should have already quit, so this is a minor bug.)'
fi
-else
- echo
- color_echo green -n 'Assigning files to ebuilds...'
- if [[ -r $LIST.4_ebuilds ]]; then
- echo " using existing $LIST.4_ebuilds."
+}
+get_build_order() {
+ if [[ ! $order_packages ]]; then
+ einfo 'Skipping package ordering'
+ return
+ fi
+ einfo 'Evaluating package order'
+ if [[ -rs $LIST.5_order ]]; then
+ einfo "Found existing $LIST.5_order"
else
- if [[ -s $LIST.3_rebuild ]]; then
- rebuildList=" $(<"$LIST.3_rebuild") "
- rebuildList="${rebuildList//[[:space:]]obj[[:space:]]/ }"
- if [[ $PORTAGE_UTILS ]]; then
- qfile -qvC $rebuildList # Don't put quotes around $rebuildList
- # elif [[ $PKGCORE ]]; then
- # This is really slow...
- # pquery --nocolor --early-out --vdb --owns-re="(${rebuildList//[[:space:]]/|})"
- # elif [[ $EQUERY ]]; then
- # equery can't seem to do this operation on multiple args at all
- else
- find /var/db/pkg -name CONTENTS |
- xargs grep -Fl "$rebuildList" |
- sed 's:/var/db/pkg/\(.*\)/CONTENTS:=\1:'
- fi > $LIST.4_ebuilds
- echo -e " done.\n ($LIST.4_ebuilds)"
+ set_trap "$LIST.5_order"
+ RAW_REBUILD_LIST=$(<"$LIST.4_ebuilds")
+ if [[ $RAW_REBUILD_LIST ]]; then
+ OLD_EMERGE_DEFAULT_OPTS="$EMERGE_DEFAULT_OPTS"
+ export EMERGE_DEFAULT_OPTS="--nospinner --pretend --oneshot --nodeps --quiet"
+ RAW_REBUILD_LIST="=${RAW_REBUILD_LIST//[[:space:]]/ =}"
+ REBUILD_GREP=$(emerge $RAW_REBUILD_LIST | sed 's/\[[^]]*\]//g') &&
+ emerge --deep $RAW_REBUILD_LIST | sed 's/\[[^]]*\]//g' |
+ grep -F "$REBUILD_GREP" > $LIST.5_order || {
+ eerror
+ eerror 'Warning: Failed to resolve package order.'
+ eerror 'Will merge in arbitrary order'
+ eerror
+ cat <<- EOF
+ Possible reasons:
+ - An ebuild is no longer in the portage tree.
+ - An ebuild is masked, use /etc/portage/packages.keyword
+ and/or /etc/portage/package.unmask to unmask it
+ EOF
+ for i in {1..5}; do
+ echo -n -e '\a.'
+ sleep 1
+ done
+ rm -f "$LIST.5_order"
+ }
+ export EMERGE_DEFAULT_OPTS="$OLD_EMERGE_DEFAULT_OPTS"
else
- echo " Nothing to rebuild"
- rm -f $LIST.4_ebuilds
+ einfo 'Nothing to rebuild.'
+ die 1 '(The program should have already quit, so this is a minor bug.)'
fi
fi
-fi
+ [[ -rs $LIST.5_order ]] && einfo "Generated new $LIST.5_order"
+}
-if [[ $order_packages ]]; then
- color_echo green -n $'\nEvaluating package order...'
- if [[ -r $LIST.5_order ]]; then
- echo " using existing $LIST.5_order."
- else
- set_trap "$LIST.5_order"
- RAW_REBUILD_LIST=$(<"$LIST.4_ebuilds")
- if [[ $RAW_REBUILD_LIST ]]; then
- OLD_EMERGE_DEFAULT_OPTS="$EMERGE_DEFAULT_OPTS"
- export EMERGE_DEFAULT_OPTS="--nospinner --pretend --oneshot --nodeps --quiet"
- RAW_REBUILD_LIST="=${RAW_REBUILD_LIST//[[:space:]]/ =}"
- REBUILD_GREP=$(emerge $RAW_REBUILD_LIST | awk '{print $NF}') &&
- emerge --deep $RAW_REBUILD_LIST | awk '{print $NF}' |
- grep -F "$REBUILD_GREP" > $LIST.5_order || {
- set_color red
- cat <<- EOF
- Warning: Failed to resolve package order.
- Will merge in "random" order!
- EOF
- set_color
- cat <<- EOF
- Possible reasons:
- - An ebuild is no longer in the portage tree.
- - An ebuild is masked, use /etc/portage/packages.keyword
- and/or /etc/portage/package.unmask to unmask it
- EOF
- for i in {1..5}; do
- echo -n -e '\a.'
- sleep 1
- done
- }
- export EMERGE_DEFAULT_OPTS="$OLD_EMERGE_DEFAULT_OPTS"
- else
- rm -f "$LIST.5_order"
- fi
- [[ -f $LIST.5_order ]] && echo -e " done.\n ($LIST.5_order)" ||
- echo -e " done.\n ($LIST.4_ebuilds)"
- fi
+get_search_env
+echo
+get_files
+echo
+get_ldpath
+echo
+main_checks
+echo
+if [[ $PACKAGE_NAMES ]]; then
+ get_packages
+ echo
+ clean_packages
+ echo
+ assign_packages_to_ebuilds
else
- color_echo green "Skipping package ordering"
+ get_exact_ebuilds
fi
+echo
+get_build_order
+echo
# Clean up no longer needed environment variables
-unset COMPLETE_LD_LIBRARY_PATH SEARCH_DIRS SEARCH_DIRS_MASK LD_LIBRARY_MASK PORTAGE_ROOT
+unset COMPLETE_LD_LIBRARY_PATH SEARCH_DIRS SEARCH_DIRS_MASK LD_LIBRARY_MASK \
+ PORTAGE_ROOT
-[[ -f $LIST.5_order ]] && REBUILD_LIST=$(<"$LIST.5_order") ||
- REBUILD_LIST=$(<"$LIST.4_ebuilds")
+[[ -rs $LIST.5_order ]] && REBUILD_LIST=($(<"$LIST.5_order")) ||
+ REBUILD_LIST=($(<"$LIST.4_ebuilds"))
trap - SIGHUP SIGINT SIGQUIT SIGABRT SIGTERM
-REBUILD_LIST="=${REBUILD_LIST//[[:space:]]/ =}"
-
-IS_REAL_MERGE=1
-for option in $EMERGE_OPTIONS; do
- case $option in
- -p|--pretend|-f|--fetchonly)
- unset IS_REAL_MERGE
- break;;
- esac
-done
+REBUILD_LIST="=${REBUILD_LIST[@]}"
+REBUILD_LIST="${REBUILD_LIST//[[:space:]]/ =}"
-echo
-color_echo green -e "All prepared. Starting rebuild..."
-
-echo "emerge --oneshot $EMERGE_OPTIONS $REBUILD_LIST"
+einfo 'All prepared. Starting rebuild'
+echo "emerge --oneshot ${EMERGE_OPTIONS[@]} $REBUILD_LIST"
-if [[ $IS_REAL_MERGE ]]; then
+if is_real_merge; then
for i in {1..10}; do
echo -n -e '\a.'
sleep 1
# Run in background to correctly handle Ctrl-C
{
- EMERGE_DEFAULT_OPTS="" emerge --oneshot $EMERGE_OPTIONS $REBUILD_LIST <&6
+ EMERGE_DEFAULT_OPTS="--oneshot ${EMERGE_OPTIONS[@]}" emerge $REBUILD_LIST <&6
echo $? > $LIST.6_status
} &
wait
exec 0<&6 6<&-
if (( $(<"$LIST.6_status") != 0 )); then
- set_color red
- cat <<- EOF
-
- revdep-rebuild failed to emerge all packages.
- you have the following choices:
-
- EOF
- set_color
- cat <<- EOF
- - if emerge failed during the build, fix the problems and re-run revdep-rebuild
- or
- - use -X or --package-names as first argument (trys to rebuild package, not exact
- ebuild)
- or
- - set ACCEPT_KEYWORDS=\"~<your platform>\" and/or /etc/portage/package.unmask
- (and remove $LIST.5_order to be evaluated again)
- or
- - modify the above emerge command and run it manually
- or
- - compile or unmerge unsatisfied packages manually, remove temporary files and
- try again (you can edit package/ebuild list first)
- EOF
- color_echo green 'To remove temporary files, please run:'
- echo "rm $LIST*.?_*"
+ ewarn
+ ewarn "$appname failed to emerge all packages."
+ ewarn 'you have the following choices:'
+ einfo "- If emerge failed during the build, fix the problems and re-run $appname."
+ einfo '- Use /etc/portage/package.keywords to unmask a newer version of the package.'
+ einfo " (and remove $LIST.5_order to be evaluated again)"
+ einfo '- Modify the above emerge command and run it manually.'
+ einfo '- Compile or unmerge unsatisfied packages manually,'
+ einfo ' remove temporary files, and try again.'
+ einfo ' (you can edit package/ebuild list first)'
+ einfo
+ einfo 'To remove temporary files, please run:'
+ einfo "rm $LIST*.?_*"
exit $EMERGE_STATUS
+elif is_real_merge; then
+ trap_cmd() {
+ eerror "terminated. Please remove the temporary files manually:"
+ eerror "rm $LIST*.?_*"
+ exit 1
+ }
+ trap trap_cmd SIGHUP SIGINT SIGQUIT SIGABRT SIGTERM
+ 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.'
else
- if [[ $IS_REAL_MERGE ]]; then
- trap "echo -e \" terminated. Please remove them manually:\nrm $LIST*.?_*\" ; exit 1" \
- SIGHUP SIGINT SIGQUIT SIGABRT SIGTERM
- color_echo green "Build finished correctly. Removing temporary files..."
- cat <<- EOF
- You can re-run revdep-rebuild to verify that all libraries and binaries
- are fixed. If some inconsistency remains, it can be orphaned file, deep
- dependency, binary package or specially evaluated library.
- EOF
- else
- color_echo green 'Now you can remove -p (or --pretend) from arguments and re-run revdep-rebuild.'
- fi
+ einfo 'Now you can remove -p (or --pretend) from arguments and re-run revdep-rebuild.'
fi