File download_assets of Package build
#!/usr/bin/perl
################################################################
#
# Copyright (c) 2021 SUSE LLC
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################
BEGIN {
if (!$::ENV{'BUILD_DIR'} && $0 ne '-' && $0 ne '-e' && -e $0 && ! -e '/etc/build.conf') {
use Cwd ();
my $p = Cwd::abs_path($0);
$::ENV{'BUILD_DIR'} = $p if $p =~ s/\/[^\/]+$// && $p ne '/usr/lib/build' && -d "$p/PBuild";
}
unshift @INC, ($::ENV{'BUILD_DIR'} && ! -e '/etc/build.conf' ? $::ENV{'BUILD_DIR'} : '/usr/lib/build');
}
use strict;
use POSIX;
use Build;
use Build::Options;
use PBuild::AssetMgr;
use PBuild::Source;
use PBuild::Cpio;
$Build::Kiwi::urlmapper = 0; # disable url -> prp mapping
my $fedpkg = 'fedpkg@https://pkgs.fedoraproject.org/repo/pkgs';
my %known_options = (
'h' => 'help',
'help' => '',
'assetdir' => ':',
'assets' => '::',
'noassetdir' => '',
'outdir' => ':', # for source service
'clean' => '',
'list' => '',
'unpack' => '',
'arch' => '::',
'dist' => ':',
'configdir' => ':',
'recipe' => ':',
'create-cpio' => '',
'show-dir-srcmd5' => '',
);
sub find_assets {
my ($assetmgr, $bconf, $p, $file) = @_;
delete $p->{'remoteassets'};
if ($file eq 'sources' || $file eq 'go.sum') {
$p->{'buildtype'} = '';
$assetmgr->find_assets($p);
return;
}
my $bt = Build::recipe2buildtype($file);
return unless $bt;
$p->{'buildtype'} = $bt;
my $d;
eval { $d = Build::parse_typed($bconf, "$p->{'dir'}/$file", $bt) };
$p->{'remoteassets'} = $d->{'remoteassets'} if $d && $d->{'remoteassets'};
$p->{'name'} ||= $d->{'name'} if $d->{'name'};
$assetmgr->find_assets($p);
}
sub read_config {
my ($dist, $arch, $configdir) = @_;
if ($dist) {
$configdir ||= ($::ENV{'BUILD_DIR'} || '/usr/lib/build') . '/configs';
return Build::read_config_dist($dist, $arch, $configdir);
}
return Build::read_config($arch);
}
my ($opts, @dirs) = Build::Options::parse_options(\%known_options, @ARGV);
if ($opts->{'create-cpio'}) {
if ($opts->{'help'}) {
print "Usage: download_assets --create-cpio dir\n";
exit(0);
}
die("Please specify a directory\n") unless @dirs >= 1;
my $dir = shift @dirs;
if (!@dirs) {
my $prefix = $dir;
$prefix =~ s/.*\///;
$prefix = '' if $prefix eq '.';
PBuild::Cpio::cpio_create(\*STDOUT, $dir, 'prefix' => ($prefix ne '' ? "$prefix/" : ''));
} else {
s/^\/// for @dirs;
PBuild::Cpio::cpio_create(\*STDOUT, $dir, 'dircontent' => \@dirs);
}
exit(0);
}
if ($opts->{'show-dir-srcmd5'}) {
die("Please specify a directory\n") unless @dirs == 1;
my $dir = shift @dirs;
die("$dir: $!\n") unless -e $dir;
die("$dir: Not a directory\n") unless -d _;
print PBuild::Source::gendirdigest($dir)."\n";
exit(0);
}
if ($opts->{'help'}) {
print "Usage: download_assets [--assetdir dir] [--clean] [--noassetdir] [--unpack] dir...\n";
exit(0);
}
die("Please specify at least one directory\n") unless @dirs;
die("The --assetdir option conflicts with --noassetdir\n") if $opts->{'assetdir'} && $opts->{'noassetdir'};
my @arch = @{$opts->{'arch'} || []};
push @arch, 'noarch' unless @arch;
for my $dir (@dirs) {
my ($files, $source_assets) = PBuild::Source::list_package($dir);
my $p = {
'pkg' => "_me",
'dir' => $dir,
'files' => $files,
};
my $assetdir = $opts->{'assetdir'} || "$dir/.assets";
my $outdir = $opts->{'outdir'} || $dir;
my $assetmgr = PBuild::AssetMgr::create($assetdir);
$assetmgr->{'keep_all_assets'} = 1 if $opts->{'clean'};
$assetmgr->add_assetshandler($_) for @{$opts->{'assets'} || []};
$assetmgr->add_assetshandler($fedpkg) if !$opts->{'assets'} && $files->{'sources'};
$assetmgr->merge_assets($p, $source_assets);
for my $arch (@arch) {
my $bconf = read_config($opts->{'dist'}, $arch, $opts->{'configdir'});
if ($opts->{'recipe'}) {
find_assets($assetmgr, $bconf, $p, $opts->{'recipe'});
} else {
for my $file (sort keys %$files) {
next unless $file eq 'sources' || $file eq 'go.sum' || $file eq 'PKGBUILD' || $file eq 'Dockerfile' || $file =~ /\.(?:spec|dsc|kiwi)/;
find_assets($assetmgr, $bconf, $p, $file);
}
}
}
if ($opts->{'clean'}) {
my $af = $p->{'asset_files'} || {};
for (values %$af) {
if ($_->{'isdir'}) {
PBuild::Util::rm_rf("$dir/$_->{'file'}") if -d "$dir/$_->{'file'}";
unlink "$dir/$_->{'file'}.obscpio" if -e "$dir/$_->{'file'}.obscpio";
} else {
unlink "$dir/$_->{'file'}" if -e "$dir/$_->{'file'}";
}
}
next;
}
if ($opts->{'list'}) {
my $af = $p->{'asset_files'} || {};
for my $file (sort keys %$af) {
my $asset = $af->{$file};
print $asset->{'isdir'} ? "$file/" : $file;
print " $asset->{'type'}";
print " $asset->{'url'}" if $asset->{'url'};
print " $asset->{'digest'}" if $asset->{'digest'};
print "\n";
}
next;
}
if ($opts->{'unpack'} && $opts->{'noassetdir'}) {
my $af = $p->{'asset_files'} || {};
for (values %$af) {
$_->{'donotpack'} = 1 if $_->{'isdir'};
}
}
# remove directory assets that we already have
if ($opts->{'unpack'}) {
my $af = $p->{'asset_files'} || {};
# delete directory assets that we already have
for (keys %$af) {
delete $af->{$_} if $af->{$_}->{'isdir'} && -d "$dir/$_";
}
}
$assetmgr->getremoteassets($p);
if ($opts->{'noassetdir'}) {
$assetmgr->move_assets($p, $outdir, $opts->{'unpack'});
PBuild::Util::rm_rf($assetdir);
} else {
$assetmgr->copy_assets($p, $outdir, $opts->{'unpack'});
}
# mark directories as assets for build script
if ($opts->{'unpack'}) {
my $af = $p->{'asset_files'} || {};
for (keys %$af) {
PBuild::Util::touch("$outdir/$_/.build.asset") if $af->{$_}->{'isdir'};
}
}
}