Skip to content

Commit a8c2f45

Browse files
committed
Greatly simplify script execution
1 parent ee60627 commit a8c2f45

File tree

1 file changed

+37
-54
lines changed

1 file changed

+37
-54
lines changed

src/job.ts

Lines changed: 37 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ export class Job {
163163
for (const rule of this.rules) {
164164
try {
165165
if (rule['if']) {
166-
const output = childProcess.execSync(`[ ${rule['if']} ] && exit 0 || exit 1`, {cwd: this.cwd, env: this.getEnvs()});
166+
const output = childProcess.execSync(`if [ ${rule['if']} ]; then exit 0; else exit 1; fi`, {cwd: this.cwd, env: this.getEnvs(), shell: 'bash'});
167167
if (output.length > 0) {
168168
process.stderr.write(`Rule output ${output}`);
169169
}
@@ -233,7 +233,7 @@ export class Job {
233233

234234
const startTime = process.hrtime();
235235
const prescripts = this.beforeScripts.concat(this.scripts);
236-
this.prescriptsExitCode = await this.exec(prescripts);
236+
this.prescriptsExitCode = await this.execScripts(prescripts);
237237
this.started = true;
238238
if (this.afterScripts.length === 0 && this.prescriptsExitCode > 0 && !this.allowFailure) {
239239
process.stderr.write(`${this.getExitedString(startTime, this.prescriptsExitCode, false)}\n`);
@@ -262,7 +262,7 @@ export class Job {
262262

263263
this.afterScriptsExitCode = 0;
264264
if (this.afterScripts.length > 0) {
265-
this.afterScriptsExitCode = await this.exec(this.afterScripts);
265+
this.afterScriptsExitCode = await this.execScripts(this.afterScripts);
266266
}
267267

268268
if (this.afterScriptsExitCode > 0) {
@@ -285,68 +285,51 @@ export class Job {
285285
return this.name;
286286
}
287287

288-
private async exec(scripts: string[]): Promise<number> {
288+
private async execScripts(scripts: string[]): Promise<number> {
289289
if (scripts.length === 0) {
290-
return Promise.resolve(0);
290+
return Promise.reject(new Error(`'scripts:' empty for ${this.name}`));
291291
}
292292

293+
const jobName = this.name;
293294
const jobNameStr = this.getJobNameString();
294295
const outputFilesPath = this.getOutputFilesPath();
296+
const scriptPath = `${this.cwd}.gitlab-ci-local/shell/${jobName}.sh`;
297+
298+
await fs.ensureFile(scriptPath);
299+
await fs.chmod(scriptPath, '755');
300+
await fs.truncate(scriptPath);
301+
302+
303+
await fs.appendFile(scriptPath, `#!/bin/bash\n`);
304+
await fs.appendFile(scriptPath, `set -e\n`);
305+
306+
for (const line of scripts) {
307+
await fs.appendFile(scriptPath, `echo '${c.green(`\$ ${line.replace(/[']/g, "\\''")}`)}'\n`);
308+
await fs.appendFile(scriptPath, `${line}\n`);
309+
}
295310

296311
return new Promise((resolve, reject) => {
297-
const bash = childProcess.spawn("bash", {cwd: this.cwd, env: this.getEnvs()});
298-
bash.on("error", (err) => {
299-
reject(err);
300-
});
301-
bash.on("close", (signal) => {
302-
resolve(signal);
303-
});
304-
305-
const nextCmd = () => {
306-
const script = scripts.shift();
307-
if (!script) {
308-
bash.stdin.write("exit 0\n");
309-
} else {
310-
process.stdout.write(`${jobNameStr} ${c.green(`\$ ${script}`)}\n`);
311-
bash.stdin.write(`${script};echo GCL_MARKER=$?\n`);
312-
}
313-
};
314-
315-
bash.stdout.on("data", (e) => {
316-
const out = `${e}`;
317-
const regExec = /GCL_MARKER=(?<exitCode>\d*)/.exec(out);
318-
const stripped = out.replace(/GCL_MARKER=\d*\n/, "");
319-
320-
if (stripped !== "") {
321-
for (const line of stripped.split(/\r?\n/)) {
322-
if (line !== "") {
323-
fs.appendFileSync(outputFilesPath, `${line}\n`);
324-
process.stdout.write(`${jobNameStr} ${c.greenBright(">")} ${line}\n`);
325-
}
312+
const p = childProcess.exec(`${scriptPath}`, { env: this.envs, cwd: this.cwd, shell: 'bash' });
313+
314+
const outFunc = (e: any, stream: NodeJS.WriteStream, colorize: (str: string) => string) => {
315+
for (const line of `${e}`.split(/\r?\n/)) {
316+
if (line.length === 0) continue;
317+
stream.write(`${jobNameStr} `);
318+
if (!line.startsWith('\u001b[32m$')) {
319+
stream.write(`${colorize(">")} `);
326320
}
321+
stream.write(`${line}\n`);
322+
fs.appendFileSync(outputFilesPath, `${line}\n`);
327323
}
324+
}
328325

329-
if (regExec && regExec.groups && regExec.groups.exitCode && regExec.groups.exitCode === "0") {
330-
nextCmd();
331-
} else if (regExec && regExec.groups && regExec.groups.exitCode && regExec.groups.exitCode !== "0") {
332-
bash.stdin.write(`exit ${regExec.groups.exitCode}\n`);
333-
} else if (regExec) {
334-
reject(`GCL_MARKER was not parsed correctly ${JSON.stringify(regExec)}`);
335-
}
336-
});
337-
bash.stderr.on("data", (e) => {
338-
const err = `${e}`;
339-
if (err !== "") {
340-
for (const line of err.split(/\r?\n/)) {
341-
if (line !== "") {
342-
fs.appendFileSync(outputFilesPath, `${line}\n`);
343-
process.stderr.write(`${jobNameStr} ${c.redBright(">")} ${line}\n`);
344-
}
345-
}
346-
}
347-
});
326+
// @ts-ignore
327+
p.stdout.on("data", (e) => outFunc(e, process.stdout, (s) => c.greenBright(s)));
328+
// @ts-ignore
329+
p.stderr.on("data", (e) => outFunc(e, process.stderr, (s) => c.redBright(s)));
348330

349-
nextCmd();
331+
p.on("error", (err) => reject(err));
332+
p.on("close", (signal) => resolve(signal));
350333
});
351334
}
352335

0 commit comments

Comments
 (0)