diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2017-11-30 13:18:08 +0100 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2017-11-30 15:31:03 +0100 |
commit | 18c46014ea554d19989b6a1b3a773254fefda092 (patch) | |
tree | bcff7a8429938a65548a356b34337b39ce0af298 | |
parent | 2f104feb62d8c9a6c27c0090a310afeefff4af09 (diff) | |
download | slackbuilder-18c46014ea554d19989b6a1b3a773254fefda092.tar.gz slackbuilder-18c46014ea554d19989b6a1b3a773254fefda092.tar.bz2 |
Install prerequisite packages and set up environment prior to running package.SlackBuild script
* lib/SlackBuild/Rc.pm: New file.
* lib/SlackBuild/Registry/Backend/FS.pm (lookup): Store relative file name.
* lib/SlackBuild/Registry/Record.pm (as_string): Use * in place of missing
version and architecture.
* lib/SlackBuilder.pm (new): Save arch name.
(arch): New method.
(request_environ,environ): New methods.
(_prepare): New method. Creates intermediate rc script for installing the
prerequisite packages.
(_build): Run _prepare.
-rw-r--r-- | lib/SlackBuild/Archive.pm | 2 | ||||
-rw-r--r-- | lib/SlackBuild/Rc.pm | 72 | ||||
-rw-r--r-- | lib/SlackBuild/Registry/Backend/FS.pm | 2 | ||||
-rw-r--r-- | lib/SlackBuild/Registry/Record.pm | 6 | ||||
-rw-r--r-- | lib/SlackBuilder.pm | 59 |
5 files changed, 133 insertions, 8 deletions
diff --git a/lib/SlackBuild/Archive.pm b/lib/SlackBuild/Archive.pm index eaa995e..746592b 100644 --- a/lib/SlackBuild/Archive.pm +++ b/lib/SlackBuild/Archive.pm @@ -37,7 +37,7 @@ sub iterate { sub add_file { my $self = shift; - push @{$self->{_dir}}, @_; + push @{$self->{_dir}}, File::Spec->no_upwards(map { s{/$}{}; $_ } @_); } sub has_file { diff --git a/lib/SlackBuild/Rc.pm b/lib/SlackBuild/Rc.pm new file mode 100644 index 0000000..350c1d1 --- /dev/null +++ b/lib/SlackBuild/Rc.pm @@ -0,0 +1,72 @@ +package SlackBuild::Rc; +use strict; +use warnings; +use Carp; +use SlackBuild::Registry::Record; + +sub new { + my ($class, $builder) = @_; + return bless { _builder => $builder }, $class; +} + +sub builder { shift->{_builder} } + +sub resolve { + my ($self, $reg) = @_; + my @packages; + my @unresolved; + foreach my $pkg (@{$self->builder->prereq}) { + my %q; + my $name; + if (ref($pkg) eq 'HASH') { + %q = %$pkg; + $name = delete $q{package}; + } else { + $name = $pkg; + } + $q{arch} = $self->builder->arch unless exists $q{arch}; + if (my $rec = $reg->lookup($name, %q)) { + push @packages, $rec->filename; + } else { + push @unresolved, + SlackBuild::Registry::Record->new($name, %q)->as_string; + } + } + return (\@packages, \@unresolved); +} + +sub code { + my ($self, $reg) = @_; + my ($pkglist, $unresolved) = $self->resolve($reg); + if (@$unresolved) { + $self->builder->error("$_: package not resolved") for (@$unresolved); + return; + } + my @code = ('#! /bin/sh', 'set -e', + map { "/sbin/installpkg /var/pkg/$_" } @$pkglist); + + my $env = $self->builder->environ; + while (my ($k,$v) = each %$env) { + next unless defined($v); + $v =~ s/[`"]/\\"/g; + push @code, "$k=\"$v\"", "export $k"; + } + + push @code, 'exec /bin/sh $@'; + return \@code; +} + +sub write { + my ($self, $reg, $file) = @_; + my $code = $self->code($reg) or return; + open(my $fd, '>', $file) + or croak "can't open \"$file\" for writing: $!"; + print $fd join("\n", @$code)."\n"; + unless (chmod(0755, $fd)) { + croak "can't chmod \"$file\": $!"; + } + close $fd; + return 1; +} + +1; diff --git a/lib/SlackBuild/Registry/Backend/FS.pm b/lib/SlackBuild/Registry/Backend/FS.pm index bc178dc..d554f9e 100644 --- a/lib/SlackBuild/Registry/Backend/FS.pm +++ b/lib/SlackBuild/Registry/Backend/FS.pm @@ -106,7 +106,7 @@ sub lookup { arch => $+{arch}, build => $+{build}, date => $st->mtime, - filename => $_) + filename => File::Spec->abs2rel($_, $self->{dir})) } else { () } diff --git a/lib/SlackBuild/Registry/Record.pm b/lib/SlackBuild/Registry/Record.pm index 90f6d05..22c6a3c 100644 --- a/lib/SlackBuild/Registry/Record.pm +++ b/lib/SlackBuild/Registry/Record.pm @@ -47,8 +47,10 @@ sub store { sub as_string { my $self = shift; - return $self->package . '-' . $self->version . '-' . $self->arch . '-' . - ($self->build || '1'); + return $self->package . '-' + . ($self->version || '*') . '-' + . ($self->arch || '*') . '-' + . ($self->build || '1'); } sub cmp { diff --git a/lib/SlackBuilder.pm b/lib/SlackBuilder.pm index 91b80a5..141af26 100644 --- a/lib/SlackBuilder.pm +++ b/lib/SlackBuilder.pm @@ -4,12 +4,14 @@ use warnings; use Carp; use SlackBuild::URI; use SlackBuild::Archive; +use SlackBuild::Registry; +use SlackBuild::Rc; use File::Spec; use File::Basename; use File::Temp qw/ tempfile tempdir /; use File::Copy; use POSIX::Run::Capture qw(:all); -use POSIX qw(:sys_wait_h strerror); +use POSIX qw(:sys_wait_h strerror uname); use constant { E_OK => 0, @@ -41,6 +43,8 @@ sub new { $self->{_verbose} = delete $args{verbose}; croak "bad number of arguments" if keys(%args); + + $self->{_arch} = (uname)[4]; $self->clear; @@ -54,6 +58,7 @@ sub logdir { shift->{_logdir} }; sub pkgdir { shift->{_pkgdir} }; sub image { shift->{_image} }; sub verbose { shift->{_verbose} }; +sub arch { shift->{_arch} }; sub error { my ($self, $diag) = @_; @@ -150,8 +155,7 @@ my @ATTRIBUTES = qw(package_name package_version package_build slackbuild_uri - source_uri - prereq); + source_uri); { no strict 'refs'; use feature 'state'; @@ -167,6 +171,36 @@ my @ATTRIBUTES = qw(package_name } } +sub prereq { + my $self = shift; + croak "too many arguments" if @_ > 1; + if (my $v = shift) { + $self->{_request}{prereq} = $v; + } + $self->{_request}{prereq} = [] unless exists $self->{_request}{prereq}; + return $self->{_request}{prereq}; +} + +sub request_environ { + my $self = shift; + croak "too many arguments" if @_ > 1; + if (my $v = shift) { + $self->{_request}{environ} = $v; + } + $self->{_request}{environ} = {} unless exists $self->{_request}{environ}; + return $self->{_request}{environ}; +} + +sub environ { + my $self = shift; + my $env = {%{$self->request_environ}, + VERSION => $self->package_version}; + if (my $b = $self->package_build) { + $env->{BUILD} = $b; + } + return $env; +} + sub file { my ($self, $name) = @_; my $src = File::Spec->catfile($self->tmpdir, $name); @@ -309,10 +343,26 @@ sub _logfilename { return File::Spec->catfile($self->logdir, $self->package_name . '.log'); } +sub _prepare { + my $self = shift; + + # Find prerequisites + # FIXME: Build a dependency graph and spawn slackbuilders for missing ones + + # FIXME: registry type should be configurable + my $reg = new SlackBuild::Registry('FS', dir => $self->pkgdir); + + my $filename = File::Spec->catfile($self->wd, 'rc'); + return unless SlackBuild::Rc->new($self)->write($reg, $filename); + return 'rc'; +} + sub _build { my $self = shift; return $self->errno if $self->errno; + my $contname = $self->package_name . '_slackbuild'; + my $rcfile = $self->_prepare or return $self->errno(E_FAIL); my @args = ( 'docker', 'run', '--rm=true', @@ -322,7 +372,8 @@ sub _build { '-v', $self->pkgdir . ':/var/pkg:ro', $self->image, '/bin/sh', - $self->slackbuild_name ); + $rcfile, + $self->slackbuild_name); print "building ".$self->package_name."\n"; |