Files
Jungfraujoch/viewer/resources/generate_licenses_html.mjs
T
leonarski_fandClaude Opus 4.8 e5034d0a2c licenses: add third-party notices, attribution texts, and viewer license window
Acknowledge all bundled third-party software and satisfy attribution/notice
requirements, while keeping it maintainable:

- THIRD_PARTY_NOTICES.md: human-readable manifest (component, copyright, SPDX
  license, link) for fetched, vendored, and runtime/SDK dependencies.
- licenses/: verbatim license texts; COLLECT.sh regenerates them from the
  build trees and system SDK locations.
- Bundle the verbatim Qt LGPL-3.0 text and the CUDA Toolkit 12.8 EULA.
- frontend: self-contained npm attribution generator (`npm run licenses` ->
  dist/THIRD_PARTY_LICENSES.txt), wired into the frontend build target.
- Install LICENSE + notices + licenses/ into share/doc/jfjoch for every
  packaged component.
- viewer: Help > "Third-party Licenses" window (QTextBrowser) showing a
  generated, self-contained HTML built from licenses/.
- docs/SOFTWARE.md: drop the stale hand-kept dependency lists; point at the
  manifest.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 18:35:50 +02:00

72 lines
2.7 KiB
JavaScript

// Generate viewer/resources/third_party_licenses.html from the repo-level licenses/ texts.
//
// The viewer embeds this file as a Qt resource (:/third_party_licenses.html) and shows it in the
// "Third-party Licenses" window (QTextBrowser). It is committed so the Windows/macOS viewer build
// needs no generator at build time; re-run this on Linux when licenses/ changes:
//
// node viewer/resources/generate_licenses_html.mjs
//
import { readFileSync, readdirSync, writeFileSync } from "node:fs";
import { join, dirname } from "node:path";
import { fileURLToPath } from "node:url";
const here = dirname(fileURLToPath(import.meta.url));
const licensesDir = join(here, "..", "..", "licenses");
const outFile = join(here, "third_party_licenses.html");
const esc = (s) =>
s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
// Friendlier titles for the few non-obvious file names; otherwise the file stem is used.
const titles = {
"Qt6-NOTICE": "Qt 6",
"Qt6-LGPL-3.0": "Qt 6 — LGPL-3.0 (full text)",
"NVIDIA-CUDA-NOTICE": "NVIDIA CUDA Toolkit",
"NVIDIA-CUDA-EULA": "NVIDIA CUDA Toolkit — EULA (full text)",
"base64-macaron": "Base64 (Macaron)",
"cpp-httplib": "cpp-httplib",
"eigen-README": "Eigen (notes)",
"fast-feedback-indexer": "Fast feedback indexer",
"nlohmann-json": "nlohmann/json",
"xbflash-qspi": "xbflash.qspi",
"xilinx-hls-headers": "Xilinx HLS arbitrary-precision headers",
"slsDetectorPackage-GPL-3.0": "slsDetectorPackage (GPL-3.0)",
"slsDetectorPackage-LGPL-3.0": "slsDetectorPackage (LGPL-3.0)",
};
const files = readdirSync(licensesDir)
.filter((f) => f.endsWith(".txt"))
.sort((a, b) => a.localeCompare(b));
const entries = files.map((f) => {
const stem = f.replace(/\.txt$/, "");
return { id: stem, title: titles[stem] || stem, text: readFileSync(join(licensesDir, f), "utf8").trimEnd() };
});
const toc = entries.map((e) => `<li><a href="#${e.id}">${esc(e.title)}</a></li>`).join("\n");
const sections = entries
.map((e) => `<h2 id="${e.id}">${esc(e.title)}</h2>\n<pre>${esc(e.text)}</pre>`)
.join("\n<hr>\n");
const html = `<!DOCTYPE html>
<!-- Generated by viewer/resources/generate_licenses_html.mjs - do not edit by hand. -->
<html>
<head><meta charset="utf-8"><title>Third-party licenses</title></head>
<body>
<h1>Third-party software licenses</h1>
<p>The Jungfraujoch viewer is licensed under the GNU General Public License v3 (GPL-3.0).
It builds on the third-party components listed below, each under its own license. The complete
manifest with copyright holders is in THIRD_PARTY_NOTICES.md in the source distribution.</p>
<h2>Contents</h2>
<ul>
${toc}
</ul>
<hr>
${sections}
</body>
</html>
`;
writeFileSync(outFile, html, "utf8");
console.log(`Wrote ${outFile} (${entries.length} components).`);