2022-10-23 22:23:44 +09:00
|
|
|
import fs from "node:fs/promises";
|
2023-12-17 19:34:12 +00:00
|
|
|
import path from "node:path";
|
2021-12-02 19:47:14 +08:00
|
|
|
import { outdent } from "outdent";
|
2024-07-02 10:01:15 +08:00
|
|
|
import rollupPluginLicense from "rollup-plugin-license";
|
2025-04-09 08:38:46 +08:00
|
|
|
import { PROJECT_ROOT } from "../utils/index.js";
|
2021-12-02 19:47:14 +08:00
|
|
|
|
|
|
|
|
const separator = `\n${"-".repeat(40)}\n\n`;
|
|
|
|
|
|
2022-10-30 11:06:57 +08:00
|
|
|
function toBlockQuote(text) {
|
|
|
|
|
return text
|
|
|
|
|
.trim()
|
|
|
|
|
.split("\n")
|
|
|
|
|
.map((line) => (line ? `> ${line}` : ">"))
|
|
|
|
|
.join("\n");
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-02 10:01:15 +08:00
|
|
|
function getDependencies(results) {
|
|
|
|
|
// A fake rollup chunk
|
|
|
|
|
const chunk = {
|
|
|
|
|
modules: Object.fromEntries(
|
|
|
|
|
results
|
|
|
|
|
.flatMap((result) =>
|
|
|
|
|
Object.keys(result.esbuildResult?.metafile.inputs ?? {}),
|
|
|
|
|
)
|
|
|
|
|
.map((file) => [file, { renderedLength: 1 }]),
|
|
|
|
|
),
|
|
|
|
|
};
|
2022-09-25 11:50:59 +08:00
|
|
|
|
2024-07-02 10:01:15 +08:00
|
|
|
let dependencies;
|
|
|
|
|
const plugin = rollupPluginLicense({
|
|
|
|
|
cwd: PROJECT_ROOT,
|
|
|
|
|
thirdParty: {
|
|
|
|
|
includePrivate: true,
|
|
|
|
|
output(_dependencies) {
|
|
|
|
|
dependencies = _dependencies;
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
plugin.renderChunk("", chunk);
|
|
|
|
|
plugin.generateBundle();
|
|
|
|
|
|
|
|
|
|
return dependencies;
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-09 18:34:14 +08:00
|
|
|
function getLicenseText(dependencies) {
|
2021-12-02 19:47:14 +08:00
|
|
|
dependencies = dependencies.filter(
|
|
|
|
|
(dependency, index) =>
|
2022-09-25 11:50:59 +08:00
|
|
|
// Exclude ourself
|
|
|
|
|
dependency.name !== "prettier" &&
|
|
|
|
|
// Unique by `name` and `version`
|
2021-12-02 19:47:14 +08:00
|
|
|
index ===
|
2022-09-25 11:50:59 +08:00
|
|
|
dependencies.findIndex(
|
|
|
|
|
({ name, version }) =>
|
|
|
|
|
dependency.name === name && dependency.version === version,
|
|
|
|
|
),
|
2021-12-02 19:47:14 +08:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
dependencies.sort(
|
|
|
|
|
(dependencyA, dependencyB) =>
|
|
|
|
|
dependencyA.name.localeCompare(dependencyB.name) ||
|
|
|
|
|
dependencyA.version.localeCompare(dependencyB.version),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const licenses = [
|
|
|
|
|
...new Set(
|
|
|
|
|
dependencies
|
|
|
|
|
.filter(({ license }) => license)
|
|
|
|
|
.map(({ license }) => license),
|
|
|
|
|
),
|
|
|
|
|
];
|
2022-09-25 11:50:59 +08:00
|
|
|
|
2025-02-09 18:34:14 +08:00
|
|
|
const head = outdent`
|
|
|
|
|
# Licenses of bundled dependencies
|
2021-12-02 19:47:14 +08:00
|
|
|
|
2025-02-09 18:34:14 +08:00
|
|
|
The published Prettier artifact additionally contains code with the following licenses:
|
|
|
|
|
${new Intl.ListFormat("en-US", { type: "conjunction" }).format(licenses)}.
|
2021-12-02 19:47:14 +08:00
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
const content = dependencies
|
|
|
|
|
.map((dependency) => {
|
2025-02-09 18:34:14 +08:00
|
|
|
let text = `## ${dependency.name}@v${dependency.version}\n`;
|
2021-12-02 19:47:14 +08:00
|
|
|
|
|
|
|
|
const meta = [];
|
|
|
|
|
|
2022-10-30 11:06:57 +08:00
|
|
|
if (dependency.description) {
|
|
|
|
|
meta.push(toBlockQuote(dependency.description) + "\n");
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-02 19:47:14 +08:00
|
|
|
if (dependency.license) {
|
2025-02-09 18:34:14 +08:00
|
|
|
meta.push(`License: ${dependency.license} `);
|
2021-12-02 19:47:14 +08:00
|
|
|
}
|
2022-10-30 11:06:57 +08:00
|
|
|
if (dependency.homepage) {
|
2025-02-09 18:34:14 +08:00
|
|
|
meta.push(`Homepage: <${dependency.homepage}> `);
|
2021-12-02 19:47:14 +08:00
|
|
|
}
|
|
|
|
|
if (dependency.repository?.url) {
|
2025-02-09 18:34:14 +08:00
|
|
|
meta.push(`Repository: <${dependency.repository.url}> `);
|
2021-12-02 19:47:14 +08:00
|
|
|
}
|
2022-10-30 11:06:57 +08:00
|
|
|
if (dependency.author) {
|
2025-02-09 18:34:14 +08:00
|
|
|
meta.push(`Author: ${dependency.author.text()} `);
|
2022-10-30 11:06:57 +08:00
|
|
|
}
|
|
|
|
|
if (dependency.contributors?.length > 0) {
|
|
|
|
|
const contributors = dependency.contributors
|
|
|
|
|
.map((contributor) => ` - ${contributor.text()}`)
|
|
|
|
|
.join("\n");
|
|
|
|
|
|
|
|
|
|
meta.push(`Contributors:\n${contributors}`);
|
|
|
|
|
}
|
2021-12-02 19:47:14 +08:00
|
|
|
|
|
|
|
|
if (meta.length > 0) {
|
|
|
|
|
text += "\n" + meta.join("\n") + "\n";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (dependency.licenseText) {
|
2022-10-30 11:06:57 +08:00
|
|
|
text += "\n" + toBlockQuote(dependency.licenseText) + "\n";
|
2021-12-02 19:47:14 +08:00
|
|
|
}
|
|
|
|
|
return text;
|
|
|
|
|
})
|
|
|
|
|
.join(separator);
|
|
|
|
|
|
2025-02-09 18:34:14 +08:00
|
|
|
return [head, content].join("\n\n");
|
2021-12-02 19:47:14 +08:00
|
|
|
}
|
|
|
|
|
|
2025-04-09 08:38:46 +08:00
|
|
|
async function buildDependenciesLicense({
|
|
|
|
|
packageConfig,
|
|
|
|
|
file,
|
|
|
|
|
results,
|
|
|
|
|
cliOptions,
|
|
|
|
|
}) {
|
|
|
|
|
const { distDirectory, files } = packageConfig;
|
|
|
|
|
|
2025-02-09 18:34:14 +08:00
|
|
|
const fileName = file.output.file;
|
|
|
|
|
|
2024-07-02 10:01:15 +08:00
|
|
|
if (files.at(-1) !== file) {
|
2025-02-09 18:34:14 +08:00
|
|
|
throw new Error(`${fileName} should be last file to build.`);
|
2022-09-25 11:50:59 +08:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 10:01:15 +08:00
|
|
|
const shouldBuildLicense =
|
|
|
|
|
!cliOptions.playground &&
|
|
|
|
|
!cliOptions.files &&
|
|
|
|
|
typeof cliOptions.minify !== "boolean";
|
|
|
|
|
|
|
|
|
|
if (!shouldBuildLicense) {
|
2025-02-09 18:34:14 +08:00
|
|
|
return { skipped: true };
|
2022-09-25 11:50:59 +08:00
|
|
|
}
|
|
|
|
|
|
2024-07-02 10:01:15 +08:00
|
|
|
const dependencies = getDependencies(results);
|
|
|
|
|
|
|
|
|
|
if (dependencies.length === 0) {
|
|
|
|
|
throw new Error("Fail to collect dependencies.");
|
2022-09-25 11:50:59 +08:00
|
|
|
}
|
|
|
|
|
|
2025-02-09 18:34:14 +08:00
|
|
|
const text = getLicenseText(dependencies);
|
2022-09-25 11:50:59 +08:00
|
|
|
|
2025-04-09 08:38:46 +08:00
|
|
|
await fs.writeFile(path.join(distDirectory, fileName), text);
|
2022-09-25 11:50:59 +08:00
|
|
|
}
|
|
|
|
|
|
2025-02-09 18:34:14 +08:00
|
|
|
export default buildDependenciesLicense;
|