diff options
-rw-r--r-- | SBO-Lib/lib/SBO/Lib.pm | 123 | ||||
-rwxr-xr-x | sbocheck | 51 | ||||
-rwxr-xr-x | sboclean | 9 | ||||
-rwxr-xr-x | sboconfig | 45 | ||||
-rwxr-xr-x | sbofind | 40 | ||||
-rwxr-xr-x | sboinstall | 4 | ||||
-rwxr-xr-x | sbosnap | 7 | ||||
-rwxr-xr-x | sboupgrade | 121 | ||||
-rw-r--r-- | t/SBO/Lib.pm | 686 | ||||
-rwxr-xr-x | t/prep.pl | 47 | ||||
-rwxr-xr-x | t/test.t | 262 |
11 files changed, 483 insertions, 912 deletions
diff --git a/SBO-Lib/lib/SBO/Lib.pm b/SBO-Lib/lib/SBO/Lib.pm index 3f75d80..959fe22 100644 --- a/SBO-Lib/lib/SBO/Lib.pm +++ b/SBO-Lib/lib/SBO/Lib.pm @@ -10,8 +10,8 @@ # license: WTFPL <http://sam.zoy.org/wtfpl/COPYING> use 5.12.3; -use warnings FATAL => 'all'; use strict; +use warnings FATAL => 'all'; package SBO::Lib 0.7; my $version = "0.7"; @@ -35,7 +35,10 @@ our @EXPORT = qw( get_sbo_location get_from_info get_tmp_extfn - get_tmp_perlfn + $tempdir + $conf_dir + $conf_file + %config ); $< == 0 or die "This script requires root privileges.\n"; @@ -46,7 +49,6 @@ use Digest::MD5; use File::Copy; use File::Path qw(make_path remove_tree); use Fcntl; -use File::Find; use File::Temp qw(tempdir tempfile); use Fcntl qw(F_SETFD F_GETFD); @@ -55,12 +57,12 @@ our $tempdir = tempdir (CLEANUP => 1); # subroutine for throwing internal script errors sub script_error (;$) { exists $_[0] ? die "A fatal script error has occurred:\n$_[0]\nExiting.\n" - : die "A fatal script error has occurred: Exiting.\n"; + : die "A fatal script error has occurred. Exiting.\n"; } # sub for opening files, second arg is like '<','>', etc -sub open_fh { - exists $_[1] or script_error ('open_fh requires two arguments'); +sub open_fh ($$) { + exists $_[1] or script_error 'open_fh requires two arguments'; unless ($_[1] eq '>') { -f $_[0] or script_error 'open_fh first argument not a file'; } @@ -73,7 +75,7 @@ sub open_read ($) { return open_fh shift, '<'; } -# pull in configuration, set sane defaults, etc. +# global config variables our $conf_dir = '/etc/sbotools'; our $conf_file = "$conf_dir/sbotools.conf"; our %config = ( @@ -84,20 +86,23 @@ our %config = ( SBO_HOME => 'FALSE', ); -# if the conf file exists, pull all the $key=$value pairs into a hash -my %conf_values; -if (-f $conf_file) { - my $fh = open_read ($conf_file); - my $text = do {local $/; <$fh>}; - %conf_values = $text =~ /^(\w+)=(.*)$/mg; - close $fh; +# subroutine to suck in config in order to facilitate unit testing +sub read_config () { + my %conf_values; + if (-f $conf_file) { + my $fh = open_read $conf_file; + my $text = do {local $/; <$fh>}; + %conf_values = $text =~ /^(\w+)=(.*)$/mg; + close $fh; + } + for my $key (keys %config) { + $config{$key} = $conf_values{$key} if exists $conf_values{$key}; + } + $config{JOBS} = 'FALSE' unless $config{JOBS} =~ /^\d+$/; + $config{SBO_HOME} = '/usr/sbo' if $config{SBO_HOME} eq 'FALSE'; } -for my $key (keys %config) { - $config{$key} = $conf_values{$key} if exists $conf_values{$key}; -} -$config{JOBS} = 'FALSE' unless $config{JOBS} =~ /^\d+$/; -$config{SBO_HOME} = '/usr/sbo' if $config{SBO_HOME} eq 'FALSE'; +read_config; # some stuff we'll need later. my $distfiles = "$config{SBO_HOME}/distfiles"; @@ -106,8 +111,8 @@ my $name_regex = '\ASLACKBUILD\s+NAME:\s+'; sub show_version () { say "sbotools version $version"; - say "licensed under the WTFPL"; - say "<http://sam.zoy.org/wtfpl/COPYING>"; + say 'licensed under the WTFPL'; + say '<http://sam.zoy.org/wtfpl/COPYING>'; } # %supported maps what's in /etc/slackware-version to what's at SBo @@ -127,7 +132,7 @@ sub get_slack_version () { # does the SLACKBUILDS.TXT file exist in the sbo tree? sub chk_slackbuilds_txt () { - return -f $slackbuilds_txt ? 1 : 0; + return -f $slackbuilds_txt ? 1 : undef; } # check for the validity of new $config{SBO_HOME} @@ -140,8 +145,9 @@ sub check_home () { die "$sbo_home exists and is not empty. Exiting.\n"; } } else { - make_path ($sbo_home) or die "Unable to create $sbo_home.\n"; + make_path ($sbo_home) or die "Unable to create $sbo_home.\n"; } + return 1; } # rsync the sbo tree from slackbuilds.org to $config{SBO_HOME} @@ -150,19 +156,19 @@ sub rsync_sbo_tree () { my @arg = ('rsync', '-a', '--exclude=*.tar.gz', '--exclude=*.tar.gz.asc'); push @arg, "rsync://slackbuilds.org/slackbuilds/$slk_version/*"; my $out = system @arg, $config{SBO_HOME}; - say "Finished." and return $out; + say 'Finished.' and return $out; } # wrappers for differing checks and output sub fetch_tree () { check_home; - say "Pulling SlackBuilds tree..."; + say 'Pulling SlackBuilds tree...'; rsync_sbo_tree, return 1; } sub update_tree () { fetch_tree, return unless chk_slackbuilds_txt; - say "Updating SlackBuilds tree..."; + say 'Updating SlackBuilds tree...'; rsync_sbo_tree, return 1; } @@ -171,8 +177,8 @@ sub update_tree () { sub slackbuilds_or_fetch () { unless (chk_slackbuilds_txt) { say 'It looks like you haven\'t run "sbosnap fetch" yet.'; - print "Would you like me to do this now? [y] "; - <STDIN> =~ /^[Yy\n]/ ? fetch_tree () : + print 'Would you like me to do this now? [y] '; + <STDIN> =~ /^[Yy\n]/ ? fetch_tree : die "Please run \"sbosnap fetch\"\n"; } return 1; @@ -240,14 +246,14 @@ sub get_from_info (%) { $$vars{$key} = [$$vars{$key}]; } } - return exists $$vars{$args{GET}} ? $$vars{$args{GET}} : 0; + return exists $$vars{$args{GET}} ? $$vars{$args{GET}} : undef; } # find the version in the tree for a given sbo (provided a location) sub get_sbo_version ($) { - exists $_[0] or script_error 'get_sbo_version requires an arguments'; + exists $_[0] or script_error 'get_sbo_version requires an argument.'; my $version = get_from_info (LOCATION => shift, GET => 'VERSION'); - return $$version[0] ? $$version[0] : 0; + return $$version[0] ? $$version[0] : undef; } # for each installed sbo, find out whether or not the version in the tree is @@ -287,9 +293,9 @@ sub get_download_info (%) { if ($args{X64}) { my $nothing; if (! $$downs[0]) { - $nothing = 1; + $nothing++; } elsif ($$downs[0] =~ qr/^UN(SUPPOR|TES)TED$/) { - $nothing = 1; + $nothing++; } if ($nothing) { $args{X64} = 0; @@ -336,7 +342,9 @@ sub get_sbo_downloads (%) { # given a link, grab the filename from the end of it sub get_filename_from_link ($) { exists $_[0] or script_error 'get_filename_from_link requires an argument'; - return "$distfiles/". (shift =~ qr#/([^/]+)$#)[0]; + my $fn = shift; + my $regex = qr#/([^/]+)$#; + return $fn =~ $regex ? $distfiles .'/'. ($fn =~ $regex)[0] : undef; } # for a given file, computer its md5sum @@ -353,7 +361,7 @@ sub compute_md5sum ($) { sub compare_md5s ($$) { exists $_[1] or script_error 'compare_md5s requires two arguments.'; my ($first, $second) = @_; - return $first eq $second ? 1 : 0; + return $first eq $second ? 1 : undef; } # for a given distfile, see whether or not it exists, and if so, if its md5sum @@ -384,7 +392,7 @@ sub get_distfile ($$) { return 1; } -# for a given distfile, what will be the full path of the symlink? +# for a given distfile, figure out what the full path to its symlink will be sub get_symlink_from_filename ($$) { exists $_[1] or script_error 'get_symlink_from_filename requires two arguments'; @@ -398,12 +406,12 @@ sub get_symlink_from_filename ($$) { sub check_x32 ($) { exists $_[0] or script_error 'check_x32 requires an argument.'; my $dl = get_from_info (LOCATION => shift, GET => 'DOWNLOAD_x86_64'); - return $$dl[0] =~ /UN(SUPPOR|TES)TED/ ? 1 : 0; + return $$dl[0] =~ /UN(SUPPOR|TES)TED/ ? 1 : undef; } # can't do 32-bit on x86_64 without this file, so we'll use it as the test to # to determine whether or not an x86_64 system is setup for multilib -sub check_multilib { +sub check_multilib () { return 1 if -f '/etc/profile.d/32dev.sh'; return; } @@ -419,7 +427,7 @@ sub rewrite_slackbuild ($$%) { my $libdir_regex = qr/^\s*LIBDIRSUFFIX="64"\s*$/; my $make_regex = qr/^\s*make(| \Q||\E exit 1)$/; my $arch_regex = qr/\$VERSION-\$ARCH-\$BUILD/; - # tie the slackbuilds, because this is the easiest way to handle this. + # tie the slackbuild, because this is the easiest way to handle this. tie my @sb_file, 'Tie::File', $slackbuild; for my $line (@sb_file) { # get the output of the tar and makepkg commands. hope like hell that v @@ -427,7 +435,7 @@ sub rewrite_slackbuild ($$%) { if ($line =~ $tar_regex || $line =~ $makepkg_regex) { $line = "$line | tee -a $tempfn"; } - # then check for and apply any %changes + # then check for and apply any other %changes if (exists $changes{libdirsuffix}) { $line =~ s/64/$changes{libdirsuffix}/ if $line =~ $libdir_regex; } @@ -460,9 +468,7 @@ sub check_distfiles (%) { my %dists = @_; for my $link (keys %dists) { my $md5sum = $dists{$link}; - unless (verify_distfile $link, $md5sum) { - die unless get_distfile $link, $md5sum; - } + get_distfile $link, $md5sum unless verify_distfile $link, $md5sum; } return 1; } @@ -518,28 +524,14 @@ sub get_pkg_name ($) { REGEX => qr/^Slackware\s+package\s+([^\s]+)\s+created\.$/); } -# clear the close-on-exec bit from a temp file handle -sub clear_coe_bit ($) { - exists $_[0] or script_error 'clear_coe_bit requires an argument'; - my $fh = shift; - fcntl ($fh, F_SETFD, 0) or die "no unset exec-close thingy\n"; - return $fh; -} - # return a filename from a temp fh for use externally sub get_tmp_extfn ($) { exists $_[0] or script_error 'get_tmp_extfn requires an argument.'; - my $fh = clear_coe_bit shift; + my $fh = shift; + fcntl ($fh, F_SETFD, 0) or die "Can't unset exec-on-close bit\n"; return '/dev/fd/'. fileno $fh; } -# return a filename from a temp fh for use internally -sub get_tmp_perlfn ($) { - exists $_[0] or script_error 'get_tmp_perlfn requires an argument.'; - my $fh = clear_coe_bit shift; - return '+<=&'. fileno $fh; -} - # prep and run .SlackBuild sub perform_sbo (%) { my %args = ( @@ -557,7 +549,7 @@ sub perform_sbo (%) { my $location = $args{LOCATION}; my $sbo = get_sbo_from_loc $location; my ($cmd, %changes); - # figure out any changes we need to make to the .SlackBuild + # set any changes we need to make to the .SlackBuild, setup the command $changes{make} = "-j $args{JOBS}" if $args{JOBS}; if ($args{ARCH} eq 'x86_64' and ($args{C32} || $args{X32})) { if ($args{C32}) { @@ -574,7 +566,7 @@ sub perform_sbo (%) { rewrite_slackbuild "$location/$sbo.SlackBuild", $fn, %changes; chdir $location, my $out = system $cmd; revert_slackbuild "$location/$sbo.SlackBuild"; - die unless $out == 0; + die "$sbo.SlackBuild returned non-zero ext status\n" unless $out == 0; my $pkg = get_pkg_name $tempfh; my $src = get_src_dir $tempfh; return $pkg, $src; @@ -587,7 +579,8 @@ sub do_convertpkg ($) { my $tempfh = tempfile (DIR => $tempdir); my $fn = get_tmp_extfn $tempfh; my $cmd = "/usr/sbin/convertpkg-compat32 -i $pkg -d /tmp | tee $fn"; - system ($cmd) == 0 or die; + system ($cmd) == 0 or + die "convertpkg-compt32 returned non-zero exit status\n"; unlink $pkg; return get_pkg_name $tempfh; } @@ -645,7 +638,7 @@ sub do_slackbuild (%) { # remove work directories (source and packaging dirs under /tmp/SBo) sub make_clean ($$$) { - exists $_[1] or script_error 'make_clean requires two arguments.'; + exists $_[2] or script_error 'make_clean requires three arguments.'; my ($sbo, $src, $version) = @_; say "Cleaning for $sbo-$version..."; my $tmpsbo = "/tmp/SBo"; @@ -667,8 +660,8 @@ sub make_distclean (%) { } my $sbo = get_sbo_from_loc $args{LOCATION}; make_clean $sbo, $args{SRC}, $args{VERSION}; - say "Distcleaning for $sbo-$version..."; - # remove any distfiles for this particular SBo + say "Distcleaning for $sbo-$args{VERSION}..."; + # remove any distfiles for this particular SBo. my %downloads = get_sbo_downloads (LOCATION => $args{LOCATION}); for my $key (keys %downloads) { my $filename = get_filename_from_link $key; @@ -10,15 +10,11 @@ # license: WTFPL <http://sam.zoy.org/wtfpl/COPYING> use 5.12.3; +use strict; +use warnings FATAL => 'all'; use SBO::Lib; -use File::Basename; use Getopt::Std; use Text::Tabulate; -use warnings FATAL => 'all'; -use strict; - -my %config = %SBO::Lib::config; -my $self = basename ($0); my %options; getopts ('v',\%options); @@ -27,24 +23,35 @@ show_version && exit 0 if exists $options{v}; update_tree; -say "Checking for updated SlackBuilds..."; -my $updates = get_available_updates; - -# pretty formatting. -my @listing; -for my $up (@$updates) { - my $string = "$$up{name}-$$up{installed}"; - $string .= " < needs updating (SBo has $$up{update})\n"; - push @listing, $string; +# retrieve and format list of available updates +sub get_update_list () { + print "Checking for updated SlackBuilds...\n"; + my $updates = get_available_updates; + # pretty formatting. + my @listing; + for my $update (@$updates) { + my $string = "$$update{name}-$$update{installed}"; + $string .= " < needs updating (SBo has $$update{update})\n"; + push @listing, $string; + } + return \@listing; } -if (exists $listing[0]) { - my $tab = new Text::Tabulate (); - $tab->configure (tab => '\s'); - my $output = $tab->format (@listing); - say "\n". $output; -} else { - say "\nNo updates available."; +# Text::Tabulate and print list of updates +sub print_output ($) { + exists $_[0] or script_error 'print_output requires an argument'; + my $listing = shift; + if (exists $$listing[0]) { + my $tab = new Text::Tabulate (); + $tab->configure (tab => '\s'); + my $output = $tab->format (@$listing); + say "\n". $output; + } else { + say "\nNo updates available."; + } } +my $output = get_update_list; +print_output $output; + exit 0; @@ -10,14 +10,13 @@ # license: WTFPL <http://sam.zoy.org/wtfpl/COPYING> use 5.12.3; +use strict; +use warnings FATAL => 'all'; use SBO::Lib; use File::Basename; use Getopt::Std; use File::Path qw(remove_tree); -use strict; -use warnings FATAL => 'all'; -my %config = %SBO::Lib::config; my $self = basename ($0); sub show_usage () { @@ -64,7 +63,7 @@ sub remove_stuff ($) { } } -remove_stuff ($config{SBO_HOME} . '/distfiles') if $clean_dist; -remove_stuff ('/tmp/SBo') if $clean_work; +remove_stuff $config{SBO_HOME} . '/distfiles' if $clean_dist; +remove_stuff '/tmp/SBo' if $clean_work; exit 0; @@ -19,7 +19,6 @@ use File::Copy; use File::Path qw(make_path); use File::Temp qw(tempfile);; -my %config = %SBO::Lib::config; my $self = basename ($0); sub show_usage () { @@ -80,48 +79,50 @@ if (exists $changes{JOBS}) { ($changes{JOBS} =~ /^\d+$/ || $changes{JOBS} eq 'FALSE'); } -my $conf_dir = $SBO::Lib::conf_dir;; -my $conf_file = $SBO::Lib::conf_file; - -# safely modify our conf file; copy to a temp location, edit the temp file, -# move the edited file into place +# safely modify our conf file; write its contents to a temp file, modify the +# temp file, write the contents of the temp file back to the conf file sub config_write ($$) { exists $_[1] or script_error 'config_write requires two arguments.'; my ($key, $val) = @_; if (! -d $conf_dir) { - mkdir ($conf_dir) or die "Unable to create $conf_dir. Exiting.\n"; + mkdir $conf_dir or die "Unable to create $conf_dir. Exiting.\n"; } if (-f $conf_file) { - my $tempfh = tempfile (DIR => $SBO::Lib::tempdir); - my $tempfn = get_tmp_perlfn $tempfh; - copy ($conf_file, $tempfn); - # tie the file so that if $key is already there, we just change that - # line and untie it - tie my @temp, 'Tie::File', $tempfn; - my $has = 0; + my $tempfh = tempfile (DIR => $tempdir); + my $conffh = open_read $conf_file; + my $conftents = do {local $/; <$conffh>}; + print {$tempfh} $conftents; + # tie the temp file so that if $key is already there, we just change + # that line and untie it + tie my @temp, 'Tie::File', $tempfh; + my $has; my $regex = qr/\A\Q$key\E=/; FIRST: for my $tmpline (@temp) { $has++, $tmpline = "$key=$val", last FIRST if $tmpline =~ $regex; } untie @temp; # otherwise, append our new $key=$value pair - unless ($has) { - my $fh = open_fh ($tempfn, '>>'); - print {$fh} "$key=$val\n"; - close $fh; - } - move ($tempfn, $conf_file); + print {$tempfh} "$key=$val\n" unless $has; + # then over write the conf file with the contents of the temp file + seek $tempfh, 0, 0; + my $contents = do {local $/; <$tempfh>}; + close $conffh; + eval { $conffh = open_fh $conf_file, '>' }; + warn "Cannot write configuration: $@\n" and return if $@; + print {$conffh} $contents or return; + close $conffh, close $tempfh; } else { # no config file, easiest case of all. - my $fh = open_fh $conf_file, '>'; + my $fh = open_fh $conf_file, '>' or return; print {$fh} "$key=$val\n"; close $fh; } + return 1; } while (my ($key, $value) = each %changes) { say "Setting $key to $value..."; - config_write $key, $value; + config_write $key, $value or warn "Unable to write to $conf_file\n"; } exit 0; @@ -10,13 +10,12 @@ # license: WTFPL <http://sam.zoy.org/wtfpl/COPYING> use 5.12.3; +use strict; +use warnings FATAL => 'all'; use SBO::Lib; use File::Basename; use Getopt::Std; -use strict; -use warnings FATAL => 'all'; -my %config = %SBO::Lib::config; my $self = basename ($0); sub show_usage () { @@ -51,26 +50,31 @@ my $search = $ARGV[0]; slackbuilds_or_fetch; # find anything with $search in its name -my ($findings, $name); -my $found = 0; -my $name_regex = qr/NAME:\s+(.*\Q$search\E.*)$/i; -my $loc_regex = qr/LOCATION:\s+(.*)$/; -my $fh = open_read "$config{SBO_HOME}/SLACKBUILDS.TXT"; -FIRST: while (my $line = <$fh>) { - unless ($found) { - $found++, next FIRST if $name = ($line =~ $name_regex)[0]; - } else { - if (my ($location) = ($line =~ $loc_regex)[0]) { - $found = 0; - $location =~ s#^\.##; - push @$findings, {$name => $config{SBO_HOME} . $location}; +sub perform_search ($) { + exists $_[0] or script_error 'perform_search requires an argument.'; + my $search = shift; + my (@findings, $name, $found); + my $name_regex = qr/NAME:\s+(.*\Q$search\E.*)$/i; + my $loc_regex = qr/LOCATION:\s+(.*)$/; + my $fh = open_read "$config{SBO_HOME}/SLACKBUILDS.TXT"; + FIRST: while (my $line = <$fh>) { + unless ($found) { + $found++, next FIRST if $name = ($line =~ $name_regex)[0]; + } else { + if (my ($location) = ($line =~ $loc_regex)[0]) { + $found = 0; + $location =~ s#^\.##; + push @findings, {$name => $config{SBO_HOME} . $location}; + } } } + return \@findings; } +# pull the contents of a file into a variable and format it for output sub get_file_contents ($) { exists $_[0] or script_error 'get_file_contents requires an argument'; - -f $_[0] or script_error 'get_file_contents argument is not a file'; + -f $_[0] or return "$_[0] doesn't exist.\n"; my $fh = open_read shift; my $contents = do {local $/; <$fh>}; $contents =~ s/\n/\n /g; @@ -78,6 +82,8 @@ sub get_file_contents ($) { return $contents; } +perform_search $search; + # pretty formatting if (exists $$findings[0]) { my @listing = ("\n"); @@ -10,11 +10,11 @@ # license: WTFPL <http://sam.zoy.org/wtfpl/COPYING> use 5.12.3; +use strict; +use warnings FATAL => 'all'; use SBO::Lib; use Getopt::Std; use File::Basename; -use strict; -use warnings FATAL => 'all'; my $self = basename ($0); @@ -9,17 +9,14 @@ # author: Jacob Pipkin <j@dawnrazor.net> # date: Setting Orange, the 37th day of Discord in the YOLD 3178 # license: WTFPL <http://sam.zoy.org/wtfpl/COPYING> -# changelog: -# .01: initial creation. use 5.12.3; +use strict; +use warnings FATAL => 'all'; use SBO::Lib; use File::Basename; use Getopt::Std; -use warnings FATAL => 'all'; -use strict; -my %config = %SBO::Lib::config; my $sbo_home = $config{SBO_HOME}; my $self = basename ($0); @@ -10,14 +10,13 @@ # license: WTFPL <http://sam.zoy.org/wtfpl/COPYING> use 5.12.3; +use strict; +use warnings FATAL => 'all'; 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 () { @@ -96,8 +95,8 @@ sub get_inst_names ($) { } # this subroutine may be getting a little out of hand. -sub grok_requirements ($$) { - exists $_[1] or script_error 'grok_requirements requires two arguments'; +sub get_requires ($$) { + exists $_[1] or script_error 'get_requires requires two arguments'; return if $no_reqs; my ($sbo, $readme) = @_; my $readme_orig = $readme; @@ -133,58 +132,68 @@ sub grok_requirements ($$) { splice @deps, $rem, 1; $_-- for @remove; } - return unless exists $deps[0]; - FIRST: for my $need (@deps) { - # compare against installed slackbuilds - my $tempname = $compat32 eq 'TRUE' ? "$need-compat32" : $need; + return \@deps; + +# ask to install any requirements found +sub ask_requires ($$$) { + exists $_[2] or script_error 'ask_requires requires three arguments.'; + my ($requires, $readme, $sbo) = shift; + FIRST: for my $req (@$requires) { + my $name = $compat32 ? "$req-compat32" : $req; my $inst = get_installed_sbos; my $inst_names = get_inst_names $inst; - next FIRST if $tempname ~~ @$inst_names; - print "\n". $readme_orig; - print "\nIt looks like this slackbuild requires $tempname; shall I"; + next FIRST if $name ~~ @$inst_names; + say $readme; + print "\nIt looks like this slackbuild requires $name; shall I"; print " attempt to install it first? [y] "; if (<STDIN> =~ /^[Yy\n]/) { - my @args = ("/usr/sbin/sboupgrade", '-oN'); + 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}; + for my $arg (qw(c d p)) { + push @args, "-$arg" if exists $options{$arg}; + } push @args, "-j $options{j}" if exists $options{j}; - push @args, "-p" if $compat32; - push @args, $need; - system (@args) == 0 or - die "Requirement failure, unable to proceed.\n"; + system (@args, $req) == 0 or die "$name failed to install.\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'; +sub get_user_group ($) { + exists $_[0] or script_error 'get_user_group requires an argument'; my $readme = shift; - my $readme_array = [split /\n/, $readme]; - my $cmd_regex = qr/^\s*#\s+((user|group)add.*)/; - my @cmds; - push @cmds, ($_ =~ $cmd_regex)[0] for @$readme_array; - return unless exists $cmds[0]; + 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) = shift; say "\n". $readme; - print "\nIt looks like this slackbuild requires the following command(s)"; - say ' to be run first:'; - say " # $_" for @cmds; + 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"; + 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'; +sub get_opts ($) { + exists $_[0] or script_error 'get_opts requires an argument'; + my $readme = shift; + return $readme =~ /[A-Z]+=[^\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; - return unless $readme =~ /[A-Z]+=[^\s]/; say "\n". $readme; print "\nIt looks this slackbuilds has options; would you like to set any"; print " when the slackbuild is run? [n] "; @@ -196,10 +205,10 @@ sub grok_options ($) { return $opts; }; my $kv_regex = qr/[A-Z]+=[^\s]+(|\s([A-Z]+=[^\s]+){0,})/; - my $opts = &$ask (); + my $opts = &$ask; FIRST: while ($opts !~ $kv_regex) { warn "Invalid input received.\n"; - $opts = &$ask (); + $opts = &$ask; } return $opts; } @@ -213,10 +222,15 @@ sub readme_prompt ($) { my $fh = open_read (get_readme_path $sbo); my $readme = do {local $/; <$fh>}; close $fh; - # check for requirements, useradd/groupadd, options - grok_requirements $sbo, $readme; - grok_user_group $readme; - my $opts = grok_options $readme; + # check for requirements, offer to install any found + my $requires = get_requires $sbo, $readme; + ask_requires $requires, $readme, $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 ref $user_group eq 'ARRAY'; + # check for options mentioned in the README + my $opts; + $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; @@ -229,7 +243,7 @@ sub readme_prompt ($) { sub process_sbos ($) { exists $_[0] or script_error 'process_sbos requires an argument.'; my $todo = shift; - my @failures; + my %failures; FIRST: for my $sbo (@$todo) { my $opts = 0; $opts = readme_prompt $sbo unless $no_readme; @@ -243,7 +257,7 @@ sub process_sbos ($) { COMPAT32 => $compat32, ); }; if ($@) { - push @failures, $sbo; + $failures{$sbo} = $@; } else { unless ($distclean eq 'TRUE') { make_clean $sbo, $src, $version unless $noclean eq 'TRUE'; @@ -272,13 +286,16 @@ sub process_sbos ($) { } } } - return @failures; + return %failures; } -sub print_failures (;@) { +sub print_failures (;%) { if (exists $_[0]) { + my %failures = @_; say "Failures:"; - say " $_" for @_; + while (my ($key, $val) = each %failures) { + say " $key: $val"; + } exit 1; } } @@ -306,20 +323,20 @@ unless ($force) { push @$todo_upgrade, $sbo if $sbo ~~ @$inst_names; } } -my @failures = process_sbos $todo_upgrade if exists $$todo_upgrade[0]; -print_failures @failures; +my %failures = process_sbos $todo_upgrade if exists $$todo_upgrade[0]; +print_failures %failures; 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 = get_installed_sbos; my $inst_names = get_inst_names $inst;; warn "$name already installed\n", 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 = 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"; @@ -334,7 +351,7 @@ FIRST: for my $sbo (@ARGV) { } push @$todo_install, $sbo; } -@failures = process_sbos $todo_install if exists $$todo_install[0]; -print_failures @failures; +%failures = process_sbos $todo_install if exists $$todo_install[0]; +print_failures %failures; exit 0; diff --git a/t/SBO/Lib.pm b/t/SBO/Lib.pm deleted file mode 100644 index 20be10b..0000000 --- a/t/SBO/Lib.pm +++ /dev/null @@ -1,686 +0,0 @@ -#!/usr/bin/env perl -# -# vim: set ts=4:noet -# -# Lib.pm -# shared functions for the sbo_ scripts. -# -# author: Jacob Pipkin <j@dawnrazor.net> -# date: Setting Orange, the 37th day of Discord in the YOLD 3178 -# license: WTFPL <http://sam.zoy.org/wtfpl/COPYING> - -use 5.12.3; -use warnings FATAL => 'all'; -use strict; - -package SBO::Lib 0.7; -my $version = "0.7"; - -require Exporter; -our @ISA = qw(Exporter); -our @EXPORT = qw(get_slack_version chk_slackbuilds_txt check_home rsync_sbo_tree get_sbo_from_loc get_sbo_version get_download_info get_arch get_sbo_downloads get_filename_from_link compute_md5sum compare_md5s verify_distfile get_distfile get_symlink_from_filename check_x32 check_multilib rewrite_slackbuild revert_slackbuild check_distfiles create_symlinks grok_temp_file get_src_dir get_pkg_name clear_coe_bit perform_sbo do_convertpkg - script_error - open_fh - open_read - show_version - slackbuilds_or_fetch - fetch_tree - update_tree - get_installed_sbos - get_available_updates - do_slackbuild - make_clean - make_distclean - do_upgradepkg - get_sbo_location - get_from_info - get_tmp_extfn - get_tmp_perlfn -); - -#$< == 0 or die "This script requires root privileges.\n"; - -use Tie::File; -use Sort::Versions; -use Digest::MD5; -use File::Copy; -use File::Path qw(make_path remove_tree); -use Fcntl; -use File::Find; -use File::Temp qw(tempdir tempfile); -use Fcntl qw(F_SETFD F_GETFD); - -our $tempdir = tempdir (CLEANUP => 1); - -# subroutine for throwing internal script errors -sub script_error (;$) { - exists $_[0] ? die "A fatal script error has occurred:\n$_[0]\nExiting.\n" - : die "A fatal script error has occurred: Exiting.\n"; -} - -# sub for opening files, second arg is like '<','>', etc -sub open_fh { - exists $_[1] or script_error ('open_fh requires two arguments'); - unless ($_[1] eq '>') { - -f $_[0] or script_error 'open_fh first argument not a file'; - } - my ($file, $op) = @_; - open my $fh, $op, $file or die "Unable to open $file.\n"; - return $fh; -} - -sub open_read ($) { - return open_fh shift, '<'; -} - -# pull in configuration, set sane defaults, etc. -our $conf_dir = '/etc/sbotools'; -our $conf_file = "$conf_dir/sbotools.conf"; -our %config = ( - NOCLEAN => 'FALSE', - DISTCLEAN => 'FALSE', - JOBS => 'FALSE', - PKG_DIR => 'FALSE', - SBO_HOME => 'FALSE', -); - -# if the conf file exists, pull all the $key=$value pairs into a hash -my %conf_values; -if (-f $conf_file) { - my $fh = open_read ($conf_file); - my $text = do {local $/; <$fh>}; - %conf_values = $text =~ /^(\w+)=(.*)$/mg; - close $fh; -} - -for my $key (keys %config) { - $config{$key} = $conf_values{$key} if exists $conf_values{$key}; -} -$config{JOBS} = 'FALSE' unless $config{JOBS} =~ /^\d+$/; -$config{SBO_HOME} = '/usr/sbo' if $config{SBO_HOME} eq 'FALSE'; - -# some stuff we'll need later. -my $distfiles = "$config{SBO_HOME}/distfiles"; -my $slackbuilds_txt = "$config{SBO_HOME}/SLACKBUILDS.TXT"; -my $name_regex = '\ASLACKBUILD\s+NAME:\s+'; - -sub show_version () { - say "sbotools version $version"; - say "licensed under the WTFPL"; - say "<http://sam.zoy.org/wtfpl/COPYING>"; -} - -# %supported maps what's in /etc/slackware-version to what's at SBo -sub get_slack_version () { - my %supported = ( - '13.37.0' => '13.37', - '14.0' => '13.37', - ); - my $fh = open_read '/etc/slackware-version'; - chomp (my $line = <$fh>); - close $fh; - my $version = ($line =~ /\s+(\d+[^\s]+)$/)[0]; - die "Unsupported Slackware version: $version\n" - unless $version ~~ %supported; - return $supported{$version}; -} - -# does the SLACKBUILDS.TXT file exist in the sbo tree? -sub chk_slackbuilds_txt () { - return -f $slackbuilds_txt ? 1 : 0; -} - -# check for the validity of new $config{SBO_HOME} -sub check_home () { - my $sbo_home = $config{SBO_HOME}; - if (-d $sbo_home) { - opendir (my $home_handle, $sbo_home); - FIRST: while (readdir $home_handle) { - next FIRST if /^\.[\.]{0,1}$/; - die "$sbo_home exists and is not empty. Exiting.\n"; - } - } else { - make_path ($sbo_home) or die "Unable to create $sbo_home.\n"; - } -} - -# rsync the sbo tree from slackbuilds.org to $config{SBO_HOME} -sub rsync_sbo_tree () { - my $slk_version = get_slack_version; - my @arg = ('rsync', '-a', '--exclude=*.tar.gz', '--exclude=*.tar.gz.asc'); - push @arg, "rsync://slackbuilds.org/slackbuilds/$slk_version/*"; - my $out = system @arg, $config{SBO_HOME}; - say "Finished." and return $out; -} - -# wrappers for differing checks and output -sub fetch_tree () { - check_home; - say "Pulling SlackBuilds tree..."; - rsync_sbo_tree, return 1; -} - -sub update_tree () { - fetch_tree, return unless chk_slackbuilds_txt; - say "Updating SlackBuilds tree..."; - rsync_sbo_tree, return 1; -} - -# if the SLACKBUILDS.TXT is not in $config{SBO_HOME}, we assume the tree has -# not been populated there; prompt the user to automagickally pull the tree. -sub slackbuilds_or_fetch () { - unless (chk_slackbuilds_txt) { - say 'It looks like you haven\'t run "sbosnap fetch" yet.'; - print "Would you like me to do this now? [y] "; - <STDIN> =~ /^[Yy\n]/ ? fetch_tree () : - die "Please run \"sbosnap fetch\"\n"; - } - return 1; -} - -# pull an array of hashes, each hash containing the name and version of an sbo -# currently installed. -sub get_installed_sbos () { - my @installed; - # $1 == name, $2 == version - my $regex = qr#/([^/]+)-([^-]+)-[^-]+-[^-]+$#; - for my $path (</var/log/packages/*_SBo>) { - my ($name, $version) = ($path =~ $regex)[0,1]; - push @installed, {name => $name, version => $version}; - } - return \@installed; -} - -# search the SLACKBUILDS.TXT for a given sbo's directory -sub get_sbo_location ($) { - exists $_[0] or script_error 'get_sbo_location requires an argument.'; - my $sbo = shift; - my $regex = qr#LOCATION:\s+\.(/[^/]+/$sbo)$#; - my $fh = open_read $slackbuilds_txt; - while (my $line = <$fh>) { - if (my $loc = ($line =~ $regex)[0]) { - return "$config{SBO_HOME}$loc"; - } - } - return; -} - -# pull the sbo name from a $location: $config{SBO_HOME}/system/wine, etc. -sub get_sbo_from_loc ($) { - exists $_[0] or script_error 'get_sbo_from_loc requires an argument.'; - return (shift =~ qr#/([^/]+)$#)[0]; -} - -# pull piece(s) of data, GET, from the $sbo.info file under LOCATION. -sub get_from_info (%) { - my %args = ( - LOCATION => '', - GET => '', - @_ - ); - unless ($args{LOCATION} && $args{GET}) { - script_error 'get_from_info requires LOCATION and GET.'; - } - state $vars = {PRGNAM => ['']}; - my $sbo = get_sbo_from_loc $args{LOCATION}; - return $$vars{$args{GET}} if $$vars{PRGNAM}[0] eq $sbo; - # if we're here, we haven't read in the .info file yet. - my $fh = open_read "$args{LOCATION}/$sbo.info"; - # suck it all in, clean it all up, stuff it all in $vars. - my $contents = do {local $/; <$fh>}; - $contents =~ s/("|\\\n)//g; - $vars = {$contents =~ /^(\w+)=(.*)$/mg}; - # fill the hash with array refs - even for single values, - # since consistency here is a lot easier than sorting it out later - for my $key (keys %$vars) { - if ($$vars{$key} =~ /\s/) { - my @array = split ' ', $$vars{$key}; - $$vars{$key} = \@array; - } else { - $$vars{$key} = [$$vars{$key}]; - } - } - return exists $$vars{$args{GET}} ? $$vars{$args{GET}} : 0; -} - -# find the version in the tree for a given sbo (provided a location) -sub get_sbo_version ($) { - exists $_[0] or script_error 'get_sbo_version requires an arguments'; - my $version = get_from_info (LOCATION => shift, GET => 'VERSION'); - return $$version[0] ? $$version[0] : 0; -} - -# for each installed sbo, find out whether or not the version in the tree is -# newer, and compile an array of hashes containing those which are -sub get_available_updates () { - my @updates; - my $pkg_list = get_installed_sbos; - FIRST: for my $key (keys @$pkg_list) { - my $location = get_sbo_location $$pkg_list[$key]{name}; - # if we can't find a location, assume invalid and skip - next FIRST unless defined $location; - my $version = get_sbo_version $location; - if (versioncmp ($version, $$pkg_list[$key]{version}) == 1) { - push @updates, { - name => $$pkg_list[$key]{name}, - installed => $$pkg_list[$key]{version}, - update => $version - }; - } - } - return \@updates; -} - -# get downloads and md5sums from an sbo's .info file, first -# checking for x86_64-specific info if we are told to -sub get_download_info (%) { - my %args = ( - LOCATION => 0, - X64 => 1, - @_ - ); - $args{LOCATION} or script_error 'get_download_info requires LOCATION.'; - my ($get, $downs, $md5s, %return); - $get = ($args{X64} ? 'DOWNLOAD_x86_64' : 'DOWNLOAD'); - $downs = get_from_info (LOCATION => $args{LOCATION}, GET => $get); - # did we get nothing back, or UNSUPPORTED/UNTESTED? - if ($args{X64}) { - my $nothing; - if (! $$downs[0]) { - $nothing = 1; - } elsif ($$downs[0] =~ qr/^UN(SUPPOR|TES)TED$/) { - $nothing = 1; - } - if ($nothing) { - $args{X64} = 0; - $downs = get_from_info (LOCATION => $args{LOCATION}, - GET => 'DOWNLOAD'); - } - } - # if we still don't have any links, something is really wrong. - return unless $$downs[0]; - # grab the md5s and build a hash - $get = $args{X64} ? 'MD5SUM_x86_64' : 'MD5SUM'; - $md5s = get_from_info (LOCATION => $args{LOCATION}, GET => $get); - return unless $$md5s[0]; - $return{$$downs[$_]} = $$md5s[$_] for (keys @$downs); - return %return; -} - -sub get_arch () { - chomp (my $arch = `uname -m`); - return $arch; -} - -# TODO: should probably combine this with get_download_info -sub get_sbo_downloads (%) { - my %args = ( - LOCATION => '', - 32 => 0, - @_ - ); - $args{LOCATION} or script_error 'get_sbo_downloads requires LOCATION.'; - my $location = $args{LOCATION}; - -d $location or script_error 'get_sbo_downloads given a non-directory.'; - my $arch = get_arch; - my %dl_info; - if ($arch eq 'x86_64') { - %dl_info = get_download_info (LOCATION => $location) unless $args{32}; - } - unless (keys %dl_info > 0) { - %dl_info = get_download_info (LOCATION => $location, X64 => 0); - } - return %dl_info; -} - -# given a link, grab the filename from the end of it -sub get_filename_from_link ($) { - exists $_[0] or script_error 'get_filename_from_link requires an argument'; - return "$distfiles/". (shift =~ qr#/([^/]+)$#)[0]; -} - -# for a given file, computer its md5sum -sub compute_md5sum ($) { - -f $_[0] or script_error 'compute_md5sum requires a file argument.'; - my $fh = open_read shift; - my $md5 = Digest::MD5->new; - $md5->addfile ($fh); - my $md5sum = $md5->hexdigest; - close $fh; - return $md5sum; -} - -sub compare_md5s ($$) { - exists $_[1] or script_error 'compare_md5s requires two arguments.'; - my ($first, $second) = @_; - return $first eq $second ? 1 : 0; -} - -# for a given distfile, see whether or not it exists, and if so, if its md5sum -# matches the sbo's .info file -sub verify_distfile ($$) { - exists $_[1] or script_error 'check_distfile requires two arguments.'; - my ($link, $info_md5sum) = @_; - my $filename = get_filename_from_link $link; - return unless -d $distfiles; - return unless -f $filename; - my $md5sum = compute_md5sum $filename; - return compare_md5s $info_md5sum, $md5sum; -} - -# for a given distfile, attempt to retrieve it and, if successful, check its -# md5sum against that in the sbo's .info file -sub get_distfile ($$) { - exists $_[1] or script_error 'get_distfile requires an argument'; - my ($link, $exp_md5) = @_; - my $filename = get_filename_from_link $link; - mkdir $distfiles unless -d $distfiles; - chdir $distfiles; - system ("wget --no-check-certificate $link") == 0 or - die "Unable to wget $link\n"; - my $md5sum = compute_md5sum $filename; - # can't do anything if the link in the .info doesn't lead to a good d/l - compare_md5s $md5sum, $exp_md5 or die "md5sum failure for $filename.\n"; - return 1; -} - -# for a given distfile, what will be the full path of the symlink? -sub get_symlink_from_filename ($$) { - exists $_[1] or script_error - 'get_symlink_from_filename requires two arguments'; - -f $_[0] or script_error - 'get_symlink_from_filename first argument is not a file'; - my ($filename, $location) = @_; - return "$location/". ($filename =~ qr#/([^/]+)$#)[0]; -} - -# determine whether or not a given sbo is 32-bit only -sub check_x32 ($) { - exists $_[0] or script_error 'check_x32 requires an argument.'; - my $dl = get_from_info (LOCATION => shift, GET => 'DOWNLOAD_x86_64'); - return $$dl[0] =~ /UN(SUPPOR|TES)TED/ ? 1 : 0; -} - -# can't do 32-bit on x86_64 without this file, so we'll use it as the test to -# to determine whether or not an x86_64 system is setup for multilib -sub check_multilib { - return 1 if -f '/etc/profile.d/32dev.sh'; - return; -} - -# make a backup of the existent SlackBuild, and rewrite the original as needed -sub rewrite_slackbuild ($$%) { - exists $_[1] or script_error 'rewrite_slackbuild requires two arguments.'; - my ($slackbuild, $tempfn, %changes) = @_; - copy ($slackbuild, "$slackbuild.orig") or - die "Unable to backup $slackbuild to $slackbuild.orig\n"; - my $tar_regex = qr/(un|)tar .*$/; - my $makepkg_regex = qr/makepkg/; - my $libdir_regex = qr/^\s*LIBDIRSUFFIX="64"\s*$/; - my $make_regex = qr/^\s*make(| \Q||\E exit 1)$/; - my $arch_regex = qr/\$VERSION-\$ARCH-\$BUILD/; - # tie the slackbuilds, because this is the easiest way to handle this. - tie my @sb_file, 'Tie::File', $slackbuild; - for my $line (@sb_file) { - # get the output of the tar and makepkg commands. hope like hell that v - # is specified among tar's arguments - if ($line =~ $tar_regex || $line =~ $makepkg_regex) { - $line = "$line | tee -a $tempfn"; - } - # then check for and apply any %changes - if (exists $changes{libdirsuffix}) { - $line =~ s/64/$changes{libdirsuffix}/ if $line =~ $libdir_regex; - } - if (exists $changes{make}) { - $line =~ s/make/make $changes{make}/ if $line =~ $make_regex; - } - if (exists $changes{arch_out}) { - $line =~ s/\$ARCH/$changes{arch_out}/ if $line =~ $arch_regex; - } - } - untie @sb_file; - return 1; -} - -# move a backed-up .SlackBuild file back into place -sub revert_slackbuild ($) { - exists $_[0] or script_error 'revert_slackbuild requires an argument'; - my $slackbuild = shift; - if (-f "$slackbuild.orig") { - unlink $slackbuild if -f $slackbuild; - rename "$slackbuild.orig", $slackbuild; - } - return 1; -} - -# for each $download, see if we have it, and if the copy we have is good, -# otherwise download a new copy -sub check_distfiles (%) { - exists $_[0] or script_error 'check_distfiles requires an argument.'; - my %dists = @_; - for my $link (keys %dists) { - my $md5sum = $dists{$link}; - unless (verify_distfile $link, $md5sum) { - die unless get_distfile $link, $md5sum; - } - } - return 1; -} - -# given a location and a list of download links, assemble a list of symlinks, -# and create them. -sub create_symlinks ($%) { - exists $_[1] or script_error 'create_symlinks requires two arguments.'; - my ($location, %downloads) = @_; - my @symlinks; - for my $link (keys %downloads) { - my $filename = get_filename_from_link $link; - my $symlink = get_symlink_from_filename $filename, $location; - push @symlinks, $symlink; - symlink $filename, $symlink; - } - return @symlinks; -} - -# pull the untarred source directory or created package name from the temp -# file (the one we tee'd to) -sub grok_temp_file (%) { - my %args = ( - FH => '', - REGEX => '', - CAPTURE => 0, - @_ - ); - unless ($args{FH} && $args{REGEX}) { - script_error 'grok_temp_file requires two arguments'; - } - my $fh = $args{FH}; - seek $fh, 0, 0; - my $out; - FIRST: while (my $line = <$fh>) { - if ($line =~ $args{REGEX}) { - $out = ($line =~ $args{REGEX})[$args{CAPTURE}]; - last FIRST; - } - } - return $out; -} - -# wrappers around grok_temp_file -sub get_src_dir ($) { - exists $_[0] or script_error 'get_src_dir requires an argument'; - return grok_temp_file (FH => shift, REGEX => qr#^([^/]+)/#); -} - -sub get_pkg_name ($) { - exists $_[0] or script_error 'get_pkg_name requires an argument'; - return grok_temp_file (FH => shift, - REGEX => qr/^Slackware\s+package\s+([^\s]+)\s+created\.$/); -} - -# clear the close-on-exec bit from a temp file handle -sub clear_coe_bit ($) { - exists $_[0] or script_error 'clear_coe_bit requires an argument'; - my $fh = shift; - fcntl ($fh, F_SETFD, 0) or die "no unset exec-close thingy\n"; - return $fh; -} - -# return a filename from a temp fh for use externally -sub get_tmp_extfn ($) { - exists $_[0] or script_error 'get_tmp_extfn requires an argument.'; - my $fh = clear_coe_bit shift; - return '/dev/fd/'. fileno $fh; -} - -# return a filename from a temp fh for use internally -sub get_tmp_perlfn ($) { - exists $_[0] or script_error 'get_tmp_perlfn requires an argument.'; - my $fh = clear_coe_bit shift; - return '+<=&'. fileno $fh; -} - -# prep and run .SlackBuild -sub perform_sbo (%) { - my %args = ( - OPTS => 0, - JOBS => 0, - LOCATION => '', - ARCH => '', - C32 => 0, - X32 => 0, - @_ - ); - unless ($args{LOCATION} && $args{ARCH}) { - script_error 'perform_sbo requires LOCATION and ARCH.'; - } - my $location = $args{LOCATION}; - my $sbo = get_sbo_from_loc $location; - my ($cmd, %changes); - # figure out any changes we need to make to the .SlackBuild - $changes{make} = "-j $args{JOBS}" if $args{JOBS}; - if ($args{ARCH} eq 'x86_64' and ($args{C32} || $args{X32})) { - if ($args{C32}) { - $changes{libdirsuffix} = ''; - } elsif ($args{X32}) { - $changes{arch_out} = 'i486'; - } - $cmd = ". /etc/profile.d/32dev.sh &&"; - } - $cmd .= "/bin/sh $location/$sbo.SlackBuild"; - $cmd = "$args{OPTS} $cmd" if $args{OPTS}; - my $tempfh = tempfile (DIR => $tempdir); - my $fn = get_tmp_extfn $tempfh; - rewrite_slackbuild "$location/$sbo.SlackBuild", $fn, %changes; - chdir $location, my $out = system $cmd; - revert_slackbuild "$location/$sbo.SlackBuild"; - die unless $out == 0; - my $pkg = get_pkg_name $tempfh; - my $src = get_src_dir $tempfh; - return $pkg, $src; -} - -# run convertpkg on a package to turn it into a -compat32 thing -sub do_convertpkg ($) { - exists $_[0] or script_error 'do_convertpkg requires an argument.'; - my $pkg = shift; - my $tempfh = tempfile (DIR => $tempdir); - my $fn = get_tmp_extfn $tempfh; - my $cmd = "/usr/sbin/convertpkg-compat32 -i $pkg -d /tmp | tee $fn"; - system ($cmd) == 0 or die; - unlink $pkg; - return get_pkg_name $tempfh; -} - -# "public interface", sort of thing. -sub do_slackbuild (%) { - my %args = ( - OPTS => 0, - JOBS => 0, - LOCATION => '', - COMPAT32 => 0, - @_ - ); - $args{LOCATION} or script_error 'do_slackbuild requires LOCATION.'; - my $location = $args{LOCATION}; - my $sbo = get_sbo_from_loc $location; - my $arch = get_arch; - my $multi = check_multilib; - my $version = get_sbo_version $location; - my $x32; - # ensure x32 stuff is set correctly, or that we're setup for it - if ($args{COMPAT32}) { - die "compat32 only works on x86_64.\n" unless $arch eq 'x86_64'; - die "compat32 requires multilib.\n" unless $multi; - die "compat32 requires /usr/sbin/convertpkg-compat32.\n" - unless -f '/usr/sbin/convertpkg-compat32'; - } else { - if ($arch eq 'x86_64') { - $x32 = check_x32 $args{LOCATION}; - if ($x32 && ! $multi) { - die "$sbo is 32-bit which requires multilib on x86_64.\n"; - } - } - } - # get a hash of downloads and md5sums, ensure we have 'em, symlink 'em - my %downloads = get_sbo_downloads ( - LOCATION => $location, - 32 => $args{COMPAT32} - ); - check_distfiles %downloads; - my @symlinks = create_symlinks $args{LOCATION}, %downloads; - # setup and run the .SlackBuild itself - my ($pkg, $src) = perform_sbo ( - OPTS => $args{OPTS}, - JOBS => $args{JOBS}, - LOCATION => $location, - ARCH => $arch, - C32 => $args{COMPAT32}, - X32 => $x32, - ); - do_convertpkg $pkg if $args{COMPAT32}; - unlink $_ for @symlinks; - return $version, $pkg, $src; -} - -# remove work directories (source and packaging dirs under /tmp/SBo) -sub make_clean ($$$) { - exists $_[1] or script_error 'make_clean requires two arguments.'; - my ($sbo, $src, $version) = @_; - say "Cleaning for $sbo-$version..."; - my $tmpsbo = "/tmp/SBo"; - remove_tree ("$tmpsbo/$src") if -d "$tmpsbo/$src"; - remove_tree ("$tmpsbo/package-$sbo") if -d "$tmpsbo/package-$sbo"; - return 1; -} - -# remove distfiles -sub make_distclean (%) { - my %args = ( - SRC => '', - VERSION => '', - LOCATION => '', - @_ - ); - unless ($args{SRC} && $args{VERSION} && $args{LOCATION}) { - script_error 'make_distclean requires four arguments.'; - } - my $sbo = get_sbo_from_loc $args{LOCATION}; - make_clean $sbo, $args{SRC}, $args{VERSION}; - say "Distcleaning for $sbo-$version..."; - # remove any distfiles for this particular SBo - my %downloads = get_sbo_downloads (LOCATION => $args{LOCATION}); - for my $key (keys %downloads) { - my $filename = get_filename_from_link $key; - unlink $filename if -f $filename; - } - return 1; -} - -# run upgradepkg for a created package -sub do_upgradepkg ($) { - exists $_[0] or script_error 'do_upgradepkg requires an argument.'; - system ('/sbin/upgradepkg', '--reinstall', '--install-new', shift); - return 1; -} - @@ -1,5 +1,6 @@ #!/usr/bin/perl +use 5.16.0; use strict; use warnings FATAL => 'all'; use File::Copy; @@ -8,6 +9,52 @@ use Tie::File; chomp (my $pwd = `pwd`); mkdir "$pwd/SBO" unless -d "$pwd/SBO"; copy ('/home/d4wnr4z0r/projects/sbotools/SBO-Lib/lib/SBO/Lib.pm', "$pwd/SBO"); + +open my $write, '>>', "$pwd/SBO/Lib.pm"; + +sub pr ($) { + my $thing = shift; + print {$write} "our \$$thing = 1;\n"; +} + +for my $thing (qw(interactive compat32 no_readme jobs distclean noclean no_install no_reqs)) { + pr $thing; +} + +print {$write} "my \%locations;\n"; +print {$write} "my \%options = (nothing => 'to see here');\n"; + +sub get_subs ($) { + my $read = shift; + my $begin_regex = qr/^sub\s+[a-z0-9_]+/; + my $usage_regex = qr/^sub\s+show_usage/; + my $end_regex = qr/^}$/; + my $begin = 0; + my $end = 0; + while (my $line = <$read>) { + if (! $begin) { + if ($line =~ $begin_regex) { + if ($line !~ $usage_regex) { + $end = 0, $begin++, print {$write} $line; + } + } + } elsif (! $end) { + if ($line =~ $end_regex) { + $begin = 0, $end++, print {$write} $line; + } else { + print {$write} $line; + } + } + } +} + +for my $file (qw(sbocheck sboclean sboconfig sbofind sboupgrade)) { + open my $read, '<', "../$file"; + get_subs $read; + close $read; +} +close $write; + my @subs; open my $file_h, '<', "$pwd/SBO/Lib.pm"; my $regex = qr/^sub\s+([^\s]+)\s+/; @@ -1,31 +1,49 @@ -#!/usr/bin/perl -I/home/d4wnr4z0r/projects/sbotools/t +#!/usr/bin/env perl use 5.16.0; use strict; use warnings FATAL => 'all'; use File::Temp qw(tempdir tempfile); -use Test::More tests => 39; +use Test::More tests => 87; +use File::Copy; +use Text::Diff; +use lib "."; use SBO::Lib; -ok (defined $SBO::Lib::tempdir, '$tempdir is defined'); +my $sbo_home = '/home/d4wnr4z0r/sbo.git/slackbuilds'; -my $fh = open_read ('/home/d4wnr4z0r/projects/sbotools/t/test.t'); -ok (ref ($fh) eq 'GLOB', 'open_read works'); +# 1, open_read, open_fh tests +my $fh = open_read ('./test.t'); +is (ref $fh, 'GLOB', 'open_read works'); close $fh; -ok ($SBO::Lib::config{DISTCLEAN} eq 'FALSE', 'config{DISTCLEAN} is good'); -ok ($SBO::Lib::config{JOBS} == 2, 'config{JOBS} is good'); -ok ($SBO::Lib::config{NOCLEAN} eq 'TRUE', 'config{NOCLEAN} is good'); -ok ($SBO::Lib::config{PKG_DIR} eq 'FALSE', 'config{PKG_DIR} is good'); -ok ($SBO::Lib::config{SBO_HOME} eq '/usr/sbo', 'config{SBO_HOME} is good'); +# 2-7, config settings tests; +ok (defined $SBO::Lib::tempdir, '$tempdir is defined'); +is ($SBO::Lib::config{DISTCLEAN}, 'FALSE', 'config{DISTCLEAN} is good'); +is ($SBO::Lib::config{JOBS}, 2, 'config{JOBS} is good'); +is ($SBO::Lib::config{NOCLEAN}, 'FALSE', 'config{NOCLEAN} is good'); +is ($SBO::Lib::config{PKG_DIR}, 'FALSE', 'config{PKG_DIR} is good'); +is ($SBO::Lib::config{SBO_HOME}, "$sbo_home", 'config{SBO_HOME} is good'); + +# 8, show_version test +is (show_version, 1, 'show_version is good'); + +# 9, get_slack_version test +is (get_slack_version, '14.0', 'get_slack_version is good'); + +# 10-11, chk_slackbuilds_txt tests +is (chk_slackbuilds_txt, 1, 'chk_slackbuilds_txt is good'); +move ("$sbo_home/SLACKBUILDS.TXT", "$sbo_home/SLACKBUILDS.TXT.moved"); +is (chk_slackbuilds_txt, undef, 'chk_slackbuilds_txt returns false with no SLACKBUILDS.TXT'); +move ("$sbo_home/SLACKBUILDS.TXT.moved", "$sbo_home/SLACKBUILDS.TXT"); -ok (show_version == 1, 'show_version is good'); -ok (get_slack_version eq '13.37', 'get_slack_version is good'); -ok (chk_slackbuilds_txt == 1, 'check_slackbuilds_txt is good'); #ok (rsync_sbo_tree == 1, 'rsync_sbo_tree is good'); #ok (update_tree == 1, 'update_tree is good'); -ok (slackbuilds_or_fetch == 1, 'slackbuilds_or_fetch is good'); +# 12, slackbuilds_or_fetch test +is (slackbuilds_or_fetch, 1, 'slackbuilds_or_fetch is good'); + +# 13-18, get_installed_sbos test print "pseudo-random sampling of get_installed_sbos output...\n"; my $installed = get_installed_sbos; for my $key (keys @$installed) { @@ -38,48 +56,67 @@ for my $key (keys @$installed) { } print "completed pseudo-random testing of get_installed_sbos \n"; -is (get_sbo_location 'nginx', '/usr/sbo/network/nginx', 'get_sbo_location is good'); +# 19-20, get_sbo_location tests +is (get_sbo_location 'nginx', "$sbo_home/network/nginx", 'get_sbo_location is good'); +is (get_sbo_location 'omgwtfbbq', undef, 'get_sbo_location returns false with not-an-sbo input'); +# 21-22, get_available_updates tests my $updates = get_available_updates; for my $key (keys @$updates) { is ($$updates[$key]{installed}, '1.15', '$$updates[$key]{installed} good for mutagen') if $$updates[$key]{name} eq 'mutagen'; is ($$updates[$key]{update}, '1.20', '$$updates[$key]{update} good for mutagen') if $$updates[$key]{name} eq 'mutagen'; } -ok (get_arch eq 'x86_64', 'get_arch is good'); +# 23, get_arch test +is (get_arch, 'x86_64', 'get_arch is good'); -my %dl_info = get_download_info (LOCATION => '/usr/sbo/system/wine', X64 => 0); +# 24-25, get_download_info tests +my %dl_info = get_download_info (LOCATION => "$sbo_home/system/wine", X64 => 0); my $link = 'http://downloads.sf.net/wine/source/1.4/wine-1.4.1.tar.bz2'; is ($dl_info{$link}, '0c28702ed478df7a1c097f3a9c4cabd6', 'get_download_info test 01 good.'); $link = 'http://www.unrealize.co.uk/source/dibeng-max-2010-11-12.zip'; is ($dl_info{$link}, '97159d77631da13952fe87e846cf1f3b', 'get_download_info test 02 good.'); -%dl_info = get_sbo_downloads (LOCATION => '/usr/sbo/system/wine'); +# 26-28, get_sbo_downloads tests +%dl_info = get_sbo_downloads (LOCATION => "$sbo_home/system/wine"); $link = 'http://downloads.sf.net/wine/source/1.4/wine-1.4.1.tar.bz2'; is ($dl_info{$link}, '0c28702ed478df7a1c097f3a9c4cabd6', 'get_sbo_downloads test 01 good.'); $link = 'http://www.unrealize.co.uk/source/dibeng-max-2010-11-12.zip'; is ($dl_info{$link}, '97159d77631da13952fe87e846cf1f3b', 'get_sbo_downloads test 02 good.'); - -my %downloads = get_sbo_downloads (LOCATION => '/usr/sbo/system/ifuse'); +my %downloads = get_sbo_downloads (LOCATION => "$sbo_home/system/ifuse"); $link = 'http://www.libimobiledevice.org/downloads/ifuse-1.1.1.tar.bz2'; is ($downloads{$link}, '8d528a79de024b91f12f8ac67965c37c', 'get_sbo_downloads test 03 good.'); -is (get_filename_from_link 'http://www.libimobiledevice.org/downloads/ifuse-1.1.1.tar.bz2', '/usr/sbo/distfiles/ifuse-1.1.1.tar.bz2', 'get_file_from_link good'); -is (compute_md5sum '/usr/sbo/distfiles//laptop-mode-tools_1.61.tar.gz', '6685af5dbb34c3d51ca27933b58f484e', 'compute_md5sum good'); -is ((verify_distfile '/usr/sbo/distfiles/laptop-mode-tools_1.61.tar.gz', '6685af5dbb34c3d51ca27933b58f484e'), 1, 'verify_distfile good'); -is (get_sbo_version '/usr/sbo/system/wine', '1.4.1', 'get_sbo_version good'); -is ((get_symlink_from_filename '/usr/sbo/distfiles/laptop-mode-tools_1.61.tar.gz', '/usr/sbo/system/laptop-mode-tools'), '/usr/sbo/system/laptop-mode-tools/laptop-mode-tools_1.61.tar.gz', 'get_symlink_from_filename good'); -ok (check_x32 '/usr/sbo/system/wine', 'check_x32 true for 32-bit only wine'); -ok (!(check_x32 '/usr/sbo/system/ifuse'), 'check_x32 false for not-32-bit-only ifuse'); -ok (check_multilib, 'check_multilib good'); +# 29, get_filename_from_link test +is (get_filename_from_link 'http://www.libimobiledevice.org/downloads/ifuse-1.1.1.tar.bz2', "$sbo_home/distfiles/ifuse-1.1.1.tar.bz2", 'get_file_from_link good'); +is (get_filename_from_link 'adf;lkajsdfaksjdfalsdjfalsdkfjdsfj', undef, 'get_filename_from_link good with invalid input'); + +# 31, compute_md5sum test +is (compute_md5sum "$sbo_home/distfiles/laptop-mode-tools_1.61.tar.gz", '6685af5dbb34c3d51ca27933b58f484e', 'compute_md5sum good'); -# TODO: find a way to write a test for rewrite_slackbuild, revert_slackbuild. +# 32, verify_distfile test +is ((verify_distfile "$sbo_home/distfiles/laptop-mode-tools_1.61.tar.gz", '6685af5dbb34c3d51ca27933b58f484e'), 1, 'verify_distfile good'); -%downloads = get_sbo_downloads (LOCATION => '/usr/sbo/system/wine', 32 => 1); -my @symlinks = create_symlinks '/usr/sbo/system/wine', %downloads; -is ($symlinks[0], '/usr/sbo/system/wine/wine-1.4.1.tar.bz2', '$symlinks[0] good for create_symlinks'); -is ($symlinks[1], '/usr/sbo/system/wine/dibeng-max-2010-11-12.zip', '$symlinks[1] good for create_symlinks'); +# 33, get_sbo_version test +is (get_sbo_version "$sbo_home/system/wine", '1.4.1', 'get_sbo_version good'); +# 34, get_symlink_from_filename test +is ((get_symlink_from_filename "$sbo_home/distfiles/laptop-mode-tools_1.61.tar.gz", "$sbo_home/system/laptop-mode-tools"), "$sbo_home/system/laptop-mode-tools/laptop-mode-tools_1.61.tar.gz", 'get_symlink_from_filename good'); + +# 35-36, check_x32 tests +ok (check_x32 "$sbo_home/system/wine", 'check_x32 true for 32-bit only wine'); +ok (!(check_x32 "$sbo_home/system/ifuse"), 'check_x32 false for not-32-bit-only ifuse'); + +# 37, check_multilib tests +ok (check_multilib, 'check_multilib good'); + +# 38-39, create_symlinks tests +%downloads = get_sbo_downloads (LOCATION => "$sbo_home/system/wine", 32 => 1); +my @symlinks = create_symlinks "$sbo_home/system/wine", %downloads; +is ($symlinks[0], "$sbo_home/system/wine/wine-1.4.1.tar.bz2", '$symlinks[0] good for create_symlinks'); +is ($symlinks[1], "$sbo_home/system/wine/dibeng-max-2010-11-12.zip", '$symlinks[1] good for create_symlinks'); + +# 40-41, grok_temp_file, get_src_dir/get_pkg_name tests my $tempdir = tempdir (CLEANUP => 1); my $tempfh = tempfile (DIR => $tempdir); my $lmt = 'laptop-mode-tools_1.60'; @@ -87,9 +124,162 @@ print {$tempfh} "$lmt/COPYING\n"; print {$tempfh} "$lmt/Documentation/\n"; print {$tempfh} "$lmt/README\n"; print {$tempfh} "Slackware package skype-2.2.0.35-i486-1_SBo.tgz created.\n"; -#close $tempfh; is (get_src_dir $tempfh, 'laptop-mode-tools_1.60', 'get_src_dir good'); is (get_pkg_name $tempfh, 'skype-2.2.0.35-i486-1_SBo.tgz', 'get_pkg_name good'); -%downloads = get_sbo_downloads (LOCATION => '/usr/sbo/system/wine', 32 => 1); +close $tempfh; + +# 42, check_distfiles test +%downloads = get_sbo_downloads (LOCATION => "$sbo_home/system/wine", 32 => 1); is ((check_distfiles %downloads), 1, 'check_distfiles good'); -#is (do_convertpkg ($package), "$package-compat32", 'do_convertpkg good'); + +# 43-45, check_home tests +system ('sudo /usr/sbin/sboconfig -s /home/d4wnr4z0r/opt_sbo') == 0 or die "unable to set sboconfig -s\n"; +read_config; +ok (check_home, 'check_home returns true with new non-existent directory'); +ok (-d '/home/d4wnr4z0r/opt_sbo', 'check_home creates $config{SBO_HOME}'); +ok (check_home, 'check_home returns true with new existent empty directory'); +system ("sudo /usr/sbin/sboconfig -s $sbo_home") == 0 or die "unable to reset sboconfig -s\n"; +read_config; +rmdir "/home/d4wnr4z0r/opt_sbo"; + +# 46-47 get_sbo_from_loc tests +is (get_sbo_from_loc '/home/d4wnr4z0r/sbo.git/system/ifuse', 'ifuse', 'get_sbo_from_loc returns correctly with valid input'); +ok (! get_sbo_from_loc 'omg_wtf_bbq', 'get_sbo_from_loc returns false with invalid input'); + +# 48-49, compare_md5s tests +is (compare_md5s ('omgwtf123456789', 'omgwtf123456789'), 1, 'compare_md5s returns true for matching parameters'); +is (compare_md5s ('omgwtf123456788', 'somethingelsebbq'), undef, 'compare_md5s returns false for not-matching parameters'); + +# 50, get_distfile tests +my $distfile = "$sbo_home/distfiles/Sort-Versions-1.5.tar.gz"; +unlink $distfile if -f $distfile; +is (get_distfile ('http://search.cpan.org/CPAN/authors/id/E/ED/EDAVIS/Sort-Versions-1.5.tar.gz', '5434f948fdea6406851c77bebbd0ed19'), 1, 'get_distfile is good'); +unlink $distfile; + +# 51-58, rewrite_slackbuilds/revert_slackbuild tests +my $rewrite_dir = tempdir (CLEANUP => 1); +copy ("$sbo_home/system/ifuse/ifuse.SlackBuild", $rewrite_dir); +my $slackbuild = "$rewrite_dir/ifuse.SlackBuild"; +$tempfh = tempfile (DIR => $rewrite_dir); +my $tempfn = get_tmp_extfn $tempfh; +my %changes; +is (rewrite_slackbuild ($slackbuild, $tempfn, %changes), 1, 'rewrite_slackbuild with no %changes good'); +ok (-f "$slackbuild.orig", 'rewrite_slackbuild backing up original is good.'); +my $expected_out = "67c67 +< tar xvf \$CWD/\$PRGNAM-\$VERSION.tar.bz2 +--- +> tar xvf \$CWD/\$PRGNAM-\$VERSION.tar.bz2 | tee -a $tempfn +103c103 +< /sbin/makepkg -l y -c n \$OUTPUT/\$PRGNAM-\$VERSION-\$ARCH-\$BUILD\$TAG.\${PKGTYPE:-tgz} +--- +> /sbin/makepkg -l y -c n \$OUTPUT/\$PRGNAM-\$VERSION-\$ARCH-\$BUILD\$TAG.\${PKGTYPE:-tgz} | tee -a $tempfn +"; +is (diff ("$slackbuild.orig", $slackbuild, {STYLE => 'OldStyle'}), $expected_out, 'tar line rewritten correctly'); +is (revert_slackbuild $slackbuild, 1, 'revert_slackbuild is good'); +$changes{libdirsuffix} = ''; +$changes{make} = '-j 5'; +$changes{arch_out} = 'i486'; +is (rewrite_slackbuild ($slackbuild, $tempfn, %changes), 1, 'rewrite_slackbuild with all %changes good'); +ok (-f "$slackbuild.orig", 'rewrite_slackbuild backing up original is good.'); +$expected_out = "55c55 +< LIBDIRSUFFIX=\"64\" +--- +> LIBDIRSUFFIX=\"\" +67c67 +< tar xvf \$CWD/\$PRGNAM-\$VERSION.tar.bz2 +--- +> tar xvf \$CWD/\$PRGNAM-\$VERSION.tar.bz2 | tee -a $tempfn +87c87 +< make +--- +> make -j 5 +103c103 +< /sbin/makepkg -l y -c n \$OUTPUT/\$PRGNAM-\$VERSION-\$ARCH-\$BUILD\$TAG.\${PKGTYPE:-tgz} +--- +> /sbin/makepkg -l y -c n \$OUTPUT/\$PRGNAM-\$VERSION-i486-\$BUILD\$TAG.\${PKGTYPE:-tgz} | tee -a $tempfn +"; +is (diff ("$slackbuild.orig", $slackbuild, {STYLE => 'OldStyle'}), $expected_out, 'all changed lines rewritten correctly'); +is (revert_slackbuild $slackbuild, 1, 'revert_slackbuild is good again'); + +# 59-61, get_from_info tests +my $test_loc = "$sbo_home/system/ifuse"; +my %params = (LOCATION => $test_loc); +my $info = get_from_info (%params, GET => 'VERSION'); +is ($$info[0], '1.1.1', 'get_from_info GET => VERSION is good'); +$info = get_from_info (%params, GET => 'HOMEPAGE'); +is ($$info[0], 'http://www.libimobiledevice.org', 'get_from_info GET => HOMEPAGE is good'); +$info = get_from_info (%params, GET => 'DOWNLOAD_x86_64'); +is ($$info[0], "", 'get_from_info GET => DOWNLOAD_x86_64 is good'); + +# 62-64, get_update_list tests +my $listing = get_update_list; +s/\s//g for @$listing; +for my $item (@$listing) { + is ($item, 'zdoom-2.5.0<needsupdating(SBohas2.6.0)', 'get_update_list output good for zdoom') if $item =~ /^zdoom/; + is ($item, 'ffmpeg-0.8.7<needsupdating(SBohas0.11.1)', 'get_update_list output good for ffmpeg') if $item =~ /^ffmpeg/; + is ($item, 'atkmm-2.22.4<needsupdating(SBohas2.22.6)', 'get_update_list output good for atkmm') if $item =~ /^atkmm/; +} + +# 65, remove_stuff test - can only really test for invalid input +is (remove_stuff '/omg/wtf/bbq', 1, 'remove_stuff good for invalid input'); + +# 66, config_write test +is (config_write ('OMG', 'WTF'), undef, 'config_write returned undef correctly'); + +# 67-74, perform_search tests +my $findings = perform_search 'desktop'; +for my $found (@$findings) { + for my $key (keys %$found) { + my $section = 'desktop';; + if ($key eq 'libdesktop-agnostic') { + $section = 'libraries'; + } elsif ($key eq 'mendeleydesktop') { + $section = 'academic'; + } elsif ($key eq 'gtk-recordmydesktop' || $key eq 'huludesktop') { + $section = 'multimedia'; + } elsif ($key eq 'gnome-python-desktop') { + $section = 'python'; + } + is ($$found{$key}, "$sbo_home/$section/$key", 'perform_search good for $search eq desktop'); + } +} + +# 75, get_inst_names test +$installed = get_installed_sbos; +my $inst_names = get_inst_names $installed; +ok ('zdoom' ~~ @$inst_names, 'get_inst_names is good'); + +# 76-81, get_reqs tests +$SBO::Lib::no_reqs = 0; +ok (! (get_requires 'stops', "$sbo_home/audio/stops"), 'get_requires good for circular requirements'); +ok (! (get_requires 'smc', "$sbo_home/games/smc"), 'get_requires good for REQUIRES="%README%"'); +ok (! (get_requires 'krb5', "$sbo_home/network/krb5"), 'get_requires good for REQUIRES=""'); +my $reqs = get_requires 'matchbox-desktop', "$sbo_home/desktop/matchbox-desktop"; +my $say = 'get_requires good for normal req list'; +is ($$reqs[0], 'libmatchbox', $say); +is ($$reqs[1], 'matchbox-window-manager', $say); +is ($$reqs[2], 'matchbox-common', $say); + +# 82-85, get_user_group tests +$fh = open_read "$sbo_home/network/nagios/README"; +my $readme = do {local $/; <$fh>}; +close $fh; +my $cmds = get_user_group $readme; +is ($$cmds[0], 'groupadd -g 213 nagios', 'get_user_group good for # groupadd'); +is ($$cmds[1], 'useradd -u 213 -d /dev/null -s /bin/false -g nagios nagios', 'get_user_group for # useradd'); +$fh = open_read "$sbo_home/network/havp/README"; +$readme = do {local $/; <$fh>}; +close $fh; +$cmds = get_user_group $readme; +is ($$cmds[0], 'groupadd -g 210 clamav', 'get_user_group good for groupadd'); +is ($$cmds[1], 'useradd -u 256 -d /dev/null -s /bin/false -g clamav havp', 'get_user_group good for useradd'); + +# 86-87, get_opts test +$fh = open_read "$sbo_home/games/vbam/README"; +$readme = do {local $/; <$fh>}; +close $fh; +ok (get_opts $readme, 'get_opts good where README defines opts'); +$fh = open_read "$sbo_home/libraries/libmatchbox/README"; +$readme = do {local $/; <$fh>}; +close $fh; +ok (! (get_opts $readme), 'get_opts good where README does not define opts'); |