App-newver
view release on metacpan or search on metacpan
lib/App/newver/Scanner.pm view on Meta::CPAN
package App::newver::Scanner;
use 5.016;
use strict;
use warnings;
our $VERSION = '0.02';
use Exporter qw(import);
our @EXPORT_OK = qw(scan_version);
use HTML::TreeBuilder 5 -weak;
use LWP::UserAgent;
use URI;
use App::newver::Version qw(version_compare);
our $user_agent = "newver/$VERSION (perl $^V; $^O)";
our $MAYBE_VERSION_RX = qr/v?(?<Version>[0-9a-zA-Z._\-+~:,;]+)/;
sub scan_version {
my %params = @_;
my $program = $params{ program }
// die "required parameter 'program' missing";
my $version = $params{ version }
// die "required parameter 'version' missing";
my $match = $params{ match }
// die "required parameter 'match' missing";
my $page = $params{ page }
// die "required parameter 'page' missing";
$match =~ s/\@VERSION\@/$MAYBE_VERSION_RX/g
or die "Match regex missing '\@VERSION\@'\n";
$match = qr/$match/;
my $ua = LWP::UserAgent->new;
$ua->agent($user_agent);
my $req = HTTP::Request->new(GET => $page);
my $res = $ua->request($req);
if (not $res->is_success) {
die sprintf "Error fetching %s: %s\n", $page, $res->status_line;
}
my $content = $res->decoded_content;
my $tree = HTML::TreeBuilder->new_from_content($content);
my @as = $tree->look_down(_tag => "a", sub { defined $_[0]->attr('href') });
if (!@as) {
die qq{Found no <a href="..."> elements in $page\n};
}
my $greatest;
for my $ae (@as) {
my $href = $ae->attr('href');
$href =~ $match or next;
my $ver = $+{ Version };
if (not defined $greatest or version_compare($ver, $greatest->[1]) == 1) {
$greatest = [ $href, $ver ];
}
}
if (not defined $greatest) {
die "Found no matches in $page\n";
}
if (version_compare($greatest->[1], $version) != 1) {
return undef;
}
return {
program => $program,
version => $greatest->[1],
url => URI->new_abs($greatest->[0], $page)->as_string,
};
}
1;
=head1 NAME
App::newver::Scanner - Scan webpage for new software versions
=head1 SYNOPSIS
use App::newver::Scanner qw(scan_version);
my $scan = scan_version(
program => 'perl',
version => '5.16',
page => 'https://github.com/Perl/perl5/tags',
match => 'v@VERSION@.tar.gz',
);
=head1 DESCRIPTION
B<App::newver::Scanner> is a module that provides the C<scan_version()>
subroutine for scanning software's upstream webpages for new software versions.
This is a private module, please consult the L<newver> manual for user
documentation.
=head1 SUBROUTINES
No subroutines are exported by default.
( run in 2.364 seconds using v1.01-cache-2.11-cpan-600a1bdf6e4 )