aboutsummaryrefslogtreecommitdiff
path: root/src/bin/paku.in
diff options
context:
space:
mode:
authorEuAndreh <eu@euandre.org>2023-03-31 11:59:52 -0300
committerEuAndreh <eu@euandre.org>2023-03-31 15:53:25 -0300
commit4a7f3e164ca3ab0e910f80cf4ad892999d7ecda8 (patch)
treee3bba8fb90ced8d18ec5eaefd0f3f522eb088f4f /src/bin/paku.in
parentpaku.lock: s/packages/pkgs/ (diff)
downloadpackage-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-xsrc/bin/paku.in208
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";