Hello all.
While port removal happens less frequently than addition, it still
happens. It involves a few different operations that are done each
time and thus could be automated. It's not that much about time
saving (port removal doesn't involve much analytics), but about
not forgetting stuff.
Here is a proposal of portrm utility. Currently it does following:
1. Remove mentions of port from category Makefile.
2. Add a record to devel/quirks (using dirty tricks, of course).
3. Removes all port files under CVS control.
The utility is intended to be run under port directory. It gives
you a chance to make sure you're removing the correct port before
going on, and leaves the actual commit to you. I verified it on
the graphics/digikam-kde4 port. :)
I think this should also check that the port isn't used by anything
else, but I want to make sure the idea is welcome by senior porters
first. So all comments are welcome.
--
WBR,
Vadim Zhukov
#!/bin/ksh
set -e
set -u
CVS=${CVS:-cvs}
PORTSDIR=${PORTSDIR:-$(make -V PORTSDIR)}
case $PORTSDIR in
*\$*)
echo 'Could not detect $PORTSDIR via make invocation,' >&2
echo 'please set it as the environment variable.' >&2
exit 1
esac
if ! command -v cvsdo >/dev/null; then
echo "cvsutils package is not installed" >&2
exit 1
fi
quirks=devel/quirks/files/Quirks.pm
if ! [ -f "$PORTSDIR/$quirks" ]; then
echo "could not find $PORTSDIR/$quirks" >&2
exit 1
fi
pkgstems=$(make show=PKGNAMES | sed -E 's/-[0-9][^[:space:]]*//g')
portpath=$(pwd)
portpath=${portpath##${PORTSDIR}/}
cat=${portpath%/*}
portname=${portpath##*/}
echo -n "removing $portname from category $cat, is it right? (yes/no) " >&2
read ans
ans=$(echo "$ans" | tr A-Z a-z)
case $ans in
y|ye|yes)
;;
*)
echo "canceled" >&2
exit 3
;;
esac
enum_files() {
find "$1" -type d -name CVS | while IFS= read cvsd; do
cvsd=${cvsd%/CVS}
awk -F / '$1 == "" {print $2}' $cvsd/CVS/Entries | sed
"s,^,$cvsd/,"
done
}
cd -- "$PORTSDIR"
qtmp=$(mktemp $quirks.XXXXXXXX)
trap "rm $qtmp" EXIT
nmsg=0
msg_found=false
msg_ended=false
obs_found=false
obs_ended=false
reason=
exec 3<$quirks
while IFS= read -ru3 line; do
case $line in
"my @msg ="*)
if $msg_found; then
echo "duplicated @msg in $quirks" >&2
exit 1
fi
msg_found=true
;;
\)\;)
if $msg_found && ! $msg_ended; then
msg_ended=true
echo "Removal reasons available:" >&2
for i in $(jot $nmsg 0); do
echo " $i. ${msg[$i]}" >&2
done
echo -n "Type a reason number, or a new reason text: "
>&2
read reason
case $reason in
+([0-9]))
if [ $reason -ge $nmsg ]; then
echo "wrong number" >&2
exit 2
fi
;;
*\"*|*\$*)
echo "invalid reason text" >&2
exit 2
;;
*)
printf "\t\"%s\", #${nmsg}\n" "$nmsg" >>$qtmp
reason=$nmsg
;;
esac
fi
;;
"my \$obsolete_reason ="*)
if ! $msg_ended; then
echo "could not find obsolete reasons message list in
$quirks" >&2
exit 1
fi
if $obs_found; then
echo "duplicated \$obsolete_reason in $quirks" >&2
exit 1
fi
obs_found=true
;;
\}\;)
if $obs_found && ! $obs_ended; then
obs_ended=true
for stem in $pkgstems; do
printf "\t'%s' => %s,\n" "$stem" $reason >>$qtmp
done
fi
;;
*)
if $msg_found && ! $msg_ended; then
msg[$nmsg]=$(echo "$line" | awk -F '"' '{print $2}')
nmsg=$((nmsg + 1))
fi
;;
esac
printf "%s\n" "$line" >>$qtmp
done
mv $qtmp $quirks
trap "" EXIT
echo "Updating affected files..." >&2
$CVS update $quirks "$cat/Makefile" "$portpath"
cvsdo rm $(enum_files "$portpath")
perl -ni -e "/SUBDIR\\s*\\+?=\\s*$portname\\b/ or print" "$cat/Makefile"
echo "Here are changes to be made outside port directory:"
$CVS diff "$cat/Makefile" $quirks || true
echo
echo "======================================================"
echo "Now you can type the following in $PORTSDIR to commit:"
echo " cd $PORTSDIR && $CVS commit $cat/Makefile $quirks $portpath"