sboupgrade (6566B)
1 #!/usr/bin/perl 2 # 3 # vim: ts=4:noet 4 # 5 # sboupgrade 6 # script to upgrade (a) SlackBuild(s) by name 7 # 8 # authors: Jacob Pipkin <j@dawnrazor.net> 9 # Luke Williams <xocel@iquidus.org> 10 # Andreas Guldstrand <andreas.guldstrand@gmail.com> 11 # maintainer: Slack Coder <slackcoder@server.ky> 12 13 use 5.16.0; 14 use strict; 15 use warnings FATAL => 'all'; 16 use SBO::Lib qw/ _ERR_USAGE get_available_updates prompt usage_error slackbuilds_or_fetch uniq get_sbo_location get_inst_names get_installed_packages get_build_queue get_sbo_locations in merge_queues user_prompt process_sbos print_failures %config show_version /; 17 use Getopt::Long qw(:config bundling); 18 use File::Basename; 19 use File::Copy; 20 21 my $self = basename($0); 22 23 sub show_usage { 24 print <<"EOF"; 25 Usage: $self (options) [package] 26 27 Options (defaults shown first where applicable): 28 -h|--help: 29 this screen. 30 -v|--version: 31 version information. 32 -c|--noclean (FALSE|TRUE): 33 set whether or not to clean working directories after building. 34 -d|--distclean (TRUE|FALSE): 35 set whether or not to clean distfiles afterward. 36 -f|--force: 37 force an update, even if the "upgrade" version is the same or lower. 38 -i|--noinstall: 39 do not run installpkg at the end of the build process. 40 -j|--jobs (FALSE|#): 41 specify "-j" setting to make, for multicore systems; overrides conf file. 42 -r|--nointeractive: 43 non-interactive; skips README and all prompts. 44 -z|--force-reqs: 45 when used with -f, will force rebuilding an SBo's requirements as well. 46 --all 47 this flag will upgrade everything reported by sbocheck(1). 48 49 EOF 50 return 1; 51 } 52 53 my $noclean = $config{NOCLEAN}; 54 my $distclean = $config{DISTCLEAN}; 55 my $jobs = $config{JOBS}; 56 my ($help, $vers, $force, $no_install, $non_int, $force_reqs, $all); 57 58 if (! GetOptions( 59 'help|h' => \$help, 60 'version|v' => \$vers, 61 'noclean|c=s' => \$noclean, 62 'distclean|d=s' => \$distclean, 63 'force|f' => \$force, 64 'noinstall|i' => \$no_install, 65 'jobs|j=s' => \$jobs, 66 'nointeractive|r' => \$non_int, 67 'force-reqs|z' => \$force_reqs, 68 'all' => \$all, 69 )) { 70 show_usage(); 71 exit 1; 72 } 73 74 if ($help) { show_usage(); exit 0 } 75 if ($vers) { show_version(); exit 0 } 76 77 unless ($< == 0) { 78 warn "This script requires root privileges.\n"; 79 exit _ERR_USAGE; 80 } 81 82 my $updates; 83 if ($all) { 84 slackbuilds_or_fetch(); 85 print "Checking for updated SlackBuilds...\n"; 86 $updates = get_available_updates(); 87 push @ARGV, map { $_->{name} } @$updates; 88 if (!@ARGV) { print "Nothing to update.\n"; exit 0 } 89 } 90 91 if (!@ARGV) { show_usage(); exit 1 } 92 93 $noclean = $noclean eq 'TRUE' ? 1 : 0; 94 $distclean = $distclean eq 'TRUE' ? 1 : 0; 95 96 if ($jobs) { 97 usage_error("You have provided an invalid value for -j|--jobs") 98 unless ($jobs =~ /^\d+$/ || $jobs eq 'FALSE'); 99 } 100 101 usage_error("-r|--nointeractive and -z|--force-reqs can not be used together.") 102 if $non_int && $force_reqs; 103 104 # if we can't find SLACKBUILDS.TXT in $config{HOME}, prompt to fetch the tree 105 slackbuilds_or_fetch(); 106 107 my @sbos = uniq @ARGV; 108 109 # Filter out standard packages 110 my $std_installs = get_inst_names(get_installed_packages('STD')); 111 my %std_names; 112 $std_names{$_} = 1 for @$std_installs; 113 @sbos = grep { not $std_names{$_} } @sbos; 114 115 # pull locations for everything specified on command line. 116 my %locations; 117 for my $sbo (@sbos) { 118 my $name = $sbo; 119 $name =~ s/-compat32//; 120 $locations{$sbo} = get_sbo_location($name); 121 if (not $locations{$sbo} and in($sbo, @ARGV)) { 122 usage_error("Unable to locate $sbo in the SlackBuilds.org tree."); 123 } 124 if ($sbo =~ /-compat32$/) { 125 usage_error("compat32 Perl SBos are not supported.") 126 if $locations{$sbo} =~ qr|/perl/[^/]+$|; 127 } 128 } 129 130 # get a list of installed SBos to check upgradability against 131 my $inst_names = get_inst_names(get_installed_packages('SBO')); 132 my %inst_names; 133 $inst_names{$_} = 1 for @$inst_names; 134 my %updates; 135 if (not $non_int or not $force) { 136 $updates = get_available_updates() if not defined $updates; 137 $updates{$$_{name}} = 1 for @$updates; 138 } 139 140 my $upgrade_queue = []; 141 my %warnings; 142 143 # doesn't matter what's updatable and what's not if force is specified, 144 # but without force, we only want to update what there are updates for 145 if ($non_int) { 146 if ($force) { 147 for my $sbo (@sbos) { 148 push @$upgrade_queue, $sbo if $inst_names{$sbo}; 149 } 150 } else { 151 for my $sbo (@sbos) { 152 push @$upgrade_queue, $sbo if $updates{$sbo}; 153 } 154 } 155 } else { 156 for my $sbo (@sbos) { 157 my $name = $sbo; 158 $name =~ s/-compat32$//; 159 my $queue = get_build_queue([$name], \%warnings); 160 if (not $force_reqs) { 161 @$queue = grep { !$inst_names{$_} or $updates{$_} } @$queue; 162 } 163 push @$queue, $name if $force; 164 my $cqueue; 165 # get locations for all the things 166 my %locs = get_sbo_locations($queue); 167 my %clocs; 168 # -compat32-ify the queue and locations if appropriate 169 if ($sbo =~ /-compat32$/) { 170 $cqueue = $queue; 171 s/$/-compat32/g for @$cqueue; 172 $queue = $cqueue; 173 for my $key (keys %locs) { 174 my $val = $locs{$key}; 175 $key =~ s/$/-compat32/; 176 $clocs{$key} = $val; 177 } 178 %locs = %clocs; 179 } 180 @locations{keys %locs} = values %locs; 181 $upgrade_queue = merge_queues($upgrade_queue, $queue); 182 } 183 } 184 185 # Get user input regarding upgrades 186 my (@temp_queue, %commands, %options); 187 FIRST: for my $sbo (@$upgrade_queue) { 188 next FIRST if $std_names{$sbo}; 189 190 if (defined $warnings{$sbo} and $warnings{$sbo} eq 'nonexistent') { 191 say "Unable to locate $sbo in the SlackBuilds.org tree."; 192 if (not $non_int) { 193 exit 0 unless prompt("Do you want to ignore it and continue?", default => 'no'); 194 } 195 next FIRST; 196 } 197 198 unless ($non_int) { 199 my ($cmds, $opts, $exit) = user_prompt($sbo, $locations{$sbo}); 200 if ($exit) { 201 warn "Unable to open README for $sbo.\n"; 202 exit $exit; 203 } 204 if ($cmds) { 205 next FIRST if $cmds eq 'N'; 206 } 207 push(@temp_queue, $sbo); 208 $commands{$sbo} = $cmds; 209 $options{$sbo} = $opts; 210 say "$sbo added to upgrade queue."; 211 } else { 212 push(@temp_queue, $sbo); 213 say "\n$sbo added to upgrade queue."; 214 } 215 } 216 @$upgrade_queue = @temp_queue; 217 218 exit 0 unless exists $$upgrade_queue[0]; 219 say "\nUpgrade queue: ". join(' ', @$upgrade_queue); 220 unless ($non_int) { 221 exit 0 unless prompt("\nAre you sure you wish to continue?", default => 'yes'); 222 } 223 224 my ($failures, $exit) = process_sbos( 225 TODO => $upgrade_queue, 226 CMDS => \%commands, 227 OPTS => \%options, 228 JOBS => $jobs, 229 LOCATIONS => \%locations, 230 NOINSTALL => $no_install, 231 NOCLEAN => $noclean, 232 DISTCLEAN => $distclean, 233 NON_INT => $non_int, 234 ); 235 print_failures($failures); 236 237 if ($exit) { 238 exit $exit; 239 } else { 240 exit 0; 241 }