#!/usr/bin/env perl # # vim: set ts=4:noet # # sboupgrade # script to update an installed SlackBuild. # # author: Jacob Pipkin # date: Boomtime, the 39th day of Discord in the YOLD 3178 # license: WTFPL use SBO::Lib; use File::Basename; use Getopt::Std; use File::Copy; use strict; use warnings FATAL => 'all'; my %config = %SBO::Lib::config; my $self = basename ($0); sub show_usage { print < =~ /^[Yy\n]/) { my @args = ("/usr/sbin/sboupgrade", '-oN'); # populate args so that they carry over correctly push @args, "-c" if exists $options{c}; push @args, "-d" if exists $options{d}; push @args, "-j $options{j}" if exists $options{j}; push @args, "-p" if $compat32 eq 'TRUE'; push @args, $need; system (@args) == 0 or die "Requirement failure, unable to proceed.\n"; } } return; } # look for any (user|group)add commands in the README sub grok_user_group { exists $_[0] or script_error ('grok_user_group requires an argument'); my $readme = shift; my @readme_array = split /\n/, $readme; my @cmds; my $cmd_regex = qr/^\s*#\s+((user|group)add.*)/; push @cmds, ($_ =~ $cmd_regex)[0] for @readme_array; return unless exists $cmds[0]; print "\n". $readme ."\n";; print "\nIt looks like this slackbuild requires the following command(s)"; print " to be run first:\n"; print " # $_\n" for @cmds; print "Shall I run it/them now? [y] "; if ( =~ /^[Yy\n]/) { for my $cmd (@cmds) { system ($cmd == 0) or warn "\"$cmd\" exited non-zero\n"; } } return 1; } # see if the README mentions any options sub grok_options { exists $_[0] or script_error ('grok_options requires an argument'); my $readme = shift; return 7 unless $readme =~ /[A-Z]+=[^\s]/; my @readme_array = split /\n/, $readme; print "\n". $readme; print "\nIt looks this slackbuilds has options; would you like to set any"; print " when the slackbuild is run? [n] "; if ( =~ /^[Yy]/) { my $ask = sub { print "\nPlease supply any options here, or enter to skip: "; chomp (my $opts = ); return 7 if $opts =~ /^$/; return $opts; }; my $kv_regex = qr/[A-Z]+=[^\s]+(|\s([A-Z]+=[^\s]+){0,})/; my $opts = &$ask (); FIRST: while ($opts !~ $kv_regex) { warn "Invalid input received.\n"; $opts = &$ask (); return 7 if $opts eq "7"; } return $opts; } return 7; } # prompt for the readme, and grok the readme at this time also. sub readme_prompt { exists $_[0] or script_error ('readme_prompt requires an argument.'); my $sbo = shift; my $fh = open_read (get_readme_path ($sbo) ); my $readme = do {local $/; <$fh>}; close $fh; grok_requirements ($sbo, $readme); grok_user_group ($readme); my $opts = grok_options ($readme); print "\n". $readme if ($opts eq "7" || ! $opts); my $name = $compat32 eq 'TRUE' ? "$sbo-compat32" : $sbo; print "\nProceed with $name? [y]: "; exit 0 unless =~ /^[Yy\n]/; return $opts if defined $opts; 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 = @_; my @failures; FIRST: for my $sbo (@todo) { my $opts = 0; $opts = readme_prompt ($sbo) unless $no_readme eq 'TRUE'; $opts = 'FALSE' if ($opts =~ /\d+/ || ! $opts); # switch compat32 on if upgrading a -compat32 $compat32 = 'TRUE' if $sbo =~ /-compat32$/; my ($version, $pkg, $src); my @sb_args = ($opts, $jobs, $sbo, $locations{$sbo}, $compat32); eval { ($version, $pkg, $src) = do_slackbuild (@sb_args); }; if ($@) { push @failures, $sbo; } else { unless ($distclean eq 'TRUE') { make_clean ($sbo, $src, $version) if $noclean eq 'FALSE'; } else { make_distclean ($sbo, $src, $version, $locations{$sbo}); } do_upgradepkg ($pkg) unless $no_install eq 'TRUE'; # 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), print "$pkg stored in $dir\n"; } else { warn "$pkg left in /tmp\n"; } } elsif ($distclean eq 'TRUE') { unlink ($pkg); } } } return @failures; } my @failed; sub print_failures { if (exists $failed[0]) { print "Failures:\n"; print " $_\n" for @failed; exit 1; } } # deal with any updates prior to any new installs. # no reason to bother if only_new is specified, ie running from sboinstall. unless ($only_new eq 'TRUE') { # doesn't matter what's updatable and what's not if force is specified my @updates unless $force eq 'TRUE'; unless ($force eq 'TRUE') { my @updates_array = get_available_updates (); push @updates, $updates_array[$_]{name} for keys @updates_array; } my @todo_upgrade; # but without force, we only want to update what there are updates for unless ($force eq 'TRUE') { for my $sbo (@ARGV) { push @todo_upgrade, $sbo if $sbo ~~ @updates; } } else { my @inst = get_installed_sbos (); FIRST: for my $sbo (@ARGV) { SECOND: for my $key (keys @inst) { if ($sbo eq $inst[$key]{name}) { push @todo_upgrade, $sbo; last SECOND; } } } } @failed = process_sbos (@todo_upgrade) if exists $todo_upgrade[0]; print_failures () unless $install_new eq 'TRUE'; } if ($install_new eq 'TRUE') { my @todo_install; FIRST: for my $sbo (@ARGV) { my $has = 'FALSE'; my $name = $compat32 eq 'TRUE' ? "$sbo-compat32" : $sbo; my @inst = get_installed_sbos (); SECOND: for my $key (keys @inst) { $has = 'TRUE', last SECOND if $name eq $inst[$key]{name}; } # if compat32 is TRUE, we need to see if the non-compat version exists. if ($compat32 eq 'TRUE') { my $has64 = 'FALSE'; my @inst = get_installed_sbos (); THIRD: for my $key (keys @inst) { $has64 = 'TRUE', last THIRD if $sbo eq $inst[$key]{name}; } unless ($has64 eq 'TRUE') { print "\nYou are attempting to install $sbo-compat32, however,"; print " $sbo is not yet installed. Shall I install it first?"; print " [y] "; if ( =~ /^[Yy\n]/) { my @args = ('/usr/sbin/sboupgrade', '-oN', $sbo); system (@args) == 0 or exit 1; } else { print "Please install $sbo\n" and exit 0; } } } $has eq 'TRUE' ? warn "$name already installed.\n" : push @todo_install, $sbo; } @failed = process_sbos (@todo_install) if exists $todo_install[0]; print_failures (); } exit 1 if exists $failed[0]; exit 0;