diff options
author | EuAndreh <eu@euandre.org> | 2023-03-31 11:59:52 -0300 |
---|---|---|
committer | EuAndreh <eu@euandre.org> | 2023-03-31 15:53:25 -0300 |
commit | 4a7f3e164ca3ab0e910f80cf4ad892999d7ecda8 (patch) | |
tree | e3bba8fb90ced8d18ec5eaefd0f3f522eb088f4f /src/bin/paku.in | |
parent | paku.lock: s/packages/pkgs/ (diff) | |
download | package-repository-4a7f3e164ca3ab0e910f80cf4ad892999d7ecda8.tar.gz package-repository-4a7f3e164ca3ab0e910f80cf4ad892999d7ecda8.tar.xz |
paku.lock: Generate this file from src/bin/paku.in
Diffstat (limited to 'src/bin/paku.in')
-rwxr-xr-x | src/bin/paku.in | 208 |
1 files changed, 206 insertions, 2 deletions
diff --git a/src/bin/paku.in b/src/bin/paku.in index f5392bd..d2900f2 100755 --- a/src/bin/paku.in +++ b/src/bin/paku.in @@ -6,10 +6,16 @@ use feature 'signatures'; no warnings ('experimental::signatures'); use Scalar::Util qw(looks_like_number); use Getopt::Std (); + use JSON (); + use File::Basename (); +use File::Temp (); +use File::Fetch (); + use Digest::MD5 (); use Digest::SHA (); +use MIME::Base64 (); sub usage($fh) { print $fh <<~'EOF' @@ -245,7 +251,7 @@ sub emit_nix() { print <<~EOF; $pkg->{name}$suffix = pkgs.stdenv.mkDerivation rec { name = "$pkg->{name}"; - version = "$pkg->{vversion}"; + version = "$pkg->{vlabel}"; src = fetchTarball { url = @@ -336,7 +342,7 @@ sub emit_guix() { (define-public $name (package (name "$pkg->{name}") - (version "$pkg->{version}") + (version "$pkg->{vlabel}") (source (origin (method url-fetch) @@ -954,6 +960,203 @@ sub emit_html() { } +sub run_template($name, $version, $template) { + return ($template =~ s/\@name\@/$name/gr) =~ s/\@version\@/$version/gr; +} + +sub set_difference($s1, $s2) { + my %idx = (); + for (@{$s1}) { + $idx{$_} = 1; + } + for (@{$s2}) { + delete $idx{$_}; + } + return keys(%idx); +} + +sub emit_refresh() { + my $json_str = do { + local $/; + <STDIN>; + }; + my $json = JSON::decode_json($json_str); + + my $defaults = { + datadir => '.paku', + guix => {}, + mappings => {}, + maintainer => { + name => '', + email => '', + }, + namespace => '', + name => '', + 'base-url' => '', + vcs => { + git => '', + http => '', + tarball => '', + }, + pkgs => [], + }; + my $out = { + %$defaults, + %$json, + }; + + my $default_package = { + maintainer => $out->{defaults}{maintainer} || '', + 'exclude-tags' => [], + }; + for my $package_any (@{$out->{packages}{any}}) { + my $package = ref $package_any ? + { %$default_package, %$package_any } : + { %$default_package, name => $package_any }; + + my $repo_url = run_template($package->{name}, '', $out->{defaults}{templates}{repository}); + my $dir = File::Temp::newdir(); + `git clone '$repo_url' '$dir'`; + die if $?; + + my @versions = (); + my $tags_any = $package->{tags} || $out->{defaults}{versions}{tags}; + my @tags = (); + if (ref $tags_any) { + push @tags, @$tags_any; + } elsif ($tags_any eq 'all') { + my @ret = `git -C '$dir' tag`; + die if $?; + chomp @ret; + + push @tags, set_difference(\@ret, $package->{'exclude-tags'}); + } else { + die "Unknown value of \"tags\": $tags_any"; + } + + for (@tags) { + my $ver = $_ =~ s/^v//gr; + my %version = ( + type => 'tag', + vversion => $_, + version => $ver, + vname => $_, + vlabel => $ver, + label => $ver =~ s/\./-/gr, + ); + push @versions, \%version; + } + + my $default_branch = + $package->{default_branch} || + $out->{defaults}{default_branch} || + 'main'; + my $branches = $package->{branches} || $out->{defaults}{versions}{branches}; + for (@{$branches}) { + my $revision = `git -C '$dir' rev-parse '$_'`; + die if $?; + chomp $revision; + + my $label = $_ eq $default_branch ? 'latest' : $_; + + my %version = ( + type => 'branch', + vversion => $revision, + version => $_, + vname => $revision, + vlabel => $revision, + label => $label, + ); + push @versions, \%version; + } + + for my $version (@versions) { + my $pkg = { + %$version, + name => $package->{name}, + architectures => 'any', + }; + + my $revision = `git -C '$dir' rev-parse '$pkg->{vversion}'`; + die if $?; + chomp $revision; + $pkg->{revision} = $revision; + + `git -C '$dir' checkout '$pkg->{vversion}'`; + die if $?; + my $url = run_template($package->{name}, $pkg->{vname}, $out->{defaults}{templates}{tarball}); + $pkg->{url} = $url; + + my $date = `git -C '$dir' log -1 --format=%cs`; + die if $?; + chomp $date; + $pkg->{date} = $date; + + $pkg->{manpages} = -d "$dir/doc/" ? JSON::true : JSON::false; + $pkg->{i18n} = -d "$dir/po/" ? JSON::true : JSON::false; + + for (qw(description long-description)) { + my $s = do { local(@ARGV, $/) = "$dir/$_"; <> }; + chomp $s; + $pkg->{$_} = $package->{$_} || $s; + } + + my @sha_guix = `guix download '$url'`; + die if $?; + chomp @sha_guix; + $pkg->{sha256guix} = $sha_guix[-1]; + + my $sha_nix = `nix-prefetch-url --unpack '$url'`; + die if $?; + chomp $sha_nix; + $pkg->{sha256nix} = $sha_nix; + + + my $ff = File::Fetch->new(uri => $url); + my $where = $ff->fetch(to => '/tmp'); + my $fh; + + open ($fh, '<', $where) or die "Can't open \"$where\": $!"; + my $sha256 = Digest::SHA->new(256)->addfile($fh)->hexdigest; + close $fh; + $pkg->{sha256} = $sha256; + + open ($fh, '<', $where) or die "Can't open \"$where\": $!"; + my $sha512 = Digest::SHA->new(512)->addfile($fh)->hexdigest; + close $fh; + $pkg->{sha512} = $sha512; + + unlink $where; + + + for (qw(base-url homepage changelog downloads-page fname)) { + $pkg->{$_} = $package->{$_} || + run_template( + $pkg->{name}, + $pkg->{vversion}, + $out->{defaults}{templates}{$_} + ); + } + + for (qw(inputs native-inputs)) { + $pkg->{$_} = $package->{$_} || []; + } + + for (qw(maintainer license)) { + $pkg->{$_} = $package->{$_} || $out->{defaults}{$_}; + } + + for (qw(maintainer description long-description)) { + $pkg->{"$_-b64"} = MIME::Base64::encode_base64($pkg->{$_}, ''); + } + + push @{$out->{pkgs}}, $pkg; + } + } + print JSON->new->pretty->canonical->encode($out); +} + + my %actions = ( 'debian-packages' => \&emit_packages, 'debian-release' => \&emit_release, @@ -965,6 +1168,7 @@ my %actions = ( alpine => \&emit_alpine, homebrew => \&emit_homebrew, html => \&emit_html, + refresh => \&emit_refresh, ); my $action = $ARGV[0] or die "Missing ACTION"; |