I have the first attempt of the dependencies deletion option. I
modified 'pkg_delete' to include an option -r that perform this task.

The main idea is to traverse the graph of package dependencies with
some kind of bfs algorithm. The queue is initialized with the original
packages to be removed. Packages that have not dependents and were not
manually installed are added to the bfs queue for exploration. This is
repeated until the queue for exploration is empty.

Below you can find the patch. My perl-fu is not very good so I am not
sure if this is the right way of doing things. Another thing is that I
developed this for OpenBSD 4.5 and I don't have a box with the
'current' branch; if somebody can test it for 4.6 that could help.

Of course, I would like to know your thoughts about it.

41c41
< our ($opt_v, $opt_D, $opt_d, $opt_n, $opt_q, $opt_p, $opt_c, $opt_L,
$opt_B, $opt_I, $opt_i, $opt_x);
---
> our ($opt_v, $opt_D, $opt_d, $opt_n, $opt_q, $opt_p, $opt_c, $opt_L, $opt_B, 
> $opt_I, $opt_i, $opt_x, $opt_r);
46c46
<       getopts('vchixDdnf:F:qpS:L:B:I',
---
>       getopts('vchixDdnf:F:qpS:L:B:Ir',
158a159,191
> }
>
> if($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 = @todo;  # queue of bfs
>       @todo = ();     # the new todo will include previous
>                       # and dependecies packages
>
>       while(@q) {
>               my $pkg = pop @q;
>
>               # pkg to delete
>               unshift (@todo, $pkg);
>
>               for my $dep (OpenBSD::Requiring->new($pkg)->list) {
>                       my @dependents = 
> OpenBSD::RequiredBy->compute_closure($dep);
>
>                       # calculate @dependen...@q-@todo. We don't care about 
> the
>                       # packages that will be removed anyway.
>                       my %qh = map {($_, 1)} @q;
>                       my %todoh = map {($_, 1)} @todo;
>                       @dependents = grep {not($qh{$_} or $todoh{$_} or ($_ eq 
> $dep))} @dependents;
>
>                       # check if $dep was manually installed
>                       my $manual = 
> OpenBSD::PackingList->from_installation($dep)->has('manual-installation');
>
>                       unshift (@q, $dep) unless (@dependents or $manual);
>               }
>       }

Reply via email to