Date: Sun, 27 Jul 2003 13:28:47 +0200 (CEST) From: Stefan Walter <sw@gegenunendlich.de> To: FreeBSD-gnats-submit@FreeBSD.org Subject: ports/54912: New port: pkg_cutleaves - Perl script for finding/pkg_deinstalling 'leaf' packages Message-ID: <20030727112847.891A9882D@kyuzo.dunkelkammer.void> Resent-Message-ID: <200307271130.h6RBUFqE091833@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>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@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@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@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@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@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:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20030727112847.891A9882D>