summaryrefslogtreecommitdiffabout
path: root/lib/SlackBuild
authorSergey Poznyakoff <gray@gnu.org.ua>2019-03-20 12:50:47 (GMT)
committer Sergey Poznyakoff <gray@gnu.org.ua>2019-03-20 13:57:30 (GMT)
commita297c865dd4611c4fd862e59c70ba1b72a142035 (patch) (side-by-side diff)
tree1751891a3b93a8ce8a2260e0be9ddf8d9e90f6a0 /lib/SlackBuild
parenta6040f631367a33f4e96759ce6ceefb759303f25 (diff)
downloadslackbuilder-a297c865dd4611c4fd862e59c70ba1b72a142035.tar.gz
slackbuilder-a297c865dd4611c4fd862e59c70ba1b72a142035.tar.bz2
Rewrite request loader.v1.0-
* lib/SlackBuild/Request.pm (load): New method. (new): Fall back to load() if given one argument. * lib/SlackBuild/Request/Auto.pm: Remove. * lib/SlackBuild/Request/Loader/dir.pm: New file. * lib/SlackBuild/Request/Loader/file.pm: New file. * lib/SlackBuild/Request/Loader/sbo.pm: New file. * lib/SlackBuild/Request/Loader/url.pm: New file. * slackbuilder: Use SlackBuild::Request->new instead of SlackBuild::Request::Auto->new * t/request.t: More tests.
Diffstat (limited to 'lib/SlackBuild') (more/less context) (ignore whitespace changes)
-rw-r--r--lib/SlackBuild/Request.pm108
-rw-r--r--lib/SlackBuild/Request/Auto.pm106
-rw-r--r--lib/SlackBuild/Request/Loader/dir.pm21
-rw-r--r--lib/SlackBuild/Request/Loader/file.pm25
-rw-r--r--lib/SlackBuild/Request/Loader/sbo.pm15
-rw-r--r--lib/SlackBuild/Request/Loader/url.pm22
6 files changed, 177 insertions, 120 deletions
diff --git a/lib/SlackBuild/Request.pm b/lib/SlackBuild/Request.pm
index 6b8e132..4ae81d3 100644
--- a/lib/SlackBuild/Request.pm
+++ b/lib/SlackBuild/Request.pm
@@ -4,12 +4,13 @@ use warnings;
use Carp;
use SlackBuild::URI;
use Text::ParseWords;
use JSON;
use File::Basename;
use Safe;
+use feature 'state';
=head1 NAME
SlackBuild::Request - slackbuild request object
=head1 DESCRIPTION
@@ -196,21 +197,12 @@ my %generics = (
$self->{$attr} = $value;
}
}
}
);
-sub _readfile {
- my ($self,$file) = @_;
- local $/ = undef;
- open(my $fd, $file) or croak "can't open file $file: $!";
- my $string = <$fd>;
- close $fd;
- decode_json($string);
-}
-
sub strategy {
my ($self, $attr) = @_;
if ($attr) {
if (exists($self->{strategy}) && exists($self->{strategy}{$attr})) {
return $self->{strategy}{$attr};
}
@@ -237,41 +229,129 @@ sub set_strategy {
new SlackBuild::Request(ATTR => VALUE,...)
Build the request from the supplied attribute/value pairs. Allowed attributes
are discussed in detail in the B<ATTRIBUTES> section. Empty argument list
is OK.
- new SlackBuild::Request($file)
+ new SlackBuild::Request($URL)
-Read the request from the disk file B<$file>. The file must contain a single
-request formatted as JSON. No empty lines or comments are allowed.
+Loads request from the $URL. This is equivalent to
+ load SlackBuild::Request($URL)
+
+See the description of B<load>, below.
+
=cut
sub new {
- my $self = bless {}, shift;
+ my $class = shift;
my %a;
if (@_ == 1) {
my $file = shift;
if (ref($file) eq 'HASH') {
%a = %$file;
} else {
- %a = %{$self->_readfile($file)}
+ %a = return $class->load($file);
}
} elsif (@_ % 2) {
croak "bad number of arguments";
} else {
%a = @_;
}
+ my $self = bless {}, $class;
while (my ($k,$v) = each %a) {
$self->${\ "set_$k"}($v);
}
return $self;
}
+=head2 load
+
+ $req = load SlackBuild::Request($URL)
+
+Loads request from the supplied $URL. Allowed arguments are:
+
+=over 4
+
+=item Local file name
+
+If $URL is the name of an existing local file, the file is loaded to the
+memory and parsed as JSON object (if it begins with a curly brace), or as
+YAML document.
+
+=item Local directory name
+
+If $URL is the name of an existing local directory, it is searched for
+any files matching the shell globbing pattern C<*.SlackBuild>. If any
+such file is found, its base name is taken as the name of the package,
+and the full pathname of the directory itself as the B<slackbuild_uri>.
+
+=item URL of the remote tarball
+
+If $URL begins with any of C<http://>, C<https://>, C<ftp://>, C<ftps://>,
+and its path name component ends in C<.tar> with optional compression
+suffix (C<.gz>, C<.xz>, C<.lz>, or C<.bz2>), the file name part of the
+URL is taken as the package name and the $URL itself as B<slackbuild_uri>.
+
+=item SBo URL
+
+ sbo:///COMMIT/CATEGORY/PACKAGE
+
+This URL refers the definition of C<PACKAGE> in B<slackbuild.org> repository.
+For example:
+
+ sbo://HEAD/system/cronie
+
+=item Package name
+
+Unqualified package name is looked up in the B<slackbuild.org> repository.
+If it is found, the retrieved data are used to build the request.
+
+=back
+
+=cut
+
+sub load {
+ my ($class, $reqname) = @_;
+
+ my $ldpack = __PACKAGE__ . '::Loader';
+ my @comp = split /::/, $ldpack;
+
+ # Current (as of perl 5.28.0) implementation of "state" only permits
+ # the initialization of scalar variables in scalar context. Therefore
+ # this variable is an array ref.
+ state $loaders //=
+ [map { $_->[1] }
+ sort { $a->[0] <=> $b->[0] }
+ map {
+ my ($modname) = $ldpack . '::' . fileparse($_, '.pm');
+ eval {
+ no strict 'refs';
+ if (scalar %{ $modname.'::' }) {
+ die "INCLUDED $modname";
+ };
+ require $_;
+ my $prio = ${$modname.'::PRIORITY'};
+ die unless $prio && $modname->can('Load');
+ [ $prio, $modname ]
+ }
+ }
+ map { glob File::Spec->catfile($_, '*.pm') }
+ grep { -d $_ }
+ map { File::Spec->catfile($_, @comp) } @INC];
+
+ foreach my $ld (@$loaders) {
+ if (my $req = $ld->Load($reqname)) {
+ return $class->new($req);
+ }
+ }
+
+ croak "unrecognized request type";
+}
+
=head1 STRING REPRESENTATION
When used is string context, objects of this class are represented as
JSON objects with attribute names sorted in lexical order. The same
representation is returned by the B<as_string> method.
diff --git a/lib/SlackBuild/Request/Auto.pm b/lib/SlackBuild/Request/Auto.pm
deleted file mode 100644
index 576d39d..0000000
--- a/lib/SlackBuild/Request/Auto.pm
+++ b/dev/null
@@ -1,106 +0,0 @@
-package SlackBuild::Request::Auto;
-use strict;
-use warnings;
-use parent 'SlackBuild::Request';
-use File::Basename;
-use File::Spec;
-use Net::SBo;
-use JSON;
-use YAML;
-use Carp;
-
-sub req {
- my ($class, $reqname) = @_;
- my $req;
-
- if (-f $reqname) {
- local $/ = undef;
- open(my $fd, $reqname) or croak "can't open file $reqname: $!";
- my $string = <$fd>;
- close $fd;
- if ($string =~ /^\{/) {
- return decode_json($string);
- }
- return YAML::Load($string);
- }
-
- if (-d $reqname) {
- if (my $file =
- (glob File::Spec->catfile($reqname, '*.SlackBuild'))[0]) {
- my ($package,$path,$suffix) = fileparse($file, '.SlackBuild');
- return { package => $package, slackbuild_uri => $path };
- }
- }
-
- if ($reqname =~ m{^\w+://}) {
- my $uri = new URI($reqname);
- if ($uri->scheme =~ m{^(?:http|ftp)s?}
- && $uri->path =~ m{.*/(.+?)\.tar(?:\.(?:[xgl]z|bz2))?}x) {
- return { package => $1, slackbuild_uri => $reqname };
- }
- if ($uri->scheme eq 'sbo') {
- return { package => $uri->package, slackbuild_uri => $reqname }
- }
- }
-
- if (my ($dir,$commit) = Net::SBo->new->find($reqname)) {
- return { package => $reqname, slackbuild_uri => "sbo://$commit/$dir"};
- }
-
- croak "unrecognized request type";
-}
-
-sub new {
- my ($class, $arg) = @_;
- return $class->SUPER::new(__PACKAGE__->req($arg));
-}
-
-1;
-__END__
-
-=head1 NAME
-
-SlackBuild::Request::Auto - automatic request convertor for SlackBuilder
-
-=head1 SYNOPSIS
-
- $req = new SlackBuild::Request::Auto($arg)
-
-=head1 DESCRIPTION
-
-Attempts to recognize the format of I<$arg> and convert it to the SlackBuilder
-build request.
-
-Argument can be any of:
-
-=over 4
-
-=item Name of an existing file
-
-The file is read and parsed as a JSON request file.
-
-=item Name of an existing directory
-
-If it contains a file B<*.SlackBuild>, a request referring to files
-in this directory is returned.
-
-=item A http, https, ftp, or ftps URL to a tar file
-
-The file component of the URL must end with B<.tar>, followed with a
-compression suffix (B<.gz>, B<.xz>, or B<.bz2>). The archive must contain
-at least the B<*.SlackBuild> file.
-
-Example:
-
- https://slackbuilds.org/slackbuilds/14.2/system/mailutils.tar.gz
-
-=item An SBo URL
-
-Example:
-
- sbo://HEAD/system/mailutils
-
-=back
-
-=cut
-
diff --git a/lib/SlackBuild/Request/Loader/dir.pm b/lib/SlackBuild/Request/Loader/dir.pm
new file mode 100644
index 0000000..5e2af9d
--- a/dev/null
+++ b/lib/SlackBuild/Request/Loader/dir.pm
@@ -0,0 +1,21 @@
+package SlackBuild::Request::Loader::dir;
+use strict;
+use warnings;
+use File::Basename;
+use File::Spec;
+
+our $PRIORITY = 20;
+
+sub Load {
+ my ($class, $reqname) = @_;
+ if (-d $reqname) {
+ if (my $file =
+ (glob File::Spec->catfile($reqname, '*.SlackBuild'))[0]) {
+ my ($package,$path) = fileparse($file, '.SlackBuild');
+ return { package => $package, slackbuild_uri => $path };
+ }
+ }
+}
+
+1;
+
diff --git a/lib/SlackBuild/Request/Loader/file.pm b/lib/SlackBuild/Request/Loader/file.pm
new file mode 100644
index 0000000..2a8cae6
--- a/dev/null
+++ b/lib/SlackBuild/Request/Loader/file.pm
@@ -0,0 +1,25 @@
+package SlackBuild::Request::Loader::file;
+use strict;
+use warnings;
+use JSON;
+use YAML ();
+use Carp;
+
+our $PRIORITY = 10;
+
+sub Load {
+ my ($class, $reqname) = @_;
+ if (-f $reqname) {
+ local $/ = undef;
+ open(my $fd, $reqname) or croak "can't open file $reqname: $!";
+ my $string = <$fd>;
+ close $fd;
+ if ($string =~ /^\{/) {
+ return decode_json($string);
+ }
+ return YAML::Load($string);
+ }
+}
+
+1;
+
diff --git a/lib/SlackBuild/Request/Loader/sbo.pm b/lib/SlackBuild/Request/Loader/sbo.pm
new file mode 100644
index 0000000..bb0ec77
--- a/dev/null
+++ b/lib/SlackBuild/Request/Loader/sbo.pm
@@ -0,0 +1,15 @@
+package SlackBuild::Request::Loader::sbo;
+use strict;
+use warnings;
+use Net::SBo;
+
+our $PRIORITY = 40;
+
+sub Load {
+ my ($class, $reqname) = @_;
+ if (my ($dir,$commit) = Net::SBo->new->find($reqname)) {
+ return { package => $reqname, slackbuild_uri => "sbo://$commit/$dir"};
+ }
+}
+
+1;
diff --git a/lib/SlackBuild/Request/Loader/url.pm b/lib/SlackBuild/Request/Loader/url.pm
new file mode 100644
index 0000000..f8ff68f
--- a/dev/null
+++ b/lib/SlackBuild/Request/Loader/url.pm
@@ -0,0 +1,22 @@
+package SlackBuild::Request::Loader::url;
+use strict;
+use warnings;
+use URI;
+
+our $PRIORITY = 30;
+
+sub Load {
+ my ($class, $reqname) = @_;
+ if ($reqname =~ m{^\w+://}) {
+ my $uri = new URI($reqname);
+ if ($uri->scheme =~ m{^(?:http|ftp)s?}
+ && $uri->path =~ m{.*/(.+?)\.tar(?:\.(?:[xgl]z|bz2))?}x) {
+ return { package => $1, slackbuild_uri => $reqname };
+ }
+ if ($uri->scheme eq 'sbo') {
+ return { package => $uri->package, slackbuild_uri => $reqname }
+ }
+ }
+}
+
+1;

Return to:

Send suggestions and report system problems to the System administrator.