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>
72 lines
2.7 KiB
JavaScript
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, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
|
|
// 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).`);
|