PHP WebShell

Текущая директория: /opt/BitGoJS/node_modules/nx/src/tasks-runner

Просмотр файла: forked-process-task-runner.js

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ForkedProcessTaskRunner = void 0;
const fs_1 = require("fs");
const dotenv = require("dotenv");
const child_process_1 = require("child_process");
const chalk = require("chalk");
const logTransformer = require("strong-log-transformer");
const workspace_root_1 = require("../utils/workspace-root");
const output_1 = require("../utils/output");
const utils_1 = require("./utils");
const path_1 = require("path");
const batch_messages_1 = require("./batch/batch-messages");
const strip_indents_1 = require("../utils/strip-indents");
const stream_1 = require("stream");
const workerPath = (0, path_1.join)(__dirname, './batch/run-batch.js');
class ForkedProcessTaskRunner {
    constructor(options) {
        this.options = options;
        this.workspaceRoot = workspace_root_1.workspaceRoot;
        this.cliPath = (0, utils_1.getCliPath)();
        this.verbose = process.env.NX_VERBOSE_LOGGING === 'true';
        this.processes = new Set();
        this.setupProcessEventListeners();
    }
    // TODO: vsavkin delegate terminal output printing
    forkProcessForBatch({ executorName, taskGraph }) {
        return new Promise((res, rej) => {
            try {
                const count = Object.keys(taskGraph.tasks).length;
                if (count > 1) {
                    output_1.output.logSingleLine(`Running ${output_1.output.bold(count)} ${output_1.output.bold('tasks')} with ${output_1.output.bold(executorName)}`);
                }
                else {
                    const args = (0, utils_1.getPrintableCommandArgsForTask)(Object.values(taskGraph.tasks)[0]);
                    output_1.output.logCommand(args.join(' '));
                    output_1.output.addNewline();
                }
                const p = (0, child_process_1.fork)(workerPath, {
                    stdio: ['inherit', 'inherit', 'inherit', 'ipc'],
                    env: this.getEnvVariablesForProcess(),
                });
                this.processes.add(p);
                p.once('exit', (code, signal) => {
                    this.processes.delete(p);
                    if (code === null)
                        code = this.signalToCode(signal);
                    if (code !== 0) {
                        const results = {};
                        for (const rootTaskId of taskGraph.roots) {
                            results[rootTaskId] = {
                                success: false,
                            };
                        }
                        rej(new Error(`"${executorName}" exited unexpectedly with code: ${code}`));
                    }
                });
                p.on('message', (message) => {
                    switch (message.type) {
                        case batch_messages_1.BatchMessageType.Complete: {
                            res(message.results);
                            break;
                        }
                        case batch_messages_1.BatchMessageType.Tasks: {
                            break;
                        }
                        default: {
                            // Re-emit any non-batch messages from the task process
                            if (process.send) {
                                process.send(message);
                            }
                        }
                    }
                });
                // Start the tasks
                p.send({
                    type: batch_messages_1.BatchMessageType.Tasks,
                    taskGraph,
                    executorName,
                });
            }
            catch (e) {
                rej(e);
            }
        });
    }
    forkProcessPipeOutputCapture(task, { streamOutput, temporaryOutputPath, }) {
        return new Promise((res, rej) => {
            try {
                const args = (0, utils_1.getPrintableCommandArgsForTask)(task);
                const serializedArgs = (0, utils_1.getSerializedArgsForTask)(task, this.verbose);
                if (streamOutput) {
                    output_1.output.logCommand(args.join(' '));
                    output_1.output.addNewline();
                }
                const p = (0, child_process_1.fork)(this.cliPath, serializedArgs, {
                    stdio: ['inherit', 'pipe', 'pipe', 'ipc'],
                    env: this.getEnvVariablesForTask(task, process.env.FORCE_COLOR === undefined
                        ? 'true'
                        : process.env.FORCE_COLOR, null, null),
                });
                this.processes.add(p);
                // Re-emit any messages from the task process
                p.on('message', (message) => {
                    if (process.send) {
                        process.send(message);
                    }
                });
                if (streamOutput) {
                    if (process.env.NX_PREFIX_OUTPUT === 'true') {
                        const color = getColor(task.target.project);
                        const prefixText = `${task.target.project}:`;
                        p.stdout
                            .pipe(logClearLineToPrefixTransformer(color.bold(prefixText) + ' '))
                            .pipe(logTransformer({ tag: color.bold(prefixText) }))
                            .pipe(process.stdout);
                        p.stderr
                            .pipe(logClearLineToPrefixTransformer(color(prefixText) + ' '))
                            .pipe(logTransformer({ tag: color(prefixText) }))
                            .pipe(process.stderr);
                    }
                    else {
                        p.stdout.pipe(logTransformer()).pipe(process.stdout);
                        p.stderr.pipe(logTransformer()).pipe(process.stderr);
                    }
                }
                let outWithErr = [];
                p.stdout.on('data', (chunk) => {
                    outWithErr.push(chunk.toString());
                });
                p.stderr.on('data', (chunk) => {
                    outWithErr.push(chunk.toString());
                });
                p.on('exit', (code, signal) => {
                    this.processes.delete(p);
                    if (code === null)
                        code = this.signalToCode(signal);
                    // we didn't print any output as we were running the command
                    // print all the collected output|
                    const terminalOutput = outWithErr.join('');
                    if (!streamOutput) {
                        this.options.lifeCycle.printTaskTerminalOutput(task, code === 0 ? 'success' : 'failure', terminalOutput);
                    }
                    this.writeTerminalOutput(temporaryOutputPath, terminalOutput);
                    res({ code, terminalOutput });
                });
            }
            catch (e) {
                console.error(e);
                rej(e);
            }
        });
    }
    forkProcessDirectOutputCapture(task, { streamOutput, temporaryOutputPath, }) {
        return new Promise((res, rej) => {
            try {
                const args = (0, utils_1.getPrintableCommandArgsForTask)(task);
                const serializedArgs = (0, utils_1.getSerializedArgsForTask)(task, this.verbose);
                if (streamOutput) {
                    output_1.output.logCommand(args.join(' '));
                    output_1.output.addNewline();
                }
                const p = (0, child_process_1.fork)(this.cliPath, serializedArgs, {
                    stdio: ['inherit', 'inherit', 'inherit', 'ipc'],
                    env: this.getEnvVariablesForTask(task, undefined, temporaryOutputPath, streamOutput),
                });
                this.processes.add(p);
                // Re-emit any messages from the task process
                p.on('message', (message) => {
                    if (process.send) {
                        process.send(message);
                    }
                });
                p.on('exit', (code, signal) => {
                    if (code === null)
                        code = this.signalToCode(signal);
                    // we didn't print any output as we were running the command
                    // print all the collected output
                    let terminalOutput = '';
                    try {
                        terminalOutput = this.readTerminalOutput(temporaryOutputPath);
                        if (!streamOutput) {
                            this.options.lifeCycle.printTaskTerminalOutput(task, code === 0 ? 'success' : 'failure', terminalOutput);
                        }
                    }
                    catch (e) {
                        console.log((0, strip_indents_1.stripIndents) `
              Unable to print terminal output for Task "${task.id}".
              Task failed with Exit Code ${code} and Signal "${signal}".

              Received error message:
              ${e.message}
            `);
                    }
                    res({
                        code,
                        terminalOutput,
                    });
                });
            }
            catch (e) {
                console.error(e);
                rej(e);
            }
        });
    }
    readTerminalOutput(outputPath) {
        return (0, fs_1.readFileSync)(outputPath).toString();
    }
    writeTerminalOutput(outputPath, content) {
        (0, fs_1.writeFileSync)(outputPath, content);
    }
    // region Environment Variables
    getEnvVariablesForProcess() {
        return Object.assign(Object.assign(Object.assign({}, this.getDotenvVariablesForForkedProcess()), process.env), this.getNxEnvVariablesForForkedProcess(process.env.FORCE_COLOR === undefined ? 'true' : process.env.FORCE_COLOR));
    }
    getEnvVariablesForTask(task, forceColor, outputPath, streamOutput) {
        const res = Object.assign(Object.assign(Object.assign({}, this.getDotenvVariablesForTask(task)), process.env), this.getNxEnvVariablesForTask(task, forceColor, outputPath, streamOutput));
        // we have to delete it because if we invoke Nx from within Nx, we need to reset those values
        if (!outputPath) {
            delete res.NX_TERMINAL_OUTPUT_PATH;
            delete res.NX_STREAM_OUTPUT;
            delete res.NX_PREFIX_OUTPUT;
        }
        delete res.NX_BASE;
        delete res.NX_HEAD;
        delete res.NX_SET_CLI;
        return res;
    }
    getNxEnvVariablesForForkedProcess(forceColor, outputPath, streamOutput) {
        const env = {
            FORCE_COLOR: forceColor,
            NX_WORKSPACE_ROOT: this.workspaceRoot,
            NX_SKIP_NX_CACHE: this.options.skipNxCache ? 'true' : undefined,
        };
        if (outputPath) {
            env.NX_TERMINAL_OUTPUT_PATH = outputPath;
            if (this.options.captureStderr) {
                env.NX_TERMINAL_CAPTURE_STDERR = 'true';
            }
            if (streamOutput) {
                env.NX_STREAM_OUTPUT = 'true';
            }
        }
        return env;
    }
    getNxEnvVariablesForTask(task, forceColor, outputPath, streamOutput) {
        var _a;
        const env = {
            NX_TASK_TARGET_PROJECT: task.target.project,
            NX_TASK_TARGET_TARGET: task.target.target,
            NX_TASK_TARGET_CONFIGURATION: (_a = task.target.configuration) !== null && _a !== void 0 ? _a : undefined,
            NX_TASK_HASH: task.hash,
            // used when Nx is invoked via Lerna
            LERNA_PACKAGE_NAME: task.target.project,
        };
        // TODO: remove this once we have a reasonable way to configure it
        if (task.target.target === 'test') {
            env.NX_TERMINAL_CAPTURE_STDERR = 'true';
        }
        return Object.assign(Object.assign({}, this.getNxEnvVariablesForForkedProcess(forceColor, outputPath, streamOutput)), env);
    }
    getDotenvVariablesForForkedProcess() {
        return Object.assign(Object.assign(Object.assign({}, parseEnv('.env')), parseEnv('.local.env')), parseEnv('.env.local'));
    }
    getDotenvVariablesForTask(task) {
        if (process.env.NX_LOAD_DOT_ENV_FILES == 'true') {
            return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, this.getDotenvVariablesForForkedProcess()), parseEnv(`.${task.target.target}.env`)), parseEnv(`.env.${task.target.target}`)), (task.target.configuration
                ? parseEnv(`.${task.target.target}.${task.target.configuration}.env`)
                : {})), (task.target.configuration
                ? parseEnv(`.env.${task.target.target}.${task.target.configuration}`)
                : {})), parseEnv(`${task.projectRoot}/.env`)), parseEnv(`${task.projectRoot}/.local.env`)), parseEnv(`${task.projectRoot}/.env.local`)), parseEnv(`${task.projectRoot}/.${task.target.target}.env`)), parseEnv(`${task.projectRoot}/.env.${task.target.target}`)), (task.target.configuration
                ? parseEnv(`${task.projectRoot}/.${task.target.target}.${task.target.configuration}.env`)
                : {})), (task.target.configuration
                ? parseEnv(`${task.projectRoot}/.env.${task.target.target}.${task.target.configuration}`)
                : {}));
        }
        else {
            return {};
        }
    }
    // endregion Environment Variables
    signalToCode(signal) {
        if (signal === 'SIGHUP')
            return 128 + 1;
        if (signal === 'SIGINT')
            return 128 + 2;
        if (signal === 'SIGTERM')
            return 128 + 15;
        return 128;
    }
    setupProcessEventListeners() {
        // When the nx process gets a message, it will be sent into the task's process
        process.on('message', (message) => {
            this.processes.forEach((p) => {
                if (p.connected) {
                    p.send(message);
                }
            });
        });
        // Terminate any task processes on exit
        process.on('SIGINT', () => {
            this.processes.forEach((p) => {
                if (p.connected) {
                    p.kill('SIGTERM');
                }
            });
            // we exit here because we don't need to write anything to cache.
            process.exit();
        });
        process.on('SIGTERM', () => {
            this.processes.forEach((p) => {
                if (p.connected) {
                    p.kill('SIGTERM');
                }
            });
            // no exit here because we expect child processes to terminate which
            // will store results to the cache and will terminate this process
        });
        process.on('SIGHUP', () => {
            this.processes.forEach((p) => {
                if (p.connected) {
                    p.kill('SIGTERM');
                }
            });
            // no exit here because we expect child processes to terminate which
            // will store results to the cache and will terminate this process
        });
    }
}
exports.ForkedProcessTaskRunner = ForkedProcessTaskRunner;
function parseEnv(path) {
    try {
        const envContents = (0, fs_1.readFileSync)(path);
        return dotenv.parse(envContents);
    }
    catch (e) { }
}
const colors = [
    chalk.green,
    chalk.greenBright,
    chalk.red,
    chalk.redBright,
    chalk.cyan,
    chalk.cyanBright,
    chalk.yellow,
    chalk.yellowBright,
    chalk.magenta,
    chalk.magentaBright,
];
function getColor(projectName) {
    let code = 0;
    for (let i = 0; i < projectName.length; ++i) {
        code += projectName.charCodeAt(i);
    }
    const colorIndex = code % colors.length;
    return colors[colorIndex];
}
/**
 * Prevents terminal escape sequence from clearing line prefix.
 */
function logClearLineToPrefixTransformer(prefix) {
    let prevChunk = null;
    return new stream_1.Transform({
        transform(chunk, _encoding, callback) {
            if (prevChunk && prevChunk.toString() === '\x1b[2K') {
                chunk = chunk.toString().replace(/\x1b\[1G/g, (m) => m + prefix);
            }
            this.push(chunk);
            prevChunk = chunk;
            callback();
        },
    });
}
//# sourceMappingURL=forked-process-task-runner.js.map

Выполнить команду


Для локальной разработки. Не используйте в интернете!