1
0
mirror of https://git.FreeBSD.org/ports.git synced 2024-10-19 19:59:43 +00:00

Add my portmaster utility. This is a shell script to manage ports

that does not require external databases or languages.
This commit is contained in:
Doug Barton 2006-02-20 23:29:03 +00:00
parent 4a16b2fd89
commit 5c9a8c6104
Notes: svn2git 2021-03-31 03:12:20 +00:00
svn path=/head/; revision=156552
9 changed files with 1531 additions and 0 deletions

View File

@ -0,0 +1,33 @@
# New ports collection makefile for: portmaster
# Date created: 20 February 2006
# Whom: Doug Barton <dougb@FreeBSD.org>
#
# $FreeBSD$
#
# This port is self contained in the files directory.
#
PORTNAME= portmaster
PORTVERSION= 1.1
CATEGORIES= sysutils
MASTER_SITES= # none
DISTFILES= # none
MAINTAINER= dougb@FreeBSD.org
COMMENT= Manage your ports without external databases or languages
NO_BUILD= yes
SUB_FILES= portmaster.sh
PLIST_FILES= sbin/portmaster
MAN8= portmaster.8
do-fetch:
@${DO_NADA}
do-install:
${INSTALL_SCRIPT} ${WRKDIR}/portmaster.sh ${PREFIX}/sbin/portmaster
${INSTALL_MAN} ${FILESDIR}/portmaster.8 ${MAN8PREFIX}/man/man8
.include <bsd.port.mk>

View File

@ -0,0 +1,130 @@
.\" Copyright (c) 2006 Doug Barton dougb@FreeBSD.org
.\" 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.
.\"
.\" $FreeBSD$
.\"
.Dd February 20, 2006
.Dt PORTMASTER 8
.Os
.Sh NAME
.Nm portmaster
.Nd manage your ports
.Sh SYNOPSIS
.Nm
.Op Fl Canv [f|i] [D|d] m Ar arguments for make
.Op Ar name of port directory in /var/db/pkg
.Pp
.Op Fl Canv [f|i] [D|d] m Ar arguments for make
.Op Ar glob pattern from /var/db/pkg
.Pp
.Op Fl Canv [f|i] [D|d] m Ar arguments for make
.Op Fl p Ar port directory in /usr/ports
.Pp
.Op Fl Canv [f|i] [D|d] m Ar arguments for make
.Op Ar full path to /usr/ports/foo/bar
.Pp
.Op Fl Cnv [f|i] [D|d] m Ar arguments for make
.Op Fl r Ar name/glob of port in /var/db/pkg
.Pp
.Op Fl h
.Pp
.Op Fl l
.Pp
.Sh DESCRIPTION
The
.Nm
utility is a simple tool for managing your ports.
It uses no external database to track what you
have installed,
rather it uses the existing ports infrastructure,
including what is located in
.Pa /var/db/pkg .
The focus of this tool is to keep the dependency
tracking information for your ports up to date,
which allows you to update a specific port without
having to update all of the ports
.Dq above
it.
In the rare case where you do need to recompile
ports which depend on a port you are updating,
the -r option exists to accomplish this.
.Pp
The options are as follows:
.Bl -tag -width F1
.It Fl C
Prevents 'make clean' being run in port directory
.It Fl a
check all ports, update as necessary
.It Fl n
do not launch child process to update dependencies
.It Fl v
verbose output
.It Fl f
always rebuild ports (overrides -i)
.It Fl i
interactive update mode
.It Fl D
prevents cleaning of distfiles
.It Fl d
always clean distfiles
.It Fl p Ar port directory in /usr/ports
Specify the full path to a port directory
.It Fl m Ar arguments for make
any arguments to supply to
.Xr make 1
.It Fl r Ar name/glob of port in /var/db/pkg
rebuild port, and all ports that depend on it
.It Fl h
display help file
.It Fl l
list all installed ports by category
.El
.Sh FILES
.Bl -tag -width ".Pa $HOME/.portmaster.rc" -compact
.It Pa /etc/portmaster.rc
.It Pa $HOME/.portmaster.rc
Optional system and user configuration files.
The variables set in the script's getopts routine
can be specified in these files to enable those options.
.El
.Sh EXIT STATUS
.Ex -std
.Sh EXAMPLES
The following is an example of a typical usage
of the
.Nm
command:
.Pp
.Dl "portmaster fooport-1.23"
.Dl "portmaster fooport"
.Dl "portmaster -p /usr/ports/foo/fooport"
.Dl "portmaster foo/fooport"
.Dl "portmaster -r fooport-1.23"
.Sh SEE ALSO
.Xr make 1
.Xr ports 7
.Sh AUTHORS
This
manual page was written by
.An Doug Barton <dougb@Freebsd.org> .

View File

