1 | "use strict";
|
2 | var __importDefault = (this && this.__importDefault) || function (mod) {
|
3 | return (mod && mod.__esModule) ? mod : { "default": mod };
|
4 | };
|
5 | Object.defineProperty(exports, "__esModule", { value: true });
|
6 | exports.RunCommand = exports.factory = void 0;
|
7 | const core_1 = require("@lerna-lite/core");
|
8 | const exec_run_common_1 = require("@lerna-lite/exec-run-common");
|
9 | const p_map_1 = __importDefault(require("p-map"));
|
10 | const lib_1 = require("./lib");
|
11 | function factory(argv) {
|
12 | return new RunCommand(argv);
|
13 | }
|
14 | exports.factory = factory;
|
15 | class RunCommand extends core_1.Command {
|
16 | constructor(argv) {
|
17 | super(argv);
|
18 |
|
19 | this.name = 'run';
|
20 | this.args = [];
|
21 | this.bail = false;
|
22 | this.prefix = false;
|
23 | this.npmClient = 'npm';
|
24 | this.packagesWithScript = [];
|
25 | this.script = '';
|
26 | }
|
27 | get requiresGit() {
|
28 | return false;
|
29 | }
|
30 | initialize() {
|
31 | const { script, npmClient = 'npm' } = this.options;
|
32 | this.script = script;
|
33 | this.args = this.options['--'] || [];
|
34 | this.npmClient = npmClient;
|
35 | if (!script) {
|
36 | throw new core_1.ValidationError('ENOSCRIPT', 'You must specify a lifecycle script to run');
|
37 | }
|
38 |
|
39 | this.bail = this.options.bail !== false;
|
40 | this.prefix = this.options.prefix !== false;
|
41 | let chain = Promise.resolve();
|
42 | if (!this.options.log) {
|
43 | this.options.log = this.logger;
|
44 | }
|
45 | chain = chain.then(() => (0, exec_run_common_1.getFilteredPackages)(this.packageGraph, this.execOpts, this.options));
|
46 | chain = chain.then((filteredPackages) => {
|
47 | this.packagesWithScript =
|
48 | script === 'env'
|
49 | ? filteredPackages
|
50 | : filteredPackages.filter((pkg) => pkg.scripts && pkg.scripts[script]);
|
51 | });
|
52 | return chain.then(() => {
|
53 | this.count = this.packagesWithScript.length;
|
54 | this.packagePlural = this.count === 1 ? 'package' : 'packages';
|
55 | this.joinedCommand = [this.npmClient, 'run', this.script].concat(this.args).join(' ');
|
56 | if (!this.count) {
|
57 | this.logger.info('run', `No packages found with the lifecycle script "${script}"`);
|
58 |
|
59 | return false;
|
60 | }
|
61 | });
|
62 | }
|
63 | execute() {
|
64 | this.logger.info('', 'Executing command in %d %s: %j', this.count, this.packagePlural, this.joinedCommand);
|
65 | let chain = Promise.resolve();
|
66 | const getElapsed = (0, lib_1.timer)();
|
67 | if (this.options.parallel) {
|
68 | this.logger.verbose('Parallel', this.joinedCommand);
|
69 | chain = chain.then(() => this.runScriptInPackagesParallel());
|
70 | }
|
71 | else if (this.toposort) {
|
72 | this.logger.verbose('Topological', this.joinedCommand);
|
73 | chain = chain.then(() => this.runScriptInPackagesTopological());
|
74 | }
|
75 | else {
|
76 | this.logger.verbose('Lexical', this.joinedCommand);
|
77 | chain = chain.then(() => this.runScriptInPackagesLexical());
|
78 | }
|
79 | if (this.bail) {
|
80 |
|
81 | chain = chain.catch((err) => {
|
82 | process.exitCode = err.exitCode;
|
83 |
|
84 | throw err;
|
85 | });
|
86 | }
|
87 | else {
|
88 |
|
89 | chain = chain.then((results) => {
|
90 |
|
91 | if (results.some((result) => result === null || result === void 0 ? void 0 : result.failed)) {
|
92 |
|
93 | const codes = results.filter((result) => result === null || result === void 0 ? void 0 : result.failed).map((result) => result.exitCode);
|
94 | const exitCode = Math.max(...codes, 1);
|
95 | this.logger.error('', 'Received non-zero exit code %d during execution', exitCode);
|
96 | if (!this.options.stream) {
|
97 | results
|
98 | .filter((result) => result === null || result === void 0 ? void 0 : result.failed)
|
99 | .forEach((result) => {
|
100 | this.logger.error('', result.pkg.name, result.stderr);
|
101 | });
|
102 | }
|
103 | process.exitCode = exitCode;
|
104 | }
|
105 | return results;
|
106 | });
|
107 | }
|
108 | return chain.then((results) => {
|
109 | const someFailed = results.some((result) => result === null || result === void 0 ? void 0 : result.failed);
|
110 | const logType = someFailed ? 'error' : 'success';
|
111 | this.logger[logType]('run', `Ran npm script '%s' in %d %s in %ss:`, this.script, this.count, this.packagePlural, (getElapsed() / 1000).toFixed(1));
|
112 | if (!this.bail) {
|
113 | results.forEach((result) => {
|
114 | if (result === null || result === void 0 ? void 0 : result.failed) {
|
115 | this.logger.error('', `- ${result.pkg.name}`);
|
116 | }
|
117 | else {
|
118 | this.logger.success('', ` - ${result.pkg.name}`);
|
119 | }
|
120 | });
|
121 | }
|
122 | else {
|
123 | this.logger.success('', this.packagesWithScript.map((pkg) => `- ${pkg.name}`).join('\n'));
|
124 | }
|
125 | });
|
126 | }
|
127 | getOpts(pkg) {
|
128 |
|
129 | return {
|
130 | args: this.args,
|
131 | npmClient: this.npmClient,
|
132 | prefix: this.prefix,
|
133 | reject: this.bail,
|
134 | pkg,
|
135 | };
|
136 | }
|
137 | getRunner() {
|
138 | return this.options.stream
|
139 | ? (pkg) => this.runScriptInPackageStreaming(pkg)
|
140 | : (pkg) => this.runScriptInPackageCapturing(pkg);
|
141 | }
|
142 | runScriptInPackagesTopological() {
|
143 | let profiler;
|
144 | let runner;
|
145 | if (this.options.profile) {
|
146 | profiler = new exec_run_common_1.Profiler({
|
147 | concurrency: this.concurrency,
|
148 | log: this.logger,
|
149 | outputDirectory: this.options.profileLocation,
|
150 | });
|
151 | const callback = this.getRunner();
|
152 | runner = (pkg) => profiler.run(() => callback(pkg), pkg.name);
|
153 | }
|
154 | else {
|
155 | runner = this.getRunner();
|
156 | }
|
157 | let chain = (0, core_1.runTopologically)(this.packagesWithScript, runner, {
|
158 | concurrency: this.concurrency,
|
159 | rejectCycles: this.options.rejectCycles,
|
160 | });
|
161 | if (profiler) {
|
162 | chain = chain.then((results) => profiler.output().then(() => results));
|
163 | }
|
164 | return chain;
|
165 | }
|
166 | runScriptInPackagesParallel() {
|
167 | return (0, p_map_1.default)(this.packagesWithScript, (pkg) => this.runScriptInPackageStreaming(pkg));
|
168 | }
|
169 | runScriptInPackagesLexical() {
|
170 | return (0, p_map_1.default)(this.packagesWithScript, this.getRunner(), { concurrency: this.concurrency });
|
171 | }
|
172 | runScriptInPackageStreaming(pkg) {
|
173 | if (this.options.cmdDryRun) {
|
174 | return this.dryRunScript(this.script, pkg.name);
|
175 | }
|
176 | const chain = (0, lib_1.npmRunScriptStreaming)(this.script, this.getOpts(pkg));
|
177 | if (!this.bail) {
|
178 | chain.then((result) => {
|
179 | return { ...result, pkg };
|
180 | });
|
181 | }
|
182 | return chain;
|
183 | }
|
184 | runScriptInPackageCapturing(pkg) {
|
185 | const getElapsed = (0, lib_1.timer)();
|
186 | if (this.options.cmdDryRun) {
|
187 | return this.dryRunScript(this.script, pkg.name);
|
188 | }
|
189 | return (0, lib_1.npmRunScript)(this.script, this.getOpts(pkg)).then((result) => {
|
190 | this.logger.info('run', `Ran npm script '%s' in '%s' in %ss:`, this.script, pkg.name, (getElapsed() / 1000).toFixed(1));
|
191 | (0, core_1.logOutput)(result.stdout);
|
192 | if (!this.bail) {
|
193 | return { ...result, pkg };
|
194 | }
|
195 | return result;
|
196 | });
|
197 | }
|
198 | dryRunScript(scriptName, pkgName) {
|
199 | this.logger.info('dry-run>', `Run npm script '%s' in '%s'`, scriptName, pkgName);
|
200 | (0, core_1.logOutput)(`dry-run> ${pkgName}`);
|
201 | return Promise.resolve();
|
202 | }
|
203 | }
|
204 | exports.RunCommand = RunCommand;
|
205 |
|
\ | No newline at end of file |