aboutsummaryrefslogtreecommitdiff
path: root/src/bin
diff options
context:
space:
mode:
authorEuAndreh <eu@euandre.org>2023-03-20 14:37:34 -0300
committerEuAndreh <eu@euandre.org>2023-03-21 07:34:35 -0300
commit58167062f674cbc5ac97991a921a1ac92118101c (patch)
treed39312ce189e459a46b0d1d41ffedf1e1c1063fa /src/bin
parentqueue.scm: Remove (mail-in-home? ...) option from Postfix and Dovecot (diff)
downloadpackage-repository-58167062f674cbc5ac97991a921a1ac92118101c.tar.gz
package-repository-58167062f674cbc5ac97991a921a1ac92118101c.tar.xz
Big revamp of paku(1): now in Perl, genating Debian packages
Diffstat (limited to '')
-rwxr-xr-xsrc/bin/paku813
1 files changed, 463 insertions, 350 deletions
diff --git a/src/bin/paku b/src/bin/paku
index 8d5a967..eb89c47 100755
--- a/src/bin/paku
+++ b/src/bin/paku
@@ -1,369 +1,482 @@
-#!/bin/sh
-set -eu
+#!/usr/bin/env perl
+
+# FIXME: add html output
+
+use v5.34;
+use warnings;
+use feature 'signatures';
+no warnings ('experimental::signatures');
+use Getopt::Std ();
+use JSON ();
+use MIME::Base64 ();
+use open IN => ':encoding(UTF-8)';
+
+sub usage($fh) {
+ print $fh <<~'EOF'
+ Usage:
+ paku [-f FILE] FIXME
+ paku -h
+ EOF
+}
-TARBALL_TEMPLATE='https://euandreh.xyz/@NAME@.git/snapshot/@NAME@-@VERSION@.tar.gz'
+sub help($fh) {
+ print $fh <<~'EOF'
+
+
+ Options:
+ -f FILE use data from FILE (default: paku.json)
+ -h, --help show this message
+
+
+ Generate package definitions for different package managers.
-tarball_url() {
- NAME="$1"
- VERSION="$2"
- echo "$TARBALL_TEMPLATE" | \
- sed -e "s/@NAME@/$NAME/g" \
- -e "s/@VERSION@/$VERSION/g"
-}
-gen_guix() {
- GUIX_OUT="$(mktemp)"
-
- cat <<EOF >>"$GUIX_OUT"
-(define-module (xyz euandreh packages)
- #:use-module ((guix licenses) #:prefix license:)
- #:use-module (guix gexp)
- #:use-module (guix packages)
- #:use-module (guix download)
- #:use-module (guix build-system gnu))
-EOF
-
- for p in $(jq -r '.packages[] | @base64' < paku.json); do
- NAME="$(echo "$p" | base64 --decode | jq -r '.name')"
- SUFFIX="$(echo "$p" | base64 --decode | jq -r '.suffix')"
- VERSION="$(echo "$p" | base64 --decode | jq -r '.version')"
- TARBALL="$(tarball_url "$NAME" "$VERSION")"
- SHA256="$(guix download "$TARBALL" | tail -n 1)"
- JSON_CHECK_INPUTS="$(echo "$p" | base64 --decode | jq -r '.check_inputs')"
- if [ "$JSON_CHECK_INPUTS" = 'null' ]; then
- CHECK_INPUTS=''
- else
- INPUTS=''
- for check_input in $(echo "$JSON_CHECK_INPUTS" | jq -r '.[]'); do
- if [ "$INPUTS" = '' ]; then
- INPUTS="(\"$check_input\" ,(specification->package \"$check_input\"))"
- else
- INPUTS="$INPUTS
- (\"$check_input\" ,(specification->package \"$check_input\"))"
- fi
- done
-
- CHECK_INPUTS="
- (inputs
- \`($INPUTS))"
- fi
-
- cat <<EOF >>"$GUIX_OUT"
-
-(define-public $NAME$SUFFIX
- (package
- (name "$NAME$SUFFIX")
- (version "$VERSION")
- (source (origin
- (method url-fetch)
- (uri (string-append
- "https://euandreh.xyz/$NAME.git/snapshot/$NAME-"
- version
- ".tar.gz"))
- (sha256
- (base32
- "$SHA256"))))
- (build-system gnu-build-system)$CHECK_INPUTS
- (arguments \`(#:make-flags
- (list (string-append "PREFIX=" %output))
- #:phases
- (modify-phases %standard-phases
- (delete 'configure))))
- (synopsis (file-append source "/description"))
- (description (file-append source "/long-description"))
- (home-page "https://euandreh.xyz/$NAME/")
- (license license:agpl3+)))
-EOF
- done
-
- printf '\n(list' >>"$GUIX_OUT"
- for p in $(jq -r '.packages[] | @base64' < paku.json); do
- NAME="$(echo "$p" | base64 --decode | jq -r '.name')"
- SUFFIX="$(echo "$p" | base64 --decode | jq -r '.suffix')"
-
- printf '\n %s%s' "$NAME" "$SUFFIX" >>"$GUIX_OUT"
- done
- printf ')\n' >>"$GUIX_OUT"
-
- mv "$GUIX_OUT" src/xyz/euandreh/packages.scm
+ Examples:
+
+ FIXME:
+
+ $ FIXME
+ EOF
}
-gen_nix() {
- NIX_OUT="$(mktemp)"
-
- cat <<EOF >>"$NIX_OUT"
-{ pkgs }:
-self: super: {
- xyz-euandreh = {
-EOF
-
- for p in $(jq -r '.packages[] | @base64' < paku.json); do
- NAME="$(echo "$p" | base64 --decode | jq -r '.name')"
- SUFFIX="$(echo "$p" | base64 --decode | jq -r '.suffix')"
- VERSION="$(echo "$p" | base64 --decode | jq -r '.version')"
- TARBALL="$(tarball_url "$NAME" "$VERSION")"
- SHA256="$(nix-prefetch-url --unpack "$TARBALL")"
- JSON_CHECK_INPUTS="$(echo "$p" | base64 --decode | jq -r '.check_inputs')"
- if [ "$JSON_CHECK_INPUTS" = 'null' ]; then
- CHECK_INPUTS=''
- else
- INPUTS='['
- for check_input in $(echo "$JSON_CHECK_INPUTS" | jq -r '.[]'); do
- INPUTS="$INPUTS $check_input"
- done
- INPUTS="$INPUTS ]"
-
- CHECK_INPUTS="
- checkInputs = with pkgs; $INPUTS;"
- fi
-
- cat <<EOF >>"$NIX_OUT"
- $NAME$SUFFIX = pkgs.stdenv.mkDerivation rec {
- name = "$NAME";
- version = "$VERSION";
-
- src = fetchTarball {
- url =
- "https://euandreh.xyz/\${name}.git/snapshot/\${name}-\${version}.tar.gz";
- sha256 = "$SHA256";
- };
-
- makeFlags = [ "PREFIX=\$(out)" ];
-$CHECK_INPUTS
- doCheck = true;
-
- meta = with pkgs.lib; {
- description = readFile "\${src}/description";
- longDescription = readFile "\${src}/long-description";
- homepage = "https://euandreh.xyz/$NAME/";
- changelog = "https://euandreh.xyz/$NAME/CHANGELOG.html";
- downloadPage = "https://euandreh.xyz/$NAME/#releases";
- license = licenses.agpl3;
- platforms = platforms.unix;
- };
- };
-EOF
- done
-
- cat <<EOF >>"$NIX_OUT"
- };
+
+for (@ARGV) {
+ last if $_ eq '--';
+ if ($_ eq '--help') {
+ usage *STDOUT;
+ help *STDOUT;
+ exit;
+ }
}
-EOF
- mv "$NIX_OUT" default.nix
+my %opts;
+if (!Getopt::Std::getopts('f:h', \%opts)) {
+ usage *STDERR;
+ exit 2;
}
-pascalize() {
- awk '{printf "%s", toupper(substr($1,1,1)) substr($1,2)}'
+if ($opts{h}) {
+ usage *STDOUT;
+ help *STDOUT;
+ exit;
}
-gen_homebrew() {
- for p in $(jq -r '.packages[] | @base64' < paku.json); do
- HOMEBREW_OUT="$(mktemp)"
- NAME="$(echo "$p" | base64 --decode | jq -r '.name')"
- NAME_UC="$(echo "$NAME" | pascalize)"
- SUFFIX="$(echo "$p" | base64 --decode | jq -r '.suffix')"
- SUFFIX_UC="$(echo "$SUFFIX" | cut -c2- | pascalize)"
- VERSION="$(echo "$p" | base64 --decode | jq -r '.version')"
- TYPE="$(echo "$p" | base64 --decode | jq -r '.type')"
- TARBALL_URL="$(tarball_url "$NAME" "$VERSION")"
- TARBALL="$(mktemp)"
- wget -O "$TARBALL" "$TARBALL_URL"
- SHA256="$(sha256sum "$TARBALL" | cut -d\ -f 1)"
- DESCRIPTION="$(tar xvf "$TARBALL" -O "$NAME-$VERSION/description")"
- JSON_CHECK_INPUTS="$(echo "$p" | base64 --decode | jq -r '.check_inputs')"
- if [ "$JSON_CHECK_INPUTS" = 'null' ]; then
- CHECK_INPUTS=''
- else
- CHECK_INPUTS=''
- for check_input in $(echo "$JSON_CHECK_INPUTS" | jq -r '.[]'); do
- CHECK_INPUTS="$CHECK_INPUTS
- depends_on '$check_input' => :build"
- done
- CHECK_INPUTS="$CHECK_INPUTS
-"
- fi
-
- TEST_SECTION=''
- if [ "$TYPE" = 'bin' ]; then
- TEST_SECTION="
-
- test do
- system \"#{bin}/$NAME\", '-V'
- end"
- fi
-
- cat <<EOF >>"$HOMEBREW_OUT"
-class ${NAME_UC}$SUFFIX_UC < Formula
- desc '$DESCRIPTION'
- homepage 'https://euandreh.xyz/$NAME/'
- url '$TARBALL_URL'
- sha256 '$SHA256'
- license 'AGPL-3.0-or-later'
-$CHECK_INPUTS
- def install
- system 'make'
- system 'make', 'check'
- system 'make', 'install', "PREFIX=#{prefix}"
- end$TEST_SECTION
-end
-EOF
- mv "$HOMEBREW_OUT" "Formula/$NAME$SUFFIX.rb"
- done
+
+my $dir = '.paku'; # FIXME: parameterize
+my $fname = $opts{f} || 'paku.lock';
+my $json_str = do {
+ open my $fh, $fname or die "Failed opening \"$fname\"";
+ local $/;
+ <$fh>;
+};
+my $json = JSON::decode_json($json_str);
+
+my $action = $ARGV[0];
+
+
+
+use Data::Dumper;
+use POSIX qw();
+use File::Basename ();
+use Digest::MD5 ();
+use Digest::SHA ();
+
+
+# FIXME
+my $base_url_prefix = 'https://euandre.org/s';
+
+if ($action eq 'release') {
+ my $f = $ARGV[1];
+ my $name = File::Basename::basename $f;
+ my $size = (stat($f))[7];
+
+ my $now = `env LANG=POSIX.UTF-8 date -u '+%a, %d %b %Y %H:%M:%S +0000'`;
+ chomp $now;
+
+ my $fh;
+
+ open ($fh, '<', $f) or die "Can't open \"$f\": $!";
+ my $md5 = Digest::MD5->new->addfile($fh)->hexdigest;
+ close $fh;
+
+ open ($fh, '<', $f) or die "Can't open \"$f\": $!";
+ my $sha1 = Digest::SHA->new(1)->addfile($fh)->hexdigest;
+ close $fh;
+
+ open ($fh, '<', $f) or die "Can't open \"$f\": $!";
+ my $sha256 = Digest::SHA->new(256)->addfile($fh)->hexdigest;
+ close $fh;
+
+ open ($fh, '<', $f) or die "Can't open \"$f\": $!";
+ my $sha512 = Digest::SHA->new(512)->addfile($fh)->hexdigest;
+ close $fh;
+
+ print <<~EOF;
+ Date: $now
+ MD5Sum:
+ $md5 $size $name
+ SHA1:
+ $sha1 $size $name
+ SHA256:
+ $sha256 $size $name
+ SHA512:
+ $sha512 $size $name
+ EOF
+ exit;
}
-refresh_packages() {
- COUNT="$(jq -r '.packages[].name' < paku.json | wc -l)"
- INDEXES="$(seq 0 "$((COUNT - 1))")"
- for N in $INDEXES; do
- NAME="$(jq -r ".packages[$N].name" < paku.json)"
- SUFFIX="$(jq -r ".packages[$N].suffix" < paku.json)"
- cd "../../published/$NAME/"
- if [ "$SUFFIX" = '-latest' ]; then
- NEW_VERSION="$(git rev-parse HEAD)"
- else
- NEW_VERSION="$(git describe --tags --abbrev=0 | cut -c2-)"
- fi
- DESCRIPTION="$(cat description)"
- cd - >/dev/null
- jq -r ".packages[$N].version = \"$NEW_VERSION\"" paku.json | sponge paku.json
- jq -r ".packages[$N].description = \"$DESCRIPTION\"" paku.json | sponge paku.json
- done
+if ($action eq 'nix') {
+ my $ns = 'org-euandre'; # FIXME
+ print <<~EOF;
+ { pkgs }:
+ self: super: {
+ $ns = rec {
+ EOF
+ for my $package (@{$json->{packages}}) {
+ for my $version (@{$package->{versions}}) {
+ my $ver = $version->{name};
+ $ver =~ s/^v//;
+ $ver =~ s/\./-/g;
+ if ($version->{type} eq 'latest') {
+ $ver = 'latest';
+ print <<~EOF;
+ $package->{name} = $package->{name}-latest;
+ EOF
+ }
+
+ my $long = $version->{'long-description'};
+ $long =~ s/^(.)/ $1/gm;
+
+ my $base_url = $base_url_prefix . '/' . $package->{name};
+
+ print <<~EOF;
+ $package->{name}-$ver = pkgs.stdenv.mkDerivation rec {
+ name = "$package->{name}";
+ version = "$version->{name}";
+
+ src = fetchTarball {
+ url =
+ "$version->{url}";
+ sha256 = "$version->{sha256}";
+ };
+
+ nativeBuildInputs = with pkgs; [
+ EOF
+
+ for my $input (@{$version->{'native-inputs'}}) {
+ print <<~EOF;
+ $input
+ EOF
+ }
+ print <<~EOF;
+ ];
+
+ buildInputs = with pkgs; [
+ EOF
+ for my $input (@{$version->{inputs}}) {
+ print <<~EOF;
+ $input
+ EOF
+ }
+ print <<~EOF;
+ ];
+
+ makeFlags = [ "PREFIX=\$(out)" ];
+
+ doCheck = true;
+ enableParallelBuilding = true;
+
+ meta = with pkgs.lib; {
+ description = "$version->{description}";
+ longDescription = ''
+ $long
+ '';
+ homepage = "$base_url/";
+ changelog = "$base_url/CHANGELOG.html";
+ downloadPage = "$base_url/#releases";
+ license = licenses.agpl3;
+ platforms = platforms.unix;
+ };
+ };
+ EOF
+ # FIXME: escape quotes in description
+ # FIXME: parameterize license
+ }
+ }
+ print <<~EOF;
+ };
+ }
+ EOF
+ exit;
}
-report_index() {
- HTML_OUT='public/paku.html'
- cat <<EOF > "$HTML_OUT"
-<!DOCTYPE html>
-<html lang="en">
- <head>
- <meta charset="UTF-8" />
- <meta name="viewport" content="width=device-width, initial-scale=" />
- <link rel="icon" type="image/svg+html" href="favicon.svg" />
- <title>Package index</title>
-
- <style>
- ul {
- list-style: none;
+
+if ($action eq 'guix') {
+ my @pkgs = ();
+ my $ns = 'org euandre'; # FIXME
+ print <<~EOF;
+ (define-module ($ns packages)
+ EOF
+ for my $module (@{$json->{guix}{'module-use'}}) {
+ print <<~EOF;
+ #:use-module (gnu packages $module)
+ EOF
+ }
+ # FIXME: rename to 'licenses:'
+ print <<~EOF;
+ #:use-module ((guix licenses) #:prefix license:)
+ #:use-module (guix gexp)
+ #:use-module (guix packages)
+ #:use-module (guix download)
+ #:use-module (guix build-system gnu))
+
+ EOF
+
+ for my $package (@{$json->{packages}}) {
+ for my $version (@{$package->{versions}}) {
+ my $ver = $version->{name};
+ $ver =~ s/^v//;
+ $ver =~ s/\./-/g;
+ if ($version->{type} eq 'latest') {
+ push @pkgs, "$package->{name}";
+ $ver = 'latest';
+ }
+
+ my $long = $version->{'long-description'};
+ $long =~ s/^(.)/ $1/gm;
+
+ my $base_url = $base_url_prefix . '/' . $package->{name};
+
+ push @pkgs, "$package->{name}-$ver";
+ # FIXME: indentation of (source ...)
+ print <<~EOF;
+ (define-public $package->{name}-$ver
+ (package
+ (name "$package->{name}-$ver")
+ (version "$version->{name}")
+ (source (origin
+ (method url-fetch)
+ (uri "$version->{url}")
+ (sha256
+ (base32 "$version->{sha256FIXME}"))))
+ (build-system gnu-build-system)
+ (native-inputs
+ EOF
+
+ print ' (list';
+ for my $input (@{$version->{'native-inputs'}}) {
+ my $name = $json->{mappings}{$input}{guix} || $input;
+ print "\n $name";
+ }
+ print "))\n";
+
+ print " (inputs\n";
+ print ' (list';
+ for my $input (@{$version->{inputs}}) {
+ my $name = $json->{mappings}{$input}{guix} || $input;
+ print "\n $name";
}
- li {
- margin-top: 30px;
+ print "))\n";
+
+ print <<~EOF;
+ (arguments
+ (list
+ #:make-flags '(list (string-append "PREFIX=" %output))
+ #:phases
+ #~(modify-phases %standard-phases
+ (delete 'configure))))
+ (synopsis "$version->{description}")
+ (description
+ "$version->{'long-description'}")
+ (home-page "$base_url/")
+ (license license:agpl3+)))
+
+ EOF
+ # FIXME: escape quotes in description
+ # FIXME: parameterize license
+ if ($version->{type} eq 'latest') {
+ print <<~EOF;
+ (define-public $package->{name} $package->{name}-latest)
+
+
+ EOF
}
- </style>
- </head>
- <body>
- <h1>
- Package index
- </h1>
- <ul>
-EOF
-
- for p in $(jq -r '.packages[] | @base64' < paku.json); do
- NAME="$(echo "$p" | base64 --decode | jq -r '.name')"
- DESCRIPTION="$(echo "$p" | base64 --decode | jq -r '.description')"
- SUFFIX="$(echo "$p" | base64 --decode | jq -r '.suffix')"
- if [ -z "$SUFFIX" ]; then
- VERSION="$(echo "$p" | base64 --decode | jq -r '.version')"
- ID='released'
- else
- VERSION='latest'
- ID='latest'
- fi
-
- cat <<EOF >> "$HTML_OUT"
- <li id="$NAME-$ID">
- <details>
- <summary><a href="#$NAME-$ID">$NAME</a> ($VERSION) - $DESCRIPTION</summary>
- <p>
- <a href="https://euandreh.xyz/$NAME/">Homepage</a>.
- </p>
-
- <section>
- <h2>Guix</h2>
- <p>
- After following the
- <a href="#guix-instructions">Guix instructions</a> to include this
- channel, now you can create an environment that includes this
- package:
- </p>
- <pre><code>$ guix environment --ad-hoc $NAME$SUFFIX</code></pre>
- <p>
- Alternatively, you can install it imperatively:
- </p>
- <pre><code>$ guix install $NAME$SUFFIX</code></pre>
- </section>
- <section>
- <h2>Nix</h2>
- <p>
- After following the
- <a href="#nix-instructions">Nix instructions</a> to include this
- repository as an overlay, now you can create a new Nix shell that
- includes this package:
- </p>
- <pre><code>$ nix-shell -p $NAME$SUFFIX</code></pre>
- <p>
- Alternatively, you can install it imperatively:
- </p>
- <pre><code>$ nix-env -i $NAME$SUFFIX</code></pre>
- </section>
- </details>
- </li>
-EOF
- done
-
- cat <<EOF >> "$HTML_OUT"
- </ul>
- <article id="guix-instructions">
- <h2>Guix instructions</h2>
- <p>
- Add this channel to your <code>~/.config/guix/channels.scm</code>:
- </p>
- <pre><code>(cons*
- (channel
- (name 'xyz-euandreh)
- (url "git://euandreh.xyz/package-repository")
- (branch "main")
- (introduction
- (make-channel-introduction
- "d749e053e6db365069cb9b2ef47a78b06f9e7361"
- (openpgp-fingerprint
- "5BDA E9B8 B2F6 C6BC BB0D 6CE5 81F9 0EC3 CD35 6060"))))
- %default-channels)</code></pre>
- </article>
-
- <article id="nix-instructions">
- <h2>Nix instructions</h2>
- <p>
- Add the overlay to your <code>/etc/nixox/configuration.nix</code>:
- </p>
- <pre></code>nixpkgs = {
- overlays = [
- (import (fetchTarball {
- url = "https://euandreh.xyz/package-repository.git/snapshot/package-repository-main.tar.gz";
- }) { inherit pkgs; })
- ];
-};</code></pre>
- </article>
- </body>
-</html>
-EOF
+ }
+ }
+ print '(list';
+ for (@pkgs) {
+ print "\n $_";
+ }
+ print ")\n";
+ exit;
}
-while getopts 'grl' flag; do
- case "$flag" in
- g)
- gen_guix
- # gen_nix
- # gen_homebrew
- ;;
- r)
- refresh_packages
- ;;
- l)
- report_index
- ;;
- *)
- printf 'Unrecognized flag "%s".\n' "$flag" >&2
- ;;
- esac
-done
+
+print <<~EOF;
+ tarballs = \\
+ EOF
+for my $package (@{$json->{packages}}) {
+ for my $version (@{$package->{versions}}) {
+ print "\t$dir/tarballs/$version->{fname} \\\n";
+ }
+}
+print "\n";
+
+
+print <<~EOF;
+ checkouts = \\
+ EOF
+for my $package (@{$json->{packages}}) {
+ for my $version (@{$package->{versions}}) {
+ print "\t$dir/checkouts/$package->{name}-$version->{name} \\\n";
+ }
+}
+print "\n";
+
+
+print <<~EOF;
+ debian-destdirs = \\
+ EOF
+for my $package (@{$json->{packages}}) {
+ for my $version (@{$package->{versions}}) {
+ next if $version->{architectures} ne 'any';
+ print "\t$dir/debian-destdir/$package->{name}-$version->{name}/DEBIAN \\\n";
+ }
+}
+print "\n";
+
+
+print <<~EOF;
+ control-files = \\
+ EOF
+for my $package (@{$json->{packages}}) {
+ for my $version (@{$package->{versions}}) {
+ next if $version->{architectures} ne 'any';
+ print "\t$dir/debian-destdir/$package->{name}-$version->{name}/DEBIAN/control \\\n";
+ }
+}
+print "\n";
+
+
+print <<~EOF;
+ destdir-debs = \\
+ EOF
+for my $package (@{$json->{packages}}) {
+ for my $version (@{$package->{versions}}) {
+ next if $version->{architectures} ne 'any';
+ print "\t$dir/debian-destdir/$package->{name}-$version->{name}.deb \\\n";
+ }
+}
+print "\n";
+
+
+print <<~EOF;
+ debs = \\
+ EOF
+for my $package (@{$json->{packages}}) {
+ for my $version (@{$package->{versions}}) {
+ next if $version->{architectures} ne 'any';
+ print "\t$dir/debian/$package->{name}_$version->{name}_all.deb \\\n";
+ }
+}
+print "\n";
+
+
+print <<~EOF;
+ FIXME = eu\@euandre.org
+
+
+ all: $dir/debian/InRelease $dir/debian/Release.gpg $dir/debian/public-key.asc
+
+ public-dir:
+ \@printf '$dir/debian'
+
+
+ $dir/debian/Packages: \$(debs)
+ cd \$(\@D) && dpkg-scanpackages -m . > \$(\@F)
+
+ $dir/debian/Release: $dir/debian/Packages
+ perl src/bin/paku release $dir/debian/Packages > \$\@
+
+ $dir/debian/Release.gpg: $dir/debian/Release
+ gpg -abs -o \$\@ $dir/debian/Release
+
+ $dir/debian/InRelease: $dir/debian/Release
+ gpg --default-key \$(FIXME) -a --clear-sign -o \$\@ $dir/debian/Release
+
+ $dir/debian/public-key.asc: $dir/debian/Release
+ gpg --armour --export \$(FIXME) > \$\@
+
+
+ EOF
+
+
+
+for my $package (@{$json->{packages}}) {
+ for my $version (@{$package->{versions}}) {
+ print <<~EOF;
+ $dir/tarballs/$version->{fname}:
+ mkdir -p \$(\@D)
+ wget -O \$\@ \\
+ '$version->{url}'
+
+ $dir/checkouts/$package->{name}-$version->{name}: $dir/tarballs/$version->{fname}
+ mkdir -p \$(\@D)
+ tar -C $dir/checkouts/ -xf $dir/tarballs/$version->{fname}
+ touch \$\@
+
+ EOF
+
+ next if $version->{architectures} ne 'any';
+ my $ver = $version->{type} eq 'latest' ? '0.' . $version->{name} . '.latest' : $version->{name};
+ $ver =~ s/^v//;
+ my $maintainer_b64 = MIME::Base64::encode_base64 $version->{maintainer}, '';
+ my $desc_b64 = MIME::Base64::encode_base64 $version->{description}, '';
+ my $long_desc_b64 = MIME::Base64::encode_base64 $version->{'long-description'}, '';
+
+
+ print <<~EOF;
+ $dir/debian-destdir/$package->{name}-$version->{name}/DEBIAN: $dir/checkouts/$package->{name}-$version->{name}
+ \$(MAKE) \\
+ -C $dir/checkouts/$package->{name}-$version->{name} \\
+ install \\
+ PREFIX=/usr \\
+ DESTDIR="\$\$PWD"/$dir/debian-destdir/$package->{name}-$version->{name}
+ mkdir -p \$\@
+ touch \$\@
+
+ $dir/debian-destdir/$package->{name}-$version->{name}/DEBIAN/control: $dir/debian-destdir/$package->{name}-$version->{name}/DEBIAN
+ printf '' > \$\@
+ printf 'Package: $package->{name}\\n' >> \$\@
+ printf 'Version: $ver\\n' >> \$\@
+ printf 'Section: custom\\n' >> \$\@
+ printf 'Depends:\\n' >> \$\@
+ printf 'Priority: optional\\n' >> \$\@
+ printf 'Architecture: all\\n' >> \$\@
+ printf 'Essential: no\\n' >> \$\@
+
+ printf 'Maintainer: ' >> \$\@
+ printf '$maintainer_b64' | base64 -d >> \$\@
+ printf '\\n' >> \$\@
+
+ printf 'Description: ' >> \$\@
+ printf '$desc_b64' | base64 -d >> \$\@
+ printf '\\n' >> \$\@
+
+ printf '$long_desc_b64' | \\
+ base64 -d | \\
+ sed 's|^\$\$|.|' | \\
+ sed 's|^| |' >> \$\@
+ printf '\\n' >> \$\@
+
+ $dir/debian-destdir/$package->{name}-$version->{name}.deb: $dir/debian-destdir/$package->{name}-$version->{name}/DEBIAN/control
+ dpkg-deb --build $dir/debian-destdir/$package->{name}-$version->{name}
+
+ $dir/debian/$package->{name}_$version->{name}_all.deb: $dir/debian-destdir/$package->{name}-$version->{name}.deb
+ mkdir -p \$(\@D)
+ cp $dir/debian-destdir/$package->{name}-$version->{name}.deb \$\@
+
+
+ EOF
+ }
+}