module.exports = /******/ (function(modules, runtime) { // webpackBootstrap /******/ "use strict"; /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ __webpack_require__.ab = __dirname + "/"; /******/ /******/ // the startup function /******/ function startup() { /******/ // Load entry module and return exports /******/ return __webpack_require__(325); /******/ }; /******/ /******/ // run startup /******/ return startup(); /******/ }) /************************************************************************/ /******/ ({ /***/ 82: /***/ (function(__unusedmodule, exports) { "use strict"; // We use any as a valid input type /* eslint-disable @typescript-eslint/no-explicit-any */ Object.defineProperty(exports, "__esModule", { value: true }); /** * Sanitizes an input into a string so it can be passed into issueCommand safely * @param input input to sanitize into a string */ function toCommandValue(input) { if (input === null || input === undefined) { return ''; } else if (typeof input === 'string' || input instanceof String) { return input; } return JSON.stringify(input); } exports.toCommandValue = toCommandValue; //# sourceMappingURL=utils.js.map /***/ }), /***/ 87: /***/ (function(module) { module.exports = require("os"); /***/ }), /***/ 102: /***/ (function(__unusedmodule, exports, __webpack_require__) { "use strict"; // For internal use, subject to change. var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; result["default"] = mod; return result; }; Object.defineProperty(exports, "__esModule", { value: true }); // We use any as a valid input type /* eslint-disable @typescript-eslint/no-explicit-any */ const fs = __importStar(__webpack_require__(747)); const os = __importStar(__webpack_require__(87)); const utils_1 = __webpack_require__(82); function issueCommand(command, message) { const filePath = process.env[`GITHUB_${command}`]; if (!filePath) { throw new Error(`Unable to find environment variable for file command ${command}`); } if (!fs.existsSync(filePath)) { throw new Error(`Missing file at path: ${filePath}`); } fs.appendFileSync(filePath, `${utils_1.toCommandValue(message)}${os.EOL}`, { encoding: 'utf8' }); } exports.issueCommand = issueCommand; //# sourceMappingURL=file-command.js.map /***/ }), /***/ 129: /***/ (function(module) { module.exports = require("child_process"); /***/ }), /***/ 156: /***/ (function(module) { function calc(m) { return function(n) { return Math.round(n * m); }; }; module.exports = { seconds: calc(1e3), minutes: calc(6e4), hours: calc(36e5), days: calc(864e5), weeks: calc(6048e5), months: calc(26298e5), years: calc(315576e5) }; /***/ }), /***/ 322: /***/ (function(__unusedmodule, exports) { "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; Object.defineProperty(exports, "__esModule", { value: true }); exports.wait = void 0; function wait(ms) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, new Promise(function (r) { return setTimeout(r, ms); })]; }); }); } exports.wait = wait; /***/ }), /***/ 325: /***/ (function(__unusedmodule, exports, __webpack_require__) { "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); var core_1 = __webpack_require__(470); var child_process_1 = __webpack_require__(129); var milliseconds_1 = __importDefault(__webpack_require__(156)); var tree_kill_1 = __importDefault(__webpack_require__(791)); var util_1 = __webpack_require__(322); // inputs var TIMEOUT_MINUTES = getInputNumber('timeout_minutes', false); var TIMEOUT_SECONDS = getInputNumber('timeout_seconds', false); var MAX_ATTEMPTS = getInputNumber('max_attempts', true) || 3; var COMMAND = core_1.getInput('command', { required: true }); var RETRY_WAIT_SECONDS = getInputNumber('retry_wait_seconds', false) || 10; var POLLING_INTERVAL_SECONDS = getInputNumber('polling_interval_seconds', false) || 1; var RETRY_ON = core_1.getInput('retry_on') || 'any'; var OUTPUT_TOTAL_ATTEMPTS_KEY = 'total_attempts'; var OUTPUT_EXIT_CODE_KEY = 'exit_code'; var OUTPUT_EXIT_ERROR_KEY = 'exit_error'; var exit; var done; function getInputNumber(id, required) { var input = core_1.getInput(id, { required: required }); var num = Number.parseInt(input); // empty is ok if (!input && !required) { return; } if (!Number.isInteger(num)) { throw "Input " + id + " only accepts numbers. Received " + input; } return num; } function retryWait() { return __awaiter(this, void 0, void 0, function () { var waitStart; return __generator(this, function (_a) { switch (_a.label) { case 0: waitStart = Date.now(); return [4 /*yield*/, util_1.wait(milliseconds_1.default.seconds(RETRY_WAIT_SECONDS))]; case 1: _a.sent(); core_1.debug("Waited " + (Date.now() - waitStart) + "ms"); core_1.debug("Configured wait: " + milliseconds_1.default.seconds(RETRY_WAIT_SECONDS) + "ms"); return [2 /*return*/]; } }); }); } function validateInputs() { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { if ((!TIMEOUT_MINUTES && !TIMEOUT_SECONDS) || (TIMEOUT_MINUTES && TIMEOUT_SECONDS)) { throw new Error('Must specify either timeout_minutes or timeout_seconds inputs'); } if (TIMEOUT_SECONDS && TIMEOUT_SECONDS < RETRY_WAIT_SECONDS) { throw new Error("timeout_seconds " + TIMEOUT_SECONDS + "s less than retry_wait_seconds " + RETRY_WAIT_SECONDS + "s"); } return [2 /*return*/]; }); }); } function getTimeout() { if (TIMEOUT_MINUTES) { return milliseconds_1.default.minutes(TIMEOUT_MINUTES); } else if (TIMEOUT_SECONDS) { return milliseconds_1.default.seconds(TIMEOUT_SECONDS); } throw new Error('Must specify either timeout_minutes or timeout_seconds inputs'); } function runCmd() { var _a, _b; return __awaiter(this, void 0, void 0, function () { var end_time, child; return __generator(this, function (_c) { switch (_c.label) { case 0: end_time = Date.now() + getTimeout(); exit = 0; done = false; child = child_process_1.exec(COMMAND); (_a = child.stdout) === null || _a === void 0 ? void 0 : _a.on('data', function (data) { process.stdout.write(data); }); (_b = child.stderr) === null || _b === void 0 ? void 0 : _b.on('data', function (data) { process.stdout.write(data); }); child.on('exit', function (code, signal) { core_1.debug("Code: " + code); core_1.debug("Signal: " + signal); if (code && code > 0) { exit = code; } // timeouts are killed manually if (signal === 'SIGTERM') { return; } done = true; }); _c.label = 1; case 1: return [4 /*yield*/, util_1.wait(milliseconds_1.default.seconds(POLLING_INTERVAL_SECONDS))]; case 2: _c.sent(); _c.label = 3; case 3: if (Date.now() < end_time && !done) return [3 /*break*/, 1]; _c.label = 4; case 4: if (!!done) return [3 /*break*/, 6]; tree_kill_1.default(child.pid); return [4 /*yield*/, retryWait()]; case 5: _c.sent(); throw new Error("Timeout of " + getTimeout() + "ms hit"); case 6: if (!(exit > 0)) return [3 /*break*/, 8]; return [4 /*yield*/, retryWait()]; case 7: _c.sent(); throw new Error("Child_process exited with error code " + exit); case 8: return [2 /*return*/]; } }); }); } function runAction() { return __awaiter(this, void 0, void 0, function () { var attempt, error_1; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, validateInputs()]; case 1: _a.sent(); attempt = 1; _a.label = 2; case 2: if (!(attempt <= MAX_ATTEMPTS)) return [3 /*break*/, 7]; _a.label = 3; case 3: _a.trys.push([3, 5, , 6]); // just keep overwriting attempts output core_1.setOutput(OUTPUT_TOTAL_ATTEMPTS_KEY, attempt); return [4 /*yield*/, runCmd()]; case 4: _a.sent(); core_1.info("Command completed after " + attempt + " attempt(s)."); return [3 /*break*/, 7]; case 5: error_1 = _a.sent(); if (attempt === MAX_ATTEMPTS) { throw new Error("Final attempt failed. " + error_1.message); } else if (!done && RETRY_ON === 'error') { // error: timeout throw error_1; } else if (exit > 0 && RETRY_ON === 'timeout') { // error: error throw error_1; } else { core_1.warning("Attempt " + attempt + " failed. Reason: " + error_1.message); } return [3 /*break*/, 6]; case 6: attempt++; return [3 /*break*/, 2]; case 7: return [2 /*return*/]; } }); }); } runAction() .then(function () { core_1.setOutput(OUTPUT_EXIT_CODE_KEY, 0); process.exit(0); // success }) .catch(function (err) { core_1.error(err.message); // these can be helpful to know if continue-on-error is true core_1.setOutput(OUTPUT_EXIT_ERROR_KEY, err.message); core_1.setOutput(OUTPUT_EXIT_CODE_KEY, exit > 0 ? exit : 1); // exit with exact error code if available, otherwise just exit with 1 process.exit(exit > 0 ? exit : 1); }); /***/ }), /***/ 431: /***/ (function(__unusedmodule, exports, __webpack_require__) { "use strict"; var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; result["default"] = mod; return result; }; Object.defineProperty(exports, "__esModule", { value: true }); const os = __importStar(__webpack_require__(87)); const utils_1 = __webpack_require__(82); /** * Commands * * Command Format: * ::name key=value,key=value::message * * Examples: * ::warning::This is the message * ::set-env name=MY_VAR::some value */ function issueCommand(command, properties, message) { const cmd = new Command(command, properties, message); process.stdout.write(cmd.toString() + os.EOL); } exports.issueCommand = issueCommand; function issue(name, message = '') { issueCommand(name, {}, message); } exports.issue = issue; const CMD_STRING = '::'; class Command { constructor(command, properties, message) { if (!command) { command = 'missing.command'; } this.command = command; this.properties = properties; this.message = message; } toString() { let cmdStr = CMD_STRING + this.command; if (this.properties && Object.keys(this.properties).length > 0) { cmdStr += ' '; let first = true; for (const key in this.properties) { if (this.properties.hasOwnProperty(key)) { const val = this.properties[key]; if (val) { if (first) { first = false; } else { cmdStr += ','; } cmdStr += `${key}=${escapeProperty(val)}`; } } } } cmdStr += `${CMD_STRING}${escapeData(this.message)}`; return cmdStr; } } function escapeData(s) { return utils_1.toCommandValue(s) .replace(/%/g, '%25') .replace(/\r/g, '%0D') .replace(/\n/g, '%0A'); } function escapeProperty(s) { return utils_1.toCommandValue(s) .replace(/%/g, '%25') .replace(/\r/g, '%0D') .replace(/\n/g, '%0A') .replace(/:/g, '%3A') .replace(/,/g, '%2C'); } //# sourceMappingURL=command.js.map /***/ }), /***/ 470: /***/ (function(__unusedmodule, exports, __webpack_require__) { "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; result["default"] = mod; return result; }; Object.defineProperty(exports, "__esModule", { value: true }); const command_1 = __webpack_require__(431); const file_command_1 = __webpack_require__(102); const utils_1 = __webpack_require__(82); const os = __importStar(__webpack_require__(87)); const path = __importStar(__webpack_require__(622)); /** * The code to exit an action */ var ExitCode; (function (ExitCode) { /** * A code indicating that the action was successful */ ExitCode[ExitCode["Success"] = 0] = "Success"; /** * A code indicating that the action was a failure */ ExitCode[ExitCode["Failure"] = 1] = "Failure"; })(ExitCode = exports.ExitCode || (exports.ExitCode = {})); //----------------------------------------------------------------------- // Variables //----------------------------------------------------------------------- /** * Sets env variable for this action and future actions in the job * @param name the name of the variable to set * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify */ // eslint-disable-next-line @typescript-eslint/no-explicit-any function exportVariable(name, val) { const convertedVal = utils_1.toCommandValue(val); process.env[name] = convertedVal; const filePath = process.env['GITHUB_ENV'] || ''; if (filePath) { const delimiter = '_GitHubActionsFileCommandDelimeter_'; const commandValue = `${name}<<${delimiter}${os.EOL}${convertedVal}${os.EOL}${delimiter}`; file_command_1.issueCommand('ENV', commandValue); } else { command_1.issueCommand('set-env', { name }, convertedVal); } } exports.exportVariable = exportVariable; /** * Registers a secret which will get masked from logs * @param secret value of the secret */ function setSecret(secret) { command_1.issueCommand('add-mask', {}, secret); } exports.setSecret = setSecret; /** * Prepends inputPath to the PATH (for this action and future actions) * @param inputPath */ function addPath(inputPath) { const filePath = process.env['GITHUB_PATH'] || ''; if (filePath) { file_command_1.issueCommand('PATH', inputPath); } else { command_1.issueCommand('add-path', {}, inputPath); } process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`; } exports.addPath = addPath; /** * Gets the value of an input. The value is also trimmed. * * @param name name of the input to get * @param options optional. See InputOptions. * @returns string */ function getInput(name, options) { const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || ''; if (options && options.required && !val) { throw new Error(`Input required and not supplied: ${name}`); } return val.trim(); } exports.getInput = getInput; /** * Sets the value of an output. * * @param name name of the output to set * @param value value to store. Non-string values will be converted to a string via JSON.stringify */ // eslint-disable-next-line @typescript-eslint/no-explicit-any function setOutput(name, value) { command_1.issueCommand('set-output', { name }, value); } exports.setOutput = setOutput; /** * Enables or disables the echoing of commands into stdout for the rest of the step. * Echoing is disabled by default if ACTIONS_STEP_DEBUG is not set. * */ function setCommandEcho(enabled) { command_1.issue('echo', enabled ? 'on' : 'off'); } exports.setCommandEcho = setCommandEcho; //----------------------------------------------------------------------- // Results //----------------------------------------------------------------------- /** * Sets the action status to failed. * When the action exits it will be with an exit code of 1 * @param message add error issue message */ function setFailed(message) { process.exitCode = ExitCode.Failure; error(message); } exports.setFailed = setFailed; //----------------------------------------------------------------------- // Logging Commands //----------------------------------------------------------------------- /** * Gets whether Actions Step Debug is on or not */ function isDebug() { return process.env['RUNNER_DEBUG'] === '1'; } exports.isDebug = isDebug; /** * Writes debug message to user log * @param message debug message */ function debug(message) { command_1.issueCommand('debug', {}, message); } exports.debug = debug; /** * Adds an error issue * @param message error issue message. Errors will be converted to string via toString() */ function error(message) { command_1.issue('error', message instanceof Error ? message.toString() : message); } exports.error = error; /** * Adds an warning issue * @param message warning issue message. Errors will be converted to string via toString() */ function warning(message) { command_1.issue('warning', message instanceof Error ? message.toString() : message); } exports.warning = warning; /** * Writes info to log with console.log. * @param message info message */ function info(message) { process.stdout.write(message + os.EOL); } exports.info = info; /** * Begin an output group. * * Output until the next `groupEnd` will be foldable in this group * * @param name The name of the output group */ function startGroup(name) { command_1.issue('group', name); } exports.startGroup = startGroup; /** * End an output group. */ function endGroup() { command_1.issue('endgroup'); } exports.endGroup = endGroup; /** * Wrap an asynchronous function call in a group. * * Returns the same type as the function itself. * * @param name The name of the group * @param fn The function to wrap in the group */ function group(name, fn) { return __awaiter(this, void 0, void 0, function* () { startGroup(name); let result; try { result = yield fn(); } finally { endGroup(); } return result; }); } exports.group = group; //----------------------------------------------------------------------- // Wrapper action state //----------------------------------------------------------------------- /** * Saves state for current action, the state can only be retrieved by this action's post job execution. * * @param name name of the state to store * @param value value to store. Non-string values will be converted to a string via JSON.stringify */ // eslint-disable-next-line @typescript-eslint/no-explicit-any function saveState(name, value) { command_1.issueCommand('save-state', { name }, value); } exports.saveState = saveState; /** * Gets the value of an state set by this action's main execution. * * @param name name of the state to get * @returns string */ function getState(name) { return process.env[`STATE_${name}`] || ''; } exports.getState = getState; //# sourceMappingURL=core.js.map /***/ }), /***/ 622: /***/ (function(module) { module.exports = require("path"); /***/ }), /***/ 747: /***/ (function(module) { module.exports = require("fs"); /***/ }), /***/ 791: /***/ (function(module, __unusedexports, __webpack_require__) { "use strict"; var childProcess = __webpack_require__(129); var spawn = childProcess.spawn; var exec = childProcess.exec; module.exports = function (pid, signal, callback) { if (typeof signal === 'function' && callback === undefined) { callback = signal; signal = undefined; } pid = parseInt(pid); if (Number.isNaN(pid)) { if (callback) { return callback(new Error("pid must be a number")); } else { throw new Error("pid must be a number"); } } var tree = {}; var pidsToProcess = {}; tree[pid] = []; pidsToProcess[pid] = 1; switch (process.platform) { case 'win32': exec('taskkill /pid ' + pid + ' /T /F', callback); break; case 'darwin': buildProcessTree(pid, tree, pidsToProcess, function (parentPid) { return spawn('pgrep', ['-P', parentPid]); }, function () { killAll(tree, signal, callback); }); break; // case 'sunos': // buildProcessTreeSunOS(pid, tree, pidsToProcess, function () { // killAll(tree, signal, callback); // }); // break; default: // Linux buildProcessTree(pid, tree, pidsToProcess, function (parentPid) { return spawn('ps', ['-o', 'pid', '--no-headers', '--ppid', parentPid]); }, function () { killAll(tree, signal, callback); }); break; } }; function killAll (tree, signal, callback) { var killed = {}; try { Object.keys(tree).forEach(function (pid) { tree[pid].forEach(function (pidpid) { if (!killed[pidpid]) { killPid(pidpid, signal); killed[pidpid] = 1; } }); if (!killed[pid]) { killPid(pid, signal); killed[pid] = 1; } }); } catch (err) { if (callback) { return callback(err); } else { throw err; } } if (callback) { return callback(); } } function killPid(pid, signal) { try { process.kill(parseInt(pid, 10), signal); } catch (err) { if (err.code !== 'ESRCH') throw err; } } function buildProcessTree (parentPid, tree, pidsToProcess, spawnChildProcessesList, cb) { var ps = spawnChildProcessesList(parentPid); var allData = ''; ps.stdout.on('data', function (data) { var data = data.toString('ascii'); allData += data; }); var onClose = function (code) { delete pidsToProcess[parentPid]; if (code != 0) { // no more parent processes if (Object.keys(pidsToProcess).length == 0) { cb(); } return; } allData.match(/\d+/g).forEach(function (pid) { pid = parseInt(pid, 10); tree[parentPid].push(pid); tree[pid] = []; pidsToProcess[pid] = 1; buildProcessTree(pid, tree, pidsToProcess, spawnChildProcessesList, cb); }); }; ps.on('close', onClose); } /***/ }) /******/ });