freebsd-ports/ports-mgmt/portmaster/files/portmaster.sh.in
Doug Barton 096b99a715 1. Change to 'make -f/usr/share/mk/bsd.port.mk' in several places due to
the DESTDIR changes today.
2. Export pd, pdb, and distdir to avoid having to look them up each time
3. Streamline find_moved() by grepping for lines, and then recursing
4. Further streamline by using variable stripping instead of cut
2007-08-05 05:04:14 +00:00

1885 lines
48 KiB
Bash

#!/bin/sh
# Local version: 1.183
# $FreeBSD$
# Copyright (c) 2005-2007 Douglas Barton, All rights reserved
# Please see detailed copyright below
trap trap_exit INT
# Keep track of the parent process
if [ -z "$PARENT_PID" ]; then
PARENT_PID=$$
: ${TMPDIR:=/tmp}
UPGRADE_TOOL=portmaster
export PARENT_PID TMPDIR UPGRADE_TOOL
fi
# %%LOCALBASE%% and %%X11BASE%% are needed in path for make
PATH=/bin:/usr/bin:/sbin:/usr/sbin:%%LOCALBASE%%/bin:%%LOCALBASE%%/sbin:%%X11BASE%%/bin
if [ -n "$CCACHE_PATH" ]; then
if [ -z "$NOCCACHE" ]; then
PATH="%%LOCALBASE%%/libexec/ccache:$PATH"
fi
fi
export PATH
umask 022
usage () {
echo "portmaster version `grep "[$]FreeBSD:" $0 | cut -d ' ' -f 4`"
echo ''
echo 'Usage:'
echo "Common flags: [--force-config] [-CGgntvw B|b uf|i D|d]"
echo " [-m <arguments for make>]"
echo " [-x <glob pattern to exclude from building>]"
echo "${0##*/} [Common flags] <full name of port directory in $pdb>"
echo "${0##*/} [Common flags] <full path to $pd/foo/bar>"
echo "${0##*/} [Common flags] Multiple full names/paths from $pdb|$pd"
echo ''
echo "${0##*/} [Common flags] <glob pattern of directory in $pdb>"
echo "${0##*/} [Common flags] -p <port directory in $pd>"
echo "${0##*/} [Common flags] . [Use in $pd/foo/bar to build that port]"
echo ''
echo "${0##*/} --show-work [-Gv] [-m <args for make>] <port, as above>"
echo ''
echo "${0##*/} [Common flags] -o <new port dir in $pd> <installed port>"
echo "${0##*/} [Common flags] [-R] -r <name/glob of port directory in $pdb>"
echo ''
echo "${0##*/} -a [Common flags]"
echo ''
echo "${0##*/} -[l|L]"
echo ''
echo "${0##*/} [-b D|d] -e <full name of port directory in $pdb>"
echo "${0##*/} [-b D|d] -s"
echo ''
echo "${0##*/} --clean-distfiles"
echo "${0##*/} --clean-distfiles-all"
echo ''
echo "${0##*/} -h"
echo ''
echo "--force-config 'make config' for all ports (must be first option)"
echo "-C prevents 'make clean' being run in port directory"
echo "-G prevents recursive 'make config' (unsets --force-config)"
echo '-B prevents creation of the backup package for the installed port'
echo '-b create and keep a backup package of an installed port'
echo '-g create a package of the new port'
echo '-n do not actually make or install any ports'
echo '-t recurse dependencies thoroughly, using all-depends-list'
echo '-v verbose output'
echo '-w save old shared libraries before deinstall'
echo "-u unattended mode -- accept defaults for all but 'make config'"
echo '[-R] -f always rebuild ports (overrides -i)'
echo '-i interactive update mode'
echo '-D prevents cleaning of distfiles'
echo '-d always clean distfiles'
echo "-m <arguments for the 'make' command line>"
echo "-x <avoid building ports as dependencies that match this pattern>"
echo ''
echo '--show-work list what ports are and would be installed'
echo ''
echo '-o replace the installed port with a port from a different origin'
echo '[-R] -r rebuild port, and all ports that depend on it'
echo '-R restart an update, skipping ports already up to date'
echo '-a check all ports, update as necessary'
echo ''
echo '-l list installed ports by category'
echo '-L list installed ports by category, and search for updates'
echo ''
echo '-e expunge a port via pkg_delete, and remove its distfiles'
echo '-s clean out stale ports that used to be depended on'
echo ''
echo '--clean-distfiles offer to delete stale distfiles'
echo '--clean-distfiles-all delete stale distfiles without prompting'
echo ''
echo '-h display this help message'
echo ''
echo 'Please see the portmaster(8) man page for more information'
exit ${1:-1}
}
fail () {
echo ''
echo "===>>> $1"
echo "===>>> Aborting update"
if [ "$$" -eq "$PARENT_PID" ]; then
trap_exit fail
else
safe_exit 1
fi
}
pmkill () {
/bin/kill $1 >/dev/null 2>/dev/null
return $?
}
kill_bad_children () {
# Make parent_N global in case PIDs are random,
# and we have to come back in here after them.
local rc pid ppid command
rc=0
ps -axo pid,ppid,command | while read pid ppid command; do
case "$ppid" in
1) case "$command" in
*" $0 "*) rc=1 ; parent_2=$pid ; pmkill $pid ;;
*dialog*) pmkill $pid ;;
esac
;;
$PARENT_PID)
case "$command" in
# Don't kill this pipeline's subshell, but do chase it
*" $0 "*) rc=1 ; parent_2=$pid ;;
*dialog*) pmkill $pid ;;
esac
;;
$parent_2)
case "$command" in
*" $0 "*) rc=1 ; parent_3=$pid ; pmkill $pid ;;
'make checksum') rc=1 ; parent_3=$pid ; pmkill $pid ;;
*dialog*) pmkill $pid ;;
esac
;;
$parent_3|1)
case "$command" in
\[sh\]|*'/sh '*) rc=1 ; parent_4=$pid ; pmkill $pid ;;
*dialog*) pmkill $pid ;;
esac
;;
$parent_4|1)
case "$command" in
\[sh\]|*'/sh '*) rc=1 ; parent_5=$pid ; pmkill $pid ;;
*dialog*) pmkill $pid ;;
esac
;;
$parent_5|1)
case "$command" in
*'/fetch '*) rc=1 ; pmkill $pid ;;
*dialog*) pmkill $pid ;;
esac
;;
esac
done
return $rc
}
trap_exit () {
local pid
TRAP=yes
if [ -n "$portdir" -a -z "$1" ]; then
echo ''
echo "===>>> Upgrade for $portdir exiting due to signal"
elif [ -z "$1" ]; then
echo "===>>> Exiting due to signal"
fi
if [ "$$" -eq "$PARENT_PID" ]; then
for file in ${TMPDIR}/fetchlog-${PARENT_PID}-*; do
pid=`awk '/^MCS_CHILD_PID / {print $2}' $file 2>/dev/null`
test -n "$pid" || continue
echo -n "===>>> Child process $pid: "
if ! pmkill $pid ; then
if ps -p $pid >/dev/null; then
echo "Did not die!"
fi
fi
rm -f $file
done
while ! kill_bad_children ; do
# cheap way to keep it looping
done
fi
safe_exit 1
}
safe_exit () {
echo ''
test -n "$grep_deps" && rm -f $grep_deps
test -n "$req_deps" && rm -f $req_deps
if [ "$$" -eq "$PARENT_PID" ]; then
test -n "$NO_DEP_UPDATES" && rm -f $NO_DEP_UPDATES
test -n "$IPC_SAVE" && rm -f $IPC_SAVE
test -n "$DI_FILES" && rm -f $DI_FILES && kill_bad_children
if [ -n "$MASTER_RB_LIST" ]; then
case "$MASTER_RB_LIST" in
*/+REQUIRED_BY) ;;
*) rm -f $MASTER_RB_LIST ;;
esac
fi
if [ -z "$TRAP" -a \
-e "${TMPDIR}/f-${PARENT_PID}-package-flag" ]; then
find ${pkgrep}/ -type f -newer ${TMPDIR}/f-${PARENT_PID}-package-flag -delete
fi
for file in ${TMPDIR}/f-${PARENT_PID}-*; do
test -f $file && unlink $file
done
if [ -n "$RESTART" -o -n "$FORCE" ]; then
if [ -z "$TRAP" ]; then
find $pdb -type f -name PM_UPGRADE_DONE_FLAG -delete
fi
fi
if [ -n "$DISPLAY_LIST" ]; then
for f in $DISPLAY_LIST; do
echo "===>>> pkg-message for ${f%/+DISPLAY}"
cat $pdb/$f
echo ''
done
echo "===>>> Done displaying pkg-message files"
fi
else
# Save state for the parent process to read back in
echo "CURRENT_DEPS_O='$CURRENT_DEPS_O'" >> $IPC_SAVE
echo "CURRENT_DEPS_I='$CURRENT_DEPS_I'" >> $IPC_SAVE
echo "IGNOREME_YES='$IGNOREME_YES'" >> $IPC_SAVE
echo "DISPLAY_LIST='$DISPLAY_LIST'" >> $IPC_SAVE
if [ -n "$INTERACTIVE_UPDATE" ]; then
echo "INTERACTIVE_YES='$INTERACTIVE_YES'" >> $IPC_SAVE
echo "INTERACTIVE_NO='$INTERACTIVE_NO'" >> $IPC_SAVE
fi
if [ -n "$URB_YES" ]; then
echo "URB_DONE_LIST='$URB_DONE_LIST'" >> $IPC_SAVE
fi
if [ -n "$FORCE" ]; then
echo "FORCE_DONE_LIST='$FORCE_DONE_LIST'" >> $IPC_SAVE
fi
fi
exit ${1:-0}
}
update_contents () {
local tempfile
tempfile=`mktemp -t tempfile-${new_port}`
sed "s/@pkgdep $1/@pkgdep $2/" $dep_port_contents > $tempfile &&
mv $tempfile $pdb/$dep_port/+CONTENTS
chmod 644 $pdb/$dep_port/+CONTENTS
if [ -n "$oldportdir" ]; then
sed "s%N:${oldportdir}\$%N:${newportdir}%" $dep_port_contents > $tempfile &&
mv $tempfile $pdb/$dep_port/+CONTENTS
chmod 644 $pdb/$dep_port/+CONTENTS
fi
}
dep_warn () {
local num_ports1
echo ''
echo "===>>> Warning! Potential unrecorded dependencies on $new_port"
echo "===>>> From existing +CONTENTS files:"
grep -B1 DEPORIGIN:$upg_origin$ $pdb/*/+CONTENTS |
sort -u | sed -e "s#$pdb/##" -e 1d
num_ports1=`grep DEPORIGIN:$upg_origin$ $pdb/*/+CONTENTS |
sort -u | wc -l | awk '{print $1}'`
echo "===>>> $num_ports1 ports"
echo ''
}
update_reqfile () {
local num_ports2 sdiff_deps
dep_warn
num_ports2=`wc -l $req_deps | awk '{print $1}'`
echo "===>>> From $pdb/$upg_port/+REQUIRED_BY:"
cat $req_deps
echo "===>>> $num_ports2 ports"
echo ''
echo "===>>> Use dependencies from existing +CONTENTS files [c]"
echo "===>>> Use dependencies from existing +REQUIRED_BY file [r]"
echo "===>>> Use sdiff to edit both files into a new file [s]"
echo ''
if [ -z "$UNATTENDED" ]; then
echo -n "===>>> Update dependency list? [r] "
read DEPUPDATE
case "$DEPUPDATE" in
[cC]) mv $grep_deps $req_deps ; unset grep_deps ;;
[sS]) sdiff_deps=`mktemp -t sdiff-deps-${short_port}`
sdiff -o $sdiff_deps --text --suppress-common-lines \
--width=`tput columns` $req_deps $grep_deps
mv $sdiff_deps $req_deps
;;
esac
else
echo "===>>> Default (use +REQUIRED_BY file) in unattended mode"
fi
}
update_port () {
local upd upd_origin
if [ -n "$NO_DEP_UPDATES" ]; then
rm -f $NO_DEP_UPDATES
unset NO_DEP_UPDATES
fi
case "$1" in
-p) upd=$2
test -n "$URB_YES" && upd_origin=${2#$pd/}
;;
*) upd=$1
test -n "$URB_YES" && upd_origin=`origin_from_pdb $pdb/$1`
;;
esac
echo "===>>> Launching child to update ${upd#$pd/}"
echo ''
if [ -z "$NO_ACTION" ]; then
($0 $ARGS $@) || fail "Update for $upd failed"
. $IPC_SAVE
# Only do this if we are in the +REQUIRED_BY code to
# avoid nasty (potential) circular dependencies
if [ -n "$URB_YES" ]; then
URB_DONE_LIST="${URB_DONE_LIST}${upd_origin}:"
fi
else
test -n "$VERBOSE" &&
echo "===>>> Build canceled due to -n flag"
fi
if [ -n "$UPDATE_ALL" ]; then
echo "===>>> Returning to update check of installed ports"
elif [ -n "$UPDATE_REQ_BYS" ]; then
return 0
elif [ -n "$CONFIG_ONLY" ]; then
echo "===>>> Continuing 'make config' dependency check for $portdir"
else
echo "===>>> Returning to dependency check for $portdir"
fi
return 0
}
check_interactive () {
local UPD_OR_NOT
if [ -n "$INTERACTIVE_UPDATE" ]; then
case "$INTERACTIVE_YES" in
*:${1}:*) return 0 ;;
esac
case "$INTERACTIVE_NO" in
*:${1}:*) return 1 ;;
esac
echo -n "===>>> Update ${1}? [y] "
read UPD_OR_NOT
case "$UPD_OR_NOT" in
[nN]*) INTERACTIVE_NO="${INTERACTIVE_NO}${1}:"
return 1
;;
*) INTERACTIVE_YES="${INTERACTIVE_YES}${1}:" ;;
esac
fi
return 0
}
iport_from_origin () {
local dir
dir=`grep -l "@comment ORIGIN:${1}$" $pdb/*/+CONTENTS`
# It should not happen that more than one port meets this
# requirement, but it can if the pkg data is corrupted.
dir="${dir%%/+CONTENTS*}"
dir="${dir#$pdb/}"
echo $dir
}
origin_from_pdb () {
grep '@comment ORIGIN' ${1}/+CONTENTS 2>/dev/null | cut -f2 -d':'
}
check_for_updates () {
local upd_port port_ver do_update
upd_port=`origin_from_pdb $pdb/$1`
if [ -z "$upd_port" ]; then
if [ -n "$VERBOSE" ]; then
echo "===>>> No ORIGIN in $pdb/$1/+CONTENTS"
echo ''
fi
return 0
fi
if [ -d "$pd/$upd_port" ]; then
if ! cd $pd/$upd_port 2>/dev/null; then
if [ -e "$pdb/$1/+IGNOREME" ]; then
echo "===>>> Warning: Unable to cd to $pd/$upd_port"
echo "===>>> Continuing due to $pdb/$1/+IGNOREME"
return 0
else
fail "Cannot cd to port directory: $pd/$upd_port"
fi
fi
port_ver=`make $PM_MAKE_ARGS -V PKGNAME`
[ -z "$port_ver" ] && fail "Is $pd/$upd_port/Makefile missing?"
if [ "$1" = "$port_ver" ]; then
if [ -z "$LIST" -a -z "$LIST_PLUS" ]; then
# Keep list both ways to increase performance
CURRENT_DEPS_O="${CURRENT_DEPS_O}${upd_port}:"
CURRENT_DEPS_I="${CURRENT_DEPS_I}${1}:"
fi
if [ -n "$FORCE" ]; then
if [ ! -e "$pdb/$1/PM_UPGRADE_DONE_FLAG" ]; then
do_update=yes
fi
elif [ -n "$URB_YES" -a -n "$RESTART" ]; then
if [ ! -e "$pdb/$1/PM_UPGRADE_DONE_FLAG" ]; then
if grep -q $1 $MASTER_RB_LIST; then
do_update=yes
fi
else
return 0
fi
else
return 0
fi
else
case `pkg_version -t $1 $port_ver` in
\<) do_update=yes ;;
=) ;; # Should not be reached
*) if [ -n "$VERBOSE" ]; then
echo ''
echo " ===>>> Port version $port_ver does not"
echo " ===>>> seem newer than installed $1"
echo ''
fi
;;
esac
fi
else
# This will fail if it doesn't exist anymore
# It will return 1 if we know nothing about the port
find_moved_port $upd_port || return 0
# If the port has moved, we have to update it
do_update=yes
fi
if [ -n "$do_update" ]; then
case "$2" in
list) if [ -z "$newportdir" ]; then
echo " ===>>> New version available: $port_ver"
num_updates=$(( $num_updates + 1 ))
else
unset newportdir
fi
return 0
;;
esac
if ! check_interactive $1 ; then
return 0
fi
update_port $1 || return 1
fi
return 0
}
find_moved_port () {
# newportdir and oldportdir are used globally
local sf IFS l
sf=$1
# To avoid having each word of the reason treated separately
IFS='
'
for l in `grep "^$sf" /usr/ports/MOVED`; do
case "$l" in
${sf}\|\|*) fail "The $sf port has been deleted: ${l##*|}"
;;
${sf}\|*) newportdir=${l#*\|}
newportdir=${newportdir%%\|*}
echo ''
echo "===>>> The $sf port moved to $newportdir"
echo "===>>> Reason: ${l##*|}"
echo ''
find_moved_port $newportdir
;;
esac
done
if [ -z "$newportdir" ]; then
echo ''
echo "===>>> No $pd/$1 exists, and no information"
echo "===>>> about $1 can be found in $pd/MOVED"
echo ''
return 1
fi
oldportdir=$1
return 0
}
ports_by_category () {
local pkg
for pkg in $pdb/*; do
if [ -s "$pkg/+REQUIRED_BY" ]; then
if grep -q '^@pkgdep ' $pkg/+CONTENTS 2>/dev/null; then
branches="$branches $pkg"
else
trunks="$trunks $pkg"
fi
else
if grep -q '^@pkgdep ' $pkg/+CONTENTS 2>/dev/null; then
leaves="$leaves $pkg"
else
test -s $pkg/+CONTENTS && roots="$roots $pkg"
fi
fi
done
}
dependency_check () {
local dep_port_list dep_port ign_p cur_p upd_args p op old_p conflicts glob conflict_port
# Print a message here because sometimes list generation takes
# a long time to return.
echo "===>>> Gathering dependency list for $portdir from ports"
dep_port_list=`make $PM_MAKE_ARGS $1 | sort -u`
if [ -z "$dep_port_list" ]; then
echo "===>>> No dependencies for $portdir"
return 0
else
if [ -n "$CONFIG_ONLY" ]; then
echo "===>>> Starting recursive 'make config' check"
else
echo "===>>> Starting dependency check"
fi
fi
for dep_port in $dep_port_list; do
case "$dep_port" in
*${EXCL}*) test -n "$VERBOSE" &&
echo "===>>> Skipping ${dep_port#$pd/} because it matches the pattern: *${EXCL}*"
continue
;;
esac
if [ -n "$SHOW_WORK" ]; then
orig=${dep_port#$pd/}
dir=`iport_from_origin $orig`
case "$dir" in
'') echo "===>>> NOT INSTALLED $orig" ;;
*) echo "===>>> Installed $orig" ;;
esac
continue
fi
test -n "$VERBOSE" &&
echo "===>>> Checking dependency: $dep_port"
# Do this first to catch out of date dependencies
if [ -n "$CONFIG_ONLY" ]; then
case "$CONFIG_SEEN_LIST" in
*:${dep_port#$pd/}:*) continue ;;
esac
CONFIG_SEEN_LIST="${CONFIG_SEEN_LIST}${dep_port#$pd/}:"
fi
case "$CURRENT_DEPS_O" in
*:${dep_port#$pd/}:*) continue ;;
esac
case "$FORCE_DONE_LIST" in
*:${dep_port#$pd/}:*) continue ;;
esac
cd $dep_port &&
conflicts=`make BEFOREPORTMK=yes $PM_MAKE_ARGS -V CONFLICTS`
for glob in $conflicts; do
conflict_port=`pkg_info -I $glob 2>/dev/null |
cut -f1 -d' '`
if [ -n "$conflict_port" ]; then
echo ''
echo "===>>> The dependency for ${dep_port#$pd/}"
echo " seems to be handled by $conflict_port"
echo ''
dep_port="$pd/`origin_from_pdb $pdb/$conflict_port`"
fi
done
ign_p=''
cur_p=`iport_from_origin ${dep_port#$pd/}`
if [ -n "$cur_p" ]; then
upd_args=$cur_p
ign_p=$cur_p
else
upd_args="-p $dep_port" # Sensible default
# Check to see if the dependency has moved because
# if so, we need to update the old port to fix it
p=${dep_port#$pd/}
op=`sed -ne "s#\([^|]*\)|$p|.*#\1#p" $pd/MOVED`
# In case there is more than one match, use the latest
op=`echo $op | sed 's/.* //'`
if [ -n "$op" ]; then
old_p=`iport_from_origin ${op}`
if [ -n "$old_p" ]; then
upd_args=$old_p
ign_p=$old_p
fi
fi
fi
if [ -e "$pdb/$ign_p/+IGNOREME" ]; then
if [ -n "$VERBOSE" ]; then
echo ''
echo "===>>> Skipping $ign_p due to +IGNOREME file"
echo ''
fi
continue
fi
if [ -n "$FORCE" ]; then
if [ ! -e "$pdb/$cur_p/PM_UPGRADE_DONE_FLAG" ]; then
echo "===>>> Forcing update for $dep_port"
update_port $upd_args
continue
fi
fi
if [ -z "$cur_p" -a -n "$old_p" ]; then
cur_p=$old_p
fi
if [ -n "$URB_YES" -a -n "$cur_p" ]; then
case "$URB_DONE_LIST" in
*:${dep_port#$pd/}:*) continue ;;
esac
if grep -q $cur_p $MASTER_RB_LIST; then
if ! check_interactive $cur_p ; then
continue
fi
if [ -z "$RESTART" -a -z "$FORCE" ]; then
update_port $cur_p || return 1
else
check_for_updates $cur_p || return 1
fi
continue
fi
fi
if [ -n "$cur_p" ]; then
check_for_updates $cur_p
else
if ! check_interactive $dep_port ; then
continue
fi
update_port -p $dep_port
fi
done
if [ -n "$CONFIG_ONLY" ]; then
echo "===>>> Recursive 'make config' check complete for $portdir"
else
echo "===>>> Dependency check complete for $portdir"
echo ''
fi
[ -n "$SHOW_WORK" ] && safe_exit
}
unset_recursive_config () {
unset CONFIG_SEEN_LIST CONFIG_ONLY
}
req_by_error () {
local DISCARD
echo "===>>> WARNING! $pdb/$1/+REQUIRED_BY "
echo "===>>> shows that $2 requires $1, but "
echo "===>>> $2 does not seem to be installed"
echo -n "===>>> Press Enter to proceed "
read DISCARD
}
find_and_delete_distfiles () {
# old_distpattern is used for subsequent invocations of the function
local distpattern file DELORNOT
distpattern=${1%[_-]*}
[ "$distpattern" = "$old_distpattern" ] && return 0
for file in ${distpattern}*; do
# This generally means the pattern did not match
case "$file" in
*\*) old_distpattern=$distpattern
find_and_delete_distfiles ${distpattern}
continue
;;
esac
case "$distfiles" in
*${file}*)
if [ -n "$VERBOSE" -a -z "$do_delete" ]; then
echo "===>>> Keeping current distfile: $file"
fi
continue # Do not delete current version
;;
*) [ ! -d "$file" ] || continue
if [ -e "$DI_FILES" ]; then
grep -q \(${file}\) $DI_FILES && continue
fi
if [ -n "$ALWAYS_SCRUB_DISTFILES" ]; then
echo "===>>> Deleting stale distfile: $file"
rm -f $file
continue
fi
echo -n "===>>> Delete $file? [n] "
read DELORNOT
case "$DELORNOT" in
[yY]) rm -f $file ;;
esac
;;
esac
done
}
delete_stale_distfiles () {
# distfiles is used globally
# inherit distdir from the environment, but only modify our copy
local distdir dist_subdir file DELORNOT distfile
dist_subdir=`make BEFOREPORTMK=yes $PM_MAKE_ARGS -V DIST_SUBDIR`
test -n "$dist_subdir" && distdir="${distdir}/${dist_subdir}"
# Also used in find_and_delete_distfiles() to make sure
# we do not delete the current set of distfiles
distfiles=`make $PM_MAKE_ARGS -V ALLFILES`
if [ -d "$distdir" ]; then
cd $distdir || fail "cd to $distdir failed!"
else
echo '' ; echo ''
echo "===>>> $distdir does not exist, therefore we"
echo " will assume that all relevant distfiles are gone."
echo ''
return 0
fi
# If these two match, it means that the distfiles in the +CONTENTS
# file are the current set, so do not delete them.
if [ ! "$cont_distfiles" = "${distfiles% }" ]; then
for file in $cont_distfiles; do
[ -f $file ] || continue
if [ -n "$ALWAYS_SCRUB_DISTFILES" ]; then
echo "===>>> Deleting stale distfile: $file"
rm -f $file
continue
fi
echo -n "===>>> Delete $file? [n] "
read DELORNOT
case "$DELORNOT" in
[yY]) rm -f $file ;;
esac
done
fi
# Eventually we will hide this behind an "aggressive distfile purge"
# flag, but until the DISTFILE stuff is well populated in +CONTENTS,
# keep doing it both ways.
for distfile in $distfiles; do
find_and_delete_distfiles $distfile
done
}
delete_all_distfiles () {
# do_delete is used globally
local DELORNOT
if ! cd $pd/$1 2>/dev/null; then
echo ''
echo "===>>> No $pd/$1 to cd to in order to delete"
echo " old distfiles, remove by hand if desired"
else
if [ -n "$ALWAYS_SCRUB_DISTFILES" ]; then
echo "===>>> Deleting all distfiles for $1"
do_delete=1
else
echo -n "===>>> Delete all distfiles for ${1}? [n] "
read DELORNOT
case "$DELORNOT" in
[yY]) do_delete=1 ;;
*) delete_stale_distfiles ;;
esac
fi
if [ -n "$do_delete" ]; then
delete_stale_distfiles
rm -f $distfiles
find $pd/distfiles/ -type d -empty -delete
fi
fi
}
backup_package () {
# bu_pkg_name is used globally
echo "===>>> Creating a backup package for old version $1"
if pkg_create -b $1; then
bu_pkg_name=`echo ${1}.*`
mv $bu_pkg_name $pkgrep/ &&
echo " ===>>> Package can be found in $pkgrep"
else
local PROCEED
if [ -z "$UNATTENDED" ]; then
echo ''
echo "===>>> Backup package creation failed for ${1}!"
echo ''
echo "===>>> Ignore this error [i]"
echo "===>>> Abort update [a]"
echo ''
echo -n "===>>> How would you like to proceed? [i] "
read PROCEED
case "$PROCEED" in
a) fail "Backup package creation failed for $1" ;;
esac
else
fail "Backup package creation failed for $1"
fi
fi
}
# Read a global rc file first
if [ -r /etc/portmaster.rc ]; then
. /etc/portmaster.rc
fi
# Read a local one next, and allow the command line to override
if [ -r "$HOME/.portmasterrc" ]; then
. $HOME/.portmasterrc
fi
# Set default values here so that they can be overriden above
if [ -z "$pd" ]; then
pd=`make BEFOREPORTMK=yes -f/usr/share/mk/bsd.port.mk -V PORTSDIR`
export pd
fi
if [ -z "$pdb" ]; then
pdb=`make -f/usr/share/mk/bsd.port.mk -V PKG_DBDIR`
export pdb
fi
if [ -z "$distdir" ]; then
distdir=`make BEFOREPORTMK=yes -f/usr/share/mk/bsd.port.mk -V DISTDIR`
export distdir
fi
case "$1" in
--clean-distfiles) CLEAN_DISTFILES=yes ;;
--clean-distfiles-all) CLEAN_DISTFILES=yes ; ALL=yes ;;
--show-work) SHOW_WORK=yes ; RECURSE_THOROUGH=yes ; shift ;;
--force-config) FORCE_CONFIG=yes ; export FORCE_CONFIG ; shift ;;
esac
read_distinfos () {
local origin distinfo disc1 file disc2
for pkg in ${pdb}/*; do
[ -d $pkg ] || continue
origin=`origin_from_pdb $pkg`
if [ ! -d "$pd/$origin" ]; then
find_moved_port $origin >/dev/null || continue
origin=$newportdir
fi
cd $pd/$origin 2>/dev/null || continue
distinfo=`make $PM_MAKE_ARGS -V MD5_FILE`
if [ -s "$distinfo" ]; then
while read disc1 file disc2; do
echo $file >> $DI_FILES
done < $distinfo
fi
done
}
if [ -n "$CLEAN_DISTFILES" ]; then
# Set the file name here because this function is
# usually called in a subshell.
DI_FILES=`mktemp -t DI-FILES-$PARENT_PID`
export DI_FILES
echo "===>>> Gathering distinfo list for installed ports"
read_distinfos
echo "===>>> Checking for stale distfiles"
for df in `find $distdir -type f`; do
f=${df#$distdir/}
if ! grep -q \(${f}\) $DI_FILES; then
if [ -n "$ALL" ]; then
echo "===>>> Deleting $f"
rm $df
else
echo -n "===>>> Delete stale file: ${f}? [y] "
read DEL_OR_NOT
case "$DEL_OR_NOT" in
[nN]*) continue ;;
*) rm $df ;;
esac
fi
fi
done
safe_exit
fi
# Save switches for potential child processes
while getopts 'BCDGLRabde:fghilm:nop:r:stuvwx:' COMMAND_LINE_ARGUMENT ; do
case "${COMMAND_LINE_ARGUMENT}" in
B) NO_BACKUP=yes; ARGS="-B $ARGS" ;;
C) DONT_PRE_CLEAN=yes; ARGS="-C $ARGS" ;;
D) DONT_SCRUB_DISTFILES=yes; ARGS="-D $ARGS" ;;
G) NO_RECURSIVE_CONFIG=yes; unset FORCE_CONFIG ; ARGS="-G $ARGS" ;;
L) LIST_PLUS=yes ;;
R) RESTART=yes ; ARGS="-R $ARGS" ;;
a) UPDATE_ALL=yes ;;
b) BACKUP=yes; ARGS="-b $ARGS" ;;
d) ALWAYS_SCRUB_DISTFILES=yes; ARGS="-d $ARGS" ;;
e) EXPUNGE=$OPTARG ;;
f) FORCE=yes
FORCE_DONE_LIST=':'
export FORCE FORCE_DONE_LIST
;;
g) MAKE_PACKAGE=yes; ARGS="-g $ARGS" ;;
h) usage 0 ;;
i) INTERACTIVE_UPDATE=yes; ARGS="-i $ARGS" ;;
l) LIST=yes ;;
m) PM_MAKE_ARGS=$OPTARG
export PM_MAKE_ARGS # For 'make checksum'
ARGS="-m $PM_MAKE_ARGS $ARGS"
;;
n) NO_ACTION=yes; ARGS="-n $ARGS" ;;
o) REPLACE_ORIGIN=yes ;;
p) portdir="${OPTARG#$pd/}" ; portdir=${portdir%/} ;;
r) UPDATE_REQ_BYS=yes; upg_port=$OPTARG ;;
s) CLEAN_STALE=yes ;;
t) RECURSE_THOROUGH=yes; ARGS="-t $ARGS" ;;
u) UNATTENDED=yes; ARGS="-u $ARGS" ;;
v) VERBOSE=yes; ARGS="-v $ARGS" ;;
w) SAVE_SHARED=yes; ARGS="-w $ARGS" ;;
x) EXCL=$OPTARG ; ARGS="-x $EXCL $ARGS" ;;
*) usage ;;
esac
done
shift $(( $OPTIND - 1 ))
: ${EXCL:=Ishouldthinkofsomethingclevertosayhere}
if [ -n "$LIST" -o -n "$LIST_PLUS" ]; then
ports_by_category
num_roots=0
num_trunks=0
num_branches=0
num_leaves=0
num_updates=0
echo "===>>> Root ports (No dependencies, not depended on)"
for port in $roots; do
echo "===>>> ${port##*/}"
[ -n "$LIST_PLUS" ] && check_for_updates ${port##*/} list
num_roots=$(( $num_roots + 1 ))
done
echo "===>>> $num_roots root ports"
echo ''
echo "===>>> Trunk ports (No dependencies, are depended on)"
for port in $trunks; do
echo "===>>> ${port##*/}"
[ -n "$LIST_PLUS" ] && check_for_updates ${port##*/} list
num_trunks=$(( $num_trunks + 1 ))
done
echo "===>>> $num_trunks trunk ports"
echo ''
echo "===>>> Branch ports (Have dependencies, are depended on)"
for port in $branches; do
echo "===>>> ${port##*/}"
[ -n "$LIST_PLUS" ] && check_for_updates ${port##*/} list
num_branches=$(( $num_branches + 1 ))
done
echo "===>>> $num_branches branch ports"
echo ''
echo "===>>> Leaf ports (Have dependencies, not depended on)"
for port in $leaves; do
echo "===>>> ${port##*/}"
[ -n "$LIST_PLUS" ] && check_for_updates ${port##*/} list
num_leaves=$(( $num_leaves + 1 ))
done
echo "===>>> $num_leaves leaf ports"
echo ''
num_ports=$(( $num_roots + $num_trunks + $num_branches + $num_leaves ))
echo "===>>> $num_ports total installed ports"
if [ "$num_updates" -gt 1 ]; then
echo " ===>>> $num_updates have new versions available"
elif [ "$num_updates" -eq 1 ]; then
echo " ===>>> 1 has a new version available"
fi
exit 0
fi
find_contents_distfiles () {
[ -n "$DONT_SCRUB_DISTFILES" ] && return 0
# cont_distfiles is used globally
local file
for file in `grep DISTFILE $pdb/$1/+CONTENTS | cut -f2 -d:`; do
cont_distfiles="${cont_distfiles} ${file#*/}"
done
cont_distfiles=${cont_distfiles# }
}
if [ -n "$EXPUNGE" ]; then
if [ -d "$pdb/$EXPUNGE" ]; then
origin=`origin_from_pdb $pdb/$EXPUNGE`
deplist=`grep -l DEPORIGIN:$origin$ $pdb/*/+CONTENTS`
if [ -n "$deplist" ]; then
echo "===>>> Warning: ports with dependencies on ${EXPUNGE}:"
for dep in $deplist; do echo ${dep%/+CON*}; done
exit 1
fi
[ -n "$BACKUP" ] && backup_package $EXPUNGE
find_contents_distfiles $EXPUNGE
echo "===>>> Running pkg_delete -f $EXPUNGE"
pkg_delete -f $EXPUNGE
if [ -z "$DONT_SCRUB_DISTFILES" ]; then
delete_all_distfiles $origin
fi
exec $0 -s $ARGS
else
fail "No such directory/port: $pdb/$EXPUNGE"
fi
exit 0 # Should not be reached
fi
if [ -n "$CLEAN_STALE" ]; then
if [ -z "$do_not_delete" ]; then
do_not_delete=':'
export do_not_delete
fi
for file in `find $pdb/ -name \+REQUIRED_BY -empty` ; do
dir="${file%/+REQUIRED_BY}"
iport=${dir#$pdb/}
case "$do_not_delete" in
*:${iport}:*) continue ;;
esac
echo ''
origin=`origin_from_pdb $dir`
deplist=`grep -l DEPORIGIN:$origin$ $pdb/*/+CONTENTS`
if [ -n "$deplist" ]; then
echo "===>>> Warning: unrecorded dependencies on ${iport}:"
for dep in $deplist; do echo ${dep%/+CON*}; done
continue
fi
pkg_info $iport
echo -n "===>>> ${iport} is no longer depended on, delete? [n] "
read YESNO
case "$YESNO" in
[yY]) [ -n "$BACKUP" ] && backup_package $iport
find_contents_distfiles $iport
echo "===>>> Running pkg_delete -f $iport"
pkg_delete -f ${iport}
if [ -z "$DONT_SCRUB_DISTFILES" ]; then
delete_all_distfiles $origin
fi
exec $0 -s $ARGS
;;
*) echo -n " ===>>> Remove empty +REQUIRED_BY file? [n] "
read DELORNOT
case "$DELORNOT" in
[yY]) rm -f $file ;;
*) do_not_delete="${do_not_delete}${iport}:" ;;
esac
;;
esac
done
exit 0
fi
test -n "$FORCE" && unset INTERACTIVE_UPDATE
if [ -n "$UNATTENDED" ]; then
unset INTERACTIVE_UPDATE
if [ -z "$DONT_SCRUB_DISTFILES" -a -z "$ALWAYS_SCRUB_DISTFILES" ]; then
ALWAYS_SCRUB_DISTFILES=yes
ARGS="-d $ARGS"
fi
fi
if [ "$$" -eq "$PARENT_PID" ]; then
CURRENT_DEPS_O=':'
CURRENT_DEPS_I=':'
IGNOREME_YES=':'
DISPLAY_LIST=''
IPC_SAVE=`mktemp -t ipc_save-$PARENT_PID`
export CURRENT_DEPS_O CURRENT_DEPS_I IGNOREME_YES DISPLAY_LIST IPC_SAVE
PORTS_PREFIX=`make BEFOREPORTMK=yes $PM_MAKE_ARGS -f/usr/share/mk/bsd.port.mk -VPREFIX`
export PORTS_PREFIX
if [ -n "$INTERACTIVE_UPDATE" ]; then
INTERACTIVE_YES=':'
INTERACTIVE_NO=':'
export INTERACTIVE_YES INTERACTIVE_NO
fi
if [ -n "$UPDATE_REQ_BYS" ]; then
URB_DONE_LIST=':'
export URB_DONE_LIST
fi
if [ -n "$UPDATE_REQ_BYS" -o -n "$FORCE" ]; then
if [ -z "$RESTART" ]; then
find $pdb -type f -name PM_UPGRADE_DONE_FLAG -delete
fi
fi
if [ -z "$CONFIG_ONLY" -a -z "$NO_RECURSIVE_CONFIG" ]; then
NO_DEP_UPDATES=`mktemp -t no_dep_updates-$PARENT_PID`
CONFIG_SEEN_LIST=':'
CONFIG_ONLY=yes
export CONFIG_SEEN_LIST CONFIG_ONLY
fi
if [ -z "$NO_BACKUP" ]; then
pkgrep=`make $PM_MAKE_ARGS -f/usr/share/mk/bsd.port.mk -VPKGREPOSITORY`
export pkgrep
mkdir -p $pkgrep
if [ -z "$BACKUP" ]; then
touch ${TMPDIR}/f-${PARENT_PID}-package-flag
fi
fi
if [ $# -gt 1 -a -z "$REPLACE_ORIGIN" ]; then
if [ -z "$NO_RECURSIVE_CONFIG" ]; then
for port in $@; do
($0 $ARGS $port) ||
fail "Update for $port failed"
. $IPC_SAVE
done
unset_recursive_config
echo ''
echo "===>>> Starting build for ports: <<<==="
echo "===>>> $@ <<<==="
echo ''
fi
for port in $@; do
($0 $ARGS $port) || fail "Update for $port failed"
. $IPC_SAVE
done
safe_exit
fi
else
# Zero out this file so that we can save our data to it safely
> $IPC_SAVE
fi
if [ -n "$UPDATE_ALL" ]; then
# Set the file name here so it's visible to the parent
DI_FILES=`mktemp -t DI-FILES-$PARENT_PID`
export DI_FILES
echo "===>>> Gathering distinfo list for installed ports in background"
(read_distinfos)&
echo "===>>> Starting check of installed ports for available updates"
ports_by_category
if [ -n "$CONFIG_ONLY" ]; then
echo "===>>> Checking ports for recursive 'make config'"
for pkg in $roots $trunks $branches $leaves; do
test -n "$VERBOSE" &&
echo "===>>> Checking installed port: ${pkg#$pdb/}"
case "$pkg" in
*${EXCL}*) test -n "$VERBOSE" &&
echo "===>>> Skipping ${pkg#$pdb/} because it matches the pattern: *${EXCL}*"
continue
;;
esac
case "$CURRENT_DEPS_I" in
*:${pkg#$pdb/}:*) continue ;;
esac
orig=`origin_from_pdb $pkg`
case "$CONFIG_SEEN_LIST" in
*:${orig}:*) continue ;;
esac
CONFIG_SEEN_LIST="${CONFIG_SEEN_LIST}${orig}:"
check_for_updates ${pkg#$pdb/} || fail 'Update failed'
done
if [ -e "$NO_DEP_UPDATES" ]; then
echo "===>>> The 'make config' check revealed no ports to update"
safe_exit
fi
unset_recursive_config
echo ''
echo "===>>> Starting build for ports that need updating <<<==="
echo ''
fi
BUILDING=yes
export BUILDING
for pkg in $roots $trunks $branches $leaves; do
case "$pkg" in
*${EXCL}*) test -n "$VERBOSE" &&
echo "===>>> Skipping ${pkg#$pdb/} because it matches the pattern: *${EXCL}*"
continue
;;
esac
if [ ! -d "$pkg" ]; then
# This port probably got updated as a dependency
# for something else
continue
fi
if [ -n "$FORCE" ]; then
p=`origin_from_pdb $pkg`
case "$FORCE_DONE_LIST" in
*:${p}:*) test -n "$VERBOSE" &&
echo "===>>> Update for $p already done"
continue
;;
esac
if [ -e "${pkg}/PM_UPGRADE_DONE_FLAG" ]; then
test -n "$VERBOSE" &&
echo "===>>> Update for $p already done"
continue
fi
echo "===>>> Forcing update for ${pkg#$pdb/}"
update_port ${pkg#$pdb/}
continue
else
test -n "$VERBOSE" &&
echo "===>>> Checking installed port: ${pkg#$pdb/}"
fi
case "$CURRENT_DEPS_I" in
*:${pkg#$pdb/}:*) continue ;;
esac
check_for_updates ${pkg#$pdb/} || fail 'Update failed'
done
echo "===>>> Update check of installed ports complete"
safe_exit
fi
if [ -n "$REPLACE_ORIGIN" ]; then
portdir="${1#$pd/}"
portdir="${portdir%/}"
newportdir=$portdir
if [ -d "$pdb/$2" ]; then
# Handle the portmaster'ish way to specify the port
upg_port=$2
else
# Handle existing portupgrade syntax
upg_port=`grep -l " ORIGIN:${2#$pd/}$" $pdb/*/+CONTENTS`
[ -n "$upg_port" ] ||
upg_port=`grep -l " ORIGIN:${2#$pd/}" $pdb/*/+CONTENTS`
[ -n "$upg_port" ] ||
fail "Cannot find an installed port with ORIGIN $2"
upg_port="${upg_port%/+CONTENTS}"
upg_port="${upg_port#$pdb/}"
fi
oldportdir=`origin_from_pdb $pdb/$upg_port`
fi
# Exercised in the common case of not using -p option
case "$portdir" in
'') argv=${1%/}
case "$argv" in
'') test -z "$UPDATE_REQ_BYS" && usage ;;
${pd}/*) portdir="${argv#$pd/}" ;;
/*) upg_port="${argv##*/}" ;;
\.) portdir="${PWD##*/ports/}" ;;
*) if [ -d "${pd}/${argv}" ]; then
portdir=$argv
else
upg_port=$argv
fi
;;
esac
esac
case "$upg_port" in
'') test -n "$portdir" || usage
old_port_dir=`iport_from_origin ${portdir}`
if [ -n "$old_port_dir" ]; then
upg_port="${old_port_dir}"
fi
;;
*) if [ ! -d "$pdb/$upg_port" ]; then
glob_dirs=`find $pdb -type d -name ${upg_port}\*`
case "$glob_dirs" in
*\*) fail "$upg_port did not match an installed port" ;;
*) for dir in $glob_dirs; do
echo -n "===>>> Update ${dir#$pdb/}? [n] "
read GLOB_DIR
case "$GLOB_DIR" in
[yY]) upg_port=${dir#$pdb/}
selected=yes
break
;;
esac
done
test -n "$selected" || usage
;;
esac
fi
echo "===>>> Port to upgrade: $upg_port"
if [ -z "$portdir" ]; then
portdir=`origin_from_pdb $pdb/$upg_port`
[ -n "$portdir" ] ||
fail "No ORIGIN in $pdb/$upg_port/+CONTENTS"
fi
;;
esac
if [ -e "$pdb/$upg_port/+IGNOREME" ]; then
echo ''
if [ -z "$UNATTENDED" ]; then
if [ -z "$BUILDING" ]; then
echo "===>>> $upg_port has an +IGNOREME file"
echo -n "===>>> Update anyway? [n] "
read UPD_OR_NOT
case "$UPD_OR_NOT" in
[yY]*) IGNOREME_YES="${IGNOREME_YES}${upg_port}:" ;;
*) safe_exit ;;
esac
else
case "$IGNOREME_YES" in
*:${upg_port}:*) ;;
*) safe_exit ;;
esac
fi
else
echo "===>>> $upg_port has an +IGNOREME file, ignoring"
safe_exit
fi
fi
if [ -d "$pd/$portdir" ]; then
echo "===>>> Port directory: $pd/$portdir"
else
find_moved_port $portdir || usage
portdir=$newportdir
fi
cd $pd/$portdir || usage
for state in FORBIDDEN BROKEN IGNORE; do
state_set=`make -V $state`
if [ -n "$state_set" ]; then
echo "===>>> This port is marked $state:"
echo "===>>> $state_set"
echo "===>>> If you are sure you can build it, remove the"
echo " $state line in the Makefile and try again."
safe_exit 1
fi
done
if [ "$$" -eq "$PARENT_PID" -a -z "$SHOW_WORK" ]; then
# Set the file name here so it's visible to the parent
DI_FILES=`mktemp -t DI-FILES-$PARENT_PID`
export DI_FILES
echo "===>>> Gathering distinfo list for installed ports in background"
(read_distinfos)&
fi
# Do these things first time through, with or without 'make config'
if [ -z "$BUILDING" -a -z "$SHOW_WORK" ]; then
dofetch () {
echo "===>>> Launching 'make checksum' for $portdir in background"
fetchlog=`mktemp -t fetchlog-${PARENT_PID}-${portdir##*/}`
(make -DBATCH $PM_MAKE_ARGS checksum >> $fetchlog 2>&1 &&
{ rm -f $fetchlog; \
rm -f ${TMPDIR}/f-${PARENT_PID}-*-${portdir##*/}.*; exit 0;}
allfiles=`make $PM_MAKE_ARGS -V ALLFILES`
make $PM_MAKE_ARGS delete-distfiles RESTRICTED_FILES="${allfiles}" \
>> $fetchlog 2>&1 &&
echo "===>>> RE-STARTING FETCH <<<===" >> $fetchlog
make $PM_MAKE_ARGS checksum >> $fetchlog 2>&1; \
rm -f ${TMPDIR}/f-${PARENT_PID}-*-${portdir##*/}.*; \
rm -f $fetchlog)&
echo "MCS_CHILD_PID $!" >> $fetchlog
}
distfiles=`make $PM_MAKE_ARGS -V ALLFILES`
for file in $distfiles; do
flag_file=f-${PARENT_PID}-${file}
if ! ls ${TMPDIR}/${flag_file}-* >/dev/null 2>&1; then
mktemp -t ${flag_file}-${portdir##*/} >/dev/null
else
DONT_FETCH=yes
break
fi
done
test -z "$DONT_FETCH" && dofetch
TESTINT=`make -V IS_INTERACTIVE`
if [ -n "$TESTINT" ]; then
echo ''
echo "===>>> Warning: $portdir is interactive, and will likely"
echo " reqire attenton during the build"
echo ''
echo -n "===>>> Press the [Enter] or [Return] key to continue "
read DISCARD
echo ''
fi
if [ -n "$UPDATE_REQ_BYS" ]; then
MASTER_RB_LIST=`mktemp -t master_rb_list-${PARENT_PID}`
export MASTER_RB_LIST
if [ -s "$pdb/$upg_port/+REQUIRED_BY" ]; then
old_rb=$pdb/$upg_port/+REQUIRED_BY
fi
upg_origin=`origin_from_pdb $pdb/$upg_port`
grep -l DEPORIGIN:$upg_origin$ $pdb/*/+CONTENTS |
cut -f 5 -d '/' | sort -u - $old_rb > $MASTER_RB_LIST
fi
fi
if [ -n "$CONFIG_ONLY" ]; then
config_type=config-conditional
test -n "$FORCE_CONFIG" && config_type=config
make $PM_MAKE_ARGS $config_type
CONFIG_SEEN_LIST="${CONFIG_SEEN_LIST}${portdir}:"
if [ -z "$RECURSE_THOROUGH" ]; then
dependency_check 'build-depends-list run-depends-list'
else
dependency_check all-depends-list
fi
if [ ! "$$" -eq "$PARENT_PID" ]; then
# Save state for the parent process to read back in
echo "CONFIG_SEEN_LIST='$CONFIG_SEEN_LIST'" > $IPC_SAVE
safe_exit
else
if [ -n "$UPDATE_REQ_BYS" ]; then
URB_YES=yes ; export URB_YES
echo ''
echo "===>>> Checking ports that depend on $upg_port"
for req_by in `cat $MASTER_RB_LIST`; do
case "$req_by" in
*${EXCL}*) test -n "$VERBOSE" &&
echo "===>>> Skipping $req_by because it matches the pattern: *${EXCL}*"
continue
;;
esac
rb_origin=`origin_from_pdb $pdb/$req_by`
case "$URB_DONE_LIST" in
*:${rb_origin}:*) continue ;;
esac
test -n "$VERBOSE" &&
echo "===>>> $upg_port is required by $req_by"
if [ ! -d "$pdb/$req_by" ]; then
# A failure here is probably just a
# stale dependency, but warn the user.
req_by_error $upg_port $req_by
continue
fi
if ! check_interactive ${req_by} ; then
continue
fi
if [ -z "$RESTART" -a -z "$FORCE" ]; then
update_port $req_by
else
check_for_updates $req_by
fi
done
rm -f $MASTER_RB_LIST
echo "===>>> Done checking ports that depend on $upg_port"
unset URB_YES
URB_DONE_LIST=':'
fi
unset_recursive_config
fi
echo ''
echo "===>>> Starting build for $portdir <<<==="
echo ''
fi
BUILDING=yes
export BUILDING
cd $pd/$portdir
if [ ! -e "$NO_DEP_UPDATES" ]; then
if [ -z "$RECURSE_THOROUGH" ]; then
echo "===>>> Starting check for build dependencies"
dependency_check build-depends-list
else
echo "===>>> Starting check for all dependencies"
dependency_check all-depends-list
fi
else
if [ -z "$NO_RECURSIVE_CONFIG" ]; then
echo "===>>> The 'make config' check revealed no dependencies to update"
echo ''
fi
fi
if [ -n "$NO_ACTION" ]; then
test -n "$VERBOSE" &&
echo "===>>> Build canceled due to -n flag"
safe_exit
fi
# In case we went elsewhere in the dependency check
cd $pd/$portdir
case "$DONT_PRE_CLEAN" in
'') make $PM_MAKE_ARGS clean NOCLEANDEPENDS=yes || fail 'make clean failed' ;;
esac
fl_read=`echo ${TMPDIR}/fetchlog-${PARENT_PID}-${portdir##*/}.*`
while [ -f "$fl_read" ]; do
echo ''
echo "===>>> Waiting on fetch & checksum for $portdir <<<==="
tail -10 $fl_read 2>/dev/null | egrep -v '^$|MCS_CHILD_PID'
echo ''
echo "===>>> Waiting on fetch & checksum for $portdir <<<==="
sleep 5
done
make $PM_MAKE_ARGS || fail "make failed for $portdir"
new_port=`make $PM_MAKE_ARGS -V PKGNAME`
prefix=`make $PM_MAKE_ARGS -V PKGNAMEPREFIX`
portname=`make $PM_MAKE_ARGS -V PORTNAME`
suffix=`make $PM_MAKE_ARGS -V PKGNAMESUFFIX`
short_port="${prefix}${portname}${suffix}"
# Check for dependencies here in case +REQUIRED_BY is not up to date or missing
grep_deps=`mktemp -t grep-deps-${short_port}`
upg_origin=$portdir
if [ -n "$upg_port" ]; then
upg_origin=`origin_from_pdb $pdb/$upg_port`
fi
grep -l DEPORIGIN:$upg_origin$ $pdb/*/+CONTENTS | cut -f 5 -d '/' |
sort -u > $grep_deps
if [ -s "$pdb/$upg_port/+REQUIRED_BY" ]; then
req_deps=`mktemp -t req-deps-${short_port}`
sort -u $pdb/$upg_port/+REQUIRED_BY > $req_deps
fi
if [ ! -s "$grep_deps" -a ! -s "$req_deps" ]; then
if [ -n "$upg_port" ]; then
echo "===>>> $upg_port is not depended on by any other ports"
fi
elif [ -s "$grep_deps" -a -s "$req_deps" ]; then
if ! cmp -s $grep_deps $req_deps; then
update_reqfile
fi
elif [ -s "$grep_deps" -a ! -s "$req_deps" ]; then
dep_warn
echo -n "===>>> Install these as the new +REQUIRED_BY file? [n] "
if [ -z "$UNATTENDED" ]; then
read INSTALLDEPS
case "$INSTALLDEPS" in
[yY]) req_deps=`mktemp -t req-deps-${short_port}`
mv $grep_deps $req_deps ; unset grep_deps
;;
esac
else
echo "===>>> Default (no) in unattended mode"
fi
else
# It should not happen that req_deps exist but grep_deps does not
echo ''
echo "===>>> $pdb/$upg_port/+REQUIRED_BY indicates"
echo " a dependency on this port, but no other ports have"
echo " it recorded. If that file does not contain any valid"
echo " dependency data, try removing it and then start again."
fail "Stale dependency data in $pdb/$upg_port/+REQUIRED_BY"
fi
# Ignore if no old port exists
if [ -n "$upg_port" ]; then
find_contents_distfiles $upg_port
UPGRADE_PORT=$upg_port
UPGRADE_PORT_VER=`echo $UPGRADE_PORT | sed 's#.*-\(.*\)#\1#'`
export UPGRADE_PORT UPGRADE_PORT_VER
if [ -z "$NO_BACKUP" ]; then
backup_package $upg_port
fi
if [ -n "$SAVE_SHARED" ]; then
ldconfig_out=`mktemp -t f-${PARENT_PID}-ldconfig`
ldconfig -r | sed 's#.* ##' |
grep -v ^${PORTS_PREFIX}/lib/compat > $ldconfig_out
mkdir -p ${PORTS_PREFIX}/lib/compat/pkg
for file in `pkg_info -q -L $upg_port | sort - $ldconfig_out | \
uniq -d`; do
cp -p $file ${PORTS_PREFIX}/lib/compat/pkg/
done
ldconfig -m ${PORTS_PREFIX}/lib/compat/pkg
fi
pkg_delete -f $upg_port || fail 'pkg_delete failed'
if [ -n "$REPLACE_ORIGIN" ]; then
installed_newport=`iport_from_origin ${newportdir}`
if [ -n "$installed_newport" ]; then
pkg_delete -f $installed_newport
fi
fi
fi
if [ -z "$RECURSE_THOROUGH" -a ! -e "$NO_DEP_UPDATES" ]; then
echo "===>>> Starting check for runtime dependencies"
dependency_check run-depends-list
fi
# In case we went elsewhere in the dependency check
cd $pd/$portdir
make $PM_MAKE_ARGS install || {
if [ -z "$NO_BACKUP" -a -n "$upg_port" ]; then
echo ''
echo "===>>> A backup package for $portdir should be located in $pkgrep"
fi
fail "Installation of new port failed";}
# Remove saved libs that match newly installed files
pkg_info -q -L $new_port | while read file; do
if [ -e "${PORTS_PREFIX}/lib/compat/pkg/${file##*/}" ]; then
unlink ${PORTS_PREFIX}/lib/compat/pkg/${file##*/}
fi
done
test -d "${PORTS_PREFIX}/lib/compat/pkg" &&
ldconfig -m ${PORTS_PREFIX}/lib/compat/pkg
# Implement storage of distfile information in the +CONTENTS file in the
# same way that it will (hopefully, soon?) be implemented in bsd.port.mk
# See http://www.freebsd.org/cgi/query-pr.cgi?pr=106483
if ! grep -q DISTFILE $pdb/$new_port/+CONTENTS; then
ds=`make BEFOREPORTMK=yes $PM_MAKE_ARGS -V DIST_SUBDIR`
test -n "$ds" && ds="${ds}/"
allfiles=`make $PM_MAKE_ARGS -V ALLFILES`
distinfo=`make $PM_MAKE_ARGS -V MD5_FILE`
for file in $allfiles; do
size=`grep "^SIZE (${ds}${file})" $distinfo | cut -f4 -d' '`
sha256=`grep "^SHA256 (${ds}${file})" $distinfo | cut -f4 -d' '`
md5=`grep "^MD5 (${ds}${file})" $distinfo | cut -f4 -d' '`
echo "@comment DISTFILE:${ds}${file}:SIZE=${size}:SHA256=${sha256}:MD5=${md5}" >> $pdb/$new_port/+CONTENTS
done
fi
if [ -n "$MAKE_PACKAGE" ]; then
echo "===>>> Creating a package for new version $new_port"
make $PM_MAKE_ARGS package || fail 'Package creation of new port failed'
echo " ===>>> Package can be found in $pkgrep"
fi
make $PM_MAKE_ARGS clean NOCLEANDEPENDS=yes
# By now, if this file exists, it should be authoritative
if [ -s "$req_deps" ]; then
update_dep_entries () {
local upg_port
test -n "$1" && upg_port=$1
echo "===>>> Updating package dependency entry for each dependent port"
while read dep_port; do
dep_port_contents="$pdb/$dep_port/+CONTENTS"
[ -e "$pdb/$dep_port/+CONTENTS" ] || continue
if grep -q "@pkgdep $upg_port" $dep_port_contents; then
update_contents $upg_port $new_port
else
echo -n "===>>> In ${dep_port}"
echo " no entry for $upg_port, trying $short_port"
update_contents "$short_port.*" $new_port
fi
done < $req_deps
}
update_dep_entries
mv $req_deps $pdb/$new_port/+REQUIRED_BY
unset req_deps
chmod 644 $pdb/$new_port/+REQUIRED_BY
if [ -n "$REPLACE_ORIGIN" ]; then
req_deps=`mktemp -t req-deps-${short_port}`
grep -l DEPORIGIN:$newportdir$ $pdb/*/+CONTENTS |
cut -f 5 -d '/' | sort -u > $req_deps
update_dep_entries $new_port
cat $req_deps >> $pdb/$new_port/+REQUIRED_BY
fi
fi
echo ''
test -z "$upg_port" && upg_port=$portdir
echo "===>>> Upgrade for $upg_port to $new_port succeeded"
test -n "$FORCE" && FORCE_DONE_LIST="${FORCE_DONE_LIST}${portdir}:"
test -e "$pdb/$new_port/+DISPLAY" &&
DISPLAY_LIST="${DISPLAY_LIST}$new_port/+DISPLAY "
if [ -n "$URB_YES" -o -n "$UPDATE_REQ_BYS" -o -n "$FORCE" ]; then
touch $pdb/$new_port/PM_UPGRADE_DONE_FLAG
fi
if [ -z "$DONT_SCRUB_DISTFILES" ]; then
if [ -z "$oldportdir" ]; then
delete_stale_distfiles
else
delete_all_distfiles ${oldportdir}
cd $pd/$newportdir && delete_stale_distfiles
fi
fi
if [ -n "$UPDATE_REQ_BYS" -a -s "$pdb/$new_port/+REQUIRED_BY" ]; then
URB_YES=yes ; export URB_YES
MASTER_RB_LIST=$pdb/$new_port/+REQUIRED_BY
echo ''
echo "===>>> Updating ports that depend on $new_port"
for req_by in `cat $pdb/$new_port/+REQUIRED_BY`; do
if [ ! -d "$pdb/$req_by" ]; then
# Since the dependency list was probably updated as
# a result of updating the parent port, a missing
# directory here is likely the result of the port
# being updated as a dependency for something else.
continue
fi
case "$req_by" in
*${EXCL}*) test -n "$VERBOSE" &&
echo "===>>> Skipping $req_by because it matches the pattern: *${EXCL}*"
continue
;;
esac
p=`origin_from_pdb $pdb/$req_by`
case "$URB_DONE_LIST" in
*:${p}:*) continue ;;
esac
case "$FORCE_DONE_LIST" in
*:${p}:*) test -n "$VERBOSE" &&
echo "===>>> Update for $p already done"
continue
;;
esac
if ! check_interactive ${req_by} ; then
continue
fi
test -n "$VERBOSE" &&
echo "===>>> $new_port is required by $req_by"
if [ -z "$RESTART" -a -z "$FORCE" ]; then
update_port $req_by
else
check_for_updates $req_by
fi
done
echo "===>>> Done updating ports that depend on $new_port"
fi
safe_exit
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright (c) 2005-2007 Douglas Barton
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.