UNPKG

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
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" };