aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xsboupgrade523
-rwxr-xr-xsboupgradex373
2 files changed, 248 insertions, 648 deletions
diff --git a/sboupgrade b/sboupgrade
index 1cfa7aa..209bd3a 100755
--- a/sboupgrade
+++ b/sboupgrade
@@ -2,8 +2,8 @@
#
# vim: set ts=4:noet
#
-# sboupgrade
-# script to update an installed SlackBuild.
+# sboinstall
+# script to install a SlackBuild by name
#
# author: Jacob Pipkin <j@dawnrazor.net>
# license: WTFPL <http://sam.zoy.org/wtfpl/COPYING>
@@ -12,14 +12,13 @@ use 5.16.0;
use strict;
use warnings FATAL => 'all';
use SBO::Lib;
-use File::Basename;
use Getopt::Long qw(:config bundling);
-use File::Copy;
+use File::Basename;
my $self = basename ($0);
sub show_usage () {
- print <<EOF
+ print <<EOF
Usage: $self (options) [package]
Options (defaults shown first where applicable):
@@ -53,275 +52,200 @@ my $noclean = $config{NOCLEAN};
my $distclean = $config{DISTCLEAN};
my $jobs = $config{JOBS};
my ($help, $vers, $force, $no_install, $install_new, $non_int, $no_reqs,
- $force_reqs, $only_new, $compat32);
+ $force_reqs, $only_new, $compat32);
GetOptions (
- 'help|h' => \$help,
- 'version|v' => \$vers,
- 'noclean|c=s' => \$noclean,
- 'distclean|d=s' => \$distclean,
- 'force|f' => \$force,
- 'noinstall|i' => \$no_install,
- 'jobs|j=s' => \$jobs,
- 'installnew|N' => \$install_new,
- 'nointeractive|r' => \$non_int,
- 'norequirements|R' => \$no_reqs,
- 'force-reqs|z' => \$force_reqs,
- 'only-new|o' => \$only_new,
- 'compat32|p' => \$compat32,
+ 'help|h' => \$help,
+ 'version|v' => \$vers,
+ 'noclean|c=s' => \$noclean,
+ 'distclean|d=s' => \$distclean,
+ 'force|f' => \$force,
+ 'noinstall|i' => \$no_install,
+ 'jobs|j=s' => \$jobs,
+ 'installnew|N' => \$install_new,
+ 'nointeractive|r' => \$non_int,
+ 'norequirements|R' => \$no_reqs,
+ 'force-reqs|z' => \$force_reqs,
+ 'only-new|o' => \$only_new,
+ 'compat32|p' => \$compat32,
);
show_usage and exit 0 if $help;
show_version and exit 0 if $vers;
+show_usage and exit 0 unless exists $ARGV[0];
+say "Invalid arguments: --force-reqs and --installnew can not be used together." and exit 0 if $force_reqs and $install_new;
$noclean = $noclean eq 'TRUE' ? 1 : 0;
$distclean = $distclean eq 'TRUE' ? 1 : 0;
-if ($jobs) {
- die "You have provided an invalid parameter for -j\n" unless
- ($jobs =~ /^\d+$/ || $jobs eq 'FALSE');
-}
-$jobs = 0 if $jobs eq 'FALSE';
-
-show_usage and exit 1 unless exists $ARGV[0];
-if ($compat32) {
- die "compat32 only works on x86_64.\n" unless get_arch eq 'x86_64';
-}
-
-# if we can't find SLACKBUILDS.TXT in $config{HOME}, prompt to fetch the tree
-slackbuilds_or_fetch;
-
-# build a hash of locations for each item provided on command line, at the same
-# time verifying each item is a valid slackbuild
+my $rootpkg = $ARGV[0];
+my %warnings;
+my %options;
+my $build_queue;
+my %commands;
my %locations;
-for my $sbo_name (@ARGV) {
- $locations{$sbo_name} = get_sbo_location ($sbo_name);
- die "Unable to locate $sbo_name in the SlackBuilds.org tree.\n" unless
- defined $locations{$sbo_name};
-}
-
-sub get_readme_path ($) {
- exists $_[0] or script_error 'get_readme_path requires an argument.';
- my $sbo = shift;
- return $locations{$sbo} .'/README';
-}
-
-# pull list of requirements
-sub get_requires ($$) {
- return if $no_reqs;
- exists $_[1] or script_error 'get_requires requires two arguments.';
- my ($sbo, $location) = @_;
- my $requires = get_from_info (LOCATION => $location, GET => 'REQUIRES');
- return unless $$requires[0];
- # do nothing if a req list contains %README%
- return if '%README%' ~~ @$requires;
- # do nothing if there's a circular requirement
- FIRST: for my $req (@$requires) {
- my $location = get_sbo_location ($req);
- my $req_req = get_from_info (LOCATION => $location, GET => 'REQUIRES');
- if ($sbo ~~ @$req_req) {
- say "I am seeing circular requirements between $sbo and $req.";
- say "Therefore, I am not going to handle requirements for $sbo.";
- print 'Do you still wish to proceed? [n] ';
- <STDIN> =~ /^[Yy]/ ? return : exit 0;
- }
- }
- return $requires;
+if ($no_reqs or $non_int) {
+ $build_queue = \@ARGV;
+} else {
+ $build_queue = get_build_queue(\@ARGV, \%warnings);
}
-
-# remove any installed requirements from req list
-sub clean_reqs ($) {
- exists $_[0] or script_error 'clean_reqs requires an argument.';
- my $reqs = shift;
- my $inst = get_installed_sbos;
- my $inst_names = get_inst_names $inst;
- my @new_reqs;
- for my $req (@$reqs) {
- $req = $compat32 ? "$req-compat32" : $req;
- push @new_reqs, $req unless $req ~~ @$inst_names;
- }
- return \@new_reqs;
+for my $sbo (@$build_queue) {
+ $locations{$sbo} = get_sbo_location ($sbo);
}
-# ask to install any requirements found
-sub ask_requires {
- my %args = (
- REQUIRES => '',
- README => '',
- SBO => '',
- @_
- );
- unless ($args{REQUIRES} && $args{README} && $args{SBO}) {
- script_error 'ask_requires requires three arguments.';
- }
- my $reqs = $args{REQUIRES};
- $reqs = clean_reqs $reqs unless ($force && $force_reqs);
- FIRST: for my $req (@$reqs) {
- my $name = $compat32 ? "$req-compat32" : $req;
- say $args{README};
- say "$args{SBO} has $name listed as a requirement.";
- print 'Shall I attempt to install it first? [y] ';
- if (<STDIN> =~ /^[Yy\n]/) {
- my @cmd_args = ('/usr/sbin/sboupgrade');
- push @cmd_args, $force_reqs ? '-N' : '-oN';
- # populate args so that they carry over correctly
- push @cmd_args, $noclean ? '-cTRUE' : '-cFALSE';
- push @cmd_args, $distclean ? '-dTRUE' : '-dFALSE';
- push @cmd_args, '-p' if $compat32;
- push @cmd_args, '-f' if $force;
- push @cmd_args, '-z' if $force_reqs;
- push @cmd_args, "-j$jobs" if $jobs;
- system (@cmd_args, $req) == 0 or die "$name failed to install.\n";
- }
- }
- return;
+sub get_readme_path ($) {
+ exists $_[0] or script_error 'get_readme_path requires an argument.';
+ my $sbo = shift;
+ return $locations{$sbo} .'/README';
}
# look for any (user|group)add commands in the README
sub get_user_group ($) {
- exists $_[0] or script_error 'get_user_group requires an argument';
- my $readme = shift;
- my @cmds = $readme =~ /^\s*#*\s*(useradd.*|groupadd.*)/mg;
- return \@cmds;
+ exists $_[0] or script_error 'get_user_group requires an argument';
+ my $readme = shift;
+ my @cmds = $readme =~ /^\s*#*\s*(useradd.*|groupadd.*)/mg;
+ return \@cmds;
}
# offer to run any user/group add commands
sub ask_user_group {
- exists $_[1] or script_error 'ask_user_group requires two arguments';
- my ($cmds, $readme) = @_;
- say "\n". $readme;
- print "\nIt looks like this slackbuild requires the following";
- say ' command(s) to be run first:';
- say " # $_" for @$cmds;
- print 'Shall I run it/them now? [y] ';
- if (<STDIN> =~ /^[Yy\n]/) {
- for my $cmd (@$cmds) {
- system ($cmd) == 0 or warn "\"$cmd\" exited non-zero\n";
- }
- }
+ exists $_[1] or script_error 'ask_user_group requires two arguments';
+ my ($cmds, $readme) = @_;
+ say "\n". $readme;
+ print "\nIt looks like this slackbuild requires the following";
+ say ' command(s) to be run first:';
+ say " # $_" for @$cmds;
+ print 'Shall I run them prior to building? [y] ';
+ return <STDIN> =~ /^[Yy\n]/ ? $cmds : undef;
}
# see if the README mentions any options
sub get_opts ($) {
- exists $_[0] or script_error 'get_opts requires an argument';
- my $readme = shift;
- return $readme =~ /[A-Z0-9]+=[^\s]/ ? 1 : undef;
+ exists $_[0] or script_error 'get_opts requires an argument';
+ my $readme = shift;
+ return $readme =~ /[A-Z0-9]+=[^\s]/ ? 1 : undef;
}
# provide an opportunity to set options
sub ask_opts ($) {
- exists $_[0] or script_error 'ask_opts requires an argument';
- my $readme = shift;
- say "\n". $readme;
- print "\nIt looks this slackbuilds has options; would you like to set any";
- print ' when the slackbuild is run? [n] ';
- if (<STDIN> =~ /^[Yy]/) {
- my $ask = sub () {
- print "\nPlease supply any options here, or enter to skip: ";
- chomp (my $opts = <STDIN>);
- return if $opts =~ /^\n/;
- return $opts;
- };
- my $kv_regex = qr/[A-Z0-9]+=[^\s]+(|\s([A-Z]+=[^\s]+){0,})/;
- my $opts = &$ask;
- return unless $opts;
- FIRST: while ($opts !~ $kv_regex) {
- warn "Invalid input received.\n";
- $opts = &$ask;
- }
- return $opts;
- }
- return;
+ exists $_[0] or script_error 'ask_opts requires an argument';
+ my $readme = shift;
+ say "\n". $readme;
+ print "\nIt looks this slackbuild has options; would you like to set any";
+ print ' when the slackbuild is run? [n] ';
+ if (<STDIN> =~ /^[Yy]/) {
+ my $ask = sub () {
+ print "\nPlease supply any options here, or enter to skip: ";
+ chomp (my $opts = <STDIN>);
+ return if $opts =~ /^\n/;
+ return $opts;
+ };
+ my $kv_regex = qr/[A-Z0-9]+=[^\s]+(|\s([A-Z]+=[^\s]+){0,})/;
+ my $opts = &$ask;
+ return unless $opts;
+ while ($opts !~ $kv_regex) {
+ warn "Invalid input received.\n";
+ $opts = &$ask;
+ }
+ return $opts;
+ }
+ return;
}
-# prompt for the readme
-sub readme_prompt {
- exists $_[0] or script_error 'readme_prompt requires an argument.';
+sub user_prompt {
+ exists $_[1] or script_error 'user_prompt requires two arguments.';
my ($sbo, $location) = @_;
- my $fh = open_read (get_readme_path $sbo);
+ my $fh = open_read ($location .'/README');
my $readme = do {local $/; <$fh>};
close $fh;
- # check for requirements, offer to install any found
- my $requires = get_requires $sbo, $location;
- ask_requires (REQUIRES => $requires, README => $readme, SBO => $sbo) if
- ref $requires eq 'ARRAY';
+
# check for user/group add commands, offer to run any found
my $user_group = get_user_group $readme;
- ask_user_group ($user_group, $readme) if $$user_group[0];
+ my $cmds;
+ $cmds = ask_user_group ($user_group, $readme) if $$user_group[0];
+ $commands{$sbo} = $cmds if defined $cmds;
# check for options mentioned in the README
- my $opts;
+ my $opts = 0;
$opts = ask_opts $readme if get_opts $readme;
print "\n". $readme unless $opts;
- # present the name as -compat32 if appropriate
- my $name = $compat32 ? "$sbo-compat32" : $sbo;
- print "\nProceed with $name? [y]: ";
- exit 0 unless <STDIN> =~ /^[Yy\n]/;
- return $opts;
+ $options{$sbo} = $opts if $opts;
+
+ print "\nProceed with $sbo? [y]: ";
+ return 0 unless <STDIN> =~ /^[Yy\n]/;
+ return 1;
}
# do the things with the provided sbos - whether upgrades or new installs.
sub process_sbos ($) {
- exists $_[0] or script_error 'process_sbos requires an argument.';
- my $todo = shift;
- my %failures;
- FIRST: for my $sbo (@$todo) {
+ exists $_[0] or script_error 'process_sbos requires an argument.';
+ my $todo = shift;
+ my %failures;
+ FIRST: for my $sbo (@$todo) {
my $opts = 0;
- $opts = readme_prompt ($sbo, $locations{$sbo}) unless $non_int;
+ $opts = $options{$sbo} if defined $options{$sbo};
+ my $cmds = $commands{$sbo} if defined $commands{$sbo};
+ for my $cmd (@$cmds) {
+ system ($cmd) == 0 or warn "\"$cmd\" exited non-zero\n";
+ }
# switch compat32 on if upgrading a -compat32
- $compat32 = 1 if $sbo =~ /-compat32$/;
+ # else make sure compat32 is off
+ $compat32 = $sbo =~ /-compat32$/ ? 1 : 0;
my ($version, $pkg, $src);
eval { ($version, $pkg, $src) = do_slackbuild (
- OPTS => $opts,
- JOBS => $jobs,
- LOCATION => $locations{$sbo},
- COMPAT32 => $compat32,
+ OPTS => $opts,
+ JOBS => $jobs,
+ LOCATION => $locations{$sbo},
+ COMPAT32 => $compat32,
); };
if ($@) {
- $failures{$sbo} = $@;
+ $failures{$sbo} = $@;
} else {
-
- do_upgradepkg $pkg unless $no_install;
-
- unless ($distclean) {
- make_clean (SBO => $sbo, SRC => $src, VERSION => $version)
- unless $noclean;
- } else {
- make_distclean (
- SBO => $sbo,
- SRC => $src,
- VERSION => $version,
- LOCATION => $locations{$sbo},
- );
- }
- # move package to $config{PKG_DIR} if defined
- unless ($config{PKG_DIR} eq 'FALSE') {
- my $dir = $config{PKG_DIR};
- unless (-d $dir) {
- mkdir ($dir) or warn "Unable to create $dir\n";
- }
- if (-d $dir) {
- move ($pkg, $dir), say "$pkg stored in $dir";
- } else {
- warn "$pkg left in /tmp\n";
- }
- } elsif ($distclean) {
- unlink $pkg;
- }
- }
- }
- return %failures;
+ do_upgradepkg $pkg unless $no_install;
+
+ unless ($distclean) {
+ make_clean (SBO => $sbo, SRC => $src, VERSION => $version)
+ unless $noclean;
+ } else {
+ make_distclean (
+ SBO => $sbo,
+ SRC => $src,
+ VERSION => $version,
+ LOCATION => $locations{$sbo},
+ );
+ }
+ # move package to $config{PKG_DIR} if defined
+ unless ($config{PKG_DIR} eq 'FALSE') {
+ my $dir = $config{PKG_DIR};
+ unless (-d $dir) {
+ mkdir ($dir) or warn "Unable to create $dir\n";
+ }
+ if (-d $dir) {
+ move ($pkg, $dir), say "$pkg stored in $dir";
+ } else {
+ warn "$pkg left in /tmp\n";
+ }
+ } elsif ($distclean) {
+ unlink $pkg;
+ }
+ }
+ }
+ return %failures;
}
sub print_failures {
- if (exists $_[0]) {
- my %failures = @_;
- say 'Failures:';
+ if (exists $_[0]) {
+ my %failures = @_;
+ say 'Failures:';
say " $_: $failures{$_}" for keys %failures;
- exit 1;
- }
+ exit 1;
+ }
}
+my $installed = get_installed_sbos;
+my $inst_names = get_inst_names $installed;
+my $upgrade_queue;
+@$upgrade_queue = ();
# deal with any updates prior to any new installs.
# no reason to bother if only_new is specified, ie running from sboinstall.
goto INSTALL_NEW if $only_new;
@@ -329,72 +253,121 @@ goto INSTALL_NEW if $only_new;
# doesn't matter what's updatable and what's not if force is specified
my @updates unless $force;
unless ($force) {
- my $updates = get_available_updates;
- push @updates, $$_{name} for @$updates;
+ my $updates = get_available_updates;
+ push @updates, $$_{name} for @$updates;
}
-my $todo_upgrade;
+
# but without force, we only want to update what there are updates for
-my @remove;
unless ($force) {
- for my $key (keys @ARGV) {
- if ($ARGV[$key] ~~ @updates) {
- push @$todo_upgrade, $ARGV[$key];
- push @remove, $key;
- }
- }
- # don't pass upgradable stuff to the install code
- for my $rem (@remove) {
- splice @ARGV, $rem, 1;
- $_-- for @remove;
- }
+ for my $sbo (@$build_queue) {
+ if ($sbo ~~ @updates) {
+ push @$upgrade_queue, $sbo;
+ }
+ }
} else {
- my $inst = get_installed_sbos;
- my $inst_names = get_inst_names $inst;
- for my $key (keys @ARGV) {
- if ($ARGV[$key] ~~ @$inst_names) {
- push @$todo_upgrade, $ARGV[$key];
- push @remove, $key;
- }
- }
- # don't pass upgradable stuff to the install code
- for my $rem (@remove) {
- splice @ARGV, $rem, 1;
- $_-- for @remove;
- }
+ if ( $force_reqs ) {
+ for my $sbo (@$build_queue) {
+ if ($sbo ~~ @$inst_names) {
+ push @$upgrade_queue, $sbo;
+ }
+ }
+ } else {
+ $upgrade_queue = \@ARGV;
+ $install_new = 1;
+ }
+}
+
+# Get user input regarding upgrades
+my @temp_queue;
+for my $sbo (@$upgrade_queue) {
+ unless ($non_int) {
+ if (user_prompt($sbo, $locations{$sbo})) {
+ push(@temp_queue, $sbo);
+ say "$sbo added to upgrade queue.";
+ } else {
+ say "skipping $sbo.";
+ }
+ } else {
+ push(@temp_queue, $sbo);
+ say "\n$sbo added to upgrade queue.";
+ }
+}
+
+# Remove upgrades from build queue
+FIRST: for my $sbo (@$upgrade_queue) {
+ if ($sbo ~~ @$build_queue) {
+ my $count = 0;
+ SECOND: for my $i (@$build_queue) {
+ if ($i eq $sbo) {
+ splice(@$build_queue, $count, 1);
+ last SECOND;
+ }
+ $count++;
+ }
+ }
}
-my %failures = process_sbos $todo_upgrade if exists $$todo_upgrade[0];
-print_failures (%failures);
+@$upgrade_queue = @temp_queue;
INSTALL_NEW:
-exit 0 unless $install_new;
-my $todo_install;
-FIRST: for my $sbo (@ARGV) {
- my $name = $compat32 ? "$sbo-compat32" : $sbo;
- my $inst = get_installed_sbos;
- my $inst_names = get_inst_names $inst;
- warn "$name already installed.\n" and next FIRST if $name ~~ @$inst_names;
- # if compat32 is TRUE, we need to see if the non-compat version exists.
- if ($compat32) {
- my $inst = get_installed_sbos;
- my $inst_names = get_inst_names $inst;
- unless ($sbo ~~ @$inst_names) {
- print "\nYou are attempting to install $name, however, $sbo is not";
- print ' yet installed. Shall I install it first? [y] ';
- if (<STDIN> =~ /^[Yy\n]/) {
- my @args = ('/usr/sbin/sboupgrade', '-oN');
- # populate args so that they carry over correctly
- push @args, $noclean ? '-cTRUE' : '-cFALSE';
- push @args, $distclean ? '-dTRUE' : '-dFALSE';
- push @args, "-j$jobs" if $jobs;
- system (@args, $sbo) == 0 or die "$sbo failed to install.\n";
- } else {
- warn "Please install $sbo\n" and exit 0;
- }
- }
- }
- push @$todo_install, $sbo;
+goto BEGIN_BUILD unless $install_new;
+@temp_queue = ();
+FIRST: for my $sbo (@$build_queue) {
+ my $name = $compat32 ? "$sbo-compat32" : $sbo;
+ if ($name ~~ @$inst_names) {
+ say "$name already installed." unless $force;
+ 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 ($sbo ~~ @$inst_names or $sbo ~~ @$upgrade_queue) {
+ if (user_prompt($sbo, $locations{$sbo})){
+ push(@temp_queue, $sbo);
+ say "$sbo added to install queue.";
+ } else {
+ last;
+ }
+ }
+ }
+ if (user_prompt($name, $locations{$name})) {
+ push(@temp_queue, $name);
+ say "$name added to install queue.";
+ } else {
+ last;
+ }
+ } else {
+ push(@temp_queue, $sbo);
+ say "\n$name added to build queue.";
+ }
+}
+@$build_queue = @temp_queue;
+
+BEGIN_BUILD:
+@$build_queue = () unless $install_new;
+exit 0 unless @$upgrade_queue or @$build_queue;
+print "\n";
+say "Upgrade queue: " . join(' ', @$upgrade_queue) if exists $$upgrade_queue[0];
+say "Install queue: " . join(' ', @$build_queue) if exists $$build_queue[0];
+unless ($non_int) {
+ print "\nAre you sure you wish to continue? [y]: ";
+ exit 0 unless <STDIN> =~ /^[Yy\n]/;
}
-%failures = process_sbos $todo_install if exists $$todo_install[0];
-print_failures (%failures);
+my %failures;
+if ( $force and ! $force_reqs) {
+ # Install missing reqs then rebuild sbo's
+ %failures = process_sbos $build_queue if exists $$build_queue[0];
+ print_failures (%failures);
+
+ %failures = process_sbos $upgrade_queue if exists $$upgrade_queue[0];
+ print_failures (%failures);
+} else {
+ # Upgrade any installed reqs/sbo's then build missing reqs/sbo's
+ %failures = process_sbos $upgrade_queue if exists $$upgrade_queue[0];
+ print_failures (%failures);
+
+ %failures = process_sbos $build_queue if exists $$build_queue[0];
+ print_failures (%failures);
+}
exit 0;
diff --git a/sboupgradex b/sboupgradex
deleted file mode 100755
index 209bd3a..0000000
--- a/sboupgradex
+++ /dev/null
@@ -1,373 +0,0 @@
-#!/usr/bin/env perl
-#
-# vim: set ts=4:noet
-#
-# sboinstall
-# script to install a SlackBuild by name
-#
-# author: Jacob Pipkin <j@dawnrazor.net>
-# license: WTFPL <http://sam.zoy.org/wtfpl/COPYING>
-
-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 <<EOF
-Usage: $self (options) [package]
-
-Options (defaults shown first where applicable):
- -h|--help:
- this screen.
- -v|--version:
- version information.
- -c|--noclean (FALSE|TRUE):
- set whether or not to clean working directories after building.
- -d|--distclean (TRUE|FALSE):
- set whether or not to clean distfiles afterward.
- -f|--force:
- force an update, even if the "upgrade" version is the same or lower.
- -i|--noinstall:
- do not run installpkg at the end of the build process.
- -j|--jobs (FALSE|#):
- specify "-j" setting to make, for multicore systems; overrides conf file.
- -N|--installnew:
- install any new SBo's listed.
- -r|--nointeractive:
- non-interactive; skips README and all prompts.
- -R|--norequirements:
- view the README but do not handle requirements, commands, or options.
- -z|--force-reqs:
- when used with -f, will force rebuilding an SBo's requirements as well.
-
-EOF
-}
-
-my $noclean = $config{NOCLEAN};
-my $distclean = $config{DISTCLEAN};
-my $jobs = $config{JOBS};
-my ($help, $vers, $force, $no_install, $install_new, $non_int, $no_reqs,
- $force_reqs, $only_new, $compat32);
-
-GetOptions (
- 'help|h' => \$help,
- 'version|v' => \$vers,
- 'noclean|c=s' => \$noclean,
- 'distclean|d=s' => \$distclean,
- 'force|f' => \$force,
- 'noinstall|i' => \$no_install,
- 'jobs|j=s' => \$jobs,
- 'installnew|N' => \$install_new,
- 'nointeractive|r' => \$non_int,
- 'norequirements|R' => \$no_reqs,
- 'force-reqs|z' => \$force_reqs,
- 'only-new|o' => \$only_new,
- 'compat32|p' => \$compat32,
-);
-
-show_usage and exit 0 if $help;
-show_version and exit 0 if $vers;
-show_usage and exit 0 unless exists $ARGV[0];
-say "Invalid arguments: --force-reqs and --installnew can not be used together." and exit 0 if $force_reqs and $install_new;
-
-$noclean = $noclean eq 'TRUE' ? 1 : 0;
-$distclean = $distclean eq 'TRUE' ? 1 : 0;
-
-my $rootpkg = $ARGV[0];
-my %warnings;
-my %options;
-my $build_queue;
-my %commands;
-my %locations;
-
-if ($no_reqs or $non_int) {
- $build_queue = \@ARGV;
-} else {
- $build_queue = get_build_queue(\@ARGV, \%warnings);
-}
-for my $sbo (@$build_queue) {
- $locations{$sbo} = get_sbo_location ($sbo);
-}
-
-sub get_readme_path ($) {
- exists $_[0] or script_error 'get_readme_path requires an argument.';
- my $sbo = shift;
- return $locations{$sbo} .'/README';
-}
-
-# look for any (user|group)add commands in the README
-sub get_user_group ($) {
- exists $_[0] or script_error 'get_user_group requires an argument';
- my $readme = shift;
- my @cmds = $readme =~ /^\s*#*\s*(useradd.*|groupadd.*)/mg;
- return \@cmds;
-}
-
-# offer to run any user/group add commands
-sub ask_user_group {
- exists $_[1] or script_error 'ask_user_group requires two arguments';
- my ($cmds, $readme) = @_;
- say "\n". $readme;
- print "\nIt looks like this slackbuild requires the following";
- say ' command(s) to be run first:';
- say " # $_" for @$cmds;
- print 'Shall I run them prior to building? [y] ';
- return <STDIN> =~ /^[Yy\n]/ ? $cmds : undef;
-}
-
-# see if the README mentions any options
-sub get_opts ($) {
- exists $_[0] or script_error 'get_opts requires an argument';
- my $readme = shift;
- return $readme =~ /[A-Z0-9]+=[^\s]/ ? 1 : undef;
-}
-
-# provide an opportunity to set options
-sub ask_opts ($) {
- exists $_[0] or script_error 'ask_opts requires an argument';
- my $readme = shift;
- say "\n". $readme;
- print "\nIt looks this slackbuild has options; would you like to set any";
- print ' when the slackbuild is run? [n] ';
- if (<STDIN> =~ /^[Yy]/) {
- my $ask = sub () {
- print "\nPlease supply any options here, or enter to skip: ";
- chomp (my $opts = <STDIN>);
- return if $opts =~ /^\n/;
- return $opts;
- };
- my $kv_regex = qr/[A-Z0-9]+=[^\s]+(|\s([A-Z]+=[^\s]+){0,})/;
- my $opts = &$ask;
- return unless $opts;
- while ($opts !~ $kv_regex) {
- warn "Invalid input received.\n";
- $opts = &$ask;
- }
- return $opts;
- }
- return;
-}
-
-sub user_prompt {
- exists $_[1] or script_error 'user_prompt requires two arguments.';
- my ($sbo, $location) = @_;
- my $fh = open_read ($location .'/README');
- my $readme = do {local $/; <$fh>};
- close $fh;
-
- # check for user/group add commands, offer to run any found
- my $user_group = get_user_group $readme;
- my $cmds;
- $cmds = ask_user_group ($user_group, $readme) if $$user_group[0];
- $commands{$sbo} = $cmds if defined $cmds;
- # check for options mentioned in the README
- my $opts = 0;
- $opts = ask_opts $readme if get_opts $readme;
- print "\n". $readme unless $opts;
- $options{$sbo} = $opts if $opts;
-
- print "\nProceed with $sbo? [y]: ";
- return 0 unless <STDIN> =~ /^[Yy\n]/;
- return 1;
-}
-
-# do the things with the provided sbos - whether upgrades or new installs.
-sub process_sbos ($) {
- exists $_[0] or script_error 'process_sbos requires an argument.';
- my $todo = shift;
- my %failures;
- FIRST: for my $sbo (@$todo) {
- my $opts = 0;
- $opts = $options{$sbo} if defined $options{$sbo};
- my $cmds = $commands{$sbo} if defined $commands{$sbo};
- for my $cmd (@$cmds) {
- system ($cmd) == 0 or warn "\"$cmd\" exited non-zero\n";
- }
- # switch compat32 on if upgrading a -compat32
- # else make sure compat32 is off
- $compat32 = $sbo =~ /-compat32$/ ? 1 : 0;
- my ($version, $pkg, $src);
- eval { ($version, $pkg, $src) = do_slackbuild (
- OPTS => $opts,
- JOBS => $jobs,
- LOCATION => $locations{$sbo},
- COMPAT32 => $compat32,
- ); };
- if ($@) {
- $failures{$sbo} = $@;
- } else {
- do_upgradepkg $pkg unless $no_install;
-
- unless ($distclean) {
- make_clean (SBO => $sbo, SRC => $src, VERSION => $version)
- unless $noclean;
- } else {
- make_distclean (
- SBO => $sbo,
- SRC => $src,
- VERSION => $version,
- LOCATION => $locations{$sbo},
- );
- }
- # move package to $config{PKG_DIR} if defined
- unless ($config{PKG_DIR} eq 'FALSE') {
- my $dir = $config{PKG_DIR};
- unless (-d $dir) {
- mkdir ($dir) or warn "Unable to create $dir\n";
- }
- if (-d $dir) {
- move ($pkg, $dir), say "$pkg stored in $dir";
- } else {
- warn "$pkg left in /tmp\n";
- }
- } elsif ($distclean) {
- unlink $pkg;
- }
- }
- }
- return %failures;
-}
-
-sub print_failures {
- if (exists $_[0]) {
- my %failures = @_;
- say 'Failures:';
- say " $_: $failures{$_}" for keys %failures;
- exit 1;
- }
-}
-
-my $installed = get_installed_sbos;
-my $inst_names = get_inst_names $installed;
-my $upgrade_queue;
-@$upgrade_queue = ();
-# deal with any updates prior to any new installs.
-# no reason to bother if only_new is specified, ie running from sboinstall.
-goto INSTALL_NEW if $only_new;
-
-# doesn't matter what's updatable and what's not if force is specified
-my @updates unless $force;
-unless ($force) {
- my $updates = get_available_updates;
- push @updates, $$_{name} for @$updates;
-}
-
-# but without force, we only want to update what there are updates for
-unless ($force) {
- for my $sbo (@$build_queue) {
- if ($sbo ~~ @updates) {
- push @$upgrade_queue, $sbo;
- }
- }
-} else {
- if ( $force_reqs ) {
- for my $sbo (@$build_queue) {
- if ($sbo ~~ @$inst_names) {
- push @$upgrade_queue, $sbo;
- }
- }
- } else {
- $upgrade_queue = \@ARGV;
- $install_new = 1;
- }
-}
-
-# Get user input regarding upgrades
-my @temp_queue;
-for my $sbo (@$upgrade_queue) {
- unless ($non_int) {
- if (user_prompt($sbo, $locations{$sbo})) {
- push(@temp_queue, $sbo);
- say "$sbo added to upgrade queue.";
- } else {
- say "skipping $sbo.";
- }
- } else {
- push(@temp_queue, $sbo);
- say "\n$sbo added to upgrade queue.";
- }
-}
-
-# Remove upgrades from build queue
-FIRST: for my $sbo (@$upgrade_queue) {
- if ($sbo ~~ @$build_queue) {
- my $count = 0;
- SECOND: for my $i (@$build_queue) {
- if ($i eq $sbo) {
- splice(@$build_queue, $count, 1);
- last SECOND;
- }
- $count++;
- }
- }
-}
-@$upgrade_queue = @temp_queue;
-
-INSTALL_NEW:
-goto BEGIN_BUILD unless $install_new;
-@temp_queue = ();
-FIRST: for my $sbo (@$build_queue) {
- my $name = $compat32 ? "$sbo-compat32" : $sbo;
- if ($name ~~ @$inst_names) {
- say "$name already installed." unless $force;
- 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 ($sbo ~~ @$inst_names or $sbo ~~ @$upgrade_queue) {
- if (user_prompt($sbo, $locations{$sbo})){
- push(@temp_queue, $sbo);
- say "$sbo added to install queue.";
- } else {
- last;
- }
- }
- }
- if (user_prompt($name, $locations{$name})) {
- push(@temp_queue, $name);
- say "$name added to install queue.";
- } else {
- last;
- }
- } else {
- push(@temp_queue, $sbo);
- say "\n$name added to build queue.";
- }
-}
-@$build_queue = @temp_queue;
-
-BEGIN_BUILD:
-@$build_queue = () unless $install_new;
-exit 0 unless @$upgrade_queue or @$build_queue;
-print "\n";
-say "Upgrade queue: " . join(' ', @$upgrade_queue) if exists $$upgrade_queue[0];
-say "Install queue: " . join(' ', @$build_queue) if exists $$build_queue[0];
-unless ($non_int) {
- print "\nAre you sure you wish to continue? [y]: ";
- exit 0 unless <STDIN> =~ /^[Yy\n]/;
-}
-
-my %failures;
-if ( $force and ! $force_reqs) {
- # Install missing reqs then rebuild sbo's
- %failures = process_sbos $build_queue if exists $$build_queue[0];
- print_failures (%failures);
-
- %failures = process_sbos $upgrade_queue if exists $$upgrade_queue[0];
- print_failures (%failures);
-} else {
- # Upgrade any installed reqs/sbo's then build missing reqs/sbo's
- %failures = process_sbos $upgrade_queue if exists $$upgrade_queue[0];
- print_failures (%failures);
-
- %failures = process_sbos $build_queue if exists $$build_queue[0];
- print_failures (%failures);
-}
-exit 0;