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"

Reply via email to