Hello World

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'};
    }
  }
}