diff options
Diffstat (limited to 'lib/SlackBuilder.pm')
-rw-r--r-- | lib/SlackBuilder.pm | 213 |
1 files changed, 73 insertions, 140 deletions
diff --git a/lib/SlackBuilder.pm b/lib/SlackBuilder.pm index 688a697..ff3ade4 100644 --- a/lib/SlackBuilder.pm +++ b/lib/SlackBuilder.pm @@ -45,8 +45,6 @@ sub new { croak "bad number of arguments" if keys(%args); - $self->{_arch} = (uname)[4]; - $self->clear; return $self; @@ -57,6 +55,10 @@ sub spooldir { shift->{_spooldir} }; sub tmpdir { shift->{_tmpdir} }; sub logdir { shift->{_logdir} }; sub pkgdir { shift->{_pkgdir} }; +sub ospkgdir { + my $self = shift; + File::Spec->catfile($self->pkgdir, $self->osversion, @_); +} sub image { shift->{_image} }; sub verbose { shift->{_verbose} }; sub arch { shift->{_arch} }; @@ -96,95 +98,26 @@ sub clear { delete $self->{_result}; } -my %kws = ( - package => { - mandatory => 1, - set => \&package_name - }, - version => { - mandatory => 1, - set => \&package_version - }, - build => { - mandatory => 0, - set => \&package_build - }, - slackbuild_uri => { - mandatory => 1, - set => \&slackbuild_uri - }, - source_uri => { - mandatory => 0, - set => sub { - my ($self, $v) = @_; - $self->source_uri(new SlackBuild::URI($v)); - } - }, - source_archive_name => { - mandatory => 0, - set => \&source_archive_name - }, - prereq => { - mandatory => 0, - set => sub { - my ($self, $v) = @_; - if (ref($v) ne 'ARRAY') { - $self->error("prereq: bad data type"); - } else { - $self->prereq($v); - } - } - }, - rc => { - mandatory => 0, - set => \&rc - } -); - -my @ATTRIBUTES = qw(package_name - package_version - package_build - rc - slackbuild_uri - source_uri); -{ - no strict 'refs'; - use feature 'state'; - foreach my $attr (@ATTRIBUTES) { - *{ __PACKAGE__ . '::' . $attr } = sub { - my $self = shift; - croak "too many arguments" if @_ > 1; - if (my $v = shift) { - $self->{_request}{$attr} = $v; - } - return $self->{_request}{$attr}; - } - } -} - -sub prereq { +sub request { my $self = shift; croak "too many arguments" if @_ > 1; if (my $v = shift) { - $self->{_request}{prereq} = $v; + $self->{_request} = $v; } - $self->{_request}{prereq} = [] unless exists $self->{_request}{prereq}; - return $self->{_request}{prereq}; + return $self->{_request}; } -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 package_name { shift->request->package } +sub package_version { shift->request->version } +sub package_build { shift->request->build } +sub rc { shift->request->rc } +sub slackbuild_uri { shift->request->slackbuild_uri } +sub source_uri { shift->request->source_uri } +sub prereq { shift->request->prereq || []} sub environ { my $self = shift; - my $env = {%{$self->request_environ}, + my $env = {%{$self->request->environ // {}}, VERSION => $self->package_version}; if (my $b = $self->package_build) { $env->{BUILD} = $b; @@ -195,7 +128,7 @@ sub environ { sub file { my ($self, $name) = @_; my $src = File::Spec->catfile($self->tmpdir, $name); - my $dst = File::Spec->catfile($self->pkgdir, $self->osversion, $name); + my $dst = $self->ospkgdir($name); my $dstdir = dirname($dst); if (! -d $dstdir) { @@ -213,18 +146,47 @@ sub file { $self->error("move($src, $dst): $!"); $self->errno(E_FAIL); } - push @{$self->{_result}{output_files}}, $name; + push @{$self->{_result}{output_files}}, $dst; } -sub osversion { +sub os_probe { my $self = shift; - croak "too many arguments" if @_ > 1; - if (my $v = shift) { - $self->{_osversion} = $v; + + unless (exists($self->{_os_release})) { + my @args = ( 'docker', + 'run', + '--rm=true', + $self->image, + '/bin/sh', + '-c', + 'uname -m; cat /etc/os-release' ); + + my $obj = new POSIX::Run::Capture(argv => \@args); + if ($obj->run) { + $self->_runcap_diag($obj); + } else { + $self->error("can't run docker: ".strerror($obj->errno)); + return $self->errno(E_EXEC); + } + $obj->rewind(SD_STDOUT); + chomp($self->{_arch} = $obj->next_line(SD_STDOUT)); + while (my $s = $obj->next_line(SD_STDOUT)) { + chomp($s); + my ($name,$value)=split /=/, $s, 2; + $value =~ s/^"(.*)"\s*$/$1/; + $self->{_os}{$name} = $value; + } } - return $self->{_osversion} // "UNKNOWN"; + return E_OK; } +sub os_release { + my ($self, $value) = @_; + return $self->{_os}{$value}; +} + +sub osversion { shift->os_release('VERSION') } + sub output_files { my $self = shift; $self->{_result}{output_files} //= []; @@ -249,48 +211,21 @@ sub slackbuild_name { return $self->package_name . '.SlackBuild'; } -sub source_archive_name { - my $self = shift; - croak "too many arguments" if @_ > 1; - if (my $v = shift) { - $self->{_request}{source_archive_name} = $v; - } - my $res; - if (exists($self->{_request}{source_archive_name})) { - $res = $self->{_request}{source_archive_name}; - } else { - $res = basename($self->source_uri->path); - } - return File::Spec->catfile($self->wd, $res); -} - sub run { - my $self = shift; - my %args; - if (@_ == 1) { - my $var = shift; - %args = %{$var}; - } else { - %args = @_; - } + my ($self, $req) = @_; $self->clear; - while (my ($k,$d) = each %kws) { - my $v = delete $args{$k}; - if (defined($v)) { - $self->${\ $d->{set}}($v); - } elsif ($d->{mandatory}) { - $self->error("$k: not present"); - } + unless ($req->package) { + $self->error("package: not present"); } - - foreach my $k (keys %args) { - $self->error("$k: unknown parameter"); + unless ($req->slackbuild_uri) { + $self->error("slackbuild_uri: not present"); } - if ($self->errors) { return $self->errno(E_SYNTAX); } + + $self->request($req); my $archive = new SlackBuild::Archive($self->package_name, $self->slackbuild_uri); @@ -301,16 +236,10 @@ sub run { return $self->errno(E_FAIL); } - if ($self->source_uri) { - unless ($self->source_uri->download($self->source_archive_name)) { - $self->error("can't download " - . $self->source_archive_name - . ": " - . $self->source_uri->download_status); - return $self->errno(E_FAIL); - } - } elsif (my $d = $archive->info('DOWNLOAD')) { - foreach my $s (split /\s+/, $d) { + $self->request->addinfo($archive->info); + + if (my $urilist = $self->request->source_uri) { + foreach my $s (@$urilist) { my $uri = new SlackBuild::URI($s); my $dest = File::Spec->catfile($self->wd, basename($uri->path)); unless ($uri->download($dest)) { @@ -361,7 +290,7 @@ sub _prepare { # 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 $reg = new SlackBuild::Registry('FS', dir => $self->ospkgdir); my $filename = File::Spec->catfile($self->wd, 'rc'); return unless SlackBuild::Rc->new($self)->write($reg, $filename); @@ -370,8 +299,10 @@ sub _prepare { sub _build { my $self = shift; + + $self->os_probe; 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', @@ -380,13 +311,17 @@ sub _build { '--workdir=/usr/src', '-v', $self->wd . ':/usr/src', '-v', $self->tmpdir . ':/tmp', - '-v', $self->pkgdir . ':/var/pkg:ro', + '-v', $self->ospkgdir . ':/var/pkg:ro', $self->image, '/bin/sh', $rcfile, $self->slackbuild_name); - print "building ".$self->package_name."\n"; + printf("building %s on %s version %s (%s)\n", + $self->package_name, + $self->os_release('NAME'), + $self->os_release('VERSION'), + $self->arch); open(my $logfd, '>', $self->_logfilename) or do { @@ -421,9 +356,7 @@ sub _build { $obj->rewind(SD_STDOUT); while (my $s = $obj->next_line(SD_STDOUT)) { chomp($s); - if ($s =~ s{^SLACKBUILDER: VERSION }{}) { - $self->osversion($s); - } elsif ($s =~ m{^Slackware package /tmp/(.+?) created}) { + if ($s =~ m{^Slackware package /tmp/(.+?) created}) { $self->file($1); } } |