UNPKG

zx

Version:

A tool for writing better scripts

1,170 lines (1,165 loc) 34.8 kB
"use strict"; const { __spreadValues, __spreadProps, __export, __toESM, __toCommonJS, __async, __await, __asyncGenerator, __yieldStar, __forAwait } = require('./esblib.cjs'); // src/core.ts var core_exports = {}; __export(core_exports, { $: () => $, Fail: () => Fail, ProcessOutput: () => ProcessOutput, ProcessPromise: () => ProcessPromise, bus: () => import_internals.bus, cd: () => cd, chalk: () => import_vendor_core3.chalk, defaults: () => defaults, kill: () => kill, log: () => log, os: () => os, path: () => import_node_path.default, ps: () => import_vendor_core3.ps, quote: () => import_util2.quote, quotePowerShell: () => import_util2.quotePowerShell, resolveDefaults: () => resolveDefaults, syncProcessCwd: () => syncProcessCwd, useBash: () => useBash, usePowerShell: () => usePowerShell, usePwsh: () => usePwsh, which: () => import_vendor_core3.which, within: () => within }); module.exports = __toCommonJS(core_exports); var import_node_async_hooks = require("async_hooks"); var import_node_buffer = require("buffer"); var import_node_child_process = __toESM(require("child_process"), 1); var import_node_events = require("events"); var import_node_fs = __toESM(require("fs"), 1); var import_node_os = require("os"); var import_node_process2 = __toESM(require("process"), 1); var import_node_util2 = require("util"); // src/error.ts var EXIT_CODES = { 2: "Misuse of shell builtins", 126: "Invoked command cannot execute", 127: "Command not found", 128: "Invalid exit argument", 129: "Hangup", 130: "Interrupt", 131: "Quit and dump core", 132: "Illegal instruction", 133: "Trace/breakpoint trap", 134: "Process aborted", 135: 'Bus error: "access to undefined portion of memory object"', 136: 'Floating point exception: "erroneous arithmetic operation"', 137: "Kill (terminate immediately)", 138: "User-defined 1", 139: "Segmentation violation", 140: "User-defined 2", 141: "Write to pipe with no one reading", 142: "Signal raised by alarm", 143: "Termination (request to terminate)", 145: "Child process terminated, stopped (or continued*)", 146: "Continue if stopped", 147: "Stop executing temporarily", 148: "Terminal stop signal", 149: 'Background process attempting to read from tty ("in")', 150: 'Background process attempting to write to tty ("out")', 151: "Urgent data available on socket", 152: "CPU time limit exceeded", 153: "File size limit exceeded", 154: 'Signal raised by timer counting virtual time: "virtual timer expired"', 155: "Profiling timer expired", 157: "Pollable event", 159: "Bad syscall" }; var ERRNO_CODES = { 0: "Success", 1: "Not super-user", 2: "No such file or directory", 3: "No such process", 4: "Interrupted system call", 5: "I/O error", 6: "No such device or address", 7: "Arg list too long", 8: "Exec format error", 9: "Bad file number", 10: "No children", 11: "No more processes", 12: "Not enough core", 13: "Permission denied", 14: "Bad address", 15: "Block device required", 16: "Mount device busy", 17: "File exists", 18: "Cross-device link", 19: "No such device", 20: "Not a directory", 21: "Is a directory", 22: "Invalid argument", 23: "Too many open files in system", 24: "Too many open files", 25: "Not a typewriter", 26: "Text file busy", 27: "File too large", 28: "No space left on device", 29: "Illegal seek", 30: "Read only file system", 31: "Too many links", 32: "Broken pipe", 33: "Math arg out of domain of func", 34: "Math result not representable", 35: "File locking deadlock error", 36: "File or path name too long", 37: "No record locks available", 38: "Function not implemented", 39: "Directory not empty", 40: "Too many symbolic links", 42: "No message of desired type", 43: "Identifier removed", 44: "Channel number out of range", 45: "Level 2 not synchronized", 46: "Level 3 halted", 47: "Level 3 reset", 48: "Link number out of range", 49: "Protocol driver not attached", 50: "No CSI structure available", 51: "Level 2 halted", 52: "Invalid exchange", 53: "Invalid request descriptor", 54: "Exchange full", 55: "No anode", 56: "Invalid request code", 57: "Invalid slot", 59: "Bad font file fmt", 60: "Device not a stream", 61: "No data (for no delay io)", 62: "Timer expired", 63: "Out of streams resources", 64: "Machine is not on the network", 65: "Package not installed", 66: "The object is remote", 67: "The link has been severed", 68: "Advertise error", 69: "Srmount error", 70: "Communication error on send", 71: "Protocol error", 72: "Multihop attempted", 73: "Cross mount point (not really error)", 74: "Trying to read unreadable message", 75: "Value too large for defined data type", 76: "Given log. name not unique", 77: "f.d. invalid for this operation", 78: "Remote address changed", 79: "Can access a needed shared lib", 80: "Accessing a corrupted shared lib", 81: ".lib section in a.out corrupted", 82: "Attempting to link in too many libs", 83: "Attempting to exec a shared library", 84: "Illegal byte sequence", 86: "Streams pipe error", 87: "Too many users", 88: "Socket operation on non-socket", 89: "Destination address required", 90: "Message too long", 91: "Protocol wrong type for socket", 92: "Protocol not available", 93: "Unknown protocol", 94: "Socket type not supported", 95: "Not supported", 96: "Protocol family not supported", 97: "Address family not supported by protocol family", 98: "Address already in use", 99: "Address not available", 100: "Network interface is not configured", 101: "Network is unreachable", 102: "Connection reset by network", 103: "Connection aborted", 104: "Connection reset by peer", 105: "No buffer space available", 106: "Socket is already connected", 107: "Socket is not connected", 108: "Can't send after socket shutdown", 109: "Too many references", 110: "Connection timed out", 111: "Connection refused", 112: "Host is down", 113: "Host is unreachable", 114: "Socket already connected", 115: "Connection already in progress", 116: "Stale file handle", 122: "Quota exceeded", 123: "No medium (in tape drive)", 125: "Operation canceled", 130: "Previous owner died", 131: "State not recoverable" }; var DOCS_URL = "https://google.github.io/zx"; var _Fail = class _Fail extends Error { static formatExitMessage(code, signal, stderr, from, details = "") { if (code == 0 && signal == null) return `exit code: ${code}`; const codeInfo = _Fail.getExitCodeInfo(code); let message = `${stderr} at ${from} exit code: ${code}${codeInfo ? " (" + codeInfo + ")" : ""}`; if (signal != null) message += ` signal: ${signal}`; if (details) message += ` details: ${details}`; return message; } static formatErrorMessage(err, from) { return `${err.message} errno: ${err.errno} (${_Fail.getErrnoMessage(err.errno)}) code: ${err.code} at ${from}`; } static formatErrorDetails(lines = [], lim = 20) { if (lines.length < lim) return lines.join("\n"); let errors = lines.filter((l) => /(fail|error|not ok|exception)/i.test(l)); if (errors.length === 0) errors = lines; return errors.slice(0, lim).join("\n") + (errors.length > lim ? "\n..." : ""); } static getExitCodeInfo(exitCode) { return EXIT_CODES[exitCode]; } static getCallerLocationFromString(stackString = "unknown") { const lines = stackString.split(/^\s*(at\s)?/m).filter((s) => s == null ? void 0 : s.includes(":")); const i = lines.findIndex((l) => l.includes("Proxy.set")); const offset = i < 0 ? i : i + 2; return (lines.find((l) => l.includes("file://")) || lines[offset] || stackString).trim(); } static getCallerLocation(err = new Error("zx error")) { return _Fail.getCallerLocationFromString(err.stack); } static getErrnoMessage(errno) { return ERRNO_CODES[-errno] || "Unknown error"; } }; _Fail.DOCS_URL = DOCS_URL; _Fail.EXIT_CODES = EXIT_CODES; _Fail.ERRNO_CODES = ERRNO_CODES; var Fail = _Fail; // src/log.ts var import_vendor_core = require("./vendor-core.cjs"); var import_node_util = require("util"); var import_node_process = __toESM(require("process"), 1); var formatters = { cmd({ cmd }) { return formatCmd(cmd); }, stdout({ data }) { return data; }, stderr({ data }) { return data; }, custom({ data }) { return data; }, fetch(entry) { const init = entry.init ? " " + (0, import_node_util.inspect)(entry.init) : ""; return `$ ${import_vendor_core.chalk.greenBright("fetch")} ${entry.url}${init} `; }, cd(entry) { return `$ ${import_vendor_core.chalk.greenBright("cd")} ${entry.dir} `; }, retry(entry) { const attempt = `Attempt: ${entry.attempt}${entry.total == Infinity ? "" : `/${entry.total}`}`; const delay = entry.delay > 0 ? `; next in ${entry.delay}ms` : ""; return `${import_vendor_core.chalk.bgRed.white(" FAIL ")} ${attempt}${delay} `; }, end() { return ""; }, kill() { return ""; } }; var log = function(entry) { var _a; if (!entry.verbose) return; const stream = log.output || import_node_process.default.stderr; const format = ((_a = log.formatters) == null ? void 0 : _a[entry.kind]) || formatters[entry.kind]; if (!format) return; stream.write(format(entry)); }; var SPACE_RE = /\s/; var SYNTAX = "()[]{}<>;:+|&="; var CMD_BREAK = "|&;><"; var RESERVED_WORDS = /* @__PURE__ */ new Set([ "if", "then", "else", "elif", "fi", "case", "esac", "for", "select", "while", "until", "do", "done", "in", "EOF" ]); function formatCmd(cmd) { if (cmd == void 0) return import_vendor_core.chalk.grey("undefined"); let q = ""; let out = "$ "; let buf = ""; let mode = ""; let pos = 0; const cap = () => { const word = buf.trim(); if (word) { pos++; if (mode === "syntax") { if (CMD_BREAK.includes(word)) { pos = 0; } out += import_vendor_core.chalk.red(buf); } else if (mode === "quote" || mode === "dollar") { out += import_vendor_core.chalk.yellowBright(buf); } else if (RESERVED_WORDS.has(word)) { out += import_vendor_core.chalk.cyanBright(buf); } else if (pos === 1) { out += import_vendor_core.chalk.greenBright(buf); pos = Infinity; } else { out += buf; } } else { out += buf; } mode = ""; buf = ""; }; for (const c of [...cmd]) { if (!q) { if (c === "$") { cap(); mode = "dollar"; buf += c; cap(); } else if (c === "'" || c === '"') { cap(); mode = "quote"; q = c; buf += c; } else if (SPACE_RE.test(c)) { cap(); buf += c; } else if (SYNTAX.includes(c)) { const isEnv = c === "=" && pos === 0; isEnv && (pos = 1); cap(); mode = "syntax"; buf += c; cap(); isEnv && (pos = -1); } else { buf += c; } } else { buf += c; if (c === q) { cap(); q = ""; } } } cap(); return out.replaceAll("\n", import_vendor_core.chalk.reset("\n> ")) + "\n"; } // src/core.ts var import_vendor_core2 = require("./vendor-core.cjs"); var import_util = require("./util.cjs"); var import_internals = require("./internals.cjs"); var import_node_path = __toESM(require("path"), 1); var os = __toESM(require("os"), 1); var import_vendor_core3 = require("./vendor-core.cjs"); var import_util2 = require("./util.cjs"); var CWD = Symbol("processCwd"); var SYNC = Symbol("syncExec"); var EPF = Symbol("end-piped-from"); var SHOT = Symbol("snapshot"); var EOL = import_node_buffer.Buffer.from(import_node_os.EOL); var BR_CC = "\n".charCodeAt(0); var DLMTR = /\r?\n/; var SIGTERM = "SIGTERM"; var ENV_PREFIX = "ZX_"; var ENV_OPTS = /* @__PURE__ */ new Set([ "cwd", "preferLocal", "detached", "verbose", "quiet", "timeout", "timeoutSignal", "killSignal", "prefix", "postfix", "shell" ]); var defaults = resolveDefaults({ [CWD]: import_node_process2.default.cwd(), [SYNC]: false, verbose: false, env: import_node_process2.default.env, sync: false, shell: true, stdio: "pipe", nothrow: false, quiet: false, detached: false, preferLocal: false, spawn: import_node_child_process.default.spawn, spawnSync: import_node_child_process.default.spawnSync, log, kill, killSignal: SIGTERM, timeoutSignal: SIGTERM }); var storage = new import_node_async_hooks.AsyncLocalStorage(); var getStore = () => storage.getStore() || defaults; var getSnapshot = (opts, from, pieces, args) => __spreadProps(__spreadValues({}, opts), { ac: opts.ac || new AbortController(), ee: new import_node_events.EventEmitter(), from, pieces, args, cmd: "" }); function within(callback) { return storage.run(__spreadValues({}, getStore()), callback); } var $ = new Proxy( // prettier-ignore function(pieces, ...args) { const opts = getStore(); if (!Array.isArray(pieces)) { return function(...args2) { return within(() => Object.assign($, opts, pieces).apply(this, args2)); }; } const from = Fail.getCallerLocation(); const cb = () => cb[SHOT] = getSnapshot(opts, from, pieces, args); const pp = new ProcessPromise(cb); if (!pp.isHalted()) pp.run(); return pp.sync ? pp.output : pp; }, { set(t, key, value) { return Reflect.set( key in Function.prototype ? t : getStore(), key === "sync" ? SYNC : key, value ); }, get(t, key) { return key === "sync" ? $({ sync: true }) : Reflect.get(key in Function.prototype ? t : getStore(), key); } } ); var _ProcessPromise = class _ProcessPromise extends Promise { constructor(executor) { let resolve; let reject; super((...args) => { ; [resolve = import_util.noop, reject = import_util.noop] = args; executor(...args); }); this._stage = "initial"; this._id = (0, import_util.randomId)(); this._piped = false; this._stdin = new import_vendor_core2.VoidStream(); this._zurk = null; this._output = null; // Stream-like API this.writable = true; const snapshot = executor[SHOT]; if (snapshot) { this._snapshot = snapshot; this._resolve = resolve; this._reject = reject; if (snapshot.halt) this._stage = "halted"; try { this.build(); } catch (err) { this.finalize(ProcessOutput.fromError(err), true); } } else _ProcessPromise.disarm(this); } // prettier-ignore build() { const $2 = this._snapshot; if (!$2.shell) throw new Fail(`No shell is available: ${Fail.DOCS_URL}/shell`); if (!$2.quote) throw new Fail(`No quote function is defined: ${Fail.DOCS_URL}/quotes`); if ($2.pieces.some((p) => p == null)) throw new Fail(`Malformed command at ${$2.from}`); $2.cmd = (0, import_vendor_core2.buildCmd)( $2.quote, $2.pieces, $2.args ); } run() { var _a, _b; _ProcessPromise.bus.runBack(this); if (this.isRunning() || this.isSettled()) return this; this._stage = "running"; const self = this; const $2 = self._snapshot; const id = self.id; const cwd = $2.cwd || $2[CWD]; if ($2.preferLocal) { const dirs = $2.preferLocal === true ? [$2.cwd, $2[CWD]] : [$2.preferLocal].flat(); $2.env = (0, import_util.preferLocalBin)($2.env, ...dirs); } this._zurk = (0, import_vendor_core2.exec)({ cmd: self.fullCmd, cwd, input: (_b = (_a = $2.input) == null ? void 0 : _a.stdout) != null ? _b : $2.input, stdin: self._stdin, sync: self.sync, signal: self.signal, shell: (0, import_util.isString)($2.shell) ? $2.shell : true, id, env: $2.env, spawn: $2.spawn, spawnSync: $2.spawnSync, store: $2.store, stdio: $2.stdio, detached: $2.detached, ee: $2.ee, run(cb, ctx) { var _a2, _b2; ((_b2 = (_a2 = self.cmd).then) == null ? void 0 : _b2.call( _a2, (cmd) => { $2.cmd = cmd; ctx.cmd = self.fullCmd; cb(); }, (error) => self.finalize(ProcessOutput.fromError(error)) )) || cb(); }, on: { start: () => { $2.log({ kind: "cmd", cmd: $2.cmd, cwd, verbose: self.isVerbose(), id }); self.timeout($2.timeout, $2.timeoutSignal); }, stdout: (data) => { $2.log({ kind: "stdout", data, verbose: !self._piped && self.isVerbose(), id }); }, stderr: (data) => { $2.log({ kind: "stderr", data, verbose: !self.isQuiet(), id }); }, end: (data, c) => { const { error: _error, status, signal: __signal, duration, ctx: { store } } = data; const { stdout, stderr } = store; const { cause, exitCode, signal: _signal } = self._breakerData || {}; const signal = _signal != null ? _signal : __signal; const code = exitCode != null ? exitCode : status; const error = cause != null ? cause : _error; const output = new ProcessOutput({ code, signal, error, duration, store, from: $2.from }); $2.log({ kind: "end", signal, exitCode: code, duration, error, verbose: self.isVerbose(), id }); if (stdout.length && (0, import_util.getLast)((0, import_util.getLast)(stdout)) !== BR_CC) c.on.stdout(EOL, c); if (stderr.length && (0, import_util.getLast)((0, import_util.getLast)(stderr)) !== BR_CC) c.on.stderr(EOL, c); self.finalize(output); } } }); return this; } break(exitCode, signal, cause) { if (!this.isRunning()) return; this._breakerData = { exitCode, signal, cause }; this.kill(signal); } finalize(output, legacy = false) { if (this.isSettled()) return; this._output = output; _ProcessPromise.bus.unpipeBack(this); if (output.ok || this.isNothrow()) { this._stage = "fulfilled"; this._resolve(output); } else { this._stage = "rejected"; if (legacy) { this._resolve(output); throw output.cause || output; } this._reject(output); if (this.sync) throw output; } } abort(reason) { if (this.isSettled()) throw new Fail("Too late to abort the process."); if (this.signal !== this.ac.signal) throw new Fail("The signal is controlled by another process."); if (!this.child) throw new Fail("Trying to abort a process without creating one."); this.ac.abort(reason); } kill(signal) { if (this.isSettled()) throw new Fail("Too late to kill the process."); if (!this.child) throw new Fail("Trying to kill a process without creating one."); if (!this.pid) throw new Fail("The process pid is undefined."); return $.kill(this.pid, signal || this._snapshot.killSignal || $.killSignal); } // Configurators stdio(stdin, stdout = "pipe", stderr = "pipe") { this._snapshot.stdio = Array.isArray(stdin) ? stdin : [stdin, stdout, stderr]; return this; } nothrow(v = true) { this._snapshot.nothrow = v; return this; } quiet(v = true) { this._snapshot.quiet = v; return this; } verbose(v = true) { this._snapshot.verbose = v; return this; } timeout(d = 0, signal = $.timeoutSignal) { if (this.isSettled()) return this; const $2 = this._snapshot; $2.timeout = (0, import_util.parseDuration)(d); $2.timeoutSignal = signal; if (this._timeoutId) clearTimeout(this._timeoutId); if ($2.timeout && this.isRunning()) { this._timeoutId = setTimeout(() => this.kill($2.timeoutSignal), $2.timeout); this.finally(() => clearTimeout(this._timeoutId)).catch(import_util.noop); } return this; } /** * @deprecated Use $({halt: true})`cmd` instead. */ halt() { return this; } // Getters get id() { return this._id; } get pid() { var _a; return (_a = this.child) == null ? void 0 : _a.pid; } get cmd() { return this._snapshot.cmd; } get fullCmd() { const { prefix = "", postfix = "", cmd } = this._snapshot; return prefix + cmd + postfix; } get child() { var _a; return (_a = this._zurk) == null ? void 0 : _a.child; } get stdin() { var _a; return (_a = this.child) == null ? void 0 : _a.stdin; } get stdout() { var _a; return (_a = this.child) == null ? void 0 : _a.stdout; } get stderr() { var _a; return (_a = this.child) == null ? void 0 : _a.stderr; } get exitCode() { return this.then( (o) => o.exitCode, (o) => o.exitCode ); } get signal() { return this._snapshot.signal || this.ac.signal; } get ac() { return this._snapshot.ac; } get output() { return this._output; } get stage() { return this._stage; } get sync() { return this._snapshot[SYNC]; } get [Symbol.toStringTag]() { return "ProcessPromise"; } [Symbol.toPrimitive]() { return this.toString(); } // Output formatters json() { return this.then((o) => o.json()); } text(encoding) { return this.then((o) => o.text(encoding)); } lines(delimiter) { return this.then((o) => o.lines(delimiter)); } buffer() { return this.then((o) => o.buffer()); } blob(type) { return this.then((o) => o.blob(type)); } // Status checkers isQuiet() { return this._snapshot.quiet; } isVerbose() { return this._snapshot.verbose && !this.isQuiet(); } isNothrow() { return this._snapshot.nothrow; } isHalted() { return this.stage === "halted" && !this.sync; } isSettled() { return !!this.output; } isRunning() { return this.stage === "running"; } // Piping // prettier-ignore get pipe() { const getPipeMethod = (kind) => this._pipe.bind(this, kind); const stdout = getPipeMethod("stdout"); const stderr = getPipeMethod("stderr"); const stdall = getPipeMethod("stdall"); return Object.assign(stdout, { stdout, stderr, stdall }); } unpipe(to) { _ProcessPromise.bus.unpipe(this, to); return this; } // prettier-ignore _pipe(source, dest, ...args) { if ((0, import_util.isString)(dest)) return this._pipe(source, import_node_fs.default.createWriteStream(dest)); if ((0, import_util.isStringLiteral)(dest, ...args)) return this._pipe( source, $({ halt: true, signal: this.signal })(dest, ...args) ); const isP = dest instanceof _ProcessPromise; if (isP && dest.isSettled()) throw new Fail("Cannot pipe to a settled process."); if (!isP && dest.writableEnded) throw new Fail("Cannot pipe to a closed stream."); this._piped = true; _ProcessPromise.bus.pipe(this, dest); const { ee } = this._snapshot; const output = this.output; const from = new import_vendor_core2.VoidStream(); const check = () => { var _a; return !!((_a = _ProcessPromise.bus.refs.get(this)) == null ? void 0 : _a.has(dest)); }; const end = () => { if (!check()) return; setImmediate(() => { _ProcessPromise.bus.unpipe(this, dest); _ProcessPromise.bus.sources(dest).length === 0 && from.end(); }); }; const fill = () => { for (const chunk of this._zurk.store[source]) from.write(chunk); }; const fillSettled = () => { if (!output) return; if (isP && !output.ok) dest.break(output.exitCode, output.signal, output.cause); fill(); end(); }; if (!output) { const onData = (chunk) => check() && from.write(chunk); ee.once(source, () => { fill(); ee.on(source, onData); }).once("end", () => { ee.removeListener(source, onData); end(); }); } if (isP) { from.pipe(dest._stdin); if (this.isHalted()) ee.once("start", () => dest.run()); else { dest.run(); this.catch((e) => dest.break(e.exitCode, e.signal, e.cause)); } fillSettled(); return dest; } from.once("end", () => dest.emit(EPF)).pipe(dest); fillSettled(); return _ProcessPromise.promisifyStream(dest, this); } // Promise API then(onfulfilled, onrejected) { return super.then(onfulfilled, onrejected); } catch(onrejected) { return super.catch(onrejected); } // Async iterator API [Symbol.asyncIterator]() { return __asyncGenerator(this, null, function* () { const memo = []; const dlmtr = this._snapshot.delimiter || $.delimiter || DLMTR; for (const chunk of this._zurk.store.stdout) { yield* __yieldStar((0, import_util.getLines)(chunk, memo, dlmtr)); } try { for (var iter = __forAwait(this.stdout || []), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) { const chunk = temp.value; yield* __yieldStar((0, import_util.getLines)(chunk, memo, dlmtr)); } } catch (temp) { error = [temp]; } finally { try { more && (temp = iter.return) && (yield new __await(temp.call(iter))); } finally { if (error) throw error[0]; } } if (memo[0]) yield memo[0]; yield new __await(this); }); } emit(event, ...args) { return this; } on(event, cb) { this._stdin.on(event, cb); return this; } once(event, cb) { this._stdin.once(event, cb); return this; } write(data, encoding, cb) { this._stdin.write(data, encoding, cb); return this; } end(chunk, cb) { this._stdin.end(chunk, cb); return this; } removeListener(event, cb) { this._stdin.removeListener(event, cb); return this; } // prettier-ignore static disarm(p, toggle = true) { Object.getOwnPropertyNames(_ProcessPromise.prototype).forEach((k) => { if (k in Promise.prototype) return; if (!toggle) { Reflect.deleteProperty(p, k); return; } Object.defineProperty(p, k, { configurable: true, get() { throw new Fail("Inappropriate usage. Apply $ instead of direct instantiation."); } }); }); } }; // prettier-ignore _ProcessPromise.bus = { refs: /* @__PURE__ */ new Map(), streams: /* @__PURE__ */ new WeakMap(), pipe(from, to) { const set = this.refs.get(from) || this.refs.set(from, /* @__PURE__ */ new Set()).get(from); set.add(to); }, unpipe(from, to) { const set = this.refs.get(from); if (!set) return; if (to) set.delete(to); if (set.size) return; this.refs.delete(from); from._piped = false; }, unpipeBack(to, from) { if (from) return this.unpipe(from, to); for (const _from of this.refs.keys()) { this.unpipe(_from, to); } }, runBack(p) { var _a; for (const from of this.sources(p)) { if (from instanceof _ProcessPromise) from.run(); else (_a = this.streams.get(from)) == null ? void 0 : _a.run(); } }, sources(p) { const refs = []; for (const [from, set] of this.refs.entries()) { set.has(p) && refs.push(from); } return refs; } }; _ProcessPromise.promisifyStream = (stream, from) => { const proxy = _ProcessPromise.bus.streams.get(stream) || (0, import_util.proxyOverride)(stream, { then(res = import_util.noop, rej = import_util.noop) { return new Promise((_res, _rej) => { const end = () => _res(res((0, import_util.proxyOverride)(stream, from.output))); stream.once("error", (e) => _rej(rej(e))).once("finish", end).once(EPF, end); }); }, run() { from.run(); }, pipe(...args) { const dest = stream.pipe.apply(stream, args); return dest instanceof _ProcessPromise ? dest : _ProcessPromise.promisifyStream(dest, from); } }); _ProcessPromise.bus.streams.set(stream, proxy); return proxy; }; var ProcessPromise = _ProcessPromise; var _ProcessOutput = class _ProcessOutput extends Error { // prettier-ignore constructor(code = null, signal = null, stdout = "", stderr = "", stdall = "", message = "", duration = 0, error = null, from = "", store = { stdout: [stdout], stderr: [stderr], stdall: [stdall] }) { super(message); const dto = code !== null && typeof code === "object" ? code : { code, signal, duration, error, from, store }; Object.defineProperties(this, { _dto: { value: dto, enumerable: false }, cause: { get() { return dto.error; }, enumerable: false }, stdout: { get: (0, import_util.once)(() => (0, import_util.bufArrJoin)(dto.store.stdout)) }, stderr: { get: (0, import_util.once)(() => (0, import_util.bufArrJoin)(dto.store.stderr)) }, stdall: { get: (0, import_util.once)(() => (0, import_util.bufArrJoin)(dto.store.stdall)) }, message: { get: (0, import_util.once)( () => dto.error || message ? _ProcessOutput.getErrorMessage(dto.error || new Error(message), dto.from) : _ProcessOutput.getExitMessage( dto.code, dto.signal, this.stderr, dto.from, this.stderr.trim() ? "" : _ProcessOutput.getErrorDetails(this.lines()) ) ) } }); } get exitCode() { return this._dto.code; } get signal() { return this._dto.signal; } get duration() { return this._dto.duration; } get [Symbol.toStringTag]() { return "ProcessOutput"; } get ok() { return !this._dto.error && this.exitCode === 0; } json() { return JSON.parse(this.stdall); } buffer() { return import_node_buffer.Buffer.from(this.stdall); } blob(type = "text/plain") { if (!globalThis.Blob) throw new Fail( "Blob is not supported in this environment. Provide a polyfill" ); return new Blob([this.buffer()], { type }); } text(encoding = "utf8") { return encoding === "utf8" ? this.toString() : this.buffer().toString(encoding); } lines(delimiter) { return (0, import_util.iteratorToArray)(this[Symbol.iterator](delimiter)); } toString() { return this.stdall; } valueOf() { return this.stdall.trim(); } [Symbol.toPrimitive]() { return this.valueOf(); } // prettier-ignore *[Symbol.iterator](dlmtr = this._dto.delimiter || $.delimiter || DLMTR) { const memo = []; for (const chunk of this._dto.store.stdall) { yield* __yieldStar((0, import_util.getLines)(chunk, memo, dlmtr)); } if (memo[0]) yield memo[0]; } [import_node_util2.inspect.custom]() { const codeInfo = _ProcessOutput.getExitCodeInfo(this.exitCode); return `ProcessOutput { stdout: ${import_vendor_core2.chalk.green((0, import_node_util2.inspect)(this.stdout))}, stderr: ${import_vendor_core2.chalk.red((0, import_node_util2.inspect)(this.stderr))}, signal: ${(0, import_node_util2.inspect)(this.signal)}, exitCode: ${(this.ok ? import_vendor_core2.chalk.green : import_vendor_core2.chalk.red)(this.exitCode)}${codeInfo ? import_vendor_core2.chalk.grey(" (" + codeInfo + ")") : ""}, duration: ${this.duration} }`; } static fromError(error) { const output = new _ProcessOutput(); output._dto.error = error; return output; } }; _ProcessOutput.getExitMessage = Fail.formatExitMessage; _ProcessOutput.getErrorMessage = Fail.formatErrorMessage; _ProcessOutput.getErrorDetails = Fail.formatErrorDetails; _ProcessOutput.getExitCodeInfo = Fail.getExitCodeInfo; var ProcessOutput = _ProcessOutput; var useBash = () => setShell("bash", false); var usePwsh = () => setShell("pwsh"); var usePowerShell = () => setShell("powershell.exe"); function setShell(n, ps3 = true) { $.shell = import_vendor_core2.which.sync(n); $.prefix = ps3 ? "" : "set -euo pipefail;"; $.postfix = ps3 ? "; exit $LastExitCode" : ""; $.quote = ps3 ? import_util.quotePowerShell : import_util.quote; } try { const { shell, prefix, postfix } = $; useBash(); if ((0, import_util.isString)(shell)) $.shell = shell; if ((0, import_util.isString)(prefix)) $.prefix = prefix; if ((0, import_util.isString)(postfix)) $.postfix = postfix; } catch (err) { } var cwdSyncHook; function syncProcessCwd(flag = true) { cwdSyncHook = cwdSyncHook || (0, import_node_async_hooks.createHook)({ init: syncCwd, before: syncCwd, promiseResolve: syncCwd, after: syncCwd, destroy: syncCwd }); if (flag) cwdSyncHook.enable(); else cwdSyncHook.disable(); } function syncCwd() { if ($[CWD] != import_node_process2.default.cwd()) import_node_process2.default.chdir($[CWD]); } function cd(dir) { if (dir instanceof ProcessOutput) { dir = dir.toString().trim(); } $.log({ kind: "cd", dir, verbose: !$.quiet && $.verbose }); import_node_process2.default.chdir(dir); $[CWD] = import_node_process2.default.cwd(); } function kill(_0) { return __async(this, arguments, function* (pid, signal = $.killSignal || SIGTERM) { if (typeof pid !== "number" && typeof pid !== "string" || !/^\d+$/.test(pid)) throw new Fail(`Invalid pid: ${pid}`); $.log({ kind: "kill", pid, signal, verbose: !$.quiet && $.verbose }); if (import_node_process2.default.platform === "win32" && (yield new Promise((resolve) => { import_node_child_process.default.exec(`taskkill /pid ${pid} /t /f`, (err) => resolve(!err)); }))) return; for (const p of yield import_vendor_core2.ps.tree({ pid, recursive: true })) { try { import_node_process2.default.kill(+p.pid, signal); } catch (e) { } } try { import_node_process2.default.kill(-pid, signal); } catch (e) { try { import_node_process2.default.kill(+pid, signal); } catch (e2) { } } }); } function resolveDefaults(defs = defaults, prefix = ENV_PREFIX, env = import_node_process2.default.env, allowed = ENV_OPTS) { return Object.entries(env).reduce((m, [k, v]) => { if (v && k.startsWith(prefix)) { const _k = (0, import_util.toCamelCase)(k.slice(prefix.length)); const _v = (0, import_util.parseBool)(v); if (allowed.has(_k)) m[_k] = _v; } return m; }, defs); } /* c8 ignore next 100 */ // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { $, Fail, ProcessOutput, ProcessPromise, bus, cd, chalk, defaults, kill, log, os, path, ps, quote, quotePowerShell, resolveDefaults, syncProcessCwd, useBash, usePowerShell, usePwsh, which, within });