summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn McQuah <jmcquah@disroot.org>2022-02-12 14:34:00 +0100
committerJuergen Daubert <jue@jue.li>2022-02-12 14:34:00 +0100
commitfd902b1b937f3f204a130d6c65b4e1d845830df6 (patch)
treec6169625ee56a2e21f65a5686d71ade9e2106abc
parent3ea64833ee045309080b2232fb2753c52538398f (diff)
downloadprt-utils-fd902b1b937f3f204a130d6c65b4e1d845830df6.tar.gz
prt-utils-fd902b1b937f3f204a130d6c65b4e1d845830df6.tar.xz
prtsweep: enable the cleanup tool to recognize sources that have been renamed
-rw-r--r--[-rwxr-xr-x]prtsweep273
-rw-r--r--prtsweep.150
2 files changed, 240 insertions, 83 deletions
diff --git a/prtsweep b/prtsweep
index f26c440..5c72a1e 100755..100644
--- a/prtsweep
+++ b/prtsweep
@@ -1,7 +1,8 @@
#!/bin/bash
#
# $Id: prtsweep,v 1.2 2003/12/17 21:17:02 opel Exp $
-# (c) 2002, 2003 by Martin Opel <martin@obbl-net.de>
+# (c) 2002, 2003 by Martin Opel <martin at obbl-net dot de>
+# Revised 2021 by John McQuah <jmcquah at disroot dot org>
#
# May be redistributed and modified under the terms of the GPL
# only usable with CRUX Linux, version 1.0 or higher
@@ -32,67 +33,88 @@ interrupted() {
}
getportdirs() {
- local f
- for f in /etc/ports/*.rsync /etc/ports/*.httpup; do
- awk -F= '$1=="destination" || $1=="ROOT_DIR" {print $2}' $f
- done
-}
-
-keepfiles() {
- local f
- for f in "${KEEP_FILES[@]}"; do
- if [ "$1" = "$f" ]; then
- return 0
- fi
- done
- return 1
+ cat /etc/ports/*.{httpup,rsync} 2>/dev/null \
+ | awk -F= '$1=="destination" || $1=="ROOT_DIR" {print $2}'
}
remove() {
item=$1
- if [ -f $item ]; then
+ if [ -f "$item" ]; then
if [ "$dryrun" = "1" ]; then
msg "removing file $item (dryrun)"
else
msg "removing file $item"
- rm $item
+ rm "$item"
fi
- elif [ -d $item ]; then
+ elif [ -d "$item" ]; then
if [ "$dryrun" = "1" ]; then
msg "removing directory $item (dryrun)"
else
msg "removing directory $item"
- rm -r $item
+ rm -r "$item"
fi
fi
}
removeemptydir() {
- if [ `find $1 | wc -l` -eq 1 ]; then
+# called if the directory lacks a Pkgfile. Still need to check whether
+# it is actually empty.
+ local baggage
+ baggage=(`find $1`)
+ if [ ${#baggage[@]} -eq 1 ]; then
remove $1
else
- info "cannot remove non-empty directory '$dir'"
+ info "files still remaining in port directory '$1'!"
+ info "okay to remove them? (y/n)"
+ read CONSENT
+ if [ "$CONSENT" = "y" ]; then
+ for (( f=1; f<${#baggage[@]}; f++ )); do
+ remove ${baggage[$f]}
+ done
+ fi
fi
}
inlist() {
+ local excode
item=$1
shift
list="$@"
+ excode=1 # assume not in the list until proven otherwise
- for i in $list; do
- if [ "$i" = "$item" ]; then
- return 0
+ while [ "$#" -gt 0 ]; do
+ if [ "$item" = "$1" ]; then
+ excode=0
+ break
+ else
+ shift
fi
done
-
- return 1
+
+ return $excode
+}
+
+PWD_filename() {
+ if [[ $1 =~ ^(http|https|ftp|file)://.*/(.+) ]]; then
+ echo "${BASH_REMATCH[2]}"
+ else
+ echo $1
+ fi
+}
+
+remote_filename() {
+ if [[ $1 =~ ^(http|https|ftp|file)://.*/(.+) ]]; then
+ echo "/remote/path/${BASH_REMATCH[2]}"
+ else
+ echo $1
+ fi
}
-sweep() {
+nsweep() {
dir=$1
- savedir=`pwd`
- printedpwd="false"
+ reset_keepfiles
+ local printedpwd="false"
+ local name version source renames pkgfiles packagename packagepath subdir
if [ ! -d $dir ]; then
error "'`pwd`/$dir' is not a directory!"
@@ -110,81 +132,184 @@ sweep() {
return
fi
- cd $dir
- unset name version source pkgfiles
- . Pkgfile
+ echo "sweeping the directory for port $dir"
- for f in ${source[@]}; do
- pkgfiles=( `basename $f` ${pkgfiles[@]} )
+ # read the port information from its Pkgfile and save the results in a bash array.
+ # This loop assumes that renaming is only applied to files downloaded over http or ftp,
+ # not under version control systems like rsync or httpup. To preserve this information,
+ # an arbitrary URI scheme is prepended before the desired filename.
+ pkgfiles=(`( . $dir/Pkgfile; PKGLOC=$(eval "printf '%s' $PKGGLOB"); \
+ PKGFILE=$(eval "printf '%s' $BLTGLOB"); \
+ for (( p=0; p<${#source[@]}; p++ )); do \
+ [ -n "${renames[$p]}" -a "${renames[$p]}" != "SKIP" ] && source[$p]="ftp://somehost/${renames[$p]}"; \
+ done; echo "$PKGLOC/$PKGFILE"; \
+ printf '%s ' "${source[@]}" )`)
+
+ cd $dir
+ # (new feature in v0.5) remove the package too, if the user requests it with the "-p" flag
+ if [ "$pkgtoo" != "1" ]; then
+ packagename=`basename ${pkgfiles[0]}`
+ packagepath=`dirname ${pkgfiles[0]}`
+ if [ "${packagepath:0:1}" = "/" ]; then
+ KEEP_FILES="${KEEP_FILES} $packagename"
+ elif [ "${packagepath:0:1}" != "/" ]; then
+ subdir=$(echo $PKGLOC | sed "s|/.*||")
+ KEEP_FILES="${KEEP_FILES} $subdir"
+ fi
+ fi
+
+ # Now that we're safely out of the nested subshell, the URI scheme can be replaced.
+ # Make the new value match the `ls -A` output unless the user has requested
+ # removal of source files too.
+ if [ "$rmsources" = 1 ]; then
+ for (( p=1; p<${#pkgfiles[@]}; p++ )); do
+ pkgfiles[$p]=`remote_filename ${pkgfiles[$p]}`
done
- for f in `ls -a`; do
- if ! keepfiles "$f"; then
- if ! echo $f | grep '.*#.*\.pkg\.tar\.[gbx]z*' >/dev/null; then
- if ! inlist $f ${pkgfiles[@]}; then
- if [ "$printedpwd" = "false" ]; then
- printedpwd="true"
- info `pwd`
- fi
- remove $f
+ else
+ for (( p=1; p<${#pkgfiles[@]}; p++ )); do
+ pkgfiles[$p]=`PWD_filename ${pkgfiles[$p]}`
+ done
+ fi
+
+ unset pkgfiles[0]
+ for f in `ls -A`; do
+ if [[ ! ${KEEP_FILES} =~ "$f" ]] && ! inlist "$f" ${pkgfiles[@]}; then
+ if [ "$printedpwd" = "false" ]; then
+ printedpwd="true"
+ info `pwd`
fi
- fi
+ remove $f
fi
done
- cd $savedir
+ cd - &>/dev/null
+}
+
+reset_keepfiles() {
+ KEEP_FILES="Pkgfile README pre-install post-install
+ .footprint .signature .32bit .nostrip"
}
getoptions() {
- while [ "$1" = "-a" -o "$1" = "-d" -o "$1" = "-n" ]; do
- if [ "$1" = "-n" ]; then
+ while [ "$1" = "-a" -o "$1" = "-d" -o "$1" = "-n" -o "$1" = "-p" -o "$1" = "-s" -o "$1" = "-q" ]; do
+ if [ "$1" = "-q" ]; then
+ quiet=1
+ shift
+ elif [ "$1" = "-s" ]; then
+ rmsources=1
+ shift
+ elif [ "$1" = "-p" ]; then
+ pkgtoo=1
+ shift
+ elif [ "$1" = "-n" ]; then
dryrun=1
shift
- fi
- if [ "$1" = "-d" ]; then
+ elif [ "$1" = "-d" ]; then
delete=1
shift
- fi
- if [ "$1" = "-a" ]; then
+ elif [ "$1" = "-a" ]; then
auto=1
shift
fi
done
ports="$@"
+
+ if [ -z "$ports" -a "$auto" != "1" ]; then
+ echo "You must explicitly call for automatic mode (-a) if you"
+ echo "do not provide the paths of ports you want cleaned."
+ usage
+ elif [ -n "$ports" -a "$auto" = "1" ]; then
+ echo "Automatic mode (-a) is incompatible with providing an"
+ echo "explicit list of ports to clean."
+ usage
+ fi
+
}
usage() {
echo
- echo "Usage: prtsweep [-a] [-d] [-n] [PORTDIR ...]"
+ echo "Usage: prtsweep [-a] [-d] [-n] [-s] [-p] [-q] [PORTDIR ...]"
echo
exit 1
}
+do_sweep() {
+ if [ -z "$ports" -a "$auto" = "1" ]; then
+ for portdir in $collections; do
+ echo $portdir
+ cd $portdir
+ for dir in *; do
+ test -d $dir && nsweep $dir
+ done
+ done
+ elif [ -n "$ports" -a "$auto" != "1" ]; then
+ for dir in $ports; do
+ test -d $dir && nsweep $dir
+ done
+ else
+ usage
+ fi
+ exit 0
+}
+
+info_portsgiven() {
+ echo "$0 will not touch anything outside of the portdirs given on the command line,"
+ echo "but it looks like the debris from building your ports might be lying around somewhere else."
+ echo "Consider following up with another script."
+ echo "Press enter to continue."
+ read ACKNOWLEDGE
+}
+
+info_auto() {
+ echo "$0 will not touch anything outside of"
+ printf '%s\n' $collections
+ echo "but it looks like the debris from building your ports might be lying around somewhere else."
+ echo "Consider following up with another script."
+ echo "Press enter to continue."
+ read ACKNOWLEDGE
+}
+
+# Main work happens below
trap "interrupted" SIGHUP SIGINT SIGQUIT SIGTERM
getoptions $@
-KEEP_FILES=(
- "Pkgfile" "README" "pre-install" "post-install"
- ".footprint" ".signature" ".32bit" ".nostrip"
- "." ".."
-)
+# First determine the directories that have been configured for downloads and built packages.
+if [ -f /etc/pkgmk.conf ]; then
+ SRCGLOB=$(grep PKGMK_SOURCE_DIR /etc/pkgmk.conf | sed "s/[\t w]*#.*//; s/.*=//")
+ PKGGLOB=$(grep PKGMK_PACKAGE_DIR /etc/pkgmk.conf | sed "s/[\t w]*#.*//; s/.*=//")
+ COMPRESSION_MODE=$(grep COMPRESSION_MODE /etc/pkgmk.conf | sed "s/[\t w]*#.*//; s/.*=//")
+fi
+# No custom setting for compression mode means that pkgmk falls back to the default, gzip.
+[ -n "$COMPRESSION_MODE" ] || COMPRESSION_MODE="gz"
+BLTGLOB='$name#$version-$release.pkg.tar.$COMPRESSION_MODE'
-if [ -z "$ports" -a "$auto" = "1" ]; then
- for portdir in `getportdirs`; do
- savedir=`pwd`
- cd $portdir
- for dir in *; do
- test -d $dir && sweep $dir
- done
- cd $savedir
- done
- exit 0
-elif [ ! -z "$ports" ]; then
- for dir in $ports; do
- sweep $dir
- done
- exit 0
+# Layouts 1 and 2: If all ports share a common directory (either for the sources or for
+# the built packages), then this script might need to be supplemented by further cleaning.
+# Suppress the warning if option -q (quiet mode) was given.
+collections=`getportdirs`
+
+if [ "$quiet" != "1" ]; then
+ if [ -n "$SRCGLOB" ] && echo "${SRCGLOB}" | grep -q -v '\$name'; then
+ if [ -n "$ports" ]; then
+ info_portsgiven
+ elif [ "$auto" = 1 ]; then
+ info_auto
+ fi
+ do_sweep
+ fi
+ if [ -n "$PKGGLOB" ] && echo "${PKGGLOB}" | grep -q -v '\$name'; then
+ if [ -n "$ports" ]; then
+ info_portsgiven
+ elif [ "$auto" = 1 ]; then
+ info_auto
+ fi
+ do_sweep
+ fi
fi
-usage
-exit 1
+# Layout 3: the admin has left either PKGMK_SOURCE_DIR or PKGMK_PACKAGE_DIR at its default,
+# or has defined at least one of them in terms of the port name. Do the sweep
+# without issuing a warning (The option -q is not applicable for this layout).
+
+do_sweep
diff --git a/prtsweep.1 b/prtsweep.1
index de49808..2272d2b 100644
--- a/prtsweep.1
+++ b/prtsweep.1
@@ -1,6 +1,7 @@
.\"
.\" prtsweep manual page.
-.\" (C) 2e003 by Martin Opel <mo@obbl-net.de>
+.\" (C) 2e003 by Martin Opel
+.\" Revised 2021 by John McQuah
.\"
.TH prtsweep 1
.SH NAME
@@ -11,12 +12,12 @@ prtsweep \- sweep old files from the ports directories
[\-a] [\-d] [\-n] [PORTDIR ...]
.SH DESCRIPTION
-The \fIprtsweep\fP program sweeps port directories from unneeded files.
-Unneeded files are either files which are not part of the source array
-in the Pkgfile or package files with a name like
+The \fIprtsweep\fP program sweeps port directories, deleting unneeded files.
+"Unneeded" here means not found in the Pkgfile source array, and not the
+built package
.PP
.nf
- name#version.pkg.tar.gz
+ name#version-release.pkg.tar.gz
.fi
.PP
All other files are removed. If a port directory is empty, the whole directory
@@ -32,7 +33,7 @@ in these directories.
.TP
.I "\-d"
Removes empty directories completely. This happens when ports are moved for
-example from unstable to stable or vice versa. Note that this option only
+example from opt to contrib or vice versa. Note that this option only
deletes empty directories, so accidently removing whole directory trees
should not happen, even if you use
.IP
@@ -43,8 +44,39 @@ should not happen, even if you use
To remove these moved ports completely you have to run \fIprtsweep\fP twice
to first remove the files and second remove the empty directory.
.TP
+.I "\-p"
+Also removes the built package.
+.TP
.I "\-n"
-Dryrun. Do not remove anything really.
+Dry-run. Do not remove anything really.
+.TP
+.I "\-q"
+Quiet mode. Do not pause to inform the user when analysis of the config file
+indicates that clutter from building ports might still remain elsewhere
+in the filesystem.
+.SH ENVIRONMENT
+In automatic mode, \fBprtsweep\fP reads from /etc/pkgmk.conf
+any custom settings for PKGMK_SOURCE_DIR and PKGMK_PACKAGE_DIR
+to determine where the clutter from a pkgmk build is likely to
+appear. If the directories potentially cluttered by pkgmk builds
+are shared among many ports, e.g., by setting a nonempty
+PKGMK_SOURCE_DIR with no reference to the port name, then
+\fBprtsweep\fP will pause and inform the user that a follow-up
+cleaning using other tools might be needed. This warning can be suppressed
+by passing the \fB\-q\fP option.
+.PP
+\fBprtsweep\fP then gets a list of active port collections
+from /etc/ports/*.{rsync,httpup}, and for each collection descends into the
+individual port directories to read the associated Pkgfiles.
+After reading the Pkgfile, \fBprtsweep\fP will know the source filenames and
+the package filename. \fBprtsweep\fP then compares the contents of the port
+directory with this list of needed files, and any non-matching filename is
+deleted (or just printed to stderr if dry-run mode is enabled).
+.PP
+After a real cleaning by \fBprtsweep\fP (not dry-run mode), each port
+directory should contain only the Pkgfile, source files obtained
+by rsync or httpup, and the built package (if present, and option -p was
+not given on the command line).
.SH EXAMPLES
@@ -71,7 +103,7 @@ for all ports directories and cleans them automatically:
...
.fi
-.SH AUTHOR
-Martin Opel <mo@obbl-net.de>
+.SH AUTHORS
+Martin Opel <mo at obbl-net dot de>, John McQuah <jmcquah at disroot dot org>
.SH "SEE ALSO"
prtwash(1)

Generated by cgit