()
| 71 | } |
| 72 | |
| 73 | override async execute() { |
| 74 | this.logger.info( |
| 75 | "", |
| 76 | "Executing command in %d %s: %j", |
| 77 | this.count, |
| 78 | this.packagePlural, |
| 79 | this.joinedCommand |
| 80 | ); |
| 81 | |
| 82 | let runCommand: () => Promise<unknown>; |
| 83 | if (this.options.parallel) { |
| 84 | runCommand = () => this.runCommandInPackagesParallel(); |
| 85 | } else if (this.toposort) { |
| 86 | runCommand = () => this.runCommandInPackagesTopological(); |
| 87 | } else { |
| 88 | runCommand = () => this.runCommandInPackagesLexical(); |
| 89 | } |
| 90 | |
| 91 | if (this.bail) { |
| 92 | // only the first error is caught |
| 93 | try { |
| 94 | await runCommand(); |
| 95 | } catch (err: any) { |
| 96 | process.exitCode = err.exitCode; |
| 97 | // rethrow to halt chain and log properly |
| 98 | throw err; |
| 99 | } |
| 100 | } else { |
| 101 | const results = (await runCommand()) as { failed: boolean; exitCode: number }[]; |
| 102 | // detect error (if any) from collected results |
| 103 | if (results.some((result) => result.failed)) { |
| 104 | // propagate "highest" error code, it's probably the most useful |
| 105 | const codes = results.filter((result) => result.failed).map((result) => result.exitCode); |
| 106 | const exitCode = Math.max(...codes, 1); |
| 107 | |
| 108 | this.logger.error("", "Received non-zero exit code %d during execution", exitCode); |
| 109 | process.exitCode = exitCode; |
| 110 | } |
| 111 | } |
| 112 | |
| 113 | this.logger.success( |
| 114 | "exec", |
| 115 | "Executed command in %d %s: %j", |
| 116 | this.count, |
| 117 | this.packagePlural, |
| 118 | this.joinedCommand |
| 119 | ); |
| 120 | } |
| 121 | |
| 122 | private getOpts(pkg: Package) { |
| 123 | // these options are passed _directly_ to execa |
nothing calls this directly
no test coverage detected