@enspirit/emb
Version:
A replacement for our Makefile-for-monorepos
57 lines (56 loc) • 1.78 kB
JavaScript
import { spawn } from 'node:child_process';
import * as z from 'zod';
import { ShellExitError } from '../../../errors.js';
import { AbstractOperation } from '../../../operations/index.js';
const schema = z.object({
shell: z.string().default('bash').optional(),
service: z
.string()
.describe('The name of the compose service to exec a shell'),
});
export class ComposeExecShellOperation extends AbstractOperation {
constructor() {
super(schema);
}
async _run(input) {
const { monorepo } = this.context;
const cmd = 'docker';
const args = ['compose', 'exec', input.service, input.shell || 'bash'];
const child = spawn(cmd, args, {
stdio: 'inherit',
cwd: monorepo.rootDir,
env: {
...process.env,
DOCKER_CLI_HINTS: 'false',
},
});
const forward = (sig) => {
try {
child.kill(sig);
}
catch { }
};
const signals = [
'SIGINT',
'SIGTERM',
'SIGHUP',
'SIGQUIT',
];
signals.forEach((sig) => {
process.on(sig, () => forward(sig));
});
return new Promise((resolve, reject) => {
child.on('error', (err) => {
reject(new Error(`Failed to execute docker: ${err.message}`));
});
child.on('exit', (code, signal) => {
if (code !== null && code !== 0) {
reject(new ShellExitError(`The shell exited unexpectedly. ${code}`, input.service, code, signal));
}
else {
resolve();
}
});
});
}
}