* Executes a command or command object (with parallel/sequential support) * @param {string|Object} command - Command string or command object with commands array * @returns {Promise} Promise that resolves when command(s) complete
(command, commandName = "unknown")
| 179 | * @returns {Promise} Promise that resolves when command(s) complete |
| 180 | */ |
| 181 | async executeCommand(command, commandName = "unknown") { |
| 182 | if (typeof command === "string" && command) { |
| 183 | return new Promise(async (resolve, reject) => { |
| 184 | if (command.trim().startsWith("ui5nps-script")) { |
| 185 | const argv = parseArgsStringToArgv(command); |
| 186 | if (!path.isAbsolute(argv[1])) { |
| 187 | throw new Error(`Script path must be absolute: ${argv[1]}`); |
| 188 | } |
| 189 | |
| 190 | const importPath = argv[1]; |
| 191 | const importedContent = require(importPath); |
| 192 | let _ui5mainFn; |
| 193 | |
| 194 | if (importedContent.__esModule) { |
| 195 | _ui5mainFn = importedContent.default._ui5mainFn; |
| 196 | } else { |
| 197 | _ui5mainFn = importedContent._ui5mainFn; |
| 198 | } |
| 199 | |
| 200 | if (!_ui5mainFn) { |
| 201 | return reject(new Error(`No valid _ui5mainFn function exported from ${importPath} tried to be executed with ui5nps-script. Either provide a valid _ui5mainFn function or use another way to execute the script (via node).`)); |
| 202 | } |
| 203 | |
| 204 | verboseLog(` | Executing command ${commandName} as module.`); |
| 205 | const result = _ui5mainFn(argv); |
| 206 | |
| 207 | if (result instanceof Promise) { |
| 208 | return result.then(resolve).catch(reject); |
| 209 | } else { |
| 210 | return resolve(); |
| 211 | } |
| 212 | } |
| 213 | |
| 214 | verboseLog(` | Executing command ${commandName} as command.\n Running: ${command}`); |
| 215 | const child = exec(command, { stdio: "inherit", env: { ...process.env, ...this.envs } }); |
| 216 | |
| 217 | child.stdout.on("data", (data) => { |
| 218 | verboseLog(data); |
| 219 | }); |
| 220 | |
| 221 | child.stderr.on("data", (data) => { |
| 222 | console.error(data); |
| 223 | }); |
| 224 | |
| 225 | child.on("error", (err) => { |
| 226 | console.error("Failed to start:", err); |
| 227 | reject(err); |
| 228 | }); |
| 229 | |
| 230 | child.on("close", (code) => { |
| 231 | code === 0 ? resolve() : reject(new Error(`Exit ${code}`)); |
| 232 | }); |
| 233 | }); |
| 234 | } else if (typeof command === "object" && command.commands) { |
| 235 | if (command.parallel) { |
| 236 | // Execute commands in parallel |
| 237 | const promises = command.commands.filter(Boolean).map(cmd => this.executeCommand(cmd, cmd.commandName || commandName)); |
| 238 | await Promise.all(promises); |