Hi Guys,

I implemented this option for the pkg_delete that remove all the 'non-used'
dependencies of all packages you are deleting. It first check that the
package is not a dependency of another installed package and it was not
installed manually.

I sent an email about this a long time ago but I guess it didn't have too
much attention. At some point @espie ask me to hold it for some time and
re-submit later. This is the discussion:
http://marc.info/?l=openbsd-misc&m=124939917102094&w=2

I am copying this functionality from other package managers like apt or
pacman. They seem to work very well and I really miss it in OpenBSD.

I am sorry for my perl-fu.

Index: pkg_delete.1
===================================================================
RCS file: /cvs/src/usr.sbin/pkg_add/pkg_delete.1,v
retrieving revision 1.35
diff -u -r1.35 pkg_delete.1
--- pkg_delete.1        5 Jun 2010 07:11:43 -0000       1.35
+++ pkg_delete.1        24 Dec 2010 16:38:36 -0000
@@ -106,6 +106,9 @@
 For signed packages, do not bother verifying signatures either.
 If used twice,
 it will not bother with checksums for configuration files either.
+.It Fl r
+Remove the package dependencies recursively except for those that are
required
+for other installed packages or were installed manually.
 .It Fl s
 Don't actually deinstall packages, report the disk size changes
 that would happen.
cvs server: Diffing OpenBSD
Index: OpenBSD/PkgDelete.pm
===================================================================
RCS file: /cvs/src/usr.sbin/pkg_add/OpenBSD/PkgDelete.pm,v
retrieving revision 1.11
diff -u -r1.11 PkgDelete.pm
--- OpenBSD/PkgDelete.pm        24 Dec 2010 09:04:14 -0000      1.11
+++ OpenBSD/PkgDelete.pm        24 Dec 2010 16:38:36 -0000
@@ -27,8 +27,8 @@
 sub handle_options
 {
        my $state = shift;
-       $state->SUPER::handle_options('',
-           '[-cIinqsvx] [-B pkg-destdir] [-D name[=value]] pkg-name
[...]');
+       $state->SUPER::handle_options('r',
+           '[-cIinqrsvx] [-B pkg-destdir] [-D name[=value]] pkg-name
[...]');

        my $base = $state->opt('B') // $ENV{'PKG_DESTDIR'} // '';
        if ($base ne '') {
@@ -108,6 +108,41 @@
                        $state->{bad}++;
                }
        }
+
+       if($state->opt('r')) {
+               # calculate dependencies to be removed:
+               # 1. Not installed manually
+               # 2. Not dependecy for other package
+
+               # bfs over the graph of packages
+               my %q = map {($_,1)} @toremove;
+               my %todoh;
+
+               while(%q) {
+                       my $pkg = (keys %q)[0];
+                       delete $q{$pkg};
+
+                       # pkg to delete
+                       $todoh{$pkg} = 1;
+
+                       # expand to the dependencies of the current pkg
+                       for my $dep (OpenBSD::Requiring->new($pkg)->list) {
+                               my @dependents =
OpenBSD::RequiredBy->compute_closure($dep);
+
+                               # if the dependent package will be removed,
then we shouldn't
+                               # be worried about keeping its dependencies.
+                               # calculate @dependen...@q-@todo.
+                               @dependents = grep {not($q{$_} or $todoh{$_}
or ($_ eq $dep))} @dependents;
+
+                               # check if $dep was manually installed
+                               my $manual =
OpenBSD::PackingList->from_installation($dep)->has('manual-installation');
+
+                               $q{$dep} = 1 unless (@dependents or
$manual);
+                       }
+               }
+               @toremove = keys %todoh;
+       }
+
        $state->{toremove} = \...@toremove;
 }

Luis.

Reply via email to