scripts/generate-versions.jq (98 lines of code) (raw):
#!/usr/bin/env -S jq -e -f
# https://github.com/tianon/debian-bin/blob/master/jq/dpkg-version.jq
def version_sort_split: (
[
if index(":") then . else "0:" + . end # force epoch to be specified
| if index("-") then . else . + "-0" end # force revision to be specified
| scan("[0-9]+|[:~-]|[^0-9:~-]+")
| try tonumber // (
split("")
| map(
# https://metacpan.org/release/GUILLEM/Dpkg-1.20.9/source/lib/Dpkg/Version.pm#L338-350
if . == "~" then
-2
elif . == "-" or . == ":" then # account for me being a little *too* clever (as discovered by using the Dpkg_Version.t test suite)
-1
else
explode[0]
+ if test("[a-zA-Z]") then 0 else 256 end
end
)
)
] + [[0]] # gotta add an extra [0] at the end to make sure "1.0" ([1,[302],0]) is higher than "1.0~" ([1,[302],0,[-1]])
);
# Example values:
# moby-engine_20.10.9+azure-1
# moby-engine_20.10.17+azure-ubuntu22.04u3
def deb_version(pkg): capture("^\(pkg)_(?<version>\\d+\\.\\d+\\.\\d+)(\\+azure)?\\-(\\w+\\d+(\\.\\d+)?u)?(?<revision>\\d+)");
# Example values:
# moby-engine-20.10.17+azure-1
def rpm_version(pkg): capture("^\(pkg)\\-(?<version>\\d+\\.\\d+\\.\\d+)(\\+azure)?\\-(?<revision>\\d+).*");
# Example values:
# moby-engine-20.10.17+azure-u3
# moby-engine-20.10.2+azure-1
def zip_version(pkg): capture("^\(pkg)\\-(?<version>\\d+\\.\\d+\\.\\d+)(\\+azure)?-\\u?(?<revision>\\d+).*");
def get_version(pkg): if test("\\.rpm$") then rpm_version(pkg) elif test("\\.zip$") then zip_version(pkg) else deb_version(pkg) end;
def parse_version: (
capture("^(?<major>\\d+)\\.(?<minor>\\d+)\\.(?<patch>\\d+)\\-(?<revision>\\d+)$")
| {major: .major | tonumber, minor: .minor | tonumber, patch: .patch | tonumber, revision: .revision | tonumber, prefix: "\(.major).\(.minor)"}
);
def join_arch: if .variant == null then .arch else "\(.arch)/\(.variant)" end;
def get_arch: split("_") | {os: .[0], arch: .[1], variant: .[2]} | join_arch;
def get_package: (
split("/") as $split
| { name: $split[0], distro: $split[2], version: $split[-1] | get_version($split[0]) | "\(.version)-\(.revision)", uri: "\($URL_PREFIX)/\(.)", arch: $split[3] | get_arch }
);
def version_gte(other): (
if . == other then true
elif .major < other.major then false
elif .major > other.major then true
elif .minor < other.minor then false
elif .minor > other.minor then true
elif .patch < other.patch then false
elif .patch > other.patch then true
elif .revision < other.revision then false
elif .revision > other.revision then true
else false
end
);
def get_min: (
$minVersions[.name] as $min
| if $min == null then "0.0.0-0" | parse_version else
$min | parse_version
end
);
def check_min_version: (
. as $self
| $self.version | parse_version | version_gte($self | get_min)
);
def reduce_pkg: reduce(.[]) as $item (
[]; . += [$item.name | get_package + {sha256: $item.sha256}]
) | map(select(check_min_version)) | sort_by(.name, .version | version_sort_split);
def sort_by_version: sort_by( .version | version_sort_split);
def only_latest: (
sort_by(.version | version_sort_split) | group_by(.distro, .name, .arch) | reduce(.[]) as $group ([]; . += [$group[-1]])
);
def build_index(filter): (
reduce(.[]) as $item (
{}; .[$item.distro][$item.name] += [$item]
)
);
def distros: map(.distro) | unique;
def only_distro(distro): select(.distro == distro);
def distro_packages(distro): map(only_distro(distro) | .name) | unique;
def build_index: build_index(.);
def to_rss: reduce(.[]) as $item (
""; . += "
<item>
<guid>\($item.uri)</guid>
<title>\($item.name) \($item.version) \($item.arch)</title>
<link>\($item.uri)</link>
<description>
Package: \($item.name), Version: \($item.version), Architecture: \($item.arch)
SHA256 Digest: \($item.sha256)
\($item.uri)
</description>
</item>
"
);