ports/54912: New port: pkg_cutleaves - Perl script for finding/pkg_deinstalling 'leaf' packages

Stefan Walter sw at gegenunendlich.de
Sun Jul 27 11:30:17 UTC 2003


>Number:         54912
>Category:       ports
>Synopsis:       New port: pkg_cutleaves - Perl script for finding/pkg_deinstalling 'leaf' packages
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-ports-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Sun Jul 27 04:30:14 PDT 2003
>Closed-Date:
>Last-Modified:
>Originator:     Stefan Walter
>Release:        FreeBSD 5.1-RELEASE i386
>Organization:
>Environment:
System: FreeBSD kyuzo.dunkelkammer.void 5.1-RELEASE FreeBSD 5.1-RELEASE #0: Sat Jul 19 11:01:42 CEST 2003 root at kyuzo.dunkelkammer.void:/usr/src/sys/i386/compile/KYUZO i386
>Description:
	pkg_cutleaves finds installed 'leaf' packages, i.e. packages that
	are not referenced by any other installed package, and lets you
	decide for each one if you want to keep or deinstall it (via
	pkg_deinstall(1)).

	Usage: pkg_cutleaves [-l] [-x] [-R]
	  -l: List leaf packages only, one per line, and don't ask for anything
	      to be deinstalled.
	  -x: Exclude packages matching expressions given in the exclude file.
	  -R: Run 'pkg_deinstall -R' instead of plain 'pkg_deinstall', so
	      packages depending on removed leaf packages will be deinstalled,
	      too.

	This port is self contained and includes the Perl script as well as
	a man page.
>How-To-Repeat:
	Install the attached port.
