Actually ship the R libraries the modules need
The first full build succeeded and produced a package that would not have worked. Three separate causes, all silent: - R was configured --with-blas --with-lapack, so it linked Arch's external BLAS and never built libRblas.so/libRlapack.so. The JASP module bundles expect those inside R_HOME, the way a conventional R and the Flatpak ship them. Now --without-blas, with a hard check after install. - buildModuleBundlesLocally.R installs jaspModuleTools via install_github, which failed on anonymous GitHub rate limits. No bundles were produced at all. GITHUB_PAT is now required rather than merely recommended. - buildAllDefaultJaspModules.R calls the bundle builder through system2(), which ignores exit status, so all of the above exited 0. Added explicit guards: jaspModuleTools must exist, Modules/local must be non-empty, and the staged tree must contain the bundles and all three R libraries. Staging was also wrong: it copied ModuleBundleBuildDir/Modules, which is cloned module *sources* with zero compiled objects, while dropping LibraryR entirely - 267MB of R packages built against the bundled R.
This commit is contained in:
@@ -0,0 +1,192 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Render the index page for https://asger.weirsoe.dk/tarballz/.
|
||||
|
||||
Reads the sidecar .json files that publish-tarball.sh writes next to each
|
||||
tarball (on stdin, one JSON object per line) and emits a standalone HTML page.
|
||||
|
||||
The theme tokens are inlined rather than linked to the main site's stylesheet:
|
||||
that file is content-hashed (_astro/_slug_.<hash>.css) and its name changes on
|
||||
every site rebuild, so a link would silently rot. Inlining costs a few hundred
|
||||
bytes and cannot break.
|
||||
"""
|
||||
|
||||
import html
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from datetime import datetime, timezone
|
||||
|
||||
GITEA_URL = "https://gitea.weircon.dk/agw/jasp-desktop-bin"
|
||||
AUR_URL = "https://aur.archlinux.org/packages/jasp-desktop-bin"
|
||||
|
||||
PAGE = """<!doctype html>
|
||||
<html lang="da" data-theme="dark">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Tarballs · Asger Weirsøe</title>
|
||||
<meta name="description" content="Prækompilerede JASP-binærer til Arch Linux, bygget automatisk og udgivet på AUR som jasp-desktop-bin.">
|
||||
<meta name="robots" content="noindex">
|
||||
<link rel="icon" type="image/svg+xml" href="https://asger.weirsoe.dk/favicon.svg">
|
||||
<script>
|
||||
// Same localStorage key the main site uses, so the chosen theme carries over.
|
||||
// Inline and before paint, otherwise the page flashes the wrong theme.
|
||||
try {
|
||||
var t = localStorage.getItem('theme');
|
||||
if (!t) t = matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark';
|
||||
document.documentElement.dataset.theme = t;
|
||||
} catch (e) {}
|
||||
</script>
|
||||
<style>
|
||||
:root, :root[data-theme=dark] {
|
||||
color-scheme: dark;
|
||||
--bg:#0b0f17; --surface:#121a27; --surface-2:#182232;
|
||||
--border:#243044; --text:#e6e9ef; --muted:#97a3b6; --accent:#38bdf8;
|
||||
}
|
||||
:root[data-theme=light] {
|
||||
color-scheme: light;
|
||||
--bg:#f6f8fb; --surface:#fff; --surface-2:#eef2f8;
|
||||
--border:#dde4ee; --text:#0f1729; --muted:#54617a; --accent:#0284c7;
|
||||
}
|
||||
:root[data-theme=terminal] {
|
||||
color-scheme: dark;
|
||||
--bg:#050a06; --surface:#0a140c; --surface-2:#102012;
|
||||
--border:#1d3a22; --text:#4bff7e; --muted:#2fae57; --accent:#7dffa8;
|
||||
}
|
||||
* { box-sizing: border-box; }
|
||||
body {
|
||||
margin:0; background:var(--bg); color:var(--text);
|
||||
font-family:"Inter Variable", ui-sans-serif, system-ui, -apple-system, sans-serif;
|
||||
-webkit-font-smoothing:antialiased; line-height:1.6;
|
||||
}
|
||||
code, .mono { font-family:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; }
|
||||
a { color:var(--accent); text-decoration:none; }
|
||||
a:hover { text-decoration:underline; }
|
||||
header { border-bottom:1px solid color-mix(in srgb, var(--border) 70%, transparent); }
|
||||
.wrap { max-width:48rem; margin:0 auto; padding:0 1.25rem; }
|
||||
header .wrap { display:flex; align-items:center; justify-content:space-between; padding-top:.875rem; padding-bottom:.875rem; }
|
||||
.brand { font-weight:700; font-size:1.125rem; letter-spacing:-.025em; color:var(--text); }
|
||||
.brand span { color:var(--accent); }
|
||||
main { padding:3rem 0 1rem; }
|
||||
h1 { font-size:2.25rem; font-weight:700; letter-spacing:-.025em; margin:0; }
|
||||
.lede { color:var(--muted); margin-top:.75rem; }
|
||||
.card { border:1px solid var(--border); border-radius:1rem; background:color-mix(in srgb, var(--surface) 60%, transparent); padding:1.25rem; }
|
||||
.install { margin-top:1.75rem; }
|
||||
.install code { display:block; background:var(--surface-2); border-radius:.55rem; padding:.6rem .8rem; font-size:.875rem; overflow-x:auto; }
|
||||
h2 { font-size:1.25rem; font-weight:600; letter-spacing:-.025em; margin:2.5rem 0 1rem; }
|
||||
ul.releases { list-style:none; margin:0; padding:0; display:grid; gap:.75rem; }
|
||||
ul.releases li { border:1px solid var(--border); border-radius:1rem; background:color-mix(in srgb, var(--surface) 60%, transparent); padding:1rem 1.25rem; }
|
||||
.row { display:flex; flex-wrap:wrap; align-items:baseline; gap:.6rem; justify-content:space-between; }
|
||||
.ver { font-weight:600; font-size:1.05rem; }
|
||||
.meta { color:var(--muted); font-size:.8rem; }
|
||||
.sha { color:var(--muted); font-size:.75rem; word-break:break-all; margin-top:.5rem; }
|
||||
.empty { color:var(--muted); }
|
||||
footer { border-top:1px solid color-mix(in srgb, var(--border) 70%, transparent); margin-top:4rem; }
|
||||
footer .wrap { padding-top:1.5rem; padding-bottom:2rem; color:color-mix(in srgb, var(--muted) 80%, transparent); font-size:.8rem; }
|
||||
footer .note { font-size:.75rem; }
|
||||
@media (max-width:480px) { h1 { font-size:1.75rem; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<header><div class="wrap">
|
||||
<a class="brand" href="https://asger.weirsoe.dk/">Asger Weirsøe<span>.</span></a>
|
||||
<nav class="meta"><a href="https://asger.weirsoe.dk/projekter">Projekter</a></nav>
|
||||
</div></header>
|
||||
|
||||
<main class="wrap">
|
||||
<h1>Tarballs</h1>
|
||||
<p class="lede">
|
||||
Prækompilerede <a href="https://jasp-stats.org/">JASP</a>-binærer til Arch Linux.
|
||||
JASP udgiver kun installere til Windows og macOS, så disse er bygget fra
|
||||
kildekoden af <a href="{gitea}">en automatisk pipeline</a> og udgivet på AUR som
|
||||
<a href="{aur}">jasp-desktop-bin</a>.
|
||||
</p>
|
||||
|
||||
<div class="install">
|
||||
<p class="meta">Du behøver normalt ikke hente herfra manuelt — brug AUR:</p>
|
||||
<code>yay -S jasp-desktop-bin</code>
|
||||
</div>
|
||||
|
||||
<h2>Tilgængelige builds</h2>
|
||||
{releases}
|
||||
|
||||
<p class="meta" style="margin-top:1.5rem">
|
||||
Hver build indeholder sin egen R og de biblioteker den linker mod, så den ikke
|
||||
bindes til bestemte versioner af noget på dit system.
|
||||
Kun de nyeste {keep} builds gemmes.
|
||||
</p>
|
||||
</main>
|
||||
|
||||
<footer><div class="wrap">
|
||||
<p class="note mono">bygget automatisk · self-hosted på proxmox · <a href="{gitea}">byggeopskrift</a></p>
|
||||
<p>© {year} Asger Weirsøe</p>
|
||||
</div></footer>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
|
||||
|
||||
def human_size(n: int) -> str:
|
||||
for unit in ("B", "KB", "MB", "GB"):
|
||||
if n < 1024 or unit == "GB":
|
||||
return f"{n:.1f} {unit}".replace(".0 ", " ")
|
||||
n /= 1024
|
||||
return f"{n} B"
|
||||
|
||||
|
||||
def main() -> int:
|
||||
entries = []
|
||||
for line in sys.stdin:
|
||||
line = line.strip()
|
||||
if not line:
|
||||
continue
|
||||
try:
|
||||
entries.append(json.loads(line))
|
||||
except json.JSONDecodeError:
|
||||
print(f"warning: skipping unparsable sidecar line", file=sys.stderr)
|
||||
|
||||
# Newest first.
|
||||
entries.sort(key=lambda e: e.get("built", ""), reverse=True)
|
||||
|
||||
if entries:
|
||||
items = []
|
||||
for e in entries:
|
||||
name = html.escape(e["tarball"])
|
||||
ver = html.escape(e.get("jasp_version", "?"))
|
||||
built = e.get("built", "")
|
||||
try:
|
||||
built_h = datetime.fromisoformat(built).strftime("%d-%m-%Y")
|
||||
except ValueError:
|
||||
built_h = html.escape(built)
|
||||
size = human_size(int(e.get("size_bytes", 0)))
|
||||
sha = html.escape(e.get("sha256", ""))
|
||||
r = html.escape(e.get("bundled_r_version", ""))
|
||||
qt = html.escape(e.get("qt6_minor", ""))
|
||||
items.append(
|
||||
f' <li>\n'
|
||||
f' <div class="row">\n'
|
||||
f' <span class="ver">JASP {ver}</span>\n'
|
||||
f' <a href="{name}" download>Hent · {size}</a>\n'
|
||||
f' </div>\n'
|
||||
f' <div class="meta">{built_h} · x86_64 · bundlet R {r} · bygget mod Qt {qt}</div>\n'
|
||||
f' <div class="sha mono">sha256 {sha}</div>\n'
|
||||
f' </li>'
|
||||
)
|
||||
releases = '<ul class="releases">\n' + "\n".join(items) + "\n </ul>"
|
||||
else:
|
||||
releases = '<p class="empty">Ingen builds tilgængelige lige nu.</p>'
|
||||
|
||||
sys.stdout.write(
|
||||
PAGE.format(
|
||||
releases=releases,
|
||||
gitea=GITEA_URL,
|
||||
aur=AUR_URL,
|
||||
keep=len(entries) if entries else 3,
|
||||
year=datetime.now(timezone.utc).year,
|
||||
)
|
||||
)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user