diff options
-rw-r--r-- | SBO-Lib/lib/SBO/Lib.pm | 49 | ||||
-rwxr-xr-x | sbocheck | 87 | ||||
-rwxr-xr-x | t/01-test.t | 8 | ||||
-rwxr-xr-x | t/13-local-check.t | 38 |
4 files changed, 140 insertions, 42 deletions
diff --git a/SBO-Lib/lib/SBO/Lib.pm b/SBO-Lib/lib/SBO/Lib.pm index 20f9f04..c767c7e 100644 --- a/SBO-Lib/lib/SBO/Lib.pm +++ b/SBO-Lib/lib/SBO/Lib.pm @@ -55,6 +55,9 @@ our @EXPORT_OK = qw( usage_error uniq is_local + get_orig_location + get_orig_version + get_local_outdated_versions in $tempdir $conf_dir @@ -426,6 +429,7 @@ sub get_inst_names { # a state variable for get_sbo_location and get_sbo_locations my $store = {}; my %local; + my %orig; sub get_sbo_location { exists $_[0] or script_error('get_sbo_location requires an argument.'); @@ -475,6 +479,7 @@ sub get_sbo_locations { my $loc = "$local/$sbo"; next unless -d $loc; $$store{$sbo} = $loc; + $orig{$sbo} //= $locations{$sbo}; $locations{$sbo} = $loc; $local{$sbo} = $local; } @@ -490,6 +495,45 @@ sub is_local { get_sbo_location($sbo); return !!$local{$sbo}; } + +sub get_orig_location { + exists $_[0] or script_error('get_orig_location requires an argument.'); + my $sbo = shift; + # Make sure we have checked for the slackbuild in question: + get_sbo_location($sbo); + return $orig{$sbo}; +} + +sub get_orig_version { + exists $_[0] or script_error('get_orig_version requires an argument.'); + my $sbo = shift; + + my $location = get_orig_location($sbo); + + return $location if not defined $location; + + return get_sbo_version($location); +} + +sub get_local_outdated_versions { + my @outdated; + + my $local = $config{LOCAL_OVERRIDES}; + unless ( $local eq 'FALSE' ) { + my $pkglist = get_installed_packages('SBO'); + my @local = grep { is_local($_->{name}) } @$pkglist; + + foreach my $sbo (@local) { + my $orig = get_orig_version($sbo->{name}); + next if not defined $orig; + next if not versioncmp($orig, $sbo->{version}); + + push @outdated, { %$sbo, orig => $orig }; + } + } + + return @outdated; +} } # pull the sbo name from a $location: $repo_path/system/wine, etc. @@ -508,9 +552,9 @@ sub get_from_info { unless ($args{LOCATION} && $args{GET}) { script_error('get_from_info requires LOCATION and GET.'); } - state $store = {PRGNAM => ['']}; + state $store = {LOCATION => ['']}; my $sbo = get_sbo_from_loc($args{LOCATION}); - return $store->{$args{GET}} if $store->{PRGNAM}[0] eq $sbo; + return $store->{$args{GET}} if $store->{LOCATION}[0] eq $args{LOCATION}; # if we're here, we haven't read in the .info file yet. my ($fh, $exit) = open_read("$args{LOCATION}/$sbo.info"); return() if $exit; @@ -519,6 +563,7 @@ sub get_from_info { $contents =~ s/("|\\\n)//g; my $last_key = ''; $store = {}; + $store->{LOCATION} = [$args{LOCATION}]; foreach my $line (split /\n/, $contents) { my ($key, $val) = $last_key; if ($line =~ /^([^=\s]+)=(.*)$/) { $key = $1; $val = $2; } @@ -13,10 +13,11 @@ use 5.16.0; use strict; use warnings FATAL => 'all'; -use SBO::Lib qw/ update_tree get_available_updates script_error open_fh is_local show_version /; +use SBO::Lib qw/ update_tree get_available_updates script_error open_fh is_local show_version get_local_outdated_versions /; use Getopt::Long; use File::Basename; use List::Util 'max'; +use Data::Dumper; my $self = basename($0); @@ -45,36 +46,68 @@ update_tree(); # retrieve and format list of available updates sub get_update_list { print "Checking for updated SlackBuilds...\n"; - my $updates = get_available_updates(); - return() unless exists $$updates[0]; - # consistent formatting - determine longest version string, which will tell - # us the max minimum length of the left side of the output for stuff that - # fits in 80 chars; stuff that doesn't will overflow. - my @up_lengths; - push @up_lengths, length $$updates[$_]{update} for keys @$updates; - my $up_length = max @up_lengths; - # "needs updating" bit without version is 30 characters - my $remaining = 80 - ($up_length + 44); - my @lengths; - push @lengths, length "$$updates[$_]{name}-$$updates[$_]{installed}" - for keys @$updates; - my @s_lengths = sort {$b <=> $a} @lengths; - my $min; - FIRST: for my $len (@s_lengths) { - if ($len < $remaining) { - $min = $len; - last FIRST; + my @updates = @{ get_available_updates() }; + my @outdated = get_local_outdated_versions(); + return() unless @outdated + @updates; + + my %updates; + for my $update (@updates) { + $updates{$update->{name}} = { + installed => $update->{installed}, + available => $update->{update}, + local => is_local($update->{name}) + }; + } + for my $update (@outdated) { + my $name = $update->{name}; + $updates{$name}{installed} //= $update->{version}; + $updates{$name}{sbo} = $update->{orig}; + $updates{$name}{local} = 1; + } + +# Output should look like this where the < is aligned to the longest sboname 1.0 string (excepting ones that would then wrap): +# sboname 1.0 < needs updating (1.1 from overrides) +# sboname 1.0 < needs updating (1.1 from SBo) +# sboname 1.0 < needs updating (1.1 from overrides, 1.2 from SBo) +# sboname 1.0 < override outdated (1.1 from SBo) + + my $max = 0; + foreach my $sbo (keys %updates) { + my $info = $updates{$sbo}; + my $current = sprintf "%s %s", $sbo, $info->{installed}; + + my $available = ''; + if (defined $info->{available} and defined $info->{sbo}) { + $available = sprintf "needs updating (%s from overrides, %s from SBo)", $info->{available}, $info->{sbo}; + } + elsif ($info->{available}) { + $available = sprintf "needs updating (%s from %s)", $info->{available}, $info->{local} ? "overrides" : "SBo"; + } + else { + $available = sprintf "override outdated (%s from SBo)", $info->{sbo}; + } + $info->{name_str} = $current; + $info->{upd_str} = $available; + + my $str = sprintf "%s < %s", $current, $available; + if (length($str) < 80) { + $max = length($current) if length($current) > $max; } } - $min = $remaining unless $min; my @listing; - for my $update (@$updates) { - my $name = sprintf "%s %s", $$update{name}, $$update{installed}; - my $upd = "SBo has %s"; - if (is_local($$update{name})) { $upd = "%s from local overrides"; } - push(@listing, sprintf "%-${min}s < needs updating ($upd)", - $name, $$update{update}); + foreach my $sbo (sort keys %updates) { + my $info = $updates{$sbo}; + + my $str = sprintf "%s < %s", $info->{name_str}, $info->{upd_str}; + if (length($str) < 80) { + $str = sprintf "%-*s < %s", $max, $info->{name_str}, $info->{upd_str}; + my $adjust = 1; + while (length($str) > 80) { + $str = sprintf "%-*s < %s", $max-$adjust++, $info->{name_str}, $info->{upd_str}; + } + } + push @listing, $str; } return \@listing; } diff --git a/t/01-test.t b/t/01-test.t index f1f9117..153e438 100755 --- a/t/01-test.t +++ b/t/01-test.t @@ -399,10 +399,10 @@ sub { my $listing; stdout_is(sub { $listing = get_update_list(); }, "Checking for updated SlackBuilds...\n", 'output of get_update_list() good'); s/\s//g for @$listing; - is (shift(@$listing), 'adobe-reader9.5.1_enu<needsupdating(SBohas9.5.1)', 'get_update_list listing good for adobe-reader'); - is (shift(@$listing), 'ffmpeg0.8.7<needsupdating(SBohas0.11.1)', 'get_update_list listing good for ffmpeg'); - is (shift(@$listing), 'libdvdnav4.1.3<needsupdating(SBohas4.2.0)', 'get_update_list listing test, libdvdnav'); - is (shift(@$listing), 'mutagen1.15<needsupdating(SBohas1.20)', 'get_update_list listing good for mutagen'); + is (shift(@$listing), 'adobe-reader9.5.1_enu<needsupdating(9.5.1fromSBo)', 'get_update_list listing good for adobe-reader'); + is (shift(@$listing), 'ffmpeg0.8.7<needsupdating(0.11.1fromSBo)', 'get_update_list listing good for ffmpeg'); + is (shift(@$listing), 'libdvdnav4.1.3<needsupdating(4.2.0fromSBo)', 'get_update_list listing test, libdvdnav'); + is (shift(@$listing), 'mutagen1.15<needsupdating(1.20fromSBo)', 'get_update_list listing good for mutagen'); }; # 47: remove_stuff test - can only really test for invalid input diff --git a/t/13-local-check.t b/t/13-local-check.t index 130ee2e..38d94a4 100755 --- a/t/13-local-check.t +++ b/t/13-local-check.t @@ -10,20 +10,21 @@ use lib $RealBin; use lib "$RealBin/../SBO-Lib/lib"; use Test::Execute; -if ($ENV{TEST_INSTALL}) { - plan tests => 0; +if ($ENV{TEST_INSTALL} and $ENV{TRAVIS}) { + plan tests => 2; } else { - plan skip_all => 'Only run these tests if TEST_INSTALL=1'; + plan skip_all => "Only run these tests if TEST_INSTALL=1 and we're running under Travis CI"; } $path = "$RealBin/../"; sub cleanup { capture_merged { - system(qw!/sbin/removepkg ...!); - unlink "$RealBin/LO-.../.../perf.dummy"; - system(qw!rm -rf /tmp/SBo/...-1.0!); - system(qw!rm -rf /tmp/package-...!); + system(qw!/sbin/removepkg nonexistentslackbuild!); + unlink "$RealBin/LO/nonexistentslackbuild/perf.dummy"; + system(qw!rm -rf /tmp/SBo/nonexistentslackbuild-1.0!); + system(qw!rm -rf /tmp/package-nonexistentslackbuild!); + system(qw!rm -rf!, "$RealBin/gitrepo"); }; } @@ -47,10 +48,21 @@ sub set_lo { $lo //= 'FALSE'; note "Saving original value of LOCAL_OVERRIDES: $lo"; $set = 1; - script (qw/ sboconfig -o /, "$RealBin/LO-...", { test => 0 }); + script (qw/ sboconfig -o /, "$RealBin/LO", { test => 0 }); } } +sub setup_gitrepo { + capture_merged { system(<<"END"); }; + cd "$RealBin"; rm -rf gitrepo; mkdir gitrepo; cd gitrepo; + git init; + + mkdir -p "test/nonexistentslackbuild"; + cp "$RealBin/LO2/nonexistentslackbuild/nonexistentslackbuild.info" "test/nonexistentslackbuild" + git add "test"; git commit -m 'initial'; +END +} + sub set_repo { state $set = 0; state $orig; @@ -73,9 +85,17 @@ sub set_repo { cleanup(); make_slackbuilds_txt(); set_lo(); +setup_gitrepo(); set_repo(); -# 1: ... +script (qw/ sbosnap fetch /, { test => 0 }); + +# 1: sbocheck without having installed nonexistentslackbuild should not show it +script (qw/ sbocheck /, { expected => sub { $_[0] !~ /nonexistentslackbuild/ } }); + +# 2: sbocheck should list nonexistentslackbuild as being newer on SBo after we've installed it +script (qw/ sboinstall nonexistentslackbuild /, { input => "y\ny", test => 0 }); +script (qw/ sbocheck /, { expected => qr/nonexistentslackbuild/ }); # Cleanup END { |