加入了node_modules
添加了新的功能项
This commit is contained in:
24
node_modules/execa/lib/verbose/complete.js
generated
vendored
Normal file
24
node_modules/execa/lib/verbose/complete.js
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
import prettyMs from 'pretty-ms';
|
||||
import {isVerbose} from './values.js';
|
||||
import {verboseLog} from './log.js';
|
||||
import {logError} from './error.js';
|
||||
|
||||
// When `verbose` is `short|full|custom`, print each command's completion, duration and error
|
||||
export const logResult = (result, verboseInfo) => {
|
||||
if (!isVerbose(verboseInfo)) {
|
||||
return;
|
||||
}
|
||||
|
||||
logError(result, verboseInfo);
|
||||
logDuration(result, verboseInfo);
|
||||
};
|
||||
|
||||
const logDuration = (result, verboseInfo) => {
|
||||
const verboseMessage = `(done in ${prettyMs(result.durationMs)})`;
|
||||
verboseLog({
|
||||
type: 'duration',
|
||||
verboseMessage,
|
||||
verboseInfo,
|
||||
result,
|
||||
});
|
||||
};
|
||||
26
node_modules/execa/lib/verbose/custom.js
generated
vendored
Normal file
26
node_modules/execa/lib/verbose/custom.js
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
import {getVerboseFunction} from './values.js';
|
||||
|
||||
// Apply the `verbose` function on each line
|
||||
export const applyVerboseOnLines = (printedLines, verboseInfo, fdNumber) => {
|
||||
const verboseFunction = getVerboseFunction(verboseInfo, fdNumber);
|
||||
return printedLines
|
||||
.map(({verboseLine, verboseObject}) => applyVerboseFunction(verboseLine, verboseObject, verboseFunction))
|
||||
.filter(printedLine => printedLine !== undefined)
|
||||
.map(printedLine => appendNewline(printedLine))
|
||||
.join('');
|
||||
};
|
||||
|
||||
const applyVerboseFunction = (verboseLine, verboseObject, verboseFunction) => {
|
||||
if (verboseFunction === undefined) {
|
||||
return verboseLine;
|
||||
}
|
||||
|
||||
const printedLine = verboseFunction(verboseLine, verboseObject);
|
||||
if (typeof printedLine === 'string') {
|
||||
return printedLine;
|
||||
}
|
||||
};
|
||||
|
||||
const appendNewline = printedLine => printedLine.endsWith('\n')
|
||||
? printedLine
|
||||
: `${printedLine}\n`;
|
||||
54
node_modules/execa/lib/verbose/default.js
generated
vendored
Normal file
54
node_modules/execa/lib/verbose/default.js
generated
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
import figures from 'figures';
|
||||
import {
|
||||
gray,
|
||||
bold,
|
||||
redBright,
|
||||
yellowBright,
|
||||
} from 'yoctocolors';
|
||||
|
||||
// Default when `verbose` is not a function
|
||||
export const defaultVerboseFunction = ({
|
||||
type,
|
||||
message,
|
||||
timestamp,
|
||||
piped,
|
||||
commandId,
|
||||
result: {failed = false} = {},
|
||||
options: {reject = true},
|
||||
}) => {
|
||||
const timestampString = serializeTimestamp(timestamp);
|
||||
const icon = ICONS[type]({failed, reject, piped});
|
||||
const color = COLORS[type]({reject});
|
||||
return `${gray(`[${timestampString}]`)} ${gray(`[${commandId}]`)} ${color(icon)} ${color(message)}`;
|
||||
};
|
||||
|
||||
// Prepending the timestamp allows debugging the slow paths of a subprocess
|
||||
const serializeTimestamp = timestamp => `${padField(timestamp.getHours(), 2)}:${padField(timestamp.getMinutes(), 2)}:${padField(timestamp.getSeconds(), 2)}.${padField(timestamp.getMilliseconds(), 3)}`;
|
||||
|
||||
const padField = (field, padding) => String(field).padStart(padding, '0');
|
||||
|
||||
const getFinalIcon = ({failed, reject}) => {
|
||||
if (!failed) {
|
||||
return figures.tick;
|
||||
}
|
||||
|
||||
return reject ? figures.cross : figures.warning;
|
||||
};
|
||||
|
||||
const ICONS = {
|
||||
command: ({piped}) => piped ? '|' : '$',
|
||||
output: () => ' ',
|
||||
ipc: () => '*',
|
||||
error: getFinalIcon,
|
||||
duration: getFinalIcon,
|
||||
};
|
||||
|
||||
const identity = string => string;
|
||||
|
||||
const COLORS = {
|
||||
command: () => bold,
|
||||
output: () => identity,
|
||||
ipc: () => identity,
|
||||
error: ({reject}) => reject ? redBright : yellowBright,
|
||||
duration: () => gray,
|
||||
};
|
||||
13
node_modules/execa/lib/verbose/error.js
generated
vendored
Normal file
13
node_modules/execa/lib/verbose/error.js
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
import {verboseLog} from './log.js';
|
||||
|
||||
// When `verbose` is `short|full|custom`, print each command's error when it fails
|
||||
export const logError = (result, verboseInfo) => {
|
||||
if (result.failed) {
|
||||
verboseLog({
|
||||
type: 'error',
|
||||
verboseMessage: result.shortMessage,
|
||||
verboseInfo,
|
||||
result,
|
||||
});
|
||||
}
|
||||
};
|
||||
39
node_modules/execa/lib/verbose/info.js
generated
vendored
Normal file
39
node_modules/execa/lib/verbose/info.js
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
import {isVerbose, VERBOSE_VALUES, isVerboseFunction} from './values.js';
|
||||
|
||||
// Information computed before spawning, used by the `verbose` option
|
||||
export const getVerboseInfo = (verbose, escapedCommand, rawOptions) => {
|
||||
validateVerbose(verbose);
|
||||
const commandId = getCommandId(verbose);
|
||||
return {
|
||||
verbose,
|
||||
escapedCommand,
|
||||
commandId,
|
||||
rawOptions,
|
||||
};
|
||||
};
|
||||
|
||||
const getCommandId = verbose => isVerbose({verbose}) ? COMMAND_ID++ : undefined;
|
||||
|
||||
// Prepending the `pid` is useful when multiple commands print their output at the same time.
|
||||
// However, we cannot use the real PID since this is not available with `child_process.spawnSync()`.
|
||||
// Also, we cannot use the real PID if we want to print it before `child_process.spawn()` is run.
|
||||
// As a pro, it is shorter than a normal PID and never re-uses the same id.
|
||||
// As a con, it cannot be used to send signals.
|
||||
let COMMAND_ID = 0n;
|
||||
|
||||
const validateVerbose = verbose => {
|
||||
for (const fdVerbose of verbose) {
|
||||
if (fdVerbose === false) {
|
||||
throw new TypeError('The "verbose: false" option was renamed to "verbose: \'none\'".');
|
||||
}
|
||||
|
||||
if (fdVerbose === true) {
|
||||
throw new TypeError('The "verbose: true" option was renamed to "verbose: \'short\'".');
|
||||
}
|
||||
|
||||
if (!VERBOSE_VALUES.includes(fdVerbose) && !isVerboseFunction(fdVerbose)) {
|
||||
const allowedValues = VERBOSE_VALUES.map(allowedValue => `'${allowedValue}'`).join(', ');
|
||||
throw new TypeError(`The "verbose" option must not be ${fdVerbose}. Allowed values are: ${allowedValues} or a function.`);
|
||||
}
|
||||
}
|
||||
};
|
||||
15
node_modules/execa/lib/verbose/ipc.js
generated
vendored
Normal file
15
node_modules/execa/lib/verbose/ipc.js
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
import {verboseLog, serializeVerboseMessage} from './log.js';
|
||||
import {isFullVerbose} from './values.js';
|
||||
|
||||
// When `verbose` is `'full'`, print IPC messages from the subprocess
|
||||
export const shouldLogIpc = verboseInfo => isFullVerbose(verboseInfo, 'ipc');
|
||||
|
||||
export const logIpcOutput = (message, verboseInfo) => {
|
||||
const verboseMessage = serializeVerboseMessage(message);
|
||||
verboseLog({
|
||||
type: 'ipc',
|
||||
verboseMessage,
|
||||
fdNumber: 'ipc',
|
||||
verboseInfo,
|
||||
});
|
||||
};
|
||||
54
node_modules/execa/lib/verbose/log.js
generated
vendored
Normal file
54
node_modules/execa/lib/verbose/log.js
generated
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
import {inspect} from 'node:util';
|
||||
import {escapeLines} from '../arguments/escape.js';
|
||||
import {defaultVerboseFunction} from './default.js';
|
||||
import {applyVerboseOnLines} from './custom.js';
|
||||
|
||||
// This prints on stderr.
|
||||
// If the subprocess prints on stdout and is using `stdout: 'inherit'`,
|
||||
// there is a chance both writes will compete (introducing a race condition).
|
||||
// This means their respective order is not deterministic.
|
||||
// In particular, this means the verbose command lines might be after the start of the subprocess output.
|
||||
// Using synchronous I/O does not solve this problem.
|
||||
// However, this only seems to happen when the stdout/stderr target
|
||||
// (e.g. a terminal) is being written to by many subprocesses at once, which is unlikely in real scenarios.
|
||||
export const verboseLog = ({type, verboseMessage, fdNumber, verboseInfo, result}) => {
|
||||
const verboseObject = getVerboseObject({type, result, verboseInfo});
|
||||
const printedLines = getPrintedLines(verboseMessage, verboseObject);
|
||||
const finalLines = applyVerboseOnLines(printedLines, verboseInfo, fdNumber);
|
||||
if (finalLines !== '') {
|
||||
console.warn(finalLines.slice(0, -1));
|
||||
}
|
||||
};
|
||||
|
||||
const getVerboseObject = ({
|
||||
type,
|
||||
result,
|
||||
verboseInfo: {escapedCommand, commandId, rawOptions: {piped = false, ...options}},
|
||||
}) => ({
|
||||
type,
|
||||
escapedCommand,
|
||||
commandId: `${commandId}`,
|
||||
timestamp: new Date(),
|
||||
piped,
|
||||
result,
|
||||
options,
|
||||
});
|
||||
|
||||
const getPrintedLines = (verboseMessage, verboseObject) => verboseMessage
|
||||
.split('\n')
|
||||
.map(message => getPrintedLine({...verboseObject, message}));
|
||||
|
||||
const getPrintedLine = verboseObject => {
|
||||
const verboseLine = defaultVerboseFunction(verboseObject);
|
||||
return {verboseLine, verboseObject};
|
||||
};
|
||||
|
||||
// Serialize any type to a line string, for logging
|
||||
export const serializeVerboseMessage = message => {
|
||||
const messageString = typeof message === 'string' ? message : inspect(message);
|
||||
const escapedMessage = escapeLines(messageString);
|
||||
return escapedMessage.replaceAll('\t', ' '.repeat(TAB_SIZE));
|
||||
};
|
||||
|
||||
// Same as `util.inspect()`
|
||||
const TAB_SIZE = 2;
|
||||
60
node_modules/execa/lib/verbose/output.js
generated
vendored
Normal file
60
node_modules/execa/lib/verbose/output.js
generated
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
import {BINARY_ENCODINGS} from '../arguments/encoding-option.js';
|
||||
import {TRANSFORM_TYPES} from '../stdio/type.js';
|
||||
import {verboseLog, serializeVerboseMessage} from './log.js';
|
||||
import {isFullVerbose} from './values.js';
|
||||
|
||||
// `ignore` opts-out of `verbose` for a specific stream.
|
||||
// `ipc` cannot use piping.
|
||||
// `inherit` would result in double printing.
|
||||
// They can also lead to double printing when passing file descriptor integers or `process.std*`.
|
||||
// This only leaves with `pipe` and `overlapped`.
|
||||
export const shouldLogOutput = ({stdioItems, encoding, verboseInfo, fdNumber}) => fdNumber !== 'all'
|
||||
&& isFullVerbose(verboseInfo, fdNumber)
|
||||
&& !BINARY_ENCODINGS.has(encoding)
|
||||
&& fdUsesVerbose(fdNumber)
|
||||
&& (stdioItems.some(({type, value}) => type === 'native' && PIPED_STDIO_VALUES.has(value))
|
||||
|| stdioItems.every(({type}) => TRANSFORM_TYPES.has(type)));
|
||||
|
||||
// Printing input streams would be confusing.
|
||||
// Files and streams can produce big outputs, which we don't want to print.
|
||||
// We could print `stdio[3+]` but it often is redirected to files and streams, with the same issue.
|
||||
// So we only print stdout and stderr.
|
||||
const fdUsesVerbose = fdNumber => fdNumber === 1 || fdNumber === 2;
|
||||
|
||||
const PIPED_STDIO_VALUES = new Set(['pipe', 'overlapped']);
|
||||
|
||||
// `verbose: 'full'` printing logic with async methods
|
||||
export const logLines = async (linesIterable, stream, fdNumber, verboseInfo) => {
|
||||
for await (const line of linesIterable) {
|
||||
if (!isPipingStream(stream)) {
|
||||
logLine(line, fdNumber, verboseInfo);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// `verbose: 'full'` printing logic with sync methods
|
||||
export const logLinesSync = (linesArray, fdNumber, verboseInfo) => {
|
||||
for (const line of linesArray) {
|
||||
logLine(line, fdNumber, verboseInfo);
|
||||
}
|
||||
};
|
||||
|
||||
// When `subprocess.stdout|stderr.pipe()` is called, `verbose` becomes a noop.
|
||||
// This prevents the following problems:
|
||||
// - `.pipe()` achieves the same result as using `stdout: 'inherit'`, `stdout: stream`, etc. which also make `verbose` a noop.
|
||||
// For example, `subprocess.stdout.pipe(process.stdin)` would print each line twice.
|
||||
// - When chaining subprocesses with `subprocess.pipe(otherSubprocess)`, only the last one should print its output.
|
||||
// Detecting whether `.pipe()` is impossible without monkey-patching it, so we use the following undocumented property.
|
||||
// This is not a critical behavior since changes of the following property would only make `verbose` more verbose.
|
||||
const isPipingStream = stream => stream._readableState.pipes.length > 0;
|
||||
|
||||
// When `verbose` is `full`, print stdout|stderr
|
||||
const logLine = (line, fdNumber, verboseInfo) => {
|
||||
const verboseMessage = serializeVerboseMessage(line);
|
||||
verboseLog({
|
||||
type: 'output',
|
||||
verboseMessage,
|
||||
fdNumber,
|
||||
verboseInfo,
|
||||
});
|
||||
};
|
||||
15
node_modules/execa/lib/verbose/start.js
generated
vendored
Normal file
15
node_modules/execa/lib/verbose/start.js
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
import {isVerbose} from './values.js';
|
||||
import {verboseLog} from './log.js';
|
||||
|
||||
// When `verbose` is `short|full|custom`, print each command
|
||||
export const logCommand = (escapedCommand, verboseInfo) => {
|
||||
if (!isVerbose(verboseInfo)) {
|
||||
return;
|
||||
}
|
||||
|
||||
verboseLog({
|
||||
type: 'command',
|
||||
verboseMessage: escapedCommand,
|
||||
verboseInfo,
|
||||
});
|
||||
};
|
||||
33
node_modules/execa/lib/verbose/values.js
generated
vendored
Normal file
33
node_modules/execa/lib/verbose/values.js
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
import {getFdSpecificValue} from '../arguments/specific.js';
|
||||
|
||||
// The `verbose` option can have different values for `stdout`/`stderr`
|
||||
export const isVerbose = ({verbose}, fdNumber) => getFdVerbose(verbose, fdNumber) !== 'none';
|
||||
|
||||
// Whether IPC and output and logged
|
||||
export const isFullVerbose = ({verbose}, fdNumber) => !['none', 'short'].includes(getFdVerbose(verbose, fdNumber));
|
||||
|
||||
// The `verbose` option can be a function to customize logging
|
||||
export const getVerboseFunction = ({verbose}, fdNumber) => {
|
||||
const fdVerbose = getFdVerbose(verbose, fdNumber);
|
||||
return isVerboseFunction(fdVerbose) ? fdVerbose : undefined;
|
||||
};
|
||||
|
||||
// When using `verbose: {stdout, stderr, fd3, ipc}`:
|
||||
// - `verbose.stdout|stderr|fd3` is used for 'output'
|
||||
// - `verbose.ipc` is only used for 'ipc'
|
||||
// - highest `verbose.*` value is used for 'command', 'error' and 'duration'
|
||||
const getFdVerbose = (verbose, fdNumber) => fdNumber === undefined
|
||||
? getFdGenericVerbose(verbose)
|
||||
: getFdSpecificValue(verbose, fdNumber);
|
||||
|
||||
// When using `verbose: {stdout, stderr, fd3, ipc}` and logging is not specific to a file descriptor.
|
||||
// We then use the highest `verbose.*` value, using the following order:
|
||||
// - function > 'full' > 'short' > 'none'
|
||||
// - if several functions are defined: stdout > stderr > fd3 > ipc
|
||||
const getFdGenericVerbose = verbose => verbose.find(fdVerbose => isVerboseFunction(fdVerbose))
|
||||
?? VERBOSE_VALUES.findLast(fdVerbose => verbose.includes(fdVerbose));
|
||||
|
||||
// Whether the `verbose` option is customized using a function
|
||||
export const isVerboseFunction = fdVerbose => typeof fdVerbose === 'function';
|
||||
|
||||
export const VERBOSE_VALUES = ['none', 'short', 'full'];
|
||||
Reference in New Issue
Block a user