>Fix:
--- pkg_cutleaves-port.shar begins here ---
# This is a shell archive.  Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file".  Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
#	pkg_cutleaves/
#	pkg_cutleaves/Makefile
#	pkg_cutleaves/src
#	pkg_cutleaves/src/pkg_cutleaves.1
#	pkg_cutleaves/src/pkg_cutleaves
#	pkg_cutleaves/pkg-descr
#	pkg_cutleaves/pkg-plist
#
echo c - pkg_cutleaves/
mkdir -p pkg_cutleaves/ > /dev/null 2>&1
echo x - pkg_cutleaves/Makefile
sed 's/^X//' >pkg_cutleaves/Makefile << 'END-of-pkg_cutleaves/Makefile'
X# New ports collection makefile for:	pkg_cutleaves
X# Date created:		27 July 2003
X# Whom:			Stefan Walter <sw at gegenunendlich.de>
X#
X# $FreeBSD$
X#
X# This port is self contained in the src directory.
X#
X
XPORTNAME=	pkg_cutleaves
XPORTVERSION=	20030727
XCATEGORIES=	sysutils
XMASTER_SITES=	# none
XDISTFILES=	# none
X
XMAINTAINER=	sw at gegenunendlich.de
XCOMMENT=	Interactive script for deinstalling 'leaf' packages
X
XRUN_DEPENDS=	${LOCALBASE}/sbin/pkg_deinstall:${PORTSDIR}/sysutils/portupgrade
X
XNO_BUILD=	yes
XUSE_PERL5=	yes
XUSE_REINPLACE=	yes
X
XSRC=		${.CURDIR}/src
X
XMAN1=		pkg_cutleaves.1
X
Xdo-fetch:
X	@${DO_NADA}
X
Xpre-patch:
X	@${CP} ${SRC}/pkg_cutleaves ${WRKDIR}/pkg_cutleaves
X	@${CP} ${SRC}/pkg_cutleaves.1 ${WRKDIR}/pkg_cutleaves.1
X
Xpost-patch:
X	@${REINPLACE_CMD} -e \
X	  's,/usr/local/etc/pkg_leaves.exclude,${PREFIX}/etc/pkg_leaves.exclude,' \
X	  ${WRKDIR}/pkg_cutleaves.1
X	@${REINPLACE_CMD} -e \
X	  's,/usr/local/etc/pkg_leaves.exclude,${PREFIX}/etc/pkg_leaves.exclude,' \
X	  ${WRKDIR}/pkg_cutleaves
X	@${REINPLACE_CMD} -e \
X	  's,/usr/local/sbin/pkg_deinstall,${LOCALBASE}/sbin/pkg_deinstall,' \
X	  ${WRKDIR}/pkg_cutleaves
X	@${REINPLACE_CMD} -e \
X	  's,/var/db/pkg,${PKG_DBDIR},' \
X	  ${WRKDIR}/pkg_cutleaves
X	@${REINPLACE_CMD} -e 's,/usr/bin/perl,${PERL},' \
X	  ${WRKDIR}/pkg_cutleaves
X
Xdo-install:
X	${INSTALL_SCRIPT} ${WRKDIR}/pkg_cutleaves ${PREFIX}/sbin/pkg_cutleaves
X	${INSTALL_MAN} ${WRKDIR}/pkg_cutleaves.1 ${MAN1PREFIX}/man/man1
X
X.include <bsd.port.mk>
END-of-pkg_cutleaves/Makefile
echo c - pkg_cutleaves/src
mkdir -p pkg_cutleaves/src > /dev/null 2>&1
echo x - pkg_cutleaves/src/pkg_cutleaves.1
sed 's/^X//' >pkg_cutleaves/src/pkg_cutleaves.1 << 'END-of-pkg_cutleaves/src/pkg_cutleaves.1'
X.TH PKG_CUTLEAVES 1 "Jul 2003" FreeBSD
X.SH NAME
Xpkg_cutleaves \- deinstall 'leaf' packages
X.SH SYNOPSIS
X.B pkg_cutleaves [-l] [-x] [-R]
X.SH DESCRIPTION
X.B pkg_cutleaves
Xfinds installed 'leaf' packages, i.e. packages that are not referenced
Xby any other installed package, and lets you decide for each one if you
Xwant to keep or deinstall it (via pkg_deinstall(1)).
XOnce the packages marked for removal have been flushed/deinstalled,
Xyou'll be asked if you want to do another run (to see packages that have
Xbecome 'leaves' now because you've deinstalled the package(s) that
Xdepended on them). In every run you will be shown only packages that you
Xhaven't marked for keeping, yet.
X
XNote that your package registry database should be up to date for this
Xto work properly, so it might be a good idea to run pkgdb(1) before
Xrunning pkg_cutleaves.
X.SH OPTIONS
X.IP -l
XList leaf packages only, one per line, and don't ask for anything to be
Xdeinstalled.
X.IP -x
XExclude packages matching expressions given in the exclude file.
X.IP -R
XRun 'pkg_deinstall -R' instead of plain 'pkg_deinstall', so packages
Xdepending on removed leaf packages will be deinstalled, too.
X.SH FILES
X.I /usr/local/etc/pkg_leaves.exclude
X.RS
XAn optional list for excluding packages when the '-x' option is given.
XIf the beginning of a package's name matches any line (except comment or
Xempty lines) in this file, the package will not be listed/offered for
Xremoval (e.g., a line saying just 'XFree86' (without the 's) will
Xexclude all packages with names starting with 'XFree86').
X.SH AUTHOR
XStefan Walter <sw at gegenunendlich.de>
X.SH SEE ALSO
Xpkg_deinstall(1), portsclean(1)
END-of-pkg_cutleaves/src/pkg_cutleaves.1
echo x - pkg_cutleaves/src/pkg_cutleaves
sed 's/^X//' >pkg_cutleaves/src/pkg_cutleaves << 'END-of-pkg_cutleaves/src/pkg_cutleaves'
X#!/usr/bin/perl
X#
X# Copyright (c) 2003 Stefan Walter <sw at gegenunendlich.de>
X#
X# All rights reserved.
X#
X# Redistribution and use in source and binary forms, with or without
X# modification, are permitted provided that the following conditions
X# are met:
X# 1. Redistributions of source code must retain the above copyright
X#    notice, this list of conditions and the following disclaimer.
X# 2. Redistributions in binary form must reproduce the above copyright
X#    notice, this list of conditions and the following disclaimer in the
X#    documentation and/or other materials provided with the distribution.
X#
X# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
X# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
X# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
X# ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
X# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
X# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
X# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
X# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
X# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
X# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
X# SUCH DAMAGE.
X#
X# $FreeBSD$
X
X# Interactive script for deinstalling "leaf" packages;
X# requires the portupgrade tools
X#
X# Syntax: pkg_cutleaves [-l] [-x] [-R]
X# Options:
X#   -l: List leaf packages only, don't ask if they should be deinstalled
X#   -x: Honor exclude list in $excludefile
X#   -R: Run 'pkg_deinstall -R' instead of plain 'pkg_deinstall'
X
Xuse strict;
X
Xmy $dbdir = "/var/db/pkg";
Xmy $excludefile = "/usr/local/etc/pkg_leaves.exclude";
Xmy $pkgdeinstall = "/usr/local/sbin/pkg_deinstall";
Xmy ($opt_listonly, $opt_excludelist, $opt_recursive);
Xmy $exclpattern;
X
X# Read the exclude list if the file exists
Xsub get_excl_pattern {
X	my $excl_file = $_[0];
X	my $excl_pattern;
X	# Does the exclude file exist?
X	if (($excl_file) && (-f $excl_file) && (-T $excl_file)) {
X		# Read the patterns to be excluded
X		my @excludes;
X		open(EXCLFILE, $excl_file)
X			or die "Couldn't open $excl_file!";
X		while(my $exclude = <EXCLFILE>) {
X			chomp($exclude);
X			# Ignore comments and empty lines, add others as regular expressions
X			unless (($exclude =~ m/(^ *#)|(^ *$)/)) {
X				$exclude = "^" . $exclude . ".*";
X				@excludes = (@excludes, $exclude);
X			}
X		}
X		close(EXCLFILE);
X		$excl_pattern = join("|", @excludes);
X	} else {
X		# Dummy exclusion pattern -> doesn't exclude anything
X		$excl_pattern = " ";
X	}
X	return $excl_pattern;
X}
X
X# Get a list of all leaves
Xsub get_leaves {
X	my $db_dir = $_[0];
X	my $excl_pattern = $_[1];
X	my @pkgdirs;
X	opendir(DBDIR, $db_dir)
X		or die "Can't open package db directory $db_dir!";
X	while(defined(my $file = readdir(DBDIR))) {
X		my $path = $db_dir . '/' . $file;
X		my $reqlist = $path . '/+REQUIRED_BY';
X		# Exclude non-directories, "." and ".."
X		if (($file ne ".") && ($file ne "..") && (-d $path) && (!-e $reqlist)) {
X			# Exclude packages matching exclude pattern, if requested
X			unless ($file =~ m/$excl_pattern/) {
X				@pkgdirs = (@pkgdirs, $file);
X			}
X		}
X	}
X	closedir(DBDIR);
X	return @pkgdirs;
X}
X
X# Examine command line arguments
Xwhile(@ARGV) {
X	my $arg = shift(@ARGV);
X	if ($arg eq "-x") {
X		$opt_excludelist = 1;
X	}
X	elsif ($arg eq "-l") {
X		$opt_listonly = 1;
X	}
X	elsif ($arg eq "-R") {
X		$opt_recursive = 1;
X	}
X}
X
X# Exclusion requested?
Xif ($opt_excludelist) {
X	# Get exclusion pattern
X	$exclpattern = get_excl_pattern($excludefile);
X} else {
X	# Spaces don't appear in package names -> this doesn't exclude anything
X	$exclpattern = " ";
X}
X
Xif ($opt_listonly) {
X	# Just print out the list of leaves, one per line
X	my @leaveslist = get_leaves($dbdir, $exclpattern);
X	foreach my $leaf (sort @leaveslist) {
X		print "$leaf\n";
X	}
X} else {
X	my %leavestokeep;
X	my %leavestocut;
X	my @cutleaves;
X	# Loop while the user wants to
X	my $again = "y";
X	ROUND: while($again eq "y") {
X		# Get list of packages and put them into an array
X		my @leaves = get_leaves($dbdir, $exclpattern);
X		LEAVESLOOP: foreach my $leaf (sort @leaves) {
X			if (!$leavestokeep{$leaf}) {
X				print "$leaf - [keep]/(d)elete/(f)lush marked pkgs/(a)bort? ";
X				my $answer = substr(lc(<STDIN>), 0, 1);
X
X				if ($answer eq "d") {
X					print "** Marking $leaf for removal.\n\n";
X					$leavestocut{$leaf} = 1;
X				}
X				elsif ($answer eq "f") {
X					print "\n";
X					last LEAVESLOOP;
X				}
X				elsif ($answer eq "a") {
X					print "\n";
X					last ROUND;
X				}
X				else {
X					print "** Keeping $leaf.\n\n";
X					$leavestokeep{$leaf} = 1;
X				}
X			}
X		} # LEAVESLOOP
X		
X		# loop through packages marked for removal and pkg_deinstall them
X		foreach my $leaf (sort keys %leavestocut) {
X			print "Deleting $leaf.\n";
X			my @deinstall_args;
X			if ($opt_recursive) {
X				@deinstall_args = ($pkgdeinstall, '-R', $leaf);
X			} else {
X				@deinstall_args = ($pkgdeinstall, $leaf);
X			}
X			if ((my $status = system(@deinstall_args) >> 8) != 0) {
X				print "\nError: pkg_deinstall returned $status - exiting, fix this first.\n\n";
X				last ROUND;
X			}
X			@cutleaves = (@cutleaves, $leaf);
X			delete $leavestocut{$leaf};
X		}
X		
X		print "Once more ((y)es/[no])? ";
X		$again = substr(lc(<STDIN>), 0, 1);
X		print "\n";
X	} # ROUND
X
X	# print list of removed packages
X	print "** Deinstalled packages:\n";
X	foreach my $cutleaf (@cutleaves) {
X		print "$cutleaf\n";
X	}
X}
X
END-of-pkg_cutleaves/src/pkg_cutleaves
echo x - pkg_cutleaves/pkg-descr
sed 's/^X//' >pkg_cutleaves/pkg-descr << 'END-of-pkg_cutleaves/pkg-descr'
Xpkg_cutleaves finds installed 'leaf' packages, i.e. packages that are
Xnot referenced by any other installed package, and lets you decide for
Xeach one if you want to keep or deinstall it (via pkg_deinstall(1)).
X
XUsage: pkg_cutleaves [-l] [-x] [-R]
X  -l: List leaf packages only, one per line, and don't ask for anything
X      to be deinstalled.
X  -x: Exclude packages matching expressions given in the exclude file.
X  -R: Run 'pkg_deinstall -R' instead of plain 'pkg_deinstall', so
X	  packages depending on removed leaf packages will be deinstalled,
X      too.
END-of-pkg_cutleaves/pkg-descr
echo x - pkg_cutleaves/pkg-plist
sed 's/^X//' >pkg_cutleaves/pkg-plist << 'END-of-pkg_cutleaves/pkg-plist'
Xsbin/pkg_cutleaves
END-of-pkg_cutleaves/pkg-plist
exit
--- pkg_cutleaves-port.shar ends here ---
>Release-Note:
>Audit-Trail:
>Unformatted:



More information about the freebsd-ports-bugs mailing list