#!/usr/bin/env perl # # vim: set ts=4:noet # # sboremove # script to remove an installed SlackBuild # # author: Luke Williams # license: WTFPL use 5.16.0; use strict; use warnings FATAL => 'all'; use SBO::Lib; use Getopt::Long qw(:config bundling); use File::Basename; my $self = basename ($0); sub show_usage() { print < \$help, 'version|v' => \$vers, 'nointeractive' => \$non_int, 'alwaysask|a' => \$alwaysask, ); show_usage and exit 0 if $help; show_version and exit 0 if $vers; show_usage and exit 0 unless exists $ARGV[0]; my $inst_names = get_inst_names(get_installed_sbos); # ensure that all provided arguments are valid sbos my @arguments; for my $sbo (@ARGV) { if (get_sbo_location($sbo)) { $sbo ~~ @$inst_names ? push @arguments, $sbo : say "$sbo is not installed"; } else { say "Unable to locate $sbo in the SlackBuilds.org tree." } } # one array of each cli-specified sbo to remove... my @sbos = @arguments; # wrapper to pull the list of requirements for a given sbo # TODO: look at moving this into Lib.pm sub get_requires($) { my $location = get_sbo_location(shift); return get_from_info(LOCATION => $location, GET => 'REQUIRES'); } # and another array to hold the requirements for each. my @sbo_reqs; push @sbo_reqs, get_requires $_ for @sbos; # clean the req listings of anything specified on the command line. for my $reqs (@sbo_reqs) { my @remove; for my $key (keys @$reqs) { push @remove, $key if $$reqs[$key] ~~ @sbos; } for my $rem (@remove) { splice(@$reqs, $rem, 1); $_-- for @remove; } } # get a two reversed copies of the req list for removing dupes my @rev_reqs; push @rev_reqs, [reverse @$_] for reverse @sbo_reqs; my @rev_copy = @rev_reqs; # remove any dupes, leaving last instance of each. for my $list (@rev_copy) { for my $item (@$list) { my $found = 0; for my $list2 (@rev_reqs) { my @remove; for my $key (keys @$list2) { if ($$list2[$key] eq $item) { push @remove, $key if $found; $found++; } } for my $rem (@remove) { splice(@$list2, $rem, 1); $_-- for @remove; } } } } # make @sbo_reqs hold the de-duped list of reqs. @sbo_reqs = (); push @sbo_reqs, [reverse @$_] for reverse @rev_reqs; my ($remove_queue, %required_by, %warnings, @confirmed); # Determine required by for all installed sbo's sub get_reverse_reqs() { FIRST: for my $inst (@$inst_names) { my $requires = get_requires $inst; next FIRST unless $$requires[0]; for my $req (@$requires) { unless ( $req eq '%README%' ) { push @{$required_by{$req}}, $inst if $req ~~ $inst_names; } } } } get_reverse_reqs; sub get_required_by($) { my $sbo = shift; my @dep_of; if ( $required_by{$sbo} ) { for my $req_by (@{$required_by{$sbo}}) { unless ($req_by ~~ @confirmed) { push @dep_of, $req_by; } } } return \@dep_of; } sub confirm_remove($) { my $sbo = shift; push @confirmed, $sbo unless $sbo ~~ @confirmed; } # Determine dependencies & warnings #if ($no_reqs) { # $remove_queue = \@remove; #} else { $remove_queue = get_build_queue(\@remove, \%warnings); @$remove_queue = reverse(@$remove_queue); #} # Check if packages in queue are actually installed on system my @temp; if ($inst_names) { for my $sbo (@$remove_queue) { push @temp, $sbo if $sbo ~~ @$inst_names; } $remove_queue = \@temp; } if ($non_int) { confirm_remove $_ for @$remove_queue; goto CONFIRMED; } for my $remove (@$remove_queue) { my $required_by = get_required_by $remove; } CONFIRMED: # Show remove queue my $remove_count = @confirmed; if ($remove_count) { say "Removing $remove_count package(s)"; for my $pkg (@confirmed) { print "$pkg "; } say "\n"; } else { say 'Nothing to remove.'; exit 0; } unless ($non_int) { print 'Are you sure you want to continue? [n] : '; unless ( =~ /^[Yy]/) { say 'Exiting.'; exit 0; } } system("/sbin/removepkg $_") for @confirmed; say "All operations have completed successfully."; exit 0;