#!/usr/bin/perl # # vim: set ts=4:noet # # sboinstall # script to install (a) SlackBuild(s) by name # # authors: Jacob Pipkin # Luke Williams # Andreas Guldstrand # license: WTFPL use 5.16.0; use strict; use warnings FATAL => 'all'; use SBO::Lib qw/ usage_error slackbuilds_or_fetch get_build_queue merge_queues get_sbo_locations get_installed_packages get_inst_names get_installed_cpans get_sbo_location user_prompt process_sbos print_failures %config get_arch /; use Getopt::Long qw(:config bundling); use File::Basename; my $self = basename($0); sub show_usage { print < \$help, 'version|v' => \$vers, 'noclean|c=s' => \$noclean, 'distclean|d=s' => \$distclean, 'noinstall|i' => \$no_install, 'jobs|j=s' => \$jobs, 'compat32|p' => \$compat32, 'nointeractive|r' => \$non_int, 'norequirements|R' => \$no_reqs, ); show_usage() and exit 0 if $help; show_version() and exit 0 if $vers; show_usage() and exit 1 unless exists $ARGV[0]; $noclean = $noclean eq 'TRUE' ? 1 : 0; $distclean = $distclean eq 'TRUE' ? 1 : 0; if ($jobs) { usage_error("You have provided an invalid value for -j|--jobs") unless ($jobs =~ /^\d+$/ || $jobs eq 'FALSE'); } if ($compat32) { usage_error("compat32 only works on x86_64.") unless get_arch eq 'x86_64'; } # if we can't find SLACKBUILDS.TXT in $config{HOME}, prompt to fetch the tree slackbuilds_or_fetch(); my (%warnings, $build_queue, %locations); if ($no_reqs or $non_int) { $build_queue = \@ARGV; } else { for my $sbo (@ARGV) { my $queue = get_build_queue([$sbo], \%warnings); $build_queue = merge_queues($build_queue, $queue); } } # populate %locations and sanity check %locations = get_sbo_locations($build_queue); for my $sbo (@$build_queue) { usage_error("Unable to locate $sbo in the SlackBuilds.org tree.") unless $locations{$sbo}; if ($compat32) { usage_error("-p|--compat32 is not supported with Perl SBos.") if $locations{$sbo} =~ qr|/perl/[^/]+$|; } } # get lists of installed packages and perl modules from CPAN my $inst_names = get_inst_names(get_installed_packages 'ALL'); my $pms = get_installed_cpans(); s/::/-/g for @$pms; # check for already-installeds and prompt for the rest my (@temp_queue, %commands, %options); my $added = ' added to install queue.'; my %inst_names; $inst_names{$_} = 1 for @$inst_names; FIRST: for my $sbo (@$build_queue) { my $name = $compat32 ? "$sbo-compat32" : $sbo; if ($inst_names{$name}) { say "$name already installed."; next FIRST; } else { if ($sbo =~ /^perl-/) { my $pm_name = $sbo; $pm_name =~ s/^perl-//; for my $pm (@$pms) { if ($pm =~ /^$pm_name$/i) { say "$sbo installed via the cpan."; next FIRST; } } } } $locations{$name} = get_sbo_location($sbo) if $compat32; unless ($non_int) { # if compat32 is TRUE, we need to see if the non-compat version exists. if ($compat32) { unless ($inst_names{$sbo}) { say "$name requires $sbo."; my ($cmds, $opts, $exit) = user_prompt($sbo, $locations{$sbo}); if ($exit) { warn "Unable to open README for $sbo.\n"; exit $exit; } if ($cmds) { next FIRST if $cmds eq 'N'; } push(@temp_queue, $sbo); $commands{$sbo} = $cmds; $options{$sbo} = $cmds; say "$sbo$added"; } } my ($cmds, $opts, $exit) = user_prompt($name, $locations{$name}); if ($exit) { warn "Unable to open README for $name.\n"; exit $exit; } if ($cmds) { next FIRST if $cmds eq 'N'; } push(@temp_queue, $name); $commands{$sbo} = $cmds; $options{$sbo} = $opts; say "$name$added"; } else { push(@temp_queue, $sbo); say "\n$name$added"; } } @$build_queue = @temp_queue; exit 0 unless exists $$build_queue[0]; say "\nInstall queue: " . join(' ', @$build_queue); unless ($non_int) { print "\nAre you sure you wish to continue? [y]: "; exit 0 unless =~ /^[Yy\n]/; } my ($failures, $exit) = process_sbos( TODO => $build_queue, CMDS => \%commands, OPTS => \%options, JOBS => $jobs, LOCATIONS => \%locations, NOINSTALL => $no_install, NOCLEAN => $noclean, DISTCLEAN => $distclean, NON_INT => $non_int, ); print_failures($failures); if ($exit) { exit $exit; } else { exit 0; }