UNPKG

@enspirit/emb

Version:

A replacement for our Makefile-for-monorepos

57 lines (56 loc) 1.78 kB
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(); } }); }); } }