UNPKG

lerna

Version:

Lerna is a fast, modern build system for managing and publishing multiple JavaScript/TypeScript packages from the same repository

154 lines (151 loc) 4.37 kB
import { Command, Profiler, ValidationError, filterProjects, getPackage, runProjectsTopologically, spawn, spawnStreaming } from "./chunk-WC2B4V4E.js"; // libs/commands/exec/src/index.ts import pMap from "p-map"; function factory(argv) { return new ExecCommand(argv); } var ExecCommand = class extends Command { command; args; bail; prefix; env; filteredProjects = []; count; packagePlural; joinedCommand = ""; get requiresGit() { return false; } async initialize() { const dashedArgs = this.options["--"] || []; this.command = this.options.cmd || dashedArgs.shift(); this.args = (this.options.args || []).concat(dashedArgs); if (!this.command) { throw new ValidationError("ENOCOMMAND", "A command to execute is required"); } this.bail = this.options.bail !== false; this.prefix = this.options.prefix !== false; this.env = Object.assign({}, process.env); this.filteredProjects = filterProjects(this.projectGraph, this.execOpts, this.options); this.count = this.filteredProjects.length; this.packagePlural = this.count === 1 ? "package" : "packages"; this.joinedCommand = [this.command].concat(this.args).join(" "); } async execute() { this.logger.info( "", "Executing command in %d %s: %j", this.count, this.packagePlural, this.joinedCommand ); let runCommand; if (this.options.parallel) { runCommand = () => this.runCommandInPackagesParallel(); } else if (this.toposort) { runCommand = () => this.runCommandInPackagesTopological(); } else { runCommand = () => this.runCommandInPackagesLexical(); } if (this.bail) { try { await runCommand(); } catch (err) { process.exitCode = err.exitCode; throw err; } } else { const results = await runCommand(); if (results.some((result) => result.failed)) { const codes = results.filter((result) => result.failed).map((result) => result.exitCode); const exitCode = Math.max(...codes, 1); this.logger.error("", "Received non-zero exit code %d during execution", exitCode); process.exitCode = exitCode; } } this.logger.success( "exec", "Executed command in %d %s: %j", this.count, this.packagePlural, this.joinedCommand ); } getOpts(pkg) { return { cwd: pkg.location, shell: true, extendEnv: false, env: Object.assign({}, this.env, { LERNA_PACKAGE_NAME: pkg.name, LERNA_ROOT_PATH: this.project.rootPath }), reject: this.bail, pkg }; } getRunner() { return this.options.stream ? (pkg) => this.runCommandInPackageStreaming(pkg) : (pkg) => this.runCommandInPackageCapturing(pkg); } getShellCommand() { return [this.joinedCommand, []]; } runCommandInPackagesTopological() { let profiler; let runner; if (this.options.profile) { profiler = new Profiler({ concurrency: this.concurrency, log: this.logger, outputDirectory: this.options.profileLocation || this.project.rootPath }); const callback = this.getRunner(); runner = (pkg) => profiler.run(() => callback(pkg), pkg.name); } else { runner = this.getRunner(); } let chain = runProjectsTopologically( this.filteredProjects, this.projectGraph, (p) => runner(getPackage(p)), { concurrency: this.concurrency, rejectCycles: this.options.rejectCycles } ); if (profiler) { chain = chain.then((results) => profiler.output().then(() => results)); } return chain; } runCommandInPackagesParallel() { return pMap(this.filteredProjects, (p) => this.runCommandInPackageStreaming(getPackage(p))); } runCommandInPackagesLexical() { return pMap(this.filteredProjects, (p) => this.getRunner()(getPackage(p)), { concurrency: this.concurrency }); } runCommandInPackageStreaming(pkg) { const [command, args] = this.getShellCommand(); return spawnStreaming(command, args, this.getOpts(pkg), this.prefix && pkg.name); } runCommandInPackageCapturing(pkg) { const [command, args] = this.getShellCommand(); return spawn(command, args, this.getOpts(pkg)); } }; export { factory, ExecCommand };