I today noticed the "pkg autoremove" command for the first time, which does 
much the same thing as pkg_cutleaves but relies on the "automatic" flag in the 
pkgng database rather than user input to determine which "leaf" ports can be 
removed. Unfortunately, the pkg2ng utility has no way of knowing which 
old-style packages it converts were installed automatically as dependencies, so 
they are all marked as non-automatic (i.e. user-requested). In my case, this 
was not true for the majority of installed ports. Since I really like this 
functionality, I decided to update my local package database to match my 
preferences.

Having succeeded, I decided a tool to make doing so easy could well benefit 
others (as well as my future self). (Plus I wanted an excuse to play with 
dialog(1) and "pkg query" a bit.) So here's the result. I'm not too attached to 
the name. It shouldn't eat your package database or steal your lunch money, but 
I'm not responsible if it does. Other than that, feedback is welcome.


JN
#!/bin/sh

# Copyright (c) 2012 John Nielsen <j...@jnielsen.net>

# This script presents a checklist of all PKGNG packages registered on
# the system, showing for each whether or not it is marked as "automatic"
# (i.e. not explicitly requested by the user). Any changes are recorded
# in the PKGNG database. I wrote it to make "pkg autoremove" useful
# following a pkg2ng migration, but other uses are conceivable.

# The PKGNG database file to use
DB=/var/db/pkg/local.sqlite

# Terminal geometry
sz=`stty size`
rows=`echo ${sz} | cut -d ' ' -f 1`
cols=`echo ${sz} | cut -d ' ' -f 2`
drows=$(( ${rows} - 3 ))
dcols=$(( ${cols} - 6 ))

# Dialog results are stored here
tmpfile=`mktemp -t set_pkg_auto`

# We always want the same style checklist
export DIALOGOPTS="--extra-button --extra-label \"Select All\" --cancel-label 
\"Deselect All\" --help-button --help-label Exit --separator ,"

# Exit with an error message
die() {
        rm -f ${tmpfile}
        echo "${1}"
        exit 1
}

# Don't leave tmpfile behind even if we are killed/interrupted
trap "die \"Interrupt received.\"" 2 15

# Run dialog to present the checklist and save the results in tmpfile
run_dialog() {
        dialog --checklist "Select packages to consider for auto-removal" 
${drows} ${dcols} ${drows} $* 2>${tmpfile}
        return $?
}

# Show the current status from the package database in the checklist
select_current() {
        run_dialog `pkg query '%n %o %a' | sed -e 's/1$/on/g' -e 's/0$/off/g'`
        return $?
}

# Select all packages in the checklist
select_all() {
        run_dialog `pkg query '%n %o' | sed -e 's/$/ on/g'`
        return $?
}

# De-select all packages in the checklist
select_none() {
        run_dialog `pkg query '%n %o' | sed -e 's/$/ off/g'`
        return $?
}

# Update the package database to match selections in the specified file
do_update() {
        autopkgs=`sed -e "s/^,//g" -e "s/\"/'/g" ${1}`
        sqlite3 ${DB} "update packages set automatic=1 where name in 
(${autopkgs});" \
                || die "SQlite error."
        sqlite3 ${DB} "update packages set automatic=0 where name not in 
(${autopkgs});" \
                || die "SQlite error."
}

# Run select_current for the first checklist
pkgset=current

# Show the checklist until "OK" or "Exit" is selected
while : ; do
        select_${pkgset}
        case $? in
                0) # OK, continue with updates
                        break;
                        ;;
                3) # Extra (Select all), show the checklist again
                        pkgset=all
                        ;;
                1) # Cancel (Deselect all), show the checklist again
                        pkgset=none
                        ;;
                *) # 4-Help (Exit) or ESC or error, exit.
                        die "No changes made."
                        ;;
        esac
done

# If we got this far then tmpfile has a list of 'automatic' packages
do_update ${tmpfile}

# Clean up
rm -f ${tmpfile}
echo "Updated successfully."

_______________________________________________
freebsd-ports@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-ports
To unsubscribe, send any mail to "freebsd-ports-unsubscr...@freebsd.org"

Reply via email to