lerna
Version:
Lerna is a fast, modern build system for managing and publishing multiple JavaScript/TypeScript packages from the same repository
167 lines (165 loc) • 6.3 kB
JavaScript
import {
Command,
npmlog_default
} from "../../chunk-WC2B4V4E.js";
import "../../chunk-MLKGABMK.js";
// packages/lerna/src/commands/add-caching/index.ts
import {
joinPathFragments,
readJsonFile,
workspaceRoot,
writeJsonFile
} from "@nx/devkit";
import execa from "execa";
import fs from "fs-extra";
import inquirer from "inquirer";
function factory(argv) {
return new AddCachingCommand(argv);
}
var AddCachingCommand = class extends Command {
uniqueScriptNames = [];
constructor(argv) {
super(argv, { skipValidations: true });
}
initialize() {
if (this.options.useNx === false) {
this.logger.error(
"add-caching",
"The `add-caching` command is only available when using the Nx task runner (do not set `useNx` to `false` in `lerna.json`)"
);
process.exit(1);
}
const packages = Object.values(this.projectGraph.nodes).filter((p) => !!p.package).map((p) => p.package);
const uniqueScriptNames = /* @__PURE__ */ new Set();
for (const pkg of packages) {
for (const scriptName of Object.keys(pkg.scripts || {})) {
uniqueScriptNames.add(scriptName);
}
}
this.uniqueScriptNames = Array.from(uniqueScriptNames);
}
async execute() {
const nxJsonPath = joinPathFragments(workspaceRoot, "nx.json");
let nxJson = {};
try {
nxJson = readJsonFile(nxJsonPath);
} catch {
}
this.logger.info(
"add-caching",
"Please answer the following questions about the scripts found in your workspace in order to generate task runner configuration"
);
process.stdout.write("\n");
npmlog_default.pause();
const existingTargetDefaults = this.uniqueScriptNames.filter(
(scriptName) => this.getTargetDefaultEntries(nxJson, scriptName).some((entry) => entry.dependsOn?.length)
);
const { targetDefaults } = await inquirer.prompt([
{
type: "checkbox",
name: "targetDefaults",
message: "Which scripts need to be run in order? (e.g. before building a project, dependent projects must be built.)\n",
choices: this.uniqueScriptNames,
default: existingTargetDefaults
}
]);
const existingCacheableOperations = this.uniqueScriptNames.filter(
(scriptName) => this.getTargetDefaultEntries(nxJson, scriptName).some((entry) => entry.cache)
);
const { cacheableOperations } = await inquirer.prompt([
{
type: "checkbox",
name: "cacheableOperations",
message: "Which scripts are cacheable? (Produce the same output given the same input, e.g. build, test and lint usually are, serve and start are not.)\n",
choices: this.uniqueScriptNames,
default: existingCacheableOperations
}
]);
const scriptOutputs = {};
for (const scriptName of cacheableOperations) {
scriptOutputs[scriptName] = await inquirer.prompt([
{
type: "input",
name: scriptName,
message: `Does the "${scriptName}" script create any outputs? If not, leave blank, otherwise provide a path relative to a project root (e.g. dist, lib, build, coverage)
`
}
]);
}
npmlog_default.resume();
process.stdout.write("\n");
this.convertAnswersToNxConfig({ cacheableOperations, targetDefaults, scriptOutputs }, nxJsonPath, nxJson);
await this.configureGitIgnore();
this.logger["success"]("add-caching", "Successfully updated task runner configuration in `nx.json`");
this.logger.info(
"add-caching",
"Learn more about task runner configuration here: https://lerna.js.org/docs/concepts/task-pipeline-configuration"
);
this.logger.info(
"add-caching",
"Note that the legacy task runner options of --sort, --no-sort and --parallel no longer apply. Learn more here: https://lerna.js.org/docs/lerna6-obsolete-options"
);
}
convertAnswersToNxConfig(answers, nxJsonPath, nxJson) {
if (nxJson.targetDefaults) {
this.logger.warn(
"add-caching",
"The `targetDefaults` property already exists in `nx.json` and will be overwritten by your answers"
);
}
const targetDefaults = nxJson.targetDefaults || {};
nxJson.targetDefaults = targetDefaults;
for (const scriptName of this.uniqueScriptNames) {
const targetDefault = this.getObjectFormTargetDefault(targetDefaults, scriptName);
if (answers.cacheableOperations.includes(scriptName)) {
targetDefault.cache = true;
} else {
delete targetDefault.cache;
}
targetDefault.dependsOn = answers.targetDefaults.includes(scriptName) ? [`^${scriptName}`] : [];
}
for (const [scriptName, scriptAnswerData] of Object.entries(answers.scriptOutputs)) {
if (!scriptAnswerData[scriptName]) {
continue;
}
const targetDefault = this.getObjectFormTargetDefault(targetDefaults, scriptName);
targetDefault.outputs = [`{projectRoot}/${scriptAnswerData[scriptName]}`];
}
writeJsonFile(nxJsonPath, nxJson);
}
// Nx 23 target defaults can also be an ordered array of filtered entries
getTargetDefaultEntries(nxJson, scriptName) {
const value = nxJson.targetDefaults?.[scriptName];
return Array.isArray(value) ? value : value ? [value] : [];
}
// Array-form target defaults cannot represent the per-script answers,
// so array-form entries are replaced with a plain object.
getObjectFormTargetDefault(targetDefaults, scriptName) {
const existing = targetDefaults[scriptName];
const targetDefault = existing && !Array.isArray(existing) ? existing : {};
targetDefaults[scriptName] = targetDefault;
return targetDefault;
}
async configureGitIgnore() {
try {
await execa("git", ["check-ignore", ".nx/cache"]);
} catch (e) {
try {
await fs.appendFile(joinPathFragments(workspaceRoot, ".gitignore"), "\n.nx/cache\n");
} catch (e2) {
this.logger.warn(
"add-caching",
"Failed to update `.gitignore` with `.nx/cache`. Please update manually."
);
}
}
}
};
var commonJsExport = Object.assign(factory, { AddCachingCommand });
var add_caching_default = commonJsExport;
export {
AddCachingCommand,
add_caching_default as default,
factory,
commonJsExport as "module.exports"
};