package SBO::Lib::Pkgs; use 5.016; use strict; use warnings; our $VERSION = '2.4'; use SBO::Lib::Util qw/ %config script_error open_read version_cmp /; use SBO::Lib::Tree qw/ get_sbo_location get_sbo_locations is_local /; use SBO::Lib::Info qw/ get_orig_version get_sbo_version /; use Exporter 'import'; our @EXPORT_OK = qw{ get_available_updates get_inst_names get_installed_cpans get_installed_packages get_local_outdated_versions }; our %EXPORT_TAGS = ( all => \@EXPORT_OK, ); =pod =encoding UTF-8 =head1 NAME SBO::Lib::Pkgs - Routines for interacting with the Slackware package database. =head1 SYNOPSIS use SBO::Lib::Pkgs qw/ get_installed_packages /; my @installed_sbos = get_installed_packages('SBO'); =head1 SUBROUTINES =cut my $pkg_db = '/var/log/packages'; =head2 get_available_updates my @updates = @{ get_available_updates() }; C compares the installed versions in C that are tagged as SBo with the version available from the SlackBuilds.org or C repository, and returns an array reference to an array of hash references which specify package names, and installed and available versions. =cut # 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_packages('SBO'); for my $pkg (@$pkg_list) { my $location = get_sbo_location($pkg->{name}); next unless $location; my $version = get_sbo_version($location); if (version_cmp($version, $pkg->{version}) != 0) { push @updates, { name => $pkg->{name}, installed => $pkg->{version}, update => $version }; } } return \@updates; } =head2 get_inst_names my @names = get_inst_names(get_available_updates()); C returns a list of package names from an array reference such as the one returned by C. =cut # for a ref to an array of hashes of installed packages, return an array ref # consisting of just their names sub get_inst_names { script_error('get_inst_names requires an argument.') unless @_ == 1; my $inst = shift; my @installed; push @installed, $$_{name} for @$inst; return \@installed; } =head2 get_installed_cpans my @cpans = @{ get_installed_cpans() }; C returns an array reference to a list of the perl modules installed from the CPAN rather than from packages on SlackBuilds.org. =cut # return a list of perl modules installed via the CPAN sub get_installed_cpans { my @contents; for my $file (grep { -f $_ } map { "$_/perllocal.pod" } @INC) { my ($fh, $exit) = open_read($file); next if $exit; push @contents, grep {/Module/} <$fh>; close $fh; } my $mod_regex = qr/C\s+L<([^\|]+)/; my (@mods, @vers); for my $line (@contents) { push @mods, ($line =~ $mod_regex)[0]; } return \@mods; } =head2 get_installed_packages my @packages = @{ get_installed_packages($type) }; C returns an array reference to a list of packages in C that match the specified C<$type>. The available types are C for non-SBo packages, C for SBo packages, and C for both. The returned array reference will hold a list of hash references representing both names, versions, and full installed package name of the returned packages. =cut # pull an array of hashes, each hash containing the name and version of a # package currently installed. Gets filtered using STD, SBO or ALL. sub get_installed_packages { script_error('get_installed_packages requires an argument.') unless @_ == 1; my $filter = shift; # Valid types: STD, SBO my (@pkgs, %types); foreach my $pkg (glob("$pkg_db/*")) { $pkg =~ s!^\Q$pkg_db/\E!!; my ($name, $version, $build) = $pkg =~ m#^([^/]+)-([^-]+)-[^-]+-([^-]+)$# or next; push @pkgs, { name => $name, version => $version, build => $build, pkg => $pkg }; $types{$name} = 'STD'; } # If we want all packages, let's just return them all return [ map { +{ name => $_->{name}, version => $_->{version}, pkg => $_->{pkg} } } @pkgs ] if $filter eq 'ALL'; # Otherwise, mark the SBO ones and filter my @sbos = map { $_->{name} } grep { $_->{build} =~ m/_SBo(|compat32)$/ } @pkgs; if (@sbos) { my %locations = get_sbo_locations(map { s/-compat32//gr } @sbos); foreach my $sbo (@sbos) { $types{$sbo} = 'SBO' if $locations{ $sbo =~ s/-compat32//gr }; } } return [ map { +{ name => $_->{name}, version => $_->{version}, pkg => $_->{pkg} } } grep { $types{$_->{name}} eq $filter } @pkgs ]; } =head2 get_local_outdated_versions my @outdated = get_local_outdated_versions(); C checks the installed SBo packages and returns a list of the ones for which the C version is different to the the version on SlackBuilds.org. =cut 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 version_cmp($orig, $sbo->{version}); push @outdated, { %$sbo, orig => $orig }; } } return @outdated; } =head1 AUTHORS SBO::Lib was originally written by Jacob Pipkin with contributions from Luke Williams and Andreas Guldstrand . =head1 LICENSE The sbotools are licensed under the WTFPL . Copyright (C) 2012-2017, Jacob Pipkin, Luke Williams, Andreas Guldstrand. =cut 1;