96 lines
3.2 KiB
JavaScript
96 lines
3.2 KiB
JavaScript
import { cp, mkdir, readFile, readdir, rm, writeFile } from "node:fs/promises";
|
|
import path from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
const publicDirectory = path.join(root, "public");
|
|
const required = [
|
|
"LICENSE",
|
|
"README.md",
|
|
"CHANGELOG.md",
|
|
"SOURCE.md",
|
|
"THIRD_PARTY_NOTICES.md",
|
|
];
|
|
|
|
await mkdir(publicDirectory, { recursive: true });
|
|
for (const name of required) {
|
|
const source = path.join(root, name);
|
|
await readFile(source);
|
|
await cp(source, path.join(publicDirectory, name));
|
|
}
|
|
|
|
const publicLicenses = path.join(publicDirectory, "LICENSES");
|
|
await rm(publicLicenses, { recursive: true, force: true });
|
|
await cp(path.join(root, "LICENSES"), publicLicenses, { recursive: true });
|
|
const publicDocs = path.join(publicDirectory, "docs");
|
|
await rm(publicDocs, { recursive: true, force: true });
|
|
await cp(path.join(root, "docs"), publicDocs, { recursive: true });
|
|
|
|
const lock = JSON.parse(
|
|
await readFile(path.join(root, "package-lock.json"), "utf8"),
|
|
);
|
|
const runtimeLicenseSections = [];
|
|
for (const [location, locked] of Object.entries(lock.packages ?? {}).sort(
|
|
([left], [right]) => (left < right ? -1 : left > right ? 1 : 0),
|
|
)) {
|
|
if (!location.includes("node_modules/") || locked.dev === true) continue;
|
|
const packageDirectory = path.join(root, location);
|
|
const details = JSON.parse(
|
|
await readFile(path.join(packageDirectory, "package.json"), "utf8"),
|
|
);
|
|
const candidates = (await readdir(packageDirectory))
|
|
.filter((name) => /^(?:licen[cs]e|copying|notice)(?:\.|$)/iu.test(name))
|
|
.sort();
|
|
const texts = [];
|
|
for (const candidate of candidates) {
|
|
try {
|
|
texts.push(
|
|
`--- ${candidate} ---\n${await readFile(path.join(packageDirectory, candidate), "utf8")}`,
|
|
);
|
|
} catch {
|
|
// Ignore directories or non-text aliases; another matching file may exist.
|
|
}
|
|
}
|
|
runtimeLicenseSections.push(
|
|
[
|
|
"=".repeat(78),
|
|
`${details.name}@${details.version}`,
|
|
`Declared licence: ${details.license ?? locked.license ?? "See upstream package"}`,
|
|
`Installed from: ${location}`,
|
|
"=".repeat(78),
|
|
texts.length
|
|
? texts.join("\n\n")
|
|
: "No package-local licence file was present; see THIRD_PARTY_NOTICES.md and the upstream source.",
|
|
].join("\n"),
|
|
);
|
|
}
|
|
await writeFile(
|
|
path.join(publicLicenses, "npm-runtime-licenses.txt"),
|
|
`${runtimeLicenseSections.join("\n\n")}\n`,
|
|
);
|
|
|
|
const packageJson = JSON.parse(
|
|
await readFile(path.join(root, "package.json"), "utf8"),
|
|
);
|
|
const rows = [
|
|
"# Runtime dependency licences",
|
|
"",
|
|
"Generated from the exact lock used for this build.",
|
|
"",
|
|
"| Package | Version | Licence |",
|
|
"| --- | --- | --- |",
|
|
];
|
|
for (const name of Object.keys(packageJson.dependencies).sort()) {
|
|
const manifestPath = path.join(root, "node_modules", name, "package.json");
|
|
const details = JSON.parse(await readFile(manifestPath, "utf8"));
|
|
rows.push(
|
|
`| \`${details.name}\` | ${details.version} | ${details.license ?? "See packaged notices"} |`,
|
|
);
|
|
}
|
|
await writeFile(
|
|
path.join(publicDirectory, "THIRD_PARTY_LICENSES.txt"),
|
|
`${rows.join("\n")}\n`,
|
|
);
|
|
|
|
console.log("Prepared static release notices");
|