Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 30 Aug 2012 16:33:09 -0600
From:      John Nielsen <lists@jnielsen.net>
To:        Baptiste Daroussin <bapt@freebsd.org>
Cc:        "ports@freebsd.org" <ports@freebsd.org>, "current@freebsd.org" <current@freebsd.org>
Subject:   Re: Script to set/unset "automatic" status in PKGNG database
Message-ID:  <BC3A517F-CA9F-42A3-A1F5-9ACA2D07A860@jnielsen.net>
In-Reply-To: <20120830212833.GN64447@ithaqua.etoilebsd.net>
References:  <CFA2273E-4498-4A64-BC9F-CE5AA560409D@jnielsen.net> <20120830212833.GN64447@ithaqua.etoilebsd.net>

index | next in thread | previous in thread | raw e-mail

[-- Attachment #1 --]
On Aug 30, 2012, at 3:28 PM, Baptiste Daroussin <bapt@freebsd.org> wrote:

> On Thu, Aug 30, 2012 at 03:19:59PM -0600, John Nielsen wrote:
>> 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.
> 
> Would you mind adding create a patch against the git tree of pkgng so that we
> can include your script into the scripts subdirectory, so that we provide your
> script along with the next pkg 1.0.1 as a contributed script?

No problem. Attached is the output of "git diff origin" after dropping my script in to my local tree. Let me know if you need something else.

Changes between this and the version I originally posted:
	Added 2-clause license and disclaimer
	Replaced SQL with 'pkg set' commands. Since I didn't come up with a fast way to list the packages not in the 'automatic' list, I first set all packages to 0 (not automatic), then set the ones in the list to 1. This is likely slower than the SQL variant was, but it's not bad and not something likely to be run frequently.

JN

[-- Attachment #2 --]
diff --git a/scripts/set_pkg_auto.sh b/scripts/set_pkg_auto.sh
new file mode 100755
index 0000000..6342e7a
--- /dev/null
+++ b/scripts/set_pkg_auto.sh
@@ -0,0 +1,116 @@
+#!/bin/sh
+
+# Copyright (c) 2012 John Nielsen <john@jnielsen.net>
+# 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
+#    in this position and unchanged.
+# 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(S) ``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(S) 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.
+
+# 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
+# via 'pkg set ...'. I wrote it to make "pkg autoremove" useful following
+# a pkg2ng migration, but other uses are conceivable.
+
+# 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"
+
+# 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' ${1}`
+	# First unset all
+	pkg set -ay -A 0
+	# Then set selected
+	pkg set -y -A 1 ${autopkgs}
+}
+
+# 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."

[-- Attachment #3 --]


help

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?BC3A517F-CA9F-42A3-A1F5-9ACA2D07A860>