add pkg_cutleaves-20030727

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).

PR:		54912
Submitted by:	Stefan Walter <sw@gegenunendlich.de>
This commit is contained in:
Yen-Ming Lee 2003-09-30 14:19:27 +00:00
parent f707a5e303
commit d85f8f76c8
Notes: svn2git 2021-03-31 03:12:20 +00:00
svn path=/head/; revision=89898
11 changed files with 587 additions and 0 deletions

View file

@ -0,0 +1,56 @@
# New ports collection makefile for: pkg_cutleaves
# Date created: 27 July 2003
# Whom: Stefan Walter <sw@gegenunendlich.de>
#
# $FreeBSD$
#
# This port is self contained in the src directory.
#
PORTNAME= pkg_cutleaves
PORTVERSION= 20030727
CATEGORIES= sysutils
MASTER_SITES= # none
DISTFILES= # none
MAINTAINER= sw@gegenunendlich.de
COMMENT= Interactive script for deinstalling 'leaf' packages
RUN_DEPENDS= ${LOCALBASE}/sbin/pkg_deinstall:${PORTSDIR}/sysutils/portupgrade
NO_BUILD= yes
USE_PERL5= yes
USE_REINPLACE= yes
SRC= ${.CURDIR}/src
MAN1= pkg_cutleaves.1
do-fetch:
@${DO_NADA}
pre-patch:
@${CP} ${SRC}/pkg_cutleaves ${WRKDIR}/pkg_cutleaves
@${CP} ${SRC}/pkg_cutleaves.1 ${WRKDIR}/pkg_cutleaves.1
post-patch:
@${REINPLACE_CMD} -e \
's,/usr/local/etc/pkg_leaves.exclude,${PREFIX}/etc/pkg_leaves.exclude,' \
${WRKDIR}/pkg_cutleaves.1
@${REINPLACE_CMD} -e \
's,/usr/local/etc/pkg_leaves.exclude,${PREFIX}/etc/pkg_leaves.exclude,' \
${WRKDIR}/pkg_cutleaves
@${REINPLACE_CMD} -e \
's,/usr/local/sbin/pkg_deinstall,${LOCALBASE}/sbin/pkg_deinstall,' \
${WRKDIR}/pkg_cutleaves
@${REINPLACE_CMD} -e \
's,/var/db/pkg,${PKG_DBDIR},' \
${WRKDIR}/pkg_cutleaves
@${REINPLACE_CMD} -e 's,/usr/bin/perl,${PERL},' \
${WRKDIR}/pkg_cutleaves
do-install:
${INSTALL_SCRIPT} ${WRKDIR}/pkg_cutleaves ${PREFIX}/sbin/pkg_cutleaves
${INSTALL_MAN} ${WRKDIR}/pkg_cutleaves.1 ${MAN1PREFIX}/man/man1
.include <bsd.port.mk>

View file

@ -0,0 +1,10 @@
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
the removed leaf packages depend(ed) on will be deinstalled, too.

View file

@ -0,0 +1 @@
sbin/pkg_cutleaves

View file