@ -0,0 +1,594 @@
#!/bin/sh
# Local version: 1.56
# $FreeBSD$
# Copyright (c) 2005-2006 Douglas Barton, All rights reserved
# Please see detailed copyright below
# %%LOCALBASE%% and %%X11BASE%% are needed in path for make
PATH=/bin:/usr/bin:/sbin:/usr/sbin:%%LOCALBASE%%/bin:%%X11BASE%%/bin
export PATH
umask 022
usage () {
VERSION_NUMBER=`grep "[$]FreeBSD:" $0 | cut -d ' ' -f 4`
echo "portmaster version $VERSION_NUMBER"
echo ''
echo 'Usage:'
echo "${0##*/} [-Canv f|i D|d] <full name of port directory in $pdb>"
echo "${0##*/} [-Canv f|i D|d] <glob pattern of directory in $pdb>"
echo "${0##*/} [-Canv f|i D|d] -p <port directory in $pd>"
echo "${0##*/} [-Canv f|i D|d] <full path to $pd/foo/bar>"
echo "${0##*/} [-Cnv f|i D|d] -r <name/glob of port directory in $pdb>"
echo "${0##*/} -h"
echo "${0##*/} -l"
echo ''
echo "-C prevents 'make clean' being run in port directory"
echo '-a check all ports, update as necessary'
echo '-n do not launch child process to update dependencies'
echo '-v verbose output'
echo '-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 '-r rebuild port, and all ports that depend on it'
echo '-h display this help file'
echo '-l list installed ports by category'
echo ''
exit 1
}
fail () {
echo ''
echo "===>>> $1"
echo "===>>> Aborting update"
exit 1
}
safe_exit () {
echo ''
rm -f $grep_deps $req_deps
test -n "$FORCE_PARENT" && rm -f $UPDATES_DONE_LIST
exit 0
}
update_contents () {
tempfile=`mktemp 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
}
dep_warn () {
echo ''
echo "===>>> Warning! Potential unrecorded dependencies on $new_port"
echo "===>>> From existing +CONTENTS files:"
grep "pkgdep ${short_port}-" $pdb/*/+CONTENTS |
sort | sed "s#$pdb/##"
num_ports1=`grep "pkgdep ${short_port}-" $pdb/*/+CONTENTS |
wc -l | awk '{print $1}'`
echo "===>>> $num_ports1 ports"
echo ''
}
update_reqfile () {
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 ''
echo -n "===>>> Update dependency list? [r] "
read DEPUPDATE
case "$DEPUPDATE" in
[cC]) mv $grep_deps $req_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
}
update_port () {
local upd
case "$1" in
-p) upd=$2 ;;
*) upd=$1 ;;
esac
echo "===>>> Launching child to update $upd"
echo ''
if [ -z "$NO_ACTION" ]; then
($0 $ARGS $@) || fail "Update for $upd failed"
fi
if [ -n "$UPDATE_ALL" ]; then
echo "===>>> Returning to update check of installed ports"
elif [ -n "$UPDATE_REQ_BYS" ]; then
return 0
else
echo "===>>> Returning to dependency check for $portdir"
fi
return 0
}
check_for_updates () {
local upd_port port_ver do_update UPD_OR_NOT
upd_port=`grep ' ORIGIN' $pdb/$1/+CONTENTS | cut -f2 -d':'`
if [ -d "$pd/$upd_port" ]; then
cd $pd/$upd_port ||
fail "Cannot cd to port directory: $pd/$upd_port"
port_ver=`make $MAKE_ARGS -V PKGNAME`
test "$1" = "$port_ver" && return 0
case `pkg_version -t $1 $port_ver` in
\<) do_update=yes ;;
*) if [ -n "$VERBOSE" ]; then
echo ''
echo "===>>> Port version $port_ver does not"
echo "===>>> seem newer than installed $1"
echo ''
fi
;;
esac
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
if [ -n "$INTERACTIVE_UPDATE" ]; then
echo -n "===>>> Update ${1}? [y] "
read UPD_OR_NOT
case "$UPD_OR_NOT" in
[nN]*) return 0 ;;
esac
fi
update_port $1 || return 1
fi
return 0
}
find_moved_port () {
newportdir=`sed -ne "s#^${1}|\([^|]*\)|.*#\1#p" $pd/MOVED`
if [ ! -n "$newportdir" ]; then
m=`sed -ne "s#^${1}||.*|\(.*\)#\1#p" $pd/MOVED`
if [ -n "$m" ]; then
fail "The $1 port has been deleted: $m"
else
echo ''
echo "===>>> No $pd/$1 exists, and no information"
echo "===>>> about $1 can be found in $pd/MOVED"
echo ''
return 1
fi
fi
# Just in case there was more than one match, use the last one
newportdir=`echo $newportdir | sed 's/.* //'`
echo "===>>> The $1 port has moved to $pd/$newportdir"
return 0
}
ports_by_category () {
local pkg
for pkg in $pdb/*; do
# Handle regular files, such as portupgrade's pkgdb.db
test -d "$pkg" || continue
if [ -e "$pkg/+REQUIRED_BY" ]; then
if grep '^@pkgdep ' $pkg/+CONTENTS >/dev/null; then
branches="$branches $pkg"
else
trunks="$trunks $pkg"
fi
else
if grep '^@pkgdep ' $pkg/+CONTENTS >/dev/null; then
leaves="$leaves $pkg"
else
roots="$roots $pkg"
fi
fi
done
}
pd=`make $MAKE_ARGS -f/dev/null -V PORTSDIR 2>/dev/null`
pdb=`make $MAKE_ARGS -f/dev/null -V PKG_DBDIR 2>/dev/null`
# 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
: ${pd:=/usr/ports}
: ${pdb:=/var/db/pkg}
# Save switches for potential child processes
while getopts 'CDadfhilnm:p:r:v' COMMAND_LINE_ARGUMENT ; do
case "${COMMAND_LINE_ARGUMENT}" in
C) DONT_PRE_CLEAN=yes; ARGS="-C $ARGS" ;;
D) DONT_SCRUB_DISTFILES=yes; ARGS="-D $ARGS" ;;
a) UPDATE_ALL=yes ;;
d) ALWAYS_SCRUB_DISTFILES=yes; ARGS="-d $ARGS" ;;
f) FORCE_PARENT=yes
FORCE=yes
UPDATES_DONE_LIST=`mktemp -t updates_done_list`
export FORCE UPDATES_DONE_LIST
;;
h) usage ; exit 0 ;;
i) INTERACTIVE_UPDATE=yes; ARGS="-i $ARGS" ;;
l) LIST=yes ;;
m) MAKE_ARGS=$OPTARG; ARGS="-m $MAKE_ARGS $ARGS" ;;
n) NO_ACTION=yes ;;
p) portdir="${OPTARG#$pd/}" ;;
r) UPDATE_REQ_BYS=yes; upg_port=$OPTARG ;;
v) VERBOSE=yes; ARGS="-v $ARGS" ;;
esac
done
test -n "$FORCE" && unset INTERACTIVE_UPDATE
if [ -n "$LIST" ]; then
ports_by_category
echo "===>>> Root ports (No dependencies, not depended on)"
for port in $roots; do
echo "===>>> ${port##*/}"
done
echo ''
echo "===>>> Trunk ports (No dependencies, are depended on)"
for port in $trunks; do
echo "===>>> ${port##*/}"
done
echo ''
echo "===>>> Branch ports (Have dependencies, are depended on)"
for port in $branches; do
echo "===>>> ${port##*/}"
done
echo ''
echo "===>>> Leaf ports (Have dependencies, not depended on)"
for port in $leaves; do
echo "===>>> ${port##*/}"
done
exit 0
fi
if [ -n "$UPDATE_ALL" ]; then
echo "===>>> Starting check of installed ports for available updates"
ports_by_category
for pkg in $roots $trunks $branches $leaves; do
if [ ! -d "$pkg" ]; then
# This port probably got updated as a dependency
# for something else
continue
fi
if [ -n "$FORCE" ]; then
p=`grep ' ORIGIN' $pkg/+CONTENTS | cut -f2 -d':'`
if [ ! `grep "${pd}/${p}$" $UPDATES_DONE_LIST` ]; then
echo "===>>> Forcing update for ${pkg##*/}"
update_port ${pkg##*/}
continue
else
test -n "$VERBOSE" &&
echo "===>>> Update for $p already done"
fi
else
test -n "$VERBOSE" &&
echo "===>>> Checking installed port: ${pkg##*/}"
fi
check_for_updates ${pkg##*/} || fail 'Update failed'
done
echo "===>>> Update check of installed ports complete"
exit 0
fi
# Exercised in the common case of not using -p option
case "$portdir" in
'') eval arg=\$${OPTIND}
case "${arg}" in
'') test -z "$UPDATE_REQ_BYS" && usage ;;
${pd}/*) portdir="${arg#$pd/}" ;;
/*) upg_port="${arg##*/}" ;;
*) upg_port=$arg ;;
esac
esac
case "$upg_port" in
'') test -n "$portdir" || usage
old_port_dir=`grep -l "@comment ORIGIN:${portdir}$" $pdb/*/+CONTENTS`
if [ -n "$old_port_dir" ]; then
old_port_dir="${old_port_dir%/+CONTENTS}"
upg_port="${old_port_dir#$pdb/}"
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=true
break
;;
esac
done
test -n "$selected" || usage
;;
esac
fi
echo "===>>> Port to upgrade: $upg_port"
portdir=`grep ' ORIGIN' $pdb/$upg_port/+CONTENTS | cut -f2 -d':'`
;;
esac
if [ -d "$pd/$portdir" ]; then
echo "===>>> Port directory: $pd/$portdir"
else
find_moved_port $portdir
portdir=$newportdir
fi
cd $pd/$portdir || usage
# Do this here so that the dependency list is accurate
make $MAKE_ARGS config
echo "===>>> Checking if dependencies of $portdir are up to date"
dep_port_list=`make $MAKE_ARGS all-depends-list`
if [ -n "$dep_port_list" ]; then
for dep_port in $dep_port_list; do
test -n "$VERBOSE" &&
echo "===>>> Checking dependency: $dep_port"
if [ -n "$UPDATES_DONE_LIST" ]; then
if [ `grep "${dep_port}$" $UPDATES_DONE_LIST` ]; then
continue
fi
fi
cur_p=`grep -l " ORIGIN:${dep_port#$pd/}$" $pdb/*/+CONTENTS`
if [ -n "$cur_p" ]; then
cur_p=${cur_p%/+CONTENTS}
cur_p=${cur_p##*/}
upd_args=$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=`grep -l " ORIGIN:${op}$" $pdb/*/+CONTENTS`
if [ -n "$old_p" ]; then
old_p=${old_p%/+CONTENTS}
old_p=${old_p##*/}
upd_args=$old_p
fi
fi
fi
if [ -n "$FORCE" ]; then
echo "===>>> Forcing update for $dep_port"
update_port $upd_args
continue
fi
# If not forcing the update
if [ -n "$cur_p" ]; then
check_for_updates $cur_p
elif [ -n "$old_p" ]; then
check_for_updates $old_p
else
if [ -n "$INTERACTIVE_UPDATE" ]; then
echo -n "===>>> Install $dep_port? [y] "
read UPD_OR_NOT
case "$UPD_OR_NOT" in
[nN]*) continue ;;
esac
fi
update_port -p $dep_port
fi
done
echo "===>>> Dependency check complete for $portdir"
else
echo "===>>> No dependencies for $portdir"
fi
case "$DONT_PRE_CLEAN" in
'') make $MAKE_ARGS clean || fail 'make clean failed' ;;
esac
# In case we went elsewhere in the dependency check
cd $pd/$portdir
make $MAKE_ARGS || fail 'make failed'
new_port=`make $MAKE_ARGS -V PKGNAME`
prefix=`make $MAKE_ARGS -V PKGNAMEPREFIX`
portname=`make $MAKE_ARGS -V PORTNAME`
suffix=`make $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}`
grep -l "pkgdep ${short_port}-" $pdb/*/+CONTENTS | cut -f 5 -d '/' |
sort > $grep_deps
if [ -s "$pdb/$upg_port/+REQUIRED_BY" ]; then
req_deps=`mktemp -t req-deps-${short_port}`
sort $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] "
read INSTALLDEPS
case "$INSTALLDEPS" in
[yY]) req_deps=`mktemp -t req-deps-${short_port}`
mv $grep_deps $req_deps
;;
esac
else
# It should not happen that req_deps exist but grep_deps does not
fail "$pdb/$upg_port/+REQUIRED_BY indicates a dependency on this port, but no other ports have this dependency recorded"
fi
# Ignore if no old port exists
if [ -n "$upg_port" ]; then
pkg_delete -f $upg_port || fail 'pkg_delete failed'
fi
make $MAKE_ARGS install clean || fail 'installation of new port failed'
# By now, if this file exists, it should be authoritative
if [ -s "$req_deps" ]; then
echo "===>>> Updating package dependency entry for each dependent port"
while read dep_port; do
dep_port_contents="$pdb/$dep_port/+CONTENTS"
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
mv $req_deps $pdb/$new_port/+REQUIRED_BY
chmod 644 $pdb/$new_port/+REQUIRED_BY
fi
echo ''
test -z "$upg_port" && upg_port=$portdir
echo "===>>> Upgrade for $upg_port to $new_port succeeded"
test -n "$UPDATES_DONE_LIST" && echo "$pd/$portdir" >> $UPDATES_DONE_LIST
if [ -z "$DONT_SCRUB_DISTFILES" ]; then
distdir=`make $MAKE_ARGS -V DISTDIR`
dist_subdir=`make $MAKE_ARGS -V DIST_SUBDIR`
test -n "$dist_subdir" && distdir="${distdir}/${dist_subdir}"
distfiles=`make $MAKE_ARGS -V DISTFILES`
distname=`make $MAKE_ARGS -V DISTNAME | cut -f 1 -d '-'`
cd $distdir || fail "cd to $distdir failed!"
for file in ${distname}*; do
# This generally means the pattern did not match
case "$file" in
*\*) continue ;;
esac
case "$distfiles" in
*${file}*) continue ;; # Do not delete current version
*) 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
fi
if [ -n "$UPDATE_REQ_BYS" -a -r "$pdb/$new_port/+REQUIRED_BY" ]; then
echo ''
echo "===>>> Updating ports that depend on $new_port"
for req_by in `cat $pdb/$new_port/+REQUIRED_BY`; do
test -n "$VERBOSE" &&
echo "===>>> $req_by is required by $new_port"
if [ ! -d "$pdb/$req_by" ]; then
echo -n "===>>> WARNING! $pdb/$new_port/+REQUIRED_BY "
echo -n "shows that $req_by requires $new_port, but "
echo "$req_by does not seem to be installed"
echo -n "===>>> Press Enter to proceed "
read DISCARD
continue
fi
if [ -n "$INTERACTIVE_UPDATE" ]; then
echo -n "===>>> Update ${req_by}? [y] "
read UPD_OR_NOT
case "$UPD_OR_NOT" in
[nN]*) continue ;;
esac
fi
update_port $req_by
done
echo "===>>> Done updating ports that depend on $new_port"
fi
safe_exit
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright (c) 2005-2006 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.

View File

@ -0,0 +1,8 @@
This script provides a simple way to manage your ports.
It uses the existing ports infrastructure to track
dependencies, and to keep those dependencies up
to date.
Because portmaster is written in /bin/sh, it needs
no other interpreted languages installed.

View File

@ -429,6 +429,7 @@
SUBDIR += portbrowser
SUBDIR += portdowngrade
SUBDIR += portmanager
SUBDIR += portmaster
SUBDIR += portsearch
SUBDIR += portsman
SUBDIR += portsnap

View File

@ -0,0 +1,33 @@
# New ports collection makefile for: portmaster
# Date created: 20 February 2006
# Whom: Doug Barton <dougb@FreeBSD.org>
#
# $FreeBSD$
#
# This port is self contained in the files directory.
#
PORTNAME= portmaster
PORTVERSION= 1.1
CATEGORIES= sysutils
MASTER_SITES= # none
DISTFILES= # none
MAINTAINER= dougb@FreeBSD.org
COMMENT= Manage your ports without external databases or languages
NO_BUILD= yes
SUB_FILES= portmaster.sh
PLIST_FILES= sbin/portmaster
MAN8= portmaster.8
do-fetch:
@${DO_NADA}
do-install:
${INSTALL_SCRIPT} ${WRKDIR}/portmaster.sh ${PREFIX}/sbin/portmaster
${INSTALL_MAN} ${FILESDIR}/portmaster.8 ${MAN8PREFIX}/man/man8
.include <bsd.port.mk>

View File

@ -0,0 +1,130 @@
.\" Copyright (c) 2006 Doug Barton dougb@FreeBSD.org
.\" 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.
.\"
.\" $FreeBSD$
.\"
.Dd February 20, 2006
.Dt PORTMASTER 8
.Os
.Sh NAME
.Nm portmaster
.Nd manage your ports
.Sh SYNOPSIS
.Nm
.Op Fl Canv [f|i] [D|d] m Ar arguments for make
.Op Ar name of port directory in /var/db/pkg
.Pp
.Op Fl Canv [f|i] [D|d] m Ar arguments for make
.Op Ar glob pattern from /var/db/pkg
.Pp
.Op Fl Canv [f|i] [D|d] m Ar arguments for make
.Op Fl p Ar port directory in /usr/ports
.Pp
.Op Fl Canv [f|i] [D|d] m Ar arguments for make
.Op Ar full path to /usr/ports/foo/bar
.Pp
.Op Fl Cnv [f|i] [D|d] m Ar arguments for make
.Op Fl r Ar name/glob of port in /var/db/pkg
.Pp
.Op Fl h
.Pp
.Op Fl l
.Pp
.Sh DESCRIPTION
The
.Nm
utility is a simple tool for managing your ports.
It uses no external database to track what you
have installed,
rather it uses the existing ports infrastructure,
including what is located in
.Pa /var/db/pkg .
The focus of this tool is to keep the dependency
tracking information for your ports up to date,
which allows you to update a specific port without
having to update all of the ports
.Dq above
it.
In the rare case where you do need to recompile
ports which depend on a port you are updating,
the -r option exists to accomplish this.
.Pp
The options are as follows:
.Bl -tag -width F1
.It Fl C
Prevents 'make clean' being run in port directory
.It Fl a
check all ports, update as necessary
.It Fl n
do not launch child process to update dependencies
.It Fl v
verbose output
.It Fl f
always rebuild ports (overrides -i)
.It Fl i
interactive update mode
.It Fl D
prevents cleaning of distfiles
.It Fl d
always clean distfiles
.It Fl p Ar port directory in /usr/ports
Specify the full path to a port directory
.It Fl m Ar arguments for make
any arguments to supply to
.Xr make 1
.It Fl r Ar name/glob of port in /var/db/pkg
rebuild port, and all ports that depend on it
.It Fl h
display help file
.It Fl l
list all installed ports by category
.El
.Sh FILES
.Bl -tag -width ".Pa $HOME/.portmaster.rc" -compact
.It Pa /etc/portmaster.rc
.It Pa $HOME/.portmaster.rc
Optional system and user configuration files.
The variables set in the script's getopts routine
can be specified in these files to enable those options.
.El
.Sh EXIT STATUS
.Ex -std
.Sh EXAMPLES
The following is an example of a typical usage
of the
.Nm
command:
.Pp
.Dl "portmaster fooport-1.23"
.Dl "portmaster fooport"
.Dl "portmaster -p /usr/ports/foo/fooport"
.Dl "portmaster foo/fooport"
.Dl "portmaster -r fooport-1.23"
.Sh SEE ALSO
.Xr make 1
.Xr ports 7
.Sh AUTHORS
This
manual page was written by
.An Doug Barton <dougb@Freebsd.org> .

View File

@ -0,0 +1,594 @@
#!/bin/sh
# Local version: 1.56
# $FreeBSD$
# Copyright (c) 2005-2006 Douglas Barton, All rights reserved
# Please see detailed copyright below
# %%LOCALBASE%% and %%X11BASE%% are needed in path for make
PATH=/bin:/usr/bin:/sbin:/usr/sbin:%%LOCALBASE%%/bin:%%X11BASE%%/bin
export PATH
umask 022
usage () {
VERSION_NUMBER=`grep "[$]FreeBSD:" $0 | cut -d ' ' -f 4`
echo "portmaster version $VERSION_NUMBER"
echo ''
echo 'Usage:'
echo "${0##*/} [-Canv f|i D|d] <full name of port directory in $pdb>"
echo "${0##*/} [-Canv f|i D|d] <glob pattern of directory in $pdb>"
echo "${0##*/} [-Canv f|i D|d] -p <port directory in $pd>"
echo "${0##*/} [-Canv f|i D|d] <full path to $pd/foo/bar>"
echo "${0##*/} [-Cnv f|i D|d] -r <name/glob of port directory in $pdb>"
echo "${0##*/} -h"
echo "${0##*/} -l"
echo ''
echo "-C prevents 'make clean' being run in port directory"
echo '-a check all ports, update as necessary'
echo '-n do not launch child process to update dependencies'
echo '-v verbose output'
echo '-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 '-r rebuild port, and all ports that depend on it'
echo '-h display this help file'
echo '-l list installed ports by category'
echo ''
exit 1
}
fail () {
echo ''
echo "===>>> $1"
echo "===>>> Aborting update"
exit 1
}
safe_exit () {
echo ''
rm -f $grep_deps $req_deps
test -n "$FORCE_PARENT" && rm -f $UPDATES_DONE_LIST
exit 0
}
update_contents () {
tempfile=`mktemp 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
}
dep_warn () {
echo ''
echo "===>>> Warning! Potential unrecorded dependencies on $new_port"
echo "===>>> From existing +CONTENTS files:"
grep "pkgdep ${short_port}-" $pdb/*/+CONTENTS |
sort | sed "s#$pdb/##"
num_ports1=`grep "pkgdep ${short_port}-" $pdb/*/+CONTENTS |
wc -l | awk '{print $1}'`
echo "===>>> $num_ports1 ports"
echo ''
}
update_reqfile () {
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 ''
echo -n "===>>> Update dependency list? [r] "
read DEPUPDATE
case "$DEPUPDATE" in
[cC]) mv $grep_deps $req_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
}
update_port () {
local upd
case "$1" in
-p) upd=$2 ;;
*) upd=$1 ;;
esac
echo "===>>> Launching child to update $upd"
echo ''
if [ -z "$NO_ACTION" ]; then
($0 $ARGS $@) || fail "Update for $upd failed"
fi
if [ -n "$UPDATE_ALL" ]; then
echo "===>>> Returning to update check of installed ports"
elif [ -n "$UPDATE_REQ_BYS" ]; then
return 0
else
echo "===>>> Returning to dependency check for $portdir"
fi
return 0
}
check_for_updates () {
local upd_port port_ver do_update UPD_OR_NOT
upd_port=`grep ' ORIGIN' $pdb/$1/+CONTENTS | cut -f2 -d':'`
if [ -d "$pd/$upd_port" ]; then
cd $pd/$upd_port ||
fail "Cannot cd to port directory: $pd/$upd_port"
port_ver=`make $MAKE_ARGS -V PKGNAME`
test "$1" = "$port_ver" && return 0
case `pkg_version -t $1 $port_ver` in
\<) do_update=yes ;;
*) if [ -n "$VERBOSE" ]; then
echo ''
echo "===>>> Port version $port_ver does not"
echo "===>>> seem newer than installed $1"
echo ''
fi
;;
esac
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
if [ -n "$INTERACTIVE_UPDATE" ]; then
echo -n "===>>> Update ${1}? [y] "
read UPD_OR_NOT
case "$UPD_OR_NOT" in
[nN]*) return 0 ;;
esac
fi
update_port $1 || return 1
fi
return 0
}
find_moved_port () {
newportdir=`sed -ne "s#^${1}|\([^|]*\)|.*#\1#p" $pd/MOVED`
if [ ! -n "$newportdir" ]; then
m=`sed -ne "s#^${1}||.*|\(.*\)#\1#p" $pd/MOVED`
if [ -n "$m" ]; then
fail "The $1 port has been deleted: $m"
else
echo ''
echo "===>>> No $pd/$1 exists, and no information"
echo "===>>> about $1 can be found in $pd/MOVED"
echo ''
return 1
fi
fi
# Just in case there was more than one match, use the last one
newportdir=`echo $newportdir | sed 's/.* //'`
echo "===>>> The $1 port has moved to $pd/$newportdir"
return 0
}
ports_by_category () {
local pkg
for pkg in $pdb/*; do
# Handle regular files, such as portupgrade's pkgdb.db
test -d "$pkg" || continue
if [ -e "$pkg/+REQUIRED_BY" ]; then
if grep '^@pkgdep ' $pkg/+CONTENTS >/dev/null; then
branches="$branches $pkg"
else
trunks="$trunks $pkg"
fi
else
if grep '^@pkgdep ' $pkg/+CONTENTS >/dev/null; then
leaves="$leaves $pkg"
else
roots="$roots $pkg"
fi
fi
done
}
pd=`make $MAKE_ARGS -f/dev/null -V PORTSDIR 2>/dev/null`
pdb=`make $MAKE_ARGS -f/dev/null -V PKG_DBDIR 2>/dev/null`
# 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
: ${pd:=/usr/ports}
: ${pdb:=/var/db/pkg}
# Save switches for potential child processes
while getopts 'CDadfhilnm:p:r:v' COMMAND_LINE_ARGUMENT ; do
case "${COMMAND_LINE_ARGUMENT}" in
C) DONT_PRE_CLEAN=yes; ARGS="-C $ARGS" ;;
D) DONT_SCRUB_DISTFILES=yes; ARGS="-D $ARGS" ;;
a) UPDATE_ALL=yes ;;
d) ALWAYS_SCRUB_DISTFILES=yes; ARGS="-d $ARGS" ;;
f) FORCE_PARENT=yes
FORCE=yes
UPDATES_DONE_LIST=`mktemp -t updates_done_list`
export FORCE UPDATES_DONE_LIST
;;
h) usage ; exit 0 ;;
i) INTERACTIVE_UPDATE=yes; ARGS="-i $ARGS" ;;
l) LIST=yes ;;
m) MAKE_ARGS=$OPTARG; ARGS="-m $MAKE_ARGS $ARGS" ;;
n) NO_ACTION=yes ;;
p) portdir="${OPTARG#$pd/}" ;;
r) UPDATE_REQ_BYS=yes; upg_port=$OPTARG ;;
v) VERBOSE=yes; ARGS="-v $ARGS" ;;
esac
done
test -n "$FORCE" && unset INTERACTIVE_UPDATE
if [ -n "$LIST" ]; then
ports_by_category
echo "===>>> Root ports (No dependencies, not depended on)"
for port in $roots; do
echo "===>>> ${port##*/}"
done
echo ''
echo "===>>> Trunk ports (No dependencies, are depended on)"
for port in $trunks; do
echo "===>>> ${port##*/}"
done
echo ''
echo "===>>> Branch ports (Have dependencies, are depended on)"
for port in $branches; do
echo "===>>> ${port##*/}"
done
echo ''
echo "===>>> Leaf ports (Have dependencies, not depended on)"
for port in $leaves; do
echo "===>>> ${port##*/}"
done
exit 0
fi
if [ -n "$UPDATE_ALL" ]; then
echo "===>>> Starting check of installed ports for available updates"
ports_by_category
for pkg in $roots $trunks $branches $leaves; do
if [ ! -d "$pkg" ]; then
# This port probably got updated as a dependency
# for something else
continue
fi
if [ -n "$FORCE" ]; then
p=`grep ' ORIGIN' $pkg/+CONTENTS | cut -f2 -d':'`
if [ ! `grep "${pd}/${p}$" $UPDATES_DONE_LIST` ]; then
echo "===>>> Forcing update for ${pkg##*/}"
update_port ${pkg##*/}
continue
else
test -n "$VERBOSE" &&
echo "===>>> Update for $p already done"
fi
else
test -n "$VERBOSE" &&
echo "===>>> Checking installed port: ${pkg##*/}"
fi
check_for_updates ${pkg##*/} || fail 'Update failed'
done
echo "===>>> Update check of installed ports complete"
exit 0
fi
# Exercised in the common case of not using -p option
case "$portdir" in
'') eval arg=\$${OPTIND}
case "${arg}" in
'') test -z "$UPDATE_REQ_BYS" && usage ;;
${pd}/*) portdir="${arg#$pd/}" ;;
/*) upg_port="${arg##*/}" ;;
*) upg_port=$arg ;;
esac
esac
case "$upg_port" in
'') test -n "$portdir" || usage
old_port_dir=`grep -l "@comment ORIGIN:${portdir}$" $pdb/*/+CONTENTS`
if [ -n "$old_port_dir" ]; then
old_port_dir="${old_port_dir%/+CONTENTS}"
upg_port="${old_port_dir#$pdb/}"
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=true
break
;;
esac
done
test -n "$selected" || usage
;;
esac
fi
echo "===>>> Port to upgrade: $upg_port"
portdir=`grep ' ORIGIN' $pdb/$upg_port/+CONTENTS | cut -f2 -d':'`
;;
esac
if [ -d "$pd/$portdir" ]; then
echo "===>>> Port directory: $pd/$portdir"
else
find_moved_port $portdir
portdir=$newportdir
fi
cd $pd/$portdir || usage
# Do this here so that the dependency list is accurate
make $MAKE_ARGS config
echo "===>>> Checking if dependencies of $portdir are up to date"
dep_port_list=`make $MAKE_ARGS all-depends-list`
if [ -n "$dep_port_list" ]; then
for dep_port in $dep_port_list; do
test -n "$VERBOSE" &&
echo "===>>> Checking dependency: $dep_port"
if [ -n "$UPDATES_DONE_LIST" ]; then
if [ `grep "${dep_port}$" $UPDATES_DONE_LIST` ]; then
continue
fi
fi
cur_p=`grep -l " ORIGIN:${dep_port#$pd/}$" $pdb/*/+CONTENTS`
if [ -n "$cur_p" ]; then
cur_p=${cur_p%/+CONTENTS}
cur_p=${cur_p##*/}
upd_args=$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=`grep -l " ORIGIN:${op}$" $pdb/*/+CONTENTS`
if [ -n "$old_p" ]; then
old_p=${old_p%/+CONTENTS}
old_p=${old_p##*/}
upd_args=$old_p
fi
fi
fi
if [ -n "$FORCE" ]; then
echo "===>>> Forcing update for $dep_port"
update_port $upd_args
continue
fi
# If not forcing the update
if [ -n "$cur_p" ]; then
check_for_updates $cur_p
elif [ -n "$old_p" ]; then
check_for_updates $old_p
else
if [ -n "$INTERACTIVE_UPDATE" ]; then
echo -n "===>>> Install $dep_port? [y] "
read UPD_OR_NOT
case "$UPD_OR_NOT" in
[nN]*) continue ;;
esac
fi
update_port -p $dep_port
fi
done
echo "===>>> Dependency check complete for $portdir"
else
echo "===>>> No dependencies for $portdir"
fi
case "$DONT_PRE_CLEAN" in
'') make $MAKE_ARGS clean || fail 'make clean failed' ;;
esac
# In case we went elsewhere in the dependency check
cd $pd/$portdir
make $MAKE_ARGS || fail 'make failed'
new_port=`make $MAKE_ARGS -V PKGNAME`
prefix=`make $MAKE_ARGS -V PKGNAMEPREFIX`
portname=`make $MAKE_ARGS -V PORTNAME`
suffix=`make $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}`
grep -l "pkgdep ${short_port}-" $pdb/*/+CONTENTS | cut -f 5 -d '/' |
sort > $grep_deps
if [ -s "$pdb/$upg_port/+REQUIRED_BY" ]; then
req_deps=`mktemp -t req-deps-${short_port}`
sort $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] "
read INSTALLDEPS
case "$INSTALLDEPS" in
[yY]) req_deps=`mktemp -t req-deps-${short_port}`
mv $grep_deps $req_deps
;;
esac
else
# It should not happen that req_deps exist but grep_deps does not
fail "$pdb/$upg_port/+REQUIRED_BY indicates a dependency on this port, but no other ports have this dependency recorded"
fi
# Ignore if no old port exists
if [ -n "$upg_port" ]; then
pkg_delete -f $upg_port || fail 'pkg_delete failed'
fi
make $MAKE_ARGS install clean || fail 'installation of new port failed'
# By now, if this file exists, it should be authoritative
if [ -s "$req_deps" ]; then
echo "===>>> Updating package dependency entry for each dependent port"
while read dep_port; do
dep_port_contents="$pdb/$dep_port/+CONTENTS"
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
mv $req_deps $pdb/$new_port/+REQUIRED_BY
chmod 644 $pdb/$new_port/+REQUIRED_BY
fi
echo ''
test -z "$upg_port" && upg_port=$portdir
echo "===>>> Upgrade for $upg_port to $new_port succeeded"
test -n "$UPDATES_DONE_LIST" && echo "$pd/$portdir" >> $UPDATES_DONE_LIST
if [ -z "$DONT_SCRUB_DISTFILES" ]; then
distdir=`make $MAKE_ARGS -V DISTDIR`
dist_subdir=`make $MAKE_ARGS -V DIST_SUBDIR`
test -n "$dist_subdir" && distdir="${distdir}/${dist_subdir}"
distfiles=`make $MAKE_ARGS -V DISTFILES`
distname=`make $MAKE_ARGS -V DISTNAME | cut -f 1 -d '-'`
cd $distdir || fail "cd to $distdir failed!"
for file in ${distname}*; do
# This generally means the pattern did not match
case "$file" in
*\*) continue ;;
esac
case "$distfiles" in
*${file}*) continue ;; # Do not delete current version
*) 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
fi
if [ -n "$UPDATE_REQ_BYS" -a -r "$pdb/$new_port/+REQUIRED_BY" ]; then
echo ''
echo "===>>> Updating ports that depend on $new_port"
for req_by in `cat $pdb/$new_port/+REQUIRED_BY`; do
test -n "$VERBOSE" &&
echo "===>>> $req_by is required by $new_port"
if [ ! -d "$pdb/$req_by" ]; then
echo -n "===>>> WARNING! $pdb/$new_port/+REQUIRED_BY "
echo -n "shows that $req_by requires $new_port, but "
echo "$req_by does not seem to be installed"
echo -n "===>>> Press Enter to proceed "
read DISCARD
continue
fi
if [ -n "$INTERACTIVE_UPDATE" ]; then
echo -n "===>>> Update ${req_by}? [y] "
read UPD_OR_NOT
case "$UPD_OR_NOT" in
[nN]*) continue ;;
esac
fi
update_port $req_by
done
echo "===>>> Done updating ports that depend on $new_port"
fi
safe_exit
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright (c) 2005-2006 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.

View File

@ -0,0 +1,8 @@
This script provides a simple way to manage your ports.
It uses the existing ports infrastructure to track
dependencies, and to keep those dependencies up
to date.
Because portmaster is written in /bin/sh, it needs
no other interpreted languages installed.