#!/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, 'norequirements|R' => \$no_reqs, '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 $rootpkg = $ARGV[0]; my $test = get_sbo_location ($rootpkg); die "Unable to locate $rootpkg in the SlackBuilds.org tree.\n" unless defined $test; my $remove_queue; my %required_by; my %warnings; my @confirmed; sub get_requires ($) { my $location = get_sbo_location(shift); my $requires = get_from_info (LOCATION => $location, GET => 'REQUIRES'); return $requires; } 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 join(" ", @dep_of); } sub confirm_remove ($) { my $sbo = shift; unless ($sbo ~~ @confirmed) { push(@confirmed, $sbo); } } # Determine dependencies & warnings of root package $remove_queue = get_build_queue($rootpkg, \%warnings); @$remove_queue = reverse(@$remove_queue); if ($no_reqs) { @$remove_queue = (); push(@$remove_queue, $rootpkg); } # Determine required by for all installed sbo's my $installed = get_installed_sbos; my $inst_names = get_inst_names $installed; for my $inst (@$inst_names) { my $requires = get_requires "$inst"; next unless $$requires[0]; for my $req (@$requires) { unless ( $req eq "%README%" ) { if ( $req ~~ $inst_names ) { push(@{$required_by{$req}}, $inst); } } } } # Check if packages in queue are actually installed on system my @temp; if ($inst_names) { for my $sbo (@$remove_queue) { if ($sbo ~~ $inst_names) { push(@temp, $sbo); } } $remove_queue = \@temp; } # Gather instructions from user my ($req_by_line, @req_by, $req_count, $cnf_count); my $is_rootpkg = 1; for my $pkg (@$remove_queue) { $req_by_line = get_required_by $pkg; @req_by = split(" ", $req_by_line); $req_count = @req_by; $cnf_count = 0; for my $val (@req_by) { if ( $val ~~ @confirmed ) { $cnf_count++; } } if ($cnf_count == $req_count or $is_rootpkg or $alwaysask) { say $pkg; if ( $req_by_line ) { say "Required by: $req_by_line"; } else { unless ($is_rootpkg) { say "It appears $pkg will no longer be required on your system"; } } $is_rootpkg = 0; if ( exists $warnings{$pkg} ) { say "$pkg suggests you view its README before proceeding,"; print "view now? [y] : "; chomp(my $viewrm = ); if ($viewrm =~ /^[Yy]/) { print "\n"; my $locrm = get_sbo_location ($pkg); $locrm .= '/README'; open(README, '<', $locrm) or die "could not open $locrm"; for my $line () { print $line; } } } print "Remove $pkg? [n] : "; chomp(my $userin = ); if ($userin =~ /^[Yy]/) { confirm_remove $pkg; say "* added $pkg to remove queue\n"; } else { say "* ignoring $pkg\n" } } } # 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; } print 'Are you sure you want to continue? [n] : '; unless ( =~ /^[Yy]/) { say 'Exiting.'; exit 0; } for my $instpkg (@confirmed) { system("/sbin/removepkg $instpkg"); } say "All operations have completed successfully."; exit 0;