@ -0,0 +1,186 @@
#!/usr/bin/perl
#
# Copyright (c) 2003 Stefan Walter <sw@gegenunendlich.de>
#
# 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.
# 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 REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
#
# $FreeBSD$
# Interactive script for deinstalling "leaf" packages;
# requires the portupgrade tools
#
# Syntax: pkg_cutleaves [-l] [-x] [-R]
# Options:
# -l: List leaf packages only, don't ask if they should be deinstalled
# -x: Honor exclude list in $excludefile
# -R: Run 'pkg_deinstall -R' instead of plain 'pkg_deinstall'
use strict;
my $dbdir = "/var/db/pkg";
my $excludefile = "/usr/local/etc/pkg_leaves.exclude";
my $pkgdeinstall = "/usr/local/sbin/pkg_deinstall";
my ($opt_listonly, $opt_excludelist, $opt_recursive);
my $exclpattern;
# Read the exclude list if the file exists
sub get_excl_pattern {
my $excl_file = $_[0];
my $excl_pattern;
# Does the exclude file exist?
if (($excl_file) && (-f $excl_file) && (-T $excl_file)) {
# Read the patterns to be excluded
my @excludes;
open(EXCLFILE, $excl_file)
or die "Couldn't open $excl_file!";
while(my $exclude = <EXCLFILE>) {
chomp($exclude);
# Ignore comments and empty lines, add others as regular expressions
unless (($exclude =~ m/(^ *#)|(^ *$)/)) {
$exclude = "^" . $exclude . ".*";
@excludes = (@excludes, $exclude);
}
}
close(EXCLFILE);
$excl_pattern = join("|", @excludes);
} else {
# Dummy exclusion pattern -> doesn't exclude anything
$excl_pattern = " ";
}
return $excl_pattern;
}
# Get a list of all leaves
sub get_leaves {
my $db_dir = $_[0];
my $excl_pattern = $_[1];
my @pkgdirs;
opendir(DBDIR, $db_dir)
or die "Can't open package db directory $db_dir!";
while(defined(my $file = readdir(DBDIR))) {
my $path = $db_dir . '/' . $file;
my $reqlist = $path . '/+REQUIRED_BY';
# Exclude non-directories, "." and ".."
if (($file ne ".") && ($file ne "..") && (-d $path) && (!-s $reqlist)) {
# Exclude packages matching exclude pattern, if requested
unless ($file =~ m/$excl_pattern/) {
@pkgdirs = (@pkgdirs, $file);
}
}
}
closedir(DBDIR);
return @pkgdirs;
}
# Examine command line arguments
while(@ARGV) {
my $arg = shift(@ARGV);
if ($arg eq "-x") {
$opt_excludelist = 1;
}
elsif ($arg eq "-l") {
$opt_listonly = 1;
}
elsif ($arg eq "-R") {
$opt_recursive = 1;
}
}
# Exclusion requested?
if ($opt_excludelist) {
# Get exclusion pattern
$exclpattern = get_excl_pattern($excludefile);
} else {
# Spaces don't appear in package names -> this doesn't exclude anything
$exclpattern = " ";
}
if ($opt_listonly) {
# Just print out the list of leaves, one per line
my @leaveslist = get_leaves($dbdir, $exclpattern);
foreach my $leaf (sort @leaveslist) {
print "$leaf\n";
}
} else {
my %leavestokeep;
my %leavestocut;
my @cutleaves;
# Loop while the user wants to
my $again = "y";
ROUND: while($again eq "y") {
# Get list of packages and put them into an array
my @leaves = get_leaves($dbdir, $exclpattern);
LEAVESLOOP: foreach my $leaf (sort @leaves) {
if (!$leavestokeep{$leaf}) {
print "$leaf - [keep]/(d)elete/(f)lush marked pkgs/(a)bort? ";
my $answer = substr(lc(<STDIN>), 0, 1);
if ($answer eq "d") {
print "** Marking $leaf for removal.\n\n";
$leavestocut{$leaf} = 1;
}
elsif ($answer eq "f") {
print "\n";
last LEAVESLOOP;
}
elsif ($answer eq "a") {
print "\n";
last ROUND;
}
else {
print "** Keeping $leaf.\n\n";
$leavestokeep{$leaf} = 1;
}
}
} # LEAVESLOOP
# loop through packages marked for removal and pkg_deinstall them
foreach my $leaf (sort keys %leavestocut) {
print "Deleting $leaf.\n";
my @deinstall_args;
if ($opt_recursive) {
@deinstall_args = ($pkgdeinstall, '-R', $leaf);
} else {
@deinstall_args = ($pkgdeinstall, $leaf);
}
if ((my $status = system(@deinstall_args) >> 8) != 0) {
print "\nError: pkg_deinstall returned $status - exiting, fix this first.\n\n";
last ROUND;
}
@cutleaves = (@cutleaves, $leaf);
delete $leavestocut{$leaf};
}
print "Once more ((y)es/[no])? ";
$again = substr(lc(<STDIN>), 0, 1);
print "\n";
} # ROUND
# print list of removed packages
print "** Deinstalled packages:\n";
foreach my $cutleaf (@cutleaves) {
print "$cutleaf\n";
}
}

View file

@ -0,0 +1,40 @@
.TH PKG_CUTLEAVES 1 "Jul 2003" FreeBSD
.SH NAME
pkg_cutleaves \- deinstall 'leaf' packages
.SH SYNOPSIS
.B pkg_cutleaves [-l] [-x] [-R]
.SH DESCRIPTION
.B 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)).
Once the packages marked for removal have been flushed/deinstalled,
you'll be asked if you want to do another run (to see packages that have
become 'leaves' now because you've deinstalled the package(s) that
depended on them). In every run you will be shown only packages that you
haven't marked for keeping, yet.
Note that your package registry database should be up to date for this
to work properly, so it might be a good idea to run pkgdb(1) before
running pkg_cutleaves.
.SH OPTIONS
.IP -l
List leaf packages only, one per line, and don't ask for anything to be
deinstalled.
.IP -x
Exclude packages matching expressions given in the exclude file.
.IP -R
Run 'pkg_deinstall -R' instead of plain 'pkg_deinstall', so packages the
removed leaf packages depend(ed) on will be deinstalled, too.
.SH FILES
.I /usr/local/etc/pkg_leaves.exclude
.RS
An optional list for excluding packages when the '-x' option is given.
If the beginning of a package's name matches any line (except comment or
empty lines) in this file, the package will not be listed/offered for
removal (e.g., a line saying just 'XFree86' (without the 's) will
exclude all packages with names starting with 'XFree86').
.SH AUTHOR
Stefan Walter <sw@gegenunendlich.de>
.SH SEE ALSO
pkg_deinstall(1), portsclean(1)

View file

@ -223,6 +223,7 @@
SUBDIR += personality SUBDIR += personality
SUBDIR += pftop SUBDIR += pftop
SUBDIR += pib SUBDIR += pib
SUBDIR += pkg_cutleaves
SUBDIR += pkg_install SUBDIR += pkg_install
SUBDIR += pkg_remove SUBDIR += pkg_remove
SUBDIR += pkg_tree SUBDIR += pkg_tree

View file

@ -0,0 +1,56 @@
# New ports collection makefile for: pkg_cutleaves
# Date created: 27 July 2003
# Whom: Stefan Walter <sw@gegenunendlich.de>
#
# $FreeBSD$
#
# This port is self contained in the src directory.
#
PORTNAME= pkg_cutleaves
PORTVERSION= 20030727
CATEGORIES= sysutils
MASTER_SITES= # none
DISTFILES= # none
MAINTAINER= sw@gegenunendlich.de
COMMENT= Interactive script for deinstalling 'leaf' packages
RUN_DEPENDS= ${LOCALBASE}/sbin/pkg_deinstall:${PORTSDIR}/sysutils/portupgrade
NO_BUILD= yes
USE_PERL5= yes
USE_REINPLACE= yes
SRC= ${.CURDIR}/src
MAN1= pkg_cutleaves.1
do-fetch:
@${DO_NADA}
pre-patch:
@${CP} ${SRC}/pkg_cutleaves ${WRKDIR}/pkg_cutleaves
@${CP} ${SRC}/pkg_cutleaves.1 ${WRKDIR}/pkg_cutleaves.1
post-patch:
@${REINPLACE_CMD} -e \
's,/usr/local/etc/pkg_leaves.exclude,${PREFIX}/etc/pkg_leaves.exclude,' \
${WRKDIR}/pkg_cutleaves.1
@${REINPLACE_CMD} -e \
's,/usr/local/etc/pkg_leaves.exclude,${PREFIX}/etc/pkg_leaves.exclude,' \
${WRKDIR}/pkg_cutleaves
@${REINPLACE_CMD} -e \
's,/usr/local/sbin/pkg_deinstall,${LOCALBASE}/sbin/pkg_deinstall,' \
${WRKDIR}/pkg_cutleaves
@${REINPLACE_CMD} -e \
's,/var/db/pkg,${PKG_DBDIR},' \
${WRKDIR}/pkg_cutleaves
@${REINPLACE_CMD} -e 's,/usr/bin/perl,${PERL},' \
${WRKDIR}/pkg_cutleaves
do-install:
${INSTALL_SCRIPT} ${WRKDIR}/pkg_cutleaves ${PREFIX}/sbin/pkg_cutleaves
${INSTALL_MAN} ${WRKDIR}/pkg_cutleaves.1 ${MAN1PREFIX}/man/man1
.include <bsd.port.mk>

View file

@ -0,0 +1,10 @@
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
the removed leaf packages depend(ed) on will be deinstalled, too.

View file

@ -0,0 +1 @@
sbin/pkg_cutleaves

View file

@ -0,0 +1,186 @@
#!/usr/bin/perl
#
# Copyright (c) 2003 Stefan Walter <sw@gegenunendlich.de>
#
# 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.
# 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 REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
#
# $FreeBSD$
# Interactive script for deinstalling "leaf" packages;
# requires the portupgrade tools
#
# Syntax: pkg_cutleaves [-l] [-x] [-R]
# Options:
# -l: List leaf packages only, don't ask if they should be deinstalled
# -x: Honor exclude list in $excludefile
# -R: Run 'pkg_deinstall -R' instead of plain 'pkg_deinstall'
use strict;
my $dbdir = "/var/db/pkg";
my $excludefile = "/usr/local/etc/pkg_leaves.exclude";
my $pkgdeinstall = "/usr/local/sbin/pkg_deinstall";
my ($opt_listonly, $opt_excludelist, $opt_recursive);
my $exclpattern;
# Read the exclude list if the file exists
sub get_excl_pattern {
my $excl_file = $_[0];
my $excl_pattern;
# Does the exclude file exist?
if (($excl_file) && (-f $excl_file) && (-T $excl_file)) {
# Read the patterns to be excluded
my @excludes;
open(EXCLFILE, $excl_file)
or die "Couldn't open $excl_file!";
while(my $exclude = <EXCLFILE>) {
chomp($exclude);
# Ignore comments and empty lines, add others as regular expressions
unless (($exclude =~ m/(^ *#)|(^ *$)/)) {
$exclude = "^" . $exclude . ".*";
@excludes = (@excludes, $exclude);
}
}
close(EXCLFILE);
$excl_pattern = join("|", @excludes);
} else {
# Dummy exclusion pattern -> doesn't exclude anything
$excl_pattern = " ";
}
return $excl_pattern;
}
# Get a list of all leaves
sub get_leaves {
my $db_dir = $_[0];
my $excl_pattern = $_[1];
my @pkgdirs;
opendir(DBDIR, $db_dir)
or die "Can't open package db directory $db_dir!";
while(defined(my $file = readdir(DBDIR))) {
my $path = $db_dir . '/' . $file;
my $reqlist = $path . '/+REQUIRED_BY';
# Exclude non-directories, "." and ".."
if (($file ne ".") && ($file ne "..") && (-d $path) && (!-s $reqlist)) {
# Exclude packages matching exclude pattern, if requested
unless ($file =~ m/$excl_pattern/) {
@pkgdirs = (@pkgdirs, $file);
}
}
}
closedir(DBDIR);
return @pkgdirs;
}
# Examine command line arguments
while(@ARGV) {
my $arg = shift(@ARGV);
if ($arg eq "-x") {
$opt_excludelist = 1;
}
elsif ($arg eq "-l") {
$opt_listonly = 1;
}
elsif ($arg eq "-R") {
$opt_recursive = 1;
}
}
# Exclusion requested?
if ($opt_excludelist) {
# Get exclusion pattern
$exclpattern = get_excl_pattern($excludefile);
} else {
# Spaces don't appear in package names -> this doesn't exclude anything
$exclpattern = " ";
}
if ($opt_listonly) {
# Just print out the list of leaves, one per line
my @leaveslist = get_leaves($dbdir, $exclpattern);
foreach my $leaf (sort @leaveslist) {
print "$leaf\n";
}
} else {
my %leavestokeep;
my %leavestocut;
my @cutleaves;
# Loop while the user wants to
my $again = "y";
ROUND: while($again eq "y") {
# Get list of packages and put them into an array
my @leaves = get_leaves($dbdir, $exclpattern);
LEAVESLOOP: foreach my $leaf (sort @leaves) {
if (!$leavestokeep{$leaf}) {
print "$leaf - [keep]/(d)elete/(f)lush marked pkgs/(a)bort? ";
my $answer = substr(lc(<STDIN>), 0, 1);
if ($answer eq "d") {
print "** Marking $leaf for removal.\n\n";
$leavestocut{$leaf} = 1;
}
elsif ($answer eq "f") {
print "\n";
last LEAVESLOOP;
}
elsif ($answer eq "a") {
print "\n";
last ROUND;
}
else {
print "** Keeping $leaf.\n\n";
$leavestokeep{$leaf} = 1;
}
}
} # LEAVESLOOP
# loop through packages marked for removal and pkg_deinstall them
foreach my $leaf (sort keys %leavestocut) {
print "Deleting $leaf.\n";
my @deinstall_args;
if ($opt_recursive) {
@deinstall_args = ($pkgdeinstall, '-R', $leaf);
} else {
@deinstall_args = ($pkgdeinstall, $leaf);
}
if ((my $status = system(@deinstall_args) >> 8) != 0) {
print "\nError: pkg_deinstall returned $status - exiting, fix this first.\n\n";
last ROUND;
}
@cutleaves = (@cutleaves, $leaf);
delete $leavestocut{$leaf};
}
print "Once more ((y)es/[no])? ";
$again = substr(lc(<STDIN>), 0, 1);
print "\n";
} # ROUND
# print list of removed packages
print "** Deinstalled packages:\n";
foreach my $cutleaf (@cutleaves) {
print "$cutleaf\n";
}
}

View file

@ -0,0 +1,40 @@
.TH PKG_CUTLEAVES 1 "Jul 2003" FreeBSD
.SH NAME
pkg_cutleaves \- deinstall 'leaf' packages
.SH SYNOPSIS
.B pkg_cutleaves [-l] [-x] [-R]
.SH DESCRIPTION
.B 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)).
Once the packages marked for removal have been flushed/deinstalled,
you'll be asked if you want to do another run (to see packages that have
become 'leaves' now because you've deinstalled the package(s) that
depended on them). In every run you will be shown only packages that you
haven't marked for keeping, yet.
Note that your package registry database should be up to date for this
to work properly, so it might be a good idea to run pkgdb(1) before
running pkg_cutleaves.
.SH OPTIONS
.IP -l
List leaf packages only, one per line, and don't ask for anything to be
deinstalled.
.IP -x
Exclude packages matching expressions given in the exclude file.
.IP -R
Run 'pkg_deinstall -R' instead of plain 'pkg_deinstall', so packages the
removed leaf packages depend(ed) on will be deinstalled, too.
.SH FILES
.I /usr/local/etc/pkg_leaves.exclude
.RS
An optional list for excluding packages when the '-x' option is given.
If the beginning of a package's name matches any line (except comment or
empty lines) in this file, the package will not be listed/offered for
removal (e.g., a line saying just 'XFree86' (without the 's) will
exclude all packages with names starting with 'XFree86').
.SH AUTHOR
Stefan Walter <sw@gegenunendlich.de>
.SH SEE ALSO
pkg_deinstall(1), portsclean(1)