mirror of https://github.com/actions/cache
Update with core 2.0.1 which has exec 2.0.0
This commit is contained in:
parent
a9d8a74065
commit
d3cff5bce3
|
|
@ -4241,7 +4241,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.isLinux = exports.isMacOS = exports.isWindows = exports.arch = exports.platform = void 0;
|
exports.isLinux = exports.isMacOS = exports.isWindows = exports.arch = exports.platform = void 0;
|
||||||
exports.getDetails = getDetails;
|
exports.getDetails = getDetails;
|
||||||
const os_1 = __importDefault(__nccwpck_require__(70857));
|
const os_1 = __importDefault(__nccwpck_require__(70857));
|
||||||
const exec = __importStar(__nccwpck_require__(9966));
|
const exec = __importStar(__nccwpck_require__(32231));
|
||||||
const getWindowsInfo = () => __awaiter(void 0, void 0, void 0, function* () {
|
const getWindowsInfo = () => __awaiter(void 0, void 0, void 0, function* () {
|
||||||
const { stdout: version } = yield exec.getExecOutput('powershell -command "(Get-CimInstance -ClassName Win32_OperatingSystem).Version"', undefined, {
|
const { stdout: version } = yield exec.getExecOutput('powershell -command "(Get-CimInstance -ClassName Win32_OperatingSystem).Version"', undefined, {
|
||||||
silent: true
|
silent: true
|
||||||
|
|
@ -4634,1237 +4634,6 @@ function toCommandProperties(annotationProperties) {
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 9966:
|
|
||||||
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
||||||
}) : (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
o[k2] = m[k];
|
|
||||||
}));
|
|
||||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
||||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
||||||
}) : function(o, v) {
|
|
||||||
o["default"] = v;
|
|
||||||
});
|
|
||||||
var __importStar = (this && this.__importStar) || function (mod) {
|
|
||||||
if (mod && mod.__esModule) return mod;
|
|
||||||
var result = {};
|
|
||||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
||||||
__setModuleDefault(result, mod);
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
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());
|
|
||||||
});
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.getExecOutput = exports.exec = void 0;
|
|
||||||
const string_decoder_1 = __nccwpck_require__(13193);
|
|
||||||
const tr = __importStar(__nccwpck_require__(89063));
|
|
||||||
/**
|
|
||||||
* Exec a command.
|
|
||||||
* Output will be streamed to the live console.
|
|
||||||
* Returns promise with return code
|
|
||||||
*
|
|
||||||
* @param commandLine command to execute (can include additional args). Must be correctly escaped.
|
|
||||||
* @param args optional arguments for tool. Escaping is handled by the lib.
|
|
||||||
* @param options optional exec options. See ExecOptions
|
|
||||||
* @returns Promise<number> exit code
|
|
||||||
*/
|
|
||||||
function exec(commandLine, args, options) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
const commandArgs = tr.argStringToArray(commandLine);
|
|
||||||
if (commandArgs.length === 0) {
|
|
||||||
throw new Error(`Parameter 'commandLine' cannot be null or empty.`);
|
|
||||||
}
|
|
||||||
// Path to tool to execute should be first arg
|
|
||||||
const toolPath = commandArgs[0];
|
|
||||||
args = commandArgs.slice(1).concat(args || []);
|
|
||||||
const runner = new tr.ToolRunner(toolPath, args, options);
|
|
||||||
return runner.exec();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.exec = exec;
|
|
||||||
/**
|
|
||||||
* Exec a command and get the output.
|
|
||||||
* Output will be streamed to the live console.
|
|
||||||
* Returns promise with the exit code and collected stdout and stderr
|
|
||||||
*
|
|
||||||
* @param commandLine command to execute (can include additional args). Must be correctly escaped.
|
|
||||||
* @param args optional arguments for tool. Escaping is handled by the lib.
|
|
||||||
* @param options optional exec options. See ExecOptions
|
|
||||||
* @returns Promise<ExecOutput> exit code, stdout, and stderr
|
|
||||||
*/
|
|
||||||
function getExecOutput(commandLine, args, options) {
|
|
||||||
var _a, _b;
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
let stdout = '';
|
|
||||||
let stderr = '';
|
|
||||||
//Using string decoder covers the case where a mult-byte character is split
|
|
||||||
const stdoutDecoder = new string_decoder_1.StringDecoder('utf8');
|
|
||||||
const stderrDecoder = new string_decoder_1.StringDecoder('utf8');
|
|
||||||
const originalStdoutListener = (_a = options === null || options === void 0 ? void 0 : options.listeners) === null || _a === void 0 ? void 0 : _a.stdout;
|
|
||||||
const originalStdErrListener = (_b = options === null || options === void 0 ? void 0 : options.listeners) === null || _b === void 0 ? void 0 : _b.stderr;
|
|
||||||
const stdErrListener = (data) => {
|
|
||||||
stderr += stderrDecoder.write(data);
|
|
||||||
if (originalStdErrListener) {
|
|
||||||
originalStdErrListener(data);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const stdOutListener = (data) => {
|
|
||||||
stdout += stdoutDecoder.write(data);
|
|
||||||
if (originalStdoutListener) {
|
|
||||||
originalStdoutListener(data);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const listeners = Object.assign(Object.assign({}, options === null || options === void 0 ? void 0 : options.listeners), { stdout: stdOutListener, stderr: stdErrListener });
|
|
||||||
const exitCode = yield exec(commandLine, args, Object.assign(Object.assign({}, options), { listeners }));
|
|
||||||
//flush any remaining characters
|
|
||||||
stdout += stdoutDecoder.end();
|
|
||||||
stderr += stderrDecoder.end();
|
|
||||||
return {
|
|
||||||
exitCode,
|
|
||||||
stdout,
|
|
||||||
stderr
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.getExecOutput = getExecOutput;
|
|
||||||
//# sourceMappingURL=exec.js.map
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 89063:
|
|
||||||
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
||||||
}) : (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
o[k2] = m[k];
|
|
||||||
}));
|
|
||||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
||||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
||||||
}) : function(o, v) {
|
|
||||||
o["default"] = v;
|
|
||||||
});
|
|
||||||
var __importStar = (this && this.__importStar) || function (mod) {
|
|
||||||
if (mod && mod.__esModule) return mod;
|
|
||||||
var result = {};
|
|
||||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
||||||
__setModuleDefault(result, mod);
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
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());
|
|
||||||
});
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.argStringToArray = exports.ToolRunner = void 0;
|
|
||||||
const os = __importStar(__nccwpck_require__(70857));
|
|
||||||
const events = __importStar(__nccwpck_require__(24434));
|
|
||||||
const child = __importStar(__nccwpck_require__(35317));
|
|
||||||
const path = __importStar(__nccwpck_require__(16928));
|
|
||||||
const io = __importStar(__nccwpck_require__(42172));
|
|
||||||
const ioUtil = __importStar(__nccwpck_require__(31485));
|
|
||||||
const timers_1 = __nccwpck_require__(53557);
|
|
||||||
/* eslint-disable @typescript-eslint/unbound-method */
|
|
||||||
const IS_WINDOWS = process.platform === 'win32';
|
|
||||||
/*
|
|
||||||
* Class for running command line tools. Handles quoting and arg parsing in a platform agnostic way.
|
|
||||||
*/
|
|
||||||
class ToolRunner extends events.EventEmitter {
|
|
||||||
constructor(toolPath, args, options) {
|
|
||||||
super();
|
|
||||||
if (!toolPath) {
|
|
||||||
throw new Error("Parameter 'toolPath' cannot be null or empty.");
|
|
||||||
}
|
|
||||||
this.toolPath = toolPath;
|
|
||||||
this.args = args || [];
|
|
||||||
this.options = options || {};
|
|
||||||
}
|
|
||||||
_debug(message) {
|
|
||||||
if (this.options.listeners && this.options.listeners.debug) {
|
|
||||||
this.options.listeners.debug(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_getCommandString(options, noPrefix) {
|
|
||||||
const toolPath = this._getSpawnFileName();
|
|
||||||
const args = this._getSpawnArgs(options);
|
|
||||||
let cmd = noPrefix ? '' : '[command]'; // omit prefix when piped to a second tool
|
|
||||||
if (IS_WINDOWS) {
|
|
||||||
// Windows + cmd file
|
|
||||||
if (this._isCmdFile()) {
|
|
||||||
cmd += toolPath;
|
|
||||||
for (const a of args) {
|
|
||||||
cmd += ` ${a}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Windows + verbatim
|
|
||||||
else if (options.windowsVerbatimArguments) {
|
|
||||||
cmd += `"${toolPath}"`;
|
|
||||||
for (const a of args) {
|
|
||||||
cmd += ` ${a}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Windows (regular)
|
|
||||||
else {
|
|
||||||
cmd += this._windowsQuoteCmdArg(toolPath);
|
|
||||||
for (const a of args) {
|
|
||||||
cmd += ` ${this._windowsQuoteCmdArg(a)}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// OSX/Linux - this can likely be improved with some form of quoting.
|
|
||||||
// creating processes on Unix is fundamentally different than Windows.
|
|
||||||
// on Unix, execvp() takes an arg array.
|
|
||||||
cmd += toolPath;
|
|
||||||
for (const a of args) {
|
|
||||||
cmd += ` ${a}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return cmd;
|
|
||||||
}
|
|
||||||
_processLineBuffer(data, strBuffer, onLine) {
|
|
||||||
try {
|
|
||||||
let s = strBuffer + data.toString();
|
|
||||||
let n = s.indexOf(os.EOL);
|
|
||||||
while (n > -1) {
|
|
||||||
const line = s.substring(0, n);
|
|
||||||
onLine(line);
|
|
||||||
// the rest of the string ...
|
|
||||||
s = s.substring(n + os.EOL.length);
|
|
||||||
n = s.indexOf(os.EOL);
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
// streaming lines to console is best effort. Don't fail a build.
|
|
||||||
this._debug(`error processing line. Failed with error ${err}`);
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_getSpawnFileName() {
|
|
||||||
if (IS_WINDOWS) {
|
|
||||||
if (this._isCmdFile()) {
|
|
||||||
return process.env['COMSPEC'] || 'cmd.exe';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this.toolPath;
|
|
||||||
}
|
|
||||||
_getSpawnArgs(options) {
|
|
||||||
if (IS_WINDOWS) {
|
|
||||||
if (this._isCmdFile()) {
|
|
||||||
let argline = `/D /S /C "${this._windowsQuoteCmdArg(this.toolPath)}`;
|
|
||||||
for (const a of this.args) {
|
|
||||||
argline += ' ';
|
|
||||||
argline += options.windowsVerbatimArguments
|
|
||||||
? a
|
|
||||||
: this._windowsQuoteCmdArg(a);
|
|
||||||
}
|
|
||||||
argline += '"';
|
|
||||||
return [argline];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this.args;
|
|
||||||
}
|
|
||||||
_endsWith(str, end) {
|
|
||||||
return str.endsWith(end);
|
|
||||||
}
|
|
||||||
_isCmdFile() {
|
|
||||||
const upperToolPath = this.toolPath.toUpperCase();
|
|
||||||
return (this._endsWith(upperToolPath, '.CMD') ||
|
|
||||||
this._endsWith(upperToolPath, '.BAT'));
|
|
||||||
}
|
|
||||||
_windowsQuoteCmdArg(arg) {
|
|
||||||
// for .exe, apply the normal quoting rules that libuv applies
|
|
||||||
if (!this._isCmdFile()) {
|
|
||||||
return this._uvQuoteCmdArg(arg);
|
|
||||||
}
|
|
||||||
// otherwise apply quoting rules specific to the cmd.exe command line parser.
|
|
||||||
// the libuv rules are generic and are not designed specifically for cmd.exe
|
|
||||||
// command line parser.
|
|
||||||
//
|
|
||||||
// for a detailed description of the cmd.exe command line parser, refer to
|
|
||||||
// http://stackoverflow.com/questions/4094699/how-does-the-windows-command-interpreter-cmd-exe-parse-scripts/7970912#7970912
|
|
||||||
// need quotes for empty arg
|
|
||||||
if (!arg) {
|
|
||||||
return '""';
|
|
||||||
}
|
|
||||||
// determine whether the arg needs to be quoted
|
|
||||||
const cmdSpecialChars = [
|
|
||||||
' ',
|
|
||||||
'\t',
|
|
||||||
'&',
|
|
||||||
'(',
|
|
||||||
')',
|
|
||||||
'[',
|
|
||||||
']',
|
|
||||||
'{',
|
|
||||||
'}',
|
|
||||||
'^',
|
|
||||||
'=',
|
|
||||||
';',
|
|
||||||
'!',
|
|
||||||
"'",
|
|
||||||
'+',
|
|
||||||
',',
|
|
||||||
'`',
|
|
||||||
'~',
|
|
||||||
'|',
|
|
||||||
'<',
|
|
||||||
'>',
|
|
||||||
'"'
|
|
||||||
];
|
|
||||||
let needsQuotes = false;
|
|
||||||
for (const char of arg) {
|
|
||||||
if (cmdSpecialChars.some(x => x === char)) {
|
|
||||||
needsQuotes = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// short-circuit if quotes not needed
|
|
||||||
if (!needsQuotes) {
|
|
||||||
return arg;
|
|
||||||
}
|
|
||||||
// the following quoting rules are very similar to the rules that by libuv applies.
|
|
||||||
//
|
|
||||||
// 1) wrap the string in quotes
|
|
||||||
//
|
|
||||||
// 2) double-up quotes - i.e. " => ""
|
|
||||||
//
|
|
||||||
// this is different from the libuv quoting rules. libuv replaces " with \", which unfortunately
|
|
||||||
// doesn't work well with a cmd.exe command line.
|
|
||||||
//
|
|
||||||
// note, replacing " with "" also works well if the arg is passed to a downstream .NET console app.
|
|
||||||
// for example, the command line:
|
|
||||||
// foo.exe "myarg:""my val"""
|
|
||||||
// is parsed by a .NET console app into an arg array:
|
|
||||||
// [ "myarg:\"my val\"" ]
|
|
||||||
// which is the same end result when applying libuv quoting rules. although the actual
|
|
||||||
// command line from libuv quoting rules would look like:
|
|
||||||
// foo.exe "myarg:\"my val\""
|
|
||||||
//
|
|
||||||
// 3) double-up slashes that precede a quote,
|
|
||||||
// e.g. hello \world => "hello \world"
|
|
||||||
// hello\"world => "hello\\""world"
|
|
||||||
// hello\\"world => "hello\\\\""world"
|
|
||||||
// hello world\ => "hello world\\"
|
|
||||||
//
|
|
||||||
// technically this is not required for a cmd.exe command line, or the batch argument parser.
|
|
||||||
// the reasons for including this as a .cmd quoting rule are:
|
|
||||||
//
|
|
||||||
// a) this is optimized for the scenario where the argument is passed from the .cmd file to an
|
|
||||||
// external program. many programs (e.g. .NET console apps) rely on the slash-doubling rule.
|
|
||||||
//
|
|
||||||
// b) it's what we've been doing previously (by deferring to node default behavior) and we
|
|
||||||
// haven't heard any complaints about that aspect.
|
|
||||||
//
|
|
||||||
// note, a weakness of the quoting rules chosen here, is that % is not escaped. in fact, % cannot be
|
|
||||||
// escaped when used on the command line directly - even though within a .cmd file % can be escaped
|
|
||||||
// by using %%.
|
|
||||||
//
|
|
||||||
// the saving grace is, on the command line, %var% is left as-is if var is not defined. this contrasts
|
|
||||||
// the line parsing rules within a .cmd file, where if var is not defined it is replaced with nothing.
|
|
||||||
//
|
|
||||||
// one option that was explored was replacing % with ^% - i.e. %var% => ^%var^%. this hack would
|
|
||||||
// often work, since it is unlikely that var^ would exist, and the ^ character is removed when the
|
|
||||||
// variable is used. the problem, however, is that ^ is not removed when %* is used to pass the args
|
|
||||||
// to an external program.
|
|
||||||
//
|
|
||||||
// an unexplored potential solution for the % escaping problem, is to create a wrapper .cmd file.
|
|
||||||
// % can be escaped within a .cmd file.
|
|
||||||
let reverse = '"';
|
|
||||||
let quoteHit = true;
|
|
||||||
for (let i = arg.length; i > 0; i--) {
|
|
||||||
// walk the string in reverse
|
|
||||||
reverse += arg[i - 1];
|
|
||||||
if (quoteHit && arg[i - 1] === '\\') {
|
|
||||||
reverse += '\\'; // double the slash
|
|
||||||
}
|
|
||||||
else if (arg[i - 1] === '"') {
|
|
||||||
quoteHit = true;
|
|
||||||
reverse += '"'; // double the quote
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
quoteHit = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
reverse += '"';
|
|
||||||
return reverse
|
|
||||||
.split('')
|
|
||||||
.reverse()
|
|
||||||
.join('');
|
|
||||||
}
|
|
||||||
_uvQuoteCmdArg(arg) {
|
|
||||||
// Tool runner wraps child_process.spawn() and needs to apply the same quoting as
|
|
||||||
// Node in certain cases where the undocumented spawn option windowsVerbatimArguments
|
|
||||||
// is used.
|
|
||||||
//
|
|
||||||
// Since this function is a port of quote_cmd_arg from Node 4.x (technically, lib UV,
|
|
||||||
// see https://github.com/nodejs/node/blob/v4.x/deps/uv/src/win/process.c for details),
|
|
||||||
// pasting copyright notice from Node within this function:
|
|
||||||
//
|
|
||||||
// Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to
|
|
||||||
// deal in the Software without restriction, including without limitation the
|
|
||||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
||||||
// sell copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in
|
|
||||||
// all copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
||||||
// IN THE SOFTWARE.
|
|
||||||
if (!arg) {
|
|
||||||
// Need double quotation for empty argument
|
|
||||||
return '""';
|
|
||||||
}
|
|
||||||
if (!arg.includes(' ') && !arg.includes('\t') && !arg.includes('"')) {
|
|
||||||
// No quotation needed
|
|
||||||
return arg;
|
|
||||||
}
|
|
||||||
if (!arg.includes('"') && !arg.includes('\\')) {
|
|
||||||
// No embedded double quotes or backslashes, so I can just wrap
|
|
||||||
// quote marks around the whole thing.
|
|
||||||
return `"${arg}"`;
|
|
||||||
}
|
|
||||||
// Expected input/output:
|
|
||||||
// input : hello"world
|
|
||||||
// output: "hello\"world"
|
|
||||||
// input : hello""world
|
|
||||||
// output: "hello\"\"world"
|
|
||||||
// input : hello\world
|
|
||||||
// output: hello\world
|
|
||||||
// input : hello\\world
|
|
||||||
// output: hello\\world
|
|
||||||
// input : hello\"world
|
|
||||||
// output: "hello\\\"world"
|
|
||||||
// input : hello\\"world
|
|
||||||
// output: "hello\\\\\"world"
|
|
||||||
// input : hello world\
|
|
||||||
// output: "hello world\\" - note the comment in libuv actually reads "hello world\"
|
|
||||||
// but it appears the comment is wrong, it should be "hello world\\"
|
|
||||||
let reverse = '"';
|
|
||||||
let quoteHit = true;
|
|
||||||
for (let i = arg.length; i > 0; i--) {
|
|
||||||
// walk the string in reverse
|
|
||||||
reverse += arg[i - 1];
|
|
||||||
if (quoteHit && arg[i - 1] === '\\') {
|
|
||||||
reverse += '\\';
|
|
||||||
}
|
|
||||||
else if (arg[i - 1] === '"') {
|
|
||||||
quoteHit = true;
|
|
||||||
reverse += '\\';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
quoteHit = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
reverse += '"';
|
|
||||||
return reverse
|
|
||||||
.split('')
|
|
||||||
.reverse()
|
|
||||||
.join('');
|
|
||||||
}
|
|
||||||
_cloneExecOptions(options) {
|
|
||||||
options = options || {};
|
|
||||||
const result = {
|
|
||||||
cwd: options.cwd || process.cwd(),
|
|
||||||
env: options.env || process.env,
|
|
||||||
silent: options.silent || false,
|
|
||||||
windowsVerbatimArguments: options.windowsVerbatimArguments || false,
|
|
||||||
failOnStdErr: options.failOnStdErr || false,
|
|
||||||
ignoreReturnCode: options.ignoreReturnCode || false,
|
|
||||||
delay: options.delay || 10000
|
|
||||||
};
|
|
||||||
result.outStream = options.outStream || process.stdout;
|
|
||||||
result.errStream = options.errStream || process.stderr;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
_getSpawnOptions(options, toolPath) {
|
|
||||||
options = options || {};
|
|
||||||
const result = {};
|
|
||||||
result.cwd = options.cwd;
|
|
||||||
result.env = options.env;
|
|
||||||
result['windowsVerbatimArguments'] =
|
|
||||||
options.windowsVerbatimArguments || this._isCmdFile();
|
|
||||||
if (options.windowsVerbatimArguments) {
|
|
||||||
result.argv0 = `"${toolPath}"`;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Exec a tool.
|
|
||||||
* Output will be streamed to the live console.
|
|
||||||
* Returns promise with return code
|
|
||||||
*
|
|
||||||
* @param tool path to tool to exec
|
|
||||||
* @param options optional exec options. See ExecOptions
|
|
||||||
* @returns number
|
|
||||||
*/
|
|
||||||
exec() {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
// root the tool path if it is unrooted and contains relative pathing
|
|
||||||
if (!ioUtil.isRooted(this.toolPath) &&
|
|
||||||
(this.toolPath.includes('/') ||
|
|
||||||
(IS_WINDOWS && this.toolPath.includes('\\')))) {
|
|
||||||
// prefer options.cwd if it is specified, however options.cwd may also need to be rooted
|
|
||||||
this.toolPath = path.resolve(process.cwd(), this.options.cwd || process.cwd(), this.toolPath);
|
|
||||||
}
|
|
||||||
// if the tool is only a file name, then resolve it from the PATH
|
|
||||||
// otherwise verify it exists (add extension on Windows if necessary)
|
|
||||||
this.toolPath = yield io.which(this.toolPath, true);
|
|
||||||
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
|
|
||||||
this._debug(`exec tool: ${this.toolPath}`);
|
|
||||||
this._debug('arguments:');
|
|
||||||
for (const arg of this.args) {
|
|
||||||
this._debug(` ${arg}`);
|
|
||||||
}
|
|
||||||
const optionsNonNull = this._cloneExecOptions(this.options);
|
|
||||||
if (!optionsNonNull.silent && optionsNonNull.outStream) {
|
|
||||||
optionsNonNull.outStream.write(this._getCommandString(optionsNonNull) + os.EOL);
|
|
||||||
}
|
|
||||||
const state = new ExecState(optionsNonNull, this.toolPath);
|
|
||||||
state.on('debug', (message) => {
|
|
||||||
this._debug(message);
|
|
||||||
});
|
|
||||||
if (this.options.cwd && !(yield ioUtil.exists(this.options.cwd))) {
|
|
||||||
return reject(new Error(`The cwd: ${this.options.cwd} does not exist!`));
|
|
||||||
}
|
|
||||||
const fileName = this._getSpawnFileName();
|
|
||||||
const cp = child.spawn(fileName, this._getSpawnArgs(optionsNonNull), this._getSpawnOptions(this.options, fileName));
|
|
||||||
let stdbuffer = '';
|
|
||||||
if (cp.stdout) {
|
|
||||||
cp.stdout.on('data', (data) => {
|
|
||||||
if (this.options.listeners && this.options.listeners.stdout) {
|
|
||||||
this.options.listeners.stdout(data);
|
|
||||||
}
|
|
||||||
if (!optionsNonNull.silent && optionsNonNull.outStream) {
|
|
||||||
optionsNonNull.outStream.write(data);
|
|
||||||
}
|
|
||||||
stdbuffer = this._processLineBuffer(data, stdbuffer, (line) => {
|
|
||||||
if (this.options.listeners && this.options.listeners.stdline) {
|
|
||||||
this.options.listeners.stdline(line);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
let errbuffer = '';
|
|
||||||
if (cp.stderr) {
|
|
||||||
cp.stderr.on('data', (data) => {
|
|
||||||
state.processStderr = true;
|
|
||||||
if (this.options.listeners && this.options.listeners.stderr) {
|
|
||||||
this.options.listeners.stderr(data);
|
|
||||||
}
|
|
||||||
if (!optionsNonNull.silent &&
|
|
||||||
optionsNonNull.errStream &&
|
|
||||||
optionsNonNull.outStream) {
|
|
||||||
const s = optionsNonNull.failOnStdErr
|
|
||||||
? optionsNonNull.errStream
|
|
||||||
: optionsNonNull.outStream;
|
|
||||||
s.write(data);
|
|
||||||
}
|
|
||||||
errbuffer = this._processLineBuffer(data, errbuffer, (line) => {
|
|
||||||
if (this.options.listeners && this.options.listeners.errline) {
|
|
||||||
this.options.listeners.errline(line);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
cp.on('error', (err) => {
|
|
||||||
state.processError = err.message;
|
|
||||||
state.processExited = true;
|
|
||||||
state.processClosed = true;
|
|
||||||
state.CheckComplete();
|
|
||||||
});
|
|
||||||
cp.on('exit', (code) => {
|
|
||||||
state.processExitCode = code;
|
|
||||||
state.processExited = true;
|
|
||||||
this._debug(`Exit code ${code} received from tool '${this.toolPath}'`);
|
|
||||||
state.CheckComplete();
|
|
||||||
});
|
|
||||||
cp.on('close', (code) => {
|
|
||||||
state.processExitCode = code;
|
|
||||||
state.processExited = true;
|
|
||||||
state.processClosed = true;
|
|
||||||
this._debug(`STDIO streams have closed for tool '${this.toolPath}'`);
|
|
||||||
state.CheckComplete();
|
|
||||||
});
|
|
||||||
state.on('done', (error, exitCode) => {
|
|
||||||
if (stdbuffer.length > 0) {
|
|
||||||
this.emit('stdline', stdbuffer);
|
|
||||||
}
|
|
||||||
if (errbuffer.length > 0) {
|
|
||||||
this.emit('errline', errbuffer);
|
|
||||||
}
|
|
||||||
cp.removeAllListeners();
|
|
||||||
if (error) {
|
|
||||||
reject(error);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
resolve(exitCode);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (this.options.input) {
|
|
||||||
if (!cp.stdin) {
|
|
||||||
throw new Error('child process missing stdin');
|
|
||||||
}
|
|
||||||
cp.stdin.end(this.options.input);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.ToolRunner = ToolRunner;
|
|
||||||
/**
|
|
||||||
* Convert an arg string to an array of args. Handles escaping
|
|
||||||
*
|
|
||||||
* @param argString string of arguments
|
|
||||||
* @returns string[] array of arguments
|
|
||||||
*/
|
|
||||||
function argStringToArray(argString) {
|
|
||||||
const args = [];
|
|
||||||
let inQuotes = false;
|
|
||||||
let escaped = false;
|
|
||||||
let arg = '';
|
|
||||||
function append(c) {
|
|
||||||
// we only escape double quotes.
|
|
||||||
if (escaped && c !== '"') {
|
|
||||||
arg += '\\';
|
|
||||||
}
|
|
||||||
arg += c;
|
|
||||||
escaped = false;
|
|
||||||
}
|
|
||||||
for (let i = 0; i < argString.length; i++) {
|
|
||||||
const c = argString.charAt(i);
|
|
||||||
if (c === '"') {
|
|
||||||
if (!escaped) {
|
|
||||||
inQuotes = !inQuotes;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
append(c);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (c === '\\' && escaped) {
|
|
||||||
append(c);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (c === '\\' && inQuotes) {
|
|
||||||
escaped = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (c === ' ' && !inQuotes) {
|
|
||||||
if (arg.length > 0) {
|
|
||||||
args.push(arg);
|
|
||||||
arg = '';
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
append(c);
|
|
||||||
}
|
|
||||||
if (arg.length > 0) {
|
|
||||||
args.push(arg.trim());
|
|
||||||
}
|
|
||||||
return args;
|
|
||||||
}
|
|
||||||
exports.argStringToArray = argStringToArray;
|
|
||||||
class ExecState extends events.EventEmitter {
|
|
||||||
constructor(options, toolPath) {
|
|
||||||
super();
|
|
||||||
this.processClosed = false; // tracks whether the process has exited and stdio is closed
|
|
||||||
this.processError = '';
|
|
||||||
this.processExitCode = 0;
|
|
||||||
this.processExited = false; // tracks whether the process has exited
|
|
||||||
this.processStderr = false; // tracks whether stderr was written to
|
|
||||||
this.delay = 10000; // 10 seconds
|
|
||||||
this.done = false;
|
|
||||||
this.timeout = null;
|
|
||||||
if (!toolPath) {
|
|
||||||
throw new Error('toolPath must not be empty');
|
|
||||||
}
|
|
||||||
this.options = options;
|
|
||||||
this.toolPath = toolPath;
|
|
||||||
if (options.delay) {
|
|
||||||
this.delay = options.delay;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CheckComplete() {
|
|
||||||
if (this.done) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (this.processClosed) {
|
|
||||||
this._setResult();
|
|
||||||
}
|
|
||||||
else if (this.processExited) {
|
|
||||||
this.timeout = timers_1.setTimeout(ExecState.HandleTimeout, this.delay, this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_debug(message) {
|
|
||||||
this.emit('debug', message);
|
|
||||||
}
|
|
||||||
_setResult() {
|
|
||||||
// determine whether there is an error
|
|
||||||
let error;
|
|
||||||
if (this.processExited) {
|
|
||||||
if (this.processError) {
|
|
||||||
error = new Error(`There was an error when attempting to execute the process '${this.toolPath}'. This may indicate the process failed to start. Error: ${this.processError}`);
|
|
||||||
}
|
|
||||||
else if (this.processExitCode !== 0 && !this.options.ignoreReturnCode) {
|
|
||||||
error = new Error(`The process '${this.toolPath}' failed with exit code ${this.processExitCode}`);
|
|
||||||
}
|
|
||||||
else if (this.processStderr && this.options.failOnStdErr) {
|
|
||||||
error = new Error(`The process '${this.toolPath}' failed because one or more lines were written to the STDERR stream`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// clear the timeout
|
|
||||||
if (this.timeout) {
|
|
||||||
clearTimeout(this.timeout);
|
|
||||||
this.timeout = null;
|
|
||||||
}
|
|
||||||
this.done = true;
|
|
||||||
this.emit('done', error, this.processExitCode);
|
|
||||||
}
|
|
||||||
static HandleTimeout(state) {
|
|
||||||
if (state.done) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!state.processClosed && state.processExited) {
|
|
||||||
const message = `The STDIO streams did not close within ${state.delay /
|
|
||||||
1000} seconds of the exit event from process '${state.toolPath}'. This may indicate a child process inherited the STDIO streams and has not yet exited.`;
|
|
||||||
state._debug(message);
|
|
||||||
}
|
|
||||||
state._setResult();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//# sourceMappingURL=toolrunner.js.map
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 31485:
|
|
||||||
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
||||||
}) : (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
o[k2] = m[k];
|
|
||||||
}));
|
|
||||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
||||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
||||||
}) : function(o, v) {
|
|
||||||
o["default"] = v;
|
|
||||||
});
|
|
||||||
var __importStar = (this && this.__importStar) || function (mod) {
|
|
||||||
if (mod && mod.__esModule) return mod;
|
|
||||||
var result = {};
|
|
||||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
||||||
__setModuleDefault(result, mod);
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
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 _a;
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.getCmdPath = exports.tryGetExecutablePath = exports.isRooted = exports.isDirectory = exports.exists = exports.READONLY = exports.UV_FS_O_EXLOCK = exports.IS_WINDOWS = exports.unlink = exports.symlink = exports.stat = exports.rmdir = exports.rm = exports.rename = exports.readlink = exports.readdir = exports.open = exports.mkdir = exports.lstat = exports.copyFile = exports.chmod = void 0;
|
|
||||||
const fs = __importStar(__nccwpck_require__(79896));
|
|
||||||
const path = __importStar(__nccwpck_require__(16928));
|
|
||||||
_a = fs.promises
|
|
||||||
// export const {open} = 'fs'
|
|
||||||
, exports.chmod = _a.chmod, exports.copyFile = _a.copyFile, exports.lstat = _a.lstat, exports.mkdir = _a.mkdir, exports.open = _a.open, exports.readdir = _a.readdir, exports.readlink = _a.readlink, exports.rename = _a.rename, exports.rm = _a.rm, exports.rmdir = _a.rmdir, exports.stat = _a.stat, exports.symlink = _a.symlink, exports.unlink = _a.unlink;
|
|
||||||
// export const {open} = 'fs'
|
|
||||||
exports.IS_WINDOWS = process.platform === 'win32';
|
|
||||||
// See https://github.com/nodejs/node/blob/d0153aee367422d0858105abec186da4dff0a0c5/deps/uv/include/uv/win.h#L691
|
|
||||||
exports.UV_FS_O_EXLOCK = 0x10000000;
|
|
||||||
exports.READONLY = fs.constants.O_RDONLY;
|
|
||||||
function exists(fsPath) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
try {
|
|
||||||
yield exports.stat(fsPath);
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
if (err.code === 'ENOENT') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.exists = exists;
|
|
||||||
function isDirectory(fsPath, useStat = false) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
const stats = useStat ? yield exports.stat(fsPath) : yield exports.lstat(fsPath);
|
|
||||||
return stats.isDirectory();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.isDirectory = isDirectory;
|
|
||||||
/**
|
|
||||||
* On OSX/Linux, true if path starts with '/'. On Windows, true for paths like:
|
|
||||||
* \, \hello, \\hello\share, C:, and C:\hello (and corresponding alternate separator cases).
|
|
||||||
*/
|
|
||||||
function isRooted(p) {
|
|
||||||
p = normalizeSeparators(p);
|
|
||||||
if (!p) {
|
|
||||||
throw new Error('isRooted() parameter "p" cannot be empty');
|
|
||||||
}
|
|
||||||
if (exports.IS_WINDOWS) {
|
|
||||||
return (p.startsWith('\\') || /^[A-Z]:/i.test(p) // e.g. \ or \hello or \\hello
|
|
||||||
); // e.g. C: or C:\hello
|
|
||||||
}
|
|
||||||
return p.startsWith('/');
|
|
||||||
}
|
|
||||||
exports.isRooted = isRooted;
|
|
||||||
/**
|
|
||||||
* Best effort attempt to determine whether a file exists and is executable.
|
|
||||||
* @param filePath file path to check
|
|
||||||
* @param extensions additional file extensions to try
|
|
||||||
* @return if file exists and is executable, returns the file path. otherwise empty string.
|
|
||||||
*/
|
|
||||||
function tryGetExecutablePath(filePath, extensions) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
let stats = undefined;
|
|
||||||
try {
|
|
||||||
// test file exists
|
|
||||||
stats = yield exports.stat(filePath);
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
if (err.code !== 'ENOENT') {
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.log(`Unexpected error attempting to determine if executable file exists '${filePath}': ${err}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (stats && stats.isFile()) {
|
|
||||||
if (exports.IS_WINDOWS) {
|
|
||||||
// on Windows, test for valid extension
|
|
||||||
const upperExt = path.extname(filePath).toUpperCase();
|
|
||||||
if (extensions.some(validExt => validExt.toUpperCase() === upperExt)) {
|
|
||||||
return filePath;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (isUnixExecutable(stats)) {
|
|
||||||
return filePath;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// try each extension
|
|
||||||
const originalFilePath = filePath;
|
|
||||||
for (const extension of extensions) {
|
|
||||||
filePath = originalFilePath + extension;
|
|
||||||
stats = undefined;
|
|
||||||
try {
|
|
||||||
stats = yield exports.stat(filePath);
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
if (err.code !== 'ENOENT') {
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.log(`Unexpected error attempting to determine if executable file exists '${filePath}': ${err}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (stats && stats.isFile()) {
|
|
||||||
if (exports.IS_WINDOWS) {
|
|
||||||
// preserve the case of the actual file (since an extension was appended)
|
|
||||||
try {
|
|
||||||
const directory = path.dirname(filePath);
|
|
||||||
const upperName = path.basename(filePath).toUpperCase();
|
|
||||||
for (const actualName of yield exports.readdir(directory)) {
|
|
||||||
if (upperName === actualName.toUpperCase()) {
|
|
||||||
filePath = path.join(directory, actualName);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.log(`Unexpected error attempting to determine the actual case of the file '${filePath}': ${err}`);
|
|
||||||
}
|
|
||||||
return filePath;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (isUnixExecutable(stats)) {
|
|
||||||
return filePath;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.tryGetExecutablePath = tryGetExecutablePath;
|
|
||||||
function normalizeSeparators(p) {
|
|
||||||
p = p || '';
|
|
||||||
if (exports.IS_WINDOWS) {
|
|
||||||
// convert slashes on Windows
|
|
||||||
p = p.replace(/\//g, '\\');
|
|
||||||
// remove redundant slashes
|
|
||||||
return p.replace(/\\\\+/g, '\\');
|
|
||||||
}
|
|
||||||
// remove redundant slashes
|
|
||||||
return p.replace(/\/\/+/g, '/');
|
|
||||||
}
|
|
||||||
// on Mac/Linux, test the execute bit
|
|
||||||
// R W X R W X R W X
|
|
||||||
// 256 128 64 32 16 8 4 2 1
|
|
||||||
function isUnixExecutable(stats) {
|
|
||||||
return ((stats.mode & 1) > 0 ||
|
|
||||||
((stats.mode & 8) > 0 && stats.gid === process.getgid()) ||
|
|
||||||
((stats.mode & 64) > 0 && stats.uid === process.getuid()));
|
|
||||||
}
|
|
||||||
// Get the path of cmd.exe in windows
|
|
||||||
function getCmdPath() {
|
|
||||||
var _a;
|
|
||||||
return (_a = process.env['COMSPEC']) !== null && _a !== void 0 ? _a : `cmd.exe`;
|
|
||||||
}
|
|
||||||
exports.getCmdPath = getCmdPath;
|
|
||||||
//# sourceMappingURL=io-util.js.map
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 42172:
|
|
||||||
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
||||||
}) : (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
o[k2] = m[k];
|
|
||||||
}));
|
|
||||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
||||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
||||||
}) : function(o, v) {
|
|
||||||
o["default"] = v;
|
|
||||||
});
|
|
||||||
var __importStar = (this && this.__importStar) || function (mod) {
|
|
||||||
if (mod && mod.__esModule) return mod;
|
|
||||||
var result = {};
|
|
||||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
||||||
__setModuleDefault(result, mod);
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
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());
|
|
||||||
});
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.findInPath = exports.which = exports.mkdirP = exports.rmRF = exports.mv = exports.cp = void 0;
|
|
||||||
const assert_1 = __nccwpck_require__(42613);
|
|
||||||
const path = __importStar(__nccwpck_require__(16928));
|
|
||||||
const ioUtil = __importStar(__nccwpck_require__(31485));
|
|
||||||
/**
|
|
||||||
* Copies a file or folder.
|
|
||||||
* Based off of shelljs - https://github.com/shelljs/shelljs/blob/9237f66c52e5daa40458f94f9565e18e8132f5a6/src/cp.js
|
|
||||||
*
|
|
||||||
* @param source source path
|
|
||||||
* @param dest destination path
|
|
||||||
* @param options optional. See CopyOptions.
|
|
||||||
*/
|
|
||||||
function cp(source, dest, options = {}) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
const { force, recursive, copySourceDirectory } = readCopyOptions(options);
|
|
||||||
const destStat = (yield ioUtil.exists(dest)) ? yield ioUtil.stat(dest) : null;
|
|
||||||
// Dest is an existing file, but not forcing
|
|
||||||
if (destStat && destStat.isFile() && !force) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// If dest is an existing directory, should copy inside.
|
|
||||||
const newDest = destStat && destStat.isDirectory() && copySourceDirectory
|
|
||||||
? path.join(dest, path.basename(source))
|
|
||||||
: dest;
|
|
||||||
if (!(yield ioUtil.exists(source))) {
|
|
||||||
throw new Error(`no such file or directory: ${source}`);
|
|
||||||
}
|
|
||||||
const sourceStat = yield ioUtil.stat(source);
|
|
||||||
if (sourceStat.isDirectory()) {
|
|
||||||
if (!recursive) {
|
|
||||||
throw new Error(`Failed to copy. ${source} is a directory, but tried to copy without recursive flag.`);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
yield cpDirRecursive(source, newDest, 0, force);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (path.relative(source, newDest) === '') {
|
|
||||||
// a file cannot be copied to itself
|
|
||||||
throw new Error(`'${newDest}' and '${source}' are the same file`);
|
|
||||||
}
|
|
||||||
yield copyFile(source, newDest, force);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.cp = cp;
|
|
||||||
/**
|
|
||||||
* Moves a path.
|
|
||||||
*
|
|
||||||
* @param source source path
|
|
||||||
* @param dest destination path
|
|
||||||
* @param options optional. See MoveOptions.
|
|
||||||
*/
|
|
||||||
function mv(source, dest, options = {}) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
if (yield ioUtil.exists(dest)) {
|
|
||||||
let destExists = true;
|
|
||||||
if (yield ioUtil.isDirectory(dest)) {
|
|
||||||
// If dest is directory copy src into dest
|
|
||||||
dest = path.join(dest, path.basename(source));
|
|
||||||
destExists = yield ioUtil.exists(dest);
|
|
||||||
}
|
|
||||||
if (destExists) {
|
|
||||||
if (options.force == null || options.force) {
|
|
||||||
yield rmRF(dest);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new Error('Destination already exists');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
yield mkdirP(path.dirname(dest));
|
|
||||||
yield ioUtil.rename(source, dest);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.mv = mv;
|
|
||||||
/**
|
|
||||||
* Remove a path recursively with force
|
|
||||||
*
|
|
||||||
* @param inputPath path to remove
|
|
||||||
*/
|
|
||||||
function rmRF(inputPath) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
if (ioUtil.IS_WINDOWS) {
|
|
||||||
// Check for invalid characters
|
|
||||||
// https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file
|
|
||||||
if (/[*"<>|]/.test(inputPath)) {
|
|
||||||
throw new Error('File path must not contain `*`, `"`, `<`, `>` or `|` on Windows');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
// note if path does not exist, error is silent
|
|
||||||
yield ioUtil.rm(inputPath, {
|
|
||||||
force: true,
|
|
||||||
maxRetries: 3,
|
|
||||||
recursive: true,
|
|
||||||
retryDelay: 300
|
|
||||||
});
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
throw new Error(`File was unable to be removed ${err}`);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.rmRF = rmRF;
|
|
||||||
/**
|
|
||||||
* Make a directory. Creates the full path with folders in between
|
|
||||||
* Will throw if it fails
|
|
||||||
*
|
|
||||||
* @param fsPath path to create
|
|
||||||
* @returns Promise<void>
|
|
||||||
*/
|
|
||||||
function mkdirP(fsPath) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
assert_1.ok(fsPath, 'a path argument must be provided');
|
|
||||||
yield ioUtil.mkdir(fsPath, { recursive: true });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.mkdirP = mkdirP;
|
|
||||||
/**
|
|
||||||
* Returns path of a tool had the tool actually been invoked. Resolves via paths.
|
|
||||||
* If you check and the tool does not exist, it will throw.
|
|
||||||
*
|
|
||||||
* @param tool name of the tool
|
|
||||||
* @param check whether to check if tool exists
|
|
||||||
* @returns Promise<string> path to tool
|
|
||||||
*/
|
|
||||||
function which(tool, check) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
if (!tool) {
|
|
||||||
throw new Error("parameter 'tool' is required");
|
|
||||||
}
|
|
||||||
// recursive when check=true
|
|
||||||
if (check) {
|
|
||||||
const result = yield which(tool, false);
|
|
||||||
if (!result) {
|
|
||||||
if (ioUtil.IS_WINDOWS) {
|
|
||||||
throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also verify the file has a valid extension for an executable file.`);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also check the file mode to verify the file is executable.`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
const matches = yield findInPath(tool);
|
|
||||||
if (matches && matches.length > 0) {
|
|
||||||
return matches[0];
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.which = which;
|
|
||||||
/**
|
|
||||||
* Returns a list of all occurrences of the given tool on the system path.
|
|
||||||
*
|
|
||||||
* @returns Promise<string[]> the paths of the tool
|
|
||||||
*/
|
|
||||||
function findInPath(tool) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
if (!tool) {
|
|
||||||
throw new Error("parameter 'tool' is required");
|
|
||||||
}
|
|
||||||
// build the list of extensions to try
|
|
||||||
const extensions = [];
|
|
||||||
if (ioUtil.IS_WINDOWS && process.env['PATHEXT']) {
|
|
||||||
for (const extension of process.env['PATHEXT'].split(path.delimiter)) {
|
|
||||||
if (extension) {
|
|
||||||
extensions.push(extension);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// if it's rooted, return it if exists. otherwise return empty.
|
|
||||||
if (ioUtil.isRooted(tool)) {
|
|
||||||
const filePath = yield ioUtil.tryGetExecutablePath(tool, extensions);
|
|
||||||
if (filePath) {
|
|
||||||
return [filePath];
|
|
||||||
}
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
// if any path separators, return empty
|
|
||||||
if (tool.includes(path.sep)) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
// build the list of directories
|
|
||||||
//
|
|
||||||
// Note, technically "where" checks the current directory on Windows. From a toolkit perspective,
|
|
||||||
// it feels like we should not do this. Checking the current directory seems like more of a use
|
|
||||||
// case of a shell, and the which() function exposed by the toolkit should strive for consistency
|
|
||||||
// across platforms.
|
|
||||||
const directories = [];
|
|
||||||
if (process.env.PATH) {
|
|
||||||
for (const p of process.env.PATH.split(path.delimiter)) {
|
|
||||||
if (p) {
|
|
||||||
directories.push(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// find all matches
|
|
||||||
const matches = [];
|
|
||||||
for (const directory of directories) {
|
|
||||||
const filePath = yield ioUtil.tryGetExecutablePath(path.join(directory, tool), extensions);
|
|
||||||
if (filePath) {
|
|
||||||
matches.push(filePath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return matches;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.findInPath = findInPath;
|
|
||||||
function readCopyOptions(options) {
|
|
||||||
const force = options.force == null ? true : options.force;
|
|
||||||
const recursive = Boolean(options.recursive);
|
|
||||||
const copySourceDirectory = options.copySourceDirectory == null
|
|
||||||
? true
|
|
||||||
: Boolean(options.copySourceDirectory);
|
|
||||||
return { force, recursive, copySourceDirectory };
|
|
||||||
}
|
|
||||||
function cpDirRecursive(sourceDir, destDir, currentDepth, force) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
// Ensure there is not a run away recursive copy
|
|
||||||
if (currentDepth >= 255)
|
|
||||||
return;
|
|
||||||
currentDepth++;
|
|
||||||
yield mkdirP(destDir);
|
|
||||||
const files = yield ioUtil.readdir(sourceDir);
|
|
||||||
for (const fileName of files) {
|
|
||||||
const srcFile = `${sourceDir}/${fileName}`;
|
|
||||||
const destFile = `${destDir}/${fileName}`;
|
|
||||||
const srcFileStat = yield ioUtil.lstat(srcFile);
|
|
||||||
if (srcFileStat.isDirectory()) {
|
|
||||||
// Recurse
|
|
||||||
yield cpDirRecursive(srcFile, destFile, currentDepth, force);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
yield copyFile(srcFile, destFile, force);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Change the mode for the newly created directory
|
|
||||||
yield ioUtil.chmod(destDir, (yield ioUtil.stat(sourceDir)).mode);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// Buffered file copy
|
|
||||||
function copyFile(srcFile, destFile, force) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
if ((yield ioUtil.lstat(srcFile)).isSymbolicLink()) {
|
|
||||||
// unlink/re-link it
|
|
||||||
try {
|
|
||||||
yield ioUtil.lstat(destFile);
|
|
||||||
yield ioUtil.unlink(destFile);
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
// Try to override file permission
|
|
||||||
if (e.code === 'EPERM') {
|
|
||||||
yield ioUtil.chmod(destFile, '0666');
|
|
||||||
yield ioUtil.unlink(destFile);
|
|
||||||
}
|
|
||||||
// other errors = it doesn't exist, no work to do
|
|
||||||
}
|
|
||||||
// Copy over symlink
|
|
||||||
const symlinkFull = yield ioUtil.readlink(srcFile);
|
|
||||||
yield ioUtil.symlink(symlinkFull, destFile, ioUtil.IS_WINDOWS ? 'junction' : null);
|
|
||||||
}
|
|
||||||
else if (!(yield ioUtil.exists(destFile)) || force) {
|
|
||||||
yield ioUtil.copyFile(srcFile, destFile);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
//# sourceMappingURL=io.js.map
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 32231:
|
/***/ 32231:
|
||||||
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4241,7 +4241,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.isLinux = exports.isMacOS = exports.isWindows = exports.arch = exports.platform = void 0;
|
exports.isLinux = exports.isMacOS = exports.isWindows = exports.arch = exports.platform = void 0;
|
||||||
exports.getDetails = getDetails;
|
exports.getDetails = getDetails;
|
||||||
const os_1 = __importDefault(__nccwpck_require__(70857));
|
const os_1 = __importDefault(__nccwpck_require__(70857));
|
||||||
const exec = __importStar(__nccwpck_require__(9966));
|
const exec = __importStar(__nccwpck_require__(32231));
|
||||||
const getWindowsInfo = () => __awaiter(void 0, void 0, void 0, function* () {
|
const getWindowsInfo = () => __awaiter(void 0, void 0, void 0, function* () {
|
||||||
const { stdout: version } = yield exec.getExecOutput('powershell -command "(Get-CimInstance -ClassName Win32_OperatingSystem).Version"', undefined, {
|
const { stdout: version } = yield exec.getExecOutput('powershell -command "(Get-CimInstance -ClassName Win32_OperatingSystem).Version"', undefined, {
|
||||||
silent: true
|
silent: true
|
||||||
|
|
@ -4634,1237 +4634,6 @@ function toCommandProperties(annotationProperties) {
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 9966:
|
|
||||||
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
||||||
}) : (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
o[k2] = m[k];
|
|
||||||
}));
|
|
||||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
||||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
||||||
}) : function(o, v) {
|
|
||||||
o["default"] = v;
|
|
||||||
});
|
|
||||||
var __importStar = (this && this.__importStar) || function (mod) {
|
|
||||||
if (mod && mod.__esModule) return mod;
|
|
||||||
var result = {};
|
|
||||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
||||||
__setModuleDefault(result, mod);
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
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());
|
|
||||||
});
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.getExecOutput = exports.exec = void 0;
|
|
||||||
const string_decoder_1 = __nccwpck_require__(13193);
|
|
||||||
const tr = __importStar(__nccwpck_require__(89063));
|
|
||||||
/**
|
|
||||||
* Exec a command.
|
|
||||||
* Output will be streamed to the live console.
|
|
||||||
* Returns promise with return code
|
|
||||||
*
|
|
||||||
* @param commandLine command to execute (can include additional args). Must be correctly escaped.
|
|
||||||
* @param args optional arguments for tool. Escaping is handled by the lib.
|
|
||||||
* @param options optional exec options. See ExecOptions
|
|
||||||
* @returns Promise<number> exit code
|
|
||||||
*/
|
|
||||||
function exec(commandLine, args, options) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
const commandArgs = tr.argStringToArray(commandLine);
|
|
||||||
if (commandArgs.length === 0) {
|
|
||||||
throw new Error(`Parameter 'commandLine' cannot be null or empty.`);
|
|
||||||
}
|
|
||||||
// Path to tool to execute should be first arg
|
|
||||||
const toolPath = commandArgs[0];
|
|
||||||
args = commandArgs.slice(1).concat(args || []);
|
|
||||||
const runner = new tr.ToolRunner(toolPath, args, options);
|
|
||||||
return runner.exec();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.exec = exec;
|
|
||||||
/**
|
|
||||||
* Exec a command and get the output.
|
|
||||||
* Output will be streamed to the live console.
|
|
||||||
* Returns promise with the exit code and collected stdout and stderr
|
|
||||||
*
|
|
||||||
* @param commandLine command to execute (can include additional args). Must be correctly escaped.
|
|
||||||
* @param args optional arguments for tool. Escaping is handled by the lib.
|
|
||||||
* @param options optional exec options. See ExecOptions
|
|
||||||
* @returns Promise<ExecOutput> exit code, stdout, and stderr
|
|
||||||
*/
|
|
||||||
function getExecOutput(commandLine, args, options) {
|
|
||||||
var _a, _b;
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
let stdout = '';
|
|
||||||
let stderr = '';
|
|
||||||
//Using string decoder covers the case where a mult-byte character is split
|
|
||||||
const stdoutDecoder = new string_decoder_1.StringDecoder('utf8');
|
|
||||||
const stderrDecoder = new string_decoder_1.StringDecoder('utf8');
|
|
||||||
const originalStdoutListener = (_a = options === null || options === void 0 ? void 0 : options.listeners) === null || _a === void 0 ? void 0 : _a.stdout;
|
|
||||||
const originalStdErrListener = (_b = options === null || options === void 0 ? void 0 : options.listeners) === null || _b === void 0 ? void 0 : _b.stderr;
|
|
||||||
const stdErrListener = (data) => {
|
|
||||||
stderr += stderrDecoder.write(data);
|
|
||||||
if (originalStdErrListener) {
|
|
||||||
originalStdErrListener(data);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const stdOutListener = (data) => {
|
|
||||||
stdout += stdoutDecoder.write(data);
|
|
||||||
if (originalStdoutListener) {
|
|
||||||
originalStdoutListener(data);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const listeners = Object.assign(Object.assign({}, options === null || options === void 0 ? void 0 : options.listeners), { stdout: stdOutListener, stderr: stdErrListener });
|
|
||||||
const exitCode = yield exec(commandLine, args, Object.assign(Object.assign({}, options), { listeners }));
|
|
||||||
//flush any remaining characters
|
|
||||||
stdout += stdoutDecoder.end();
|
|
||||||
stderr += stderrDecoder.end();
|
|
||||||
return {
|
|
||||||
exitCode,
|
|
||||||
stdout,
|
|
||||||
stderr
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.getExecOutput = getExecOutput;
|
|
||||||
//# sourceMappingURL=exec.js.map
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 89063:
|
|
||||||
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
||||||
}) : (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
o[k2] = m[k];
|
|
||||||
}));
|
|
||||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
||||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
||||||
}) : function(o, v) {
|
|
||||||
o["default"] = v;
|
|
||||||
});
|
|
||||||
var __importStar = (this && this.__importStar) || function (mod) {
|
|
||||||
if (mod && mod.__esModule) return mod;
|
|
||||||
var result = {};
|
|
||||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
||||||
__setModuleDefault(result, mod);
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
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());
|
|
||||||
});
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.argStringToArray = exports.ToolRunner = void 0;
|
|
||||||
const os = __importStar(__nccwpck_require__(70857));
|
|
||||||
const events = __importStar(__nccwpck_require__(24434));
|
|
||||||
const child = __importStar(__nccwpck_require__(35317));
|
|
||||||
const path = __importStar(__nccwpck_require__(16928));
|
|
||||||
const io = __importStar(__nccwpck_require__(42172));
|
|
||||||
const ioUtil = __importStar(__nccwpck_require__(31485));
|
|
||||||
const timers_1 = __nccwpck_require__(53557);
|
|
||||||
/* eslint-disable @typescript-eslint/unbound-method */
|
|
||||||
const IS_WINDOWS = process.platform === 'win32';
|
|
||||||
/*
|
|
||||||
* Class for running command line tools. Handles quoting and arg parsing in a platform agnostic way.
|
|
||||||
*/
|
|
||||||
class ToolRunner extends events.EventEmitter {
|
|
||||||
constructor(toolPath, args, options) {
|
|
||||||
super();
|
|
||||||
if (!toolPath) {
|
|
||||||
throw new Error("Parameter 'toolPath' cannot be null or empty.");
|
|
||||||
}
|
|
||||||
this.toolPath = toolPath;
|
|
||||||
this.args = args || [];
|
|
||||||
this.options = options || {};
|
|
||||||
}
|
|
||||||
_debug(message) {
|
|
||||||
if (this.options.listeners && this.options.listeners.debug) {
|
|
||||||
this.options.listeners.debug(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_getCommandString(options, noPrefix) {
|
|
||||||
const toolPath = this._getSpawnFileName();
|
|
||||||
const args = this._getSpawnArgs(options);
|
|
||||||
let cmd = noPrefix ? '' : '[command]'; // omit prefix when piped to a second tool
|
|
||||||
if (IS_WINDOWS) {
|
|
||||||
// Windows + cmd file
|
|
||||||
if (this._isCmdFile()) {
|
|
||||||
cmd += toolPath;
|
|
||||||
for (const a of args) {
|
|
||||||
cmd += ` ${a}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Windows + verbatim
|
|
||||||
else if (options.windowsVerbatimArguments) {
|
|
||||||
cmd += `"${toolPath}"`;
|
|
||||||
for (const a of args) {
|
|
||||||
cmd += ` ${a}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Windows (regular)
|
|
||||||
else {
|
|
||||||
cmd += this._windowsQuoteCmdArg(toolPath);
|
|
||||||
for (const a of args) {
|
|
||||||
cmd += ` ${this._windowsQuoteCmdArg(a)}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// OSX/Linux - this can likely be improved with some form of quoting.
|
|
||||||
// creating processes on Unix is fundamentally different than Windows.
|
|
||||||
// on Unix, execvp() takes an arg array.
|
|
||||||
cmd += toolPath;
|
|
||||||
for (const a of args) {
|
|
||||||
cmd += ` ${a}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return cmd;
|
|
||||||
}
|
|
||||||
_processLineBuffer(data, strBuffer, onLine) {
|
|
||||||
try {
|
|
||||||
let s = strBuffer + data.toString();
|
|
||||||
let n = s.indexOf(os.EOL);
|
|
||||||
while (n > -1) {
|
|
||||||
const line = s.substring(0, n);
|
|
||||||
onLine(line);
|
|
||||||
// the rest of the string ...
|
|
||||||
s = s.substring(n + os.EOL.length);
|
|
||||||
n = s.indexOf(os.EOL);
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
// streaming lines to console is best effort. Don't fail a build.
|
|
||||||
this._debug(`error processing line. Failed with error ${err}`);
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_getSpawnFileName() {
|
|
||||||
if (IS_WINDOWS) {
|
|
||||||
if (this._isCmdFile()) {
|
|
||||||
return process.env['COMSPEC'] || 'cmd.exe';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this.toolPath;
|
|
||||||
}
|
|
||||||
_getSpawnArgs(options) {
|
|
||||||
if (IS_WINDOWS) {
|
|
||||||
if (this._isCmdFile()) {
|
|
||||||
let argline = `/D /S /C "${this._windowsQuoteCmdArg(this.toolPath)}`;
|
|
||||||
for (const a of this.args) {
|
|
||||||
argline += ' ';
|
|
||||||
argline += options.windowsVerbatimArguments
|
|
||||||
? a
|
|
||||||
: this._windowsQuoteCmdArg(a);
|
|
||||||
}
|
|
||||||
argline += '"';
|
|
||||||
return [argline];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this.args;
|
|
||||||
}
|
|
||||||
_endsWith(str, end) {
|
|
||||||
return str.endsWith(end);
|
|
||||||
}
|
|
||||||
_isCmdFile() {
|
|
||||||
const upperToolPath = this.toolPath.toUpperCase();
|
|
||||||
return (this._endsWith(upperToolPath, '.CMD') ||
|
|
||||||
this._endsWith(upperToolPath, '.BAT'));
|
|
||||||
}
|
|
||||||
_windowsQuoteCmdArg(arg) {
|
|
||||||
// for .exe, apply the normal quoting rules that libuv applies
|
|
||||||
if (!this._isCmdFile()) {
|
|
||||||
return this._uvQuoteCmdArg(arg);
|
|
||||||
}
|
|
||||||
// otherwise apply quoting rules specific to the cmd.exe command line parser.
|
|
||||||
// the libuv rules are generic and are not designed specifically for cmd.exe
|
|
||||||
// command line parser.
|
|
||||||
//
|
|
||||||
// for a detailed description of the cmd.exe command line parser, refer to
|
|
||||||
// http://stackoverflow.com/questions/4094699/how-does-the-windows-command-interpreter-cmd-exe-parse-scripts/7970912#7970912
|
|
||||||
// need quotes for empty arg
|
|
||||||
if (!arg) {
|
|
||||||
return '""';
|
|
||||||
}
|
|
||||||
// determine whether the arg needs to be quoted
|
|
||||||
const cmdSpecialChars = [
|
|
||||||
' ',
|
|
||||||
'\t',
|
|
||||||
'&',
|
|
||||||
'(',
|
|
||||||
')',
|
|
||||||
'[',
|
|
||||||
']',
|
|
||||||
'{',
|
|
||||||
'}',
|
|
||||||
'^',
|
|
||||||
'=',
|
|
||||||
';',
|
|
||||||
'!',
|
|
||||||
"'",
|
|
||||||
'+',
|
|
||||||
',',
|
|
||||||
'`',
|
|
||||||
'~',
|
|
||||||
'|',
|
|
||||||
'<',
|
|
||||||
'>',
|
|
||||||
'"'
|
|
||||||
];
|
|
||||||
let needsQuotes = false;
|
|
||||||
for (const char of arg) {
|
|
||||||
if (cmdSpecialChars.some(x => x === char)) {
|
|
||||||
needsQuotes = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// short-circuit if quotes not needed
|
|
||||||
if (!needsQuotes) {
|
|
||||||
return arg;
|
|
||||||
}
|
|
||||||
// the following quoting rules are very similar to the rules that by libuv applies.
|
|
||||||
//
|
|
||||||
// 1) wrap the string in quotes
|
|
||||||
//
|
|
||||||
// 2) double-up quotes - i.e. " => ""
|
|
||||||
//
|
|
||||||
// this is different from the libuv quoting rules. libuv replaces " with \", which unfortunately
|
|
||||||
// doesn't work well with a cmd.exe command line.
|
|
||||||
//
|
|
||||||
// note, replacing " with "" also works well if the arg is passed to a downstream .NET console app.
|
|
||||||
// for example, the command line:
|
|
||||||
// foo.exe "myarg:""my val"""
|
|
||||||
// is parsed by a .NET console app into an arg array:
|
|
||||||
// [ "myarg:\"my val\"" ]
|
|
||||||
// which is the same end result when applying libuv quoting rules. although the actual
|
|
||||||
// command line from libuv quoting rules would look like:
|
|
||||||
// foo.exe "myarg:\"my val\""
|
|
||||||
//
|
|
||||||
// 3) double-up slashes that precede a quote,
|
|
||||||
// e.g. hello \world => "hello \world"
|
|
||||||
// hello\"world => "hello\\""world"
|
|
||||||
// hello\\"world => "hello\\\\""world"
|
|
||||||
// hello world\ => "hello world\\"
|
|
||||||
//
|
|
||||||
// technically this is not required for a cmd.exe command line, or the batch argument parser.
|
|
||||||
// the reasons for including this as a .cmd quoting rule are:
|
|
||||||
//
|
|
||||||
// a) this is optimized for the scenario where the argument is passed from the .cmd file to an
|
|
||||||
// external program. many programs (e.g. .NET console apps) rely on the slash-doubling rule.
|
|
||||||
//
|
|
||||||
// b) it's what we've been doing previously (by deferring to node default behavior) and we
|
|
||||||
// haven't heard any complaints about that aspect.
|
|
||||||
//
|
|
||||||
// note, a weakness of the quoting rules chosen here, is that % is not escaped. in fact, % cannot be
|
|
||||||
// escaped when used on the command line directly - even though within a .cmd file % can be escaped
|
|
||||||
// by using %%.
|
|
||||||
//
|
|
||||||
// the saving grace is, on the command line, %var% is left as-is if var is not defined. this contrasts
|
|
||||||
// the line parsing rules within a .cmd file, where if var is not defined it is replaced with nothing.
|
|
||||||
//
|
|
||||||
// one option that was explored was replacing % with ^% - i.e. %var% => ^%var^%. this hack would
|
|
||||||
// often work, since it is unlikely that var^ would exist, and the ^ character is removed when the
|
|
||||||
// variable is used. the problem, however, is that ^ is not removed when %* is used to pass the args
|
|
||||||
// to an external program.
|
|
||||||
//
|
|
||||||
// an unexplored potential solution for the % escaping problem, is to create a wrapper .cmd file.
|
|
||||||
// % can be escaped within a .cmd file.
|
|
||||||
let reverse = '"';
|
|
||||||
let quoteHit = true;
|
|
||||||
for (let i = arg.length; i > 0; i--) {
|
|
||||||
// walk the string in reverse
|
|
||||||
reverse += arg[i - 1];
|
|
||||||
if (quoteHit && arg[i - 1] === '\\') {
|
|
||||||
reverse += '\\'; // double the slash
|
|
||||||
}
|
|
||||||
else if (arg[i - 1] === '"') {
|
|
||||||
quoteHit = true;
|
|
||||||
reverse += '"'; // double the quote
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
quoteHit = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
reverse += '"';
|
|
||||||
return reverse
|
|
||||||
.split('')
|
|
||||||
.reverse()
|
|
||||||
.join('');
|
|
||||||
}
|
|
||||||
_uvQuoteCmdArg(arg) {
|
|
||||||
// Tool runner wraps child_process.spawn() and needs to apply the same quoting as
|
|
||||||
// Node in certain cases where the undocumented spawn option windowsVerbatimArguments
|
|
||||||
// is used.
|
|
||||||
//
|
|
||||||
// Since this function is a port of quote_cmd_arg from Node 4.x (technically, lib UV,
|
|
||||||
// see https://github.com/nodejs/node/blob/v4.x/deps/uv/src/win/process.c for details),
|
|
||||||
// pasting copyright notice from Node within this function:
|
|
||||||
//
|
|
||||||
// Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to
|
|
||||||
// deal in the Software without restriction, including without limitation the
|
|
||||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
||||||
// sell copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in
|
|
||||||
// all copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
||||||
// IN THE SOFTWARE.
|
|
||||||
if (!arg) {
|
|
||||||
// Need double quotation for empty argument
|
|
||||||
return '""';
|
|
||||||
}
|
|
||||||
if (!arg.includes(' ') && !arg.includes('\t') && !arg.includes('"')) {
|
|
||||||
// No quotation needed
|
|
||||||
return arg;
|
|
||||||
}
|
|
||||||
if (!arg.includes('"') && !arg.includes('\\')) {
|
|
||||||
// No embedded double quotes or backslashes, so I can just wrap
|
|
||||||
// quote marks around the whole thing.
|
|
||||||
return `"${arg}"`;
|
|
||||||
}
|
|
||||||
// Expected input/output:
|
|
||||||
// input : hello"world
|
|
||||||
// output: "hello\"world"
|
|
||||||
// input : hello""world
|
|
||||||
// output: "hello\"\"world"
|
|
||||||
// input : hello\world
|
|
||||||
// output: hello\world
|
|
||||||
// input : hello\\world
|
|
||||||
// output: hello\\world
|
|
||||||
// input : hello\"world
|
|
||||||
// output: "hello\\\"world"
|
|
||||||
// input : hello\\"world
|
|
||||||
// output: "hello\\\\\"world"
|
|
||||||
// input : hello world\
|
|
||||||
// output: "hello world\\" - note the comment in libuv actually reads "hello world\"
|
|
||||||
// but it appears the comment is wrong, it should be "hello world\\"
|
|
||||||
let reverse = '"';
|
|
||||||
let quoteHit = true;
|
|
||||||
for (let i = arg.length; i > 0; i--) {
|
|
||||||
// walk the string in reverse
|
|
||||||
reverse += arg[i - 1];
|
|
||||||
if (quoteHit && arg[i - 1] === '\\') {
|
|
||||||
reverse += '\\';
|
|
||||||
}
|
|
||||||
else if (arg[i - 1] === '"') {
|
|
||||||
quoteHit = true;
|
|
||||||
reverse += '\\';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
quoteHit = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
reverse += '"';
|
|
||||||
return reverse
|
|
||||||
.split('')
|
|
||||||
.reverse()
|
|
||||||
.join('');
|
|
||||||
}
|
|
||||||
_cloneExecOptions(options) {
|
|
||||||
options = options || {};
|
|
||||||
const result = {
|
|
||||||
cwd: options.cwd || process.cwd(),
|
|
||||||
env: options.env || process.env,
|
|
||||||
silent: options.silent || false,
|
|
||||||
windowsVerbatimArguments: options.windowsVerbatimArguments || false,
|
|
||||||
failOnStdErr: options.failOnStdErr || false,
|
|
||||||
ignoreReturnCode: options.ignoreReturnCode || false,
|
|
||||||
delay: options.delay || 10000
|
|
||||||
};
|
|
||||||
result.outStream = options.outStream || process.stdout;
|
|
||||||
result.errStream = options.errStream || process.stderr;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
_getSpawnOptions(options, toolPath) {
|
|
||||||
options = options || {};
|
|
||||||
const result = {};
|
|
||||||
result.cwd = options.cwd;
|
|
||||||
result.env = options.env;
|
|
||||||
result['windowsVerbatimArguments'] =
|
|
||||||
options.windowsVerbatimArguments || this._isCmdFile();
|
|
||||||
if (options.windowsVerbatimArguments) {
|
|
||||||
result.argv0 = `"${toolPath}"`;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Exec a tool.
|
|
||||||
* Output will be streamed to the live console.
|
|
||||||
* Returns promise with return code
|
|
||||||
*
|
|
||||||
* @param tool path to tool to exec
|
|
||||||
* @param options optional exec options. See ExecOptions
|
|
||||||
* @returns number
|
|
||||||
*/
|
|
||||||
exec() {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
// root the tool path if it is unrooted and contains relative pathing
|
|
||||||
if (!ioUtil.isRooted(this.toolPath) &&
|
|
||||||
(this.toolPath.includes('/') ||
|
|
||||||
(IS_WINDOWS && this.toolPath.includes('\\')))) {
|
|
||||||
// prefer options.cwd if it is specified, however options.cwd may also need to be rooted
|
|
||||||
this.toolPath = path.resolve(process.cwd(), this.options.cwd || process.cwd(), this.toolPath);
|
|
||||||
}
|
|
||||||
// if the tool is only a file name, then resolve it from the PATH
|
|
||||||
// otherwise verify it exists (add extension on Windows if necessary)
|
|
||||||
this.toolPath = yield io.which(this.toolPath, true);
|
|
||||||
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
|
|
||||||
this._debug(`exec tool: ${this.toolPath}`);
|
|
||||||
this._debug('arguments:');
|
|
||||||
for (const arg of this.args) {
|
|
||||||
this._debug(` ${arg}`);
|
|
||||||
}
|
|
||||||
const optionsNonNull = this._cloneExecOptions(this.options);
|
|
||||||
if (!optionsNonNull.silent && optionsNonNull.outStream) {
|
|
||||||
optionsNonNull.outStream.write(this._getCommandString(optionsNonNull) + os.EOL);
|
|
||||||
}
|
|
||||||
const state = new ExecState(optionsNonNull, this.toolPath);
|
|
||||||
state.on('debug', (message) => {
|
|
||||||
this._debug(message);
|
|
||||||
});
|
|
||||||
if (this.options.cwd && !(yield ioUtil.exists(this.options.cwd))) {
|
|
||||||
return reject(new Error(`The cwd: ${this.options.cwd} does not exist!`));
|
|
||||||
}
|
|
||||||
const fileName = this._getSpawnFileName();
|
|
||||||
const cp = child.spawn(fileName, this._getSpawnArgs(optionsNonNull), this._getSpawnOptions(this.options, fileName));
|
|
||||||
let stdbuffer = '';
|
|
||||||
if (cp.stdout) {
|
|
||||||
cp.stdout.on('data', (data) => {
|
|
||||||
if (this.options.listeners && this.options.listeners.stdout) {
|
|
||||||
this.options.listeners.stdout(data);
|
|
||||||
}
|
|
||||||
if (!optionsNonNull.silent && optionsNonNull.outStream) {
|
|
||||||
optionsNonNull.outStream.write(data);
|
|
||||||
}
|
|
||||||
stdbuffer = this._processLineBuffer(data, stdbuffer, (line) => {
|
|
||||||
if (this.options.listeners && this.options.listeners.stdline) {
|
|
||||||
this.options.listeners.stdline(line);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
let errbuffer = '';
|
|
||||||
if (cp.stderr) {
|
|
||||||
cp.stderr.on('data', (data) => {
|
|
||||||
state.processStderr = true;
|
|
||||||
if (this.options.listeners && this.options.listeners.stderr) {
|
|
||||||
this.options.listeners.stderr(data);
|
|
||||||
}
|
|
||||||
if (!optionsNonNull.silent &&
|
|
||||||
optionsNonNull.errStream &&
|
|
||||||
optionsNonNull.outStream) {
|
|
||||||
const s = optionsNonNull.failOnStdErr
|
|
||||||
? optionsNonNull.errStream
|
|
||||||
: optionsNonNull.outStream;
|
|
||||||
s.write(data);
|
|
||||||
}
|
|
||||||
errbuffer = this._processLineBuffer(data, errbuffer, (line) => {
|
|
||||||
if (this.options.listeners && this.options.listeners.errline) {
|
|
||||||
this.options.listeners.errline(line);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
cp.on('error', (err) => {
|
|
||||||
state.processError = err.message;
|
|
||||||
state.processExited = true;
|
|
||||||
state.processClosed = true;
|
|
||||||
state.CheckComplete();
|
|
||||||
});
|
|
||||||
cp.on('exit', (code) => {
|
|
||||||
state.processExitCode = code;
|
|
||||||
state.processExited = true;
|
|
||||||
this._debug(`Exit code ${code} received from tool '${this.toolPath}'`);
|
|
||||||
state.CheckComplete();
|
|
||||||
});
|
|
||||||
cp.on('close', (code) => {
|
|
||||||
state.processExitCode = code;
|
|
||||||
state.processExited = true;
|
|
||||||
state.processClosed = true;
|
|
||||||
this._debug(`STDIO streams have closed for tool '${this.toolPath}'`);
|
|
||||||
state.CheckComplete();
|
|
||||||
});
|
|
||||||
state.on('done', (error, exitCode) => {
|
|
||||||
if (stdbuffer.length > 0) {
|
|
||||||
this.emit('stdline', stdbuffer);
|
|
||||||
}
|
|
||||||
if (errbuffer.length > 0) {
|
|
||||||
this.emit('errline', errbuffer);
|
|
||||||
}
|
|
||||||
cp.removeAllListeners();
|
|
||||||
if (error) {
|
|
||||||
reject(error);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
resolve(exitCode);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (this.options.input) {
|
|
||||||
if (!cp.stdin) {
|
|
||||||
throw new Error('child process missing stdin');
|
|
||||||
}
|
|
||||||
cp.stdin.end(this.options.input);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.ToolRunner = ToolRunner;
|
|
||||||
/**
|
|
||||||
* Convert an arg string to an array of args. Handles escaping
|
|
||||||
*
|
|
||||||
* @param argString string of arguments
|
|
||||||
* @returns string[] array of arguments
|
|
||||||
*/
|
|
||||||
function argStringToArray(argString) {
|
|
||||||
const args = [];
|
|
||||||
let inQuotes = false;
|
|
||||||
let escaped = false;
|
|
||||||
let arg = '';
|
|
||||||
function append(c) {
|
|
||||||
// we only escape double quotes.
|
|
||||||
if (escaped && c !== '"') {
|
|
||||||
arg += '\\';
|
|
||||||
}
|
|
||||||
arg += c;
|
|
||||||
escaped = false;
|
|
||||||
}
|
|
||||||
for (let i = 0; i < argString.length; i++) {
|
|
||||||
const c = argString.charAt(i);
|
|
||||||
if (c === '"') {
|
|
||||||
if (!escaped) {
|
|
||||||
inQuotes = !inQuotes;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
append(c);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (c === '\\' && escaped) {
|
|
||||||
append(c);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (c === '\\' && inQuotes) {
|
|
||||||
escaped = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (c === ' ' && !inQuotes) {
|
|
||||||
if (arg.length > 0) {
|
|
||||||
args.push(arg);
|
|
||||||
arg = '';
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
append(c);
|
|
||||||
}
|
|
||||||
if (arg.length > 0) {
|
|
||||||
args.push(arg.trim());
|
|
||||||
}
|
|
||||||
return args;
|
|
||||||
}
|
|
||||||
exports.argStringToArray = argStringToArray;
|
|
||||||
class ExecState extends events.EventEmitter {
|
|
||||||
constructor(options, toolPath) {
|
|
||||||
super();
|
|
||||||
this.processClosed = false; // tracks whether the process has exited and stdio is closed
|
|
||||||
this.processError = '';
|
|
||||||
this.processExitCode = 0;
|
|
||||||
this.processExited = false; // tracks whether the process has exited
|
|
||||||
this.processStderr = false; // tracks whether stderr was written to
|
|
||||||
this.delay = 10000; // 10 seconds
|
|
||||||
this.done = false;
|
|
||||||
this.timeout = null;
|
|
||||||
if (!toolPath) {
|
|
||||||
throw new Error('toolPath must not be empty');
|
|
||||||
}
|
|
||||||
this.options = options;
|
|
||||||
this.toolPath = toolPath;
|
|
||||||
if (options.delay) {
|
|
||||||
this.delay = options.delay;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CheckComplete() {
|
|
||||||
if (this.done) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (this.processClosed) {
|
|
||||||
this._setResult();
|
|
||||||
}
|
|
||||||
else if (this.processExited) {
|
|
||||||
this.timeout = timers_1.setTimeout(ExecState.HandleTimeout, this.delay, this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_debug(message) {
|
|
||||||
this.emit('debug', message);
|
|
||||||
}
|
|
||||||
_setResult() {
|
|
||||||
// determine whether there is an error
|
|
||||||
let error;
|
|
||||||
if (this.processExited) {
|
|
||||||
if (this.processError) {
|
|
||||||
error = new Error(`There was an error when attempting to execute the process '${this.toolPath}'. This may indicate the process failed to start. Error: ${this.processError}`);
|
|
||||||
}
|
|
||||||
else if (this.processExitCode !== 0 && !this.options.ignoreReturnCode) {
|
|
||||||
error = new Error(`The process '${this.toolPath}' failed with exit code ${this.processExitCode}`);
|
|
||||||
}
|
|
||||||
else if (this.processStderr && this.options.failOnStdErr) {
|
|
||||||
error = new Error(`The process '${this.toolPath}' failed because one or more lines were written to the STDERR stream`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// clear the timeout
|
|
||||||
if (this.timeout) {
|
|
||||||
clearTimeout(this.timeout);
|
|
||||||
this.timeout = null;
|
|
||||||
}
|
|
||||||
this.done = true;
|
|
||||||
this.emit('done', error, this.processExitCode);
|
|
||||||
}
|
|
||||||
static HandleTimeout(state) {
|
|
||||||
if (state.done) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!state.processClosed && state.processExited) {
|
|
||||||
const message = `The STDIO streams did not close within ${state.delay /
|
|
||||||
1000} seconds of the exit event from process '${state.toolPath}'. This may indicate a child process inherited the STDIO streams and has not yet exited.`;
|
|
||||||
state._debug(message);
|
|
||||||
}
|
|
||||||
state._setResult();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//# sourceMappingURL=toolrunner.js.map
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 31485:
|
|
||||||
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
||||||
}) : (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
o[k2] = m[k];
|
|
||||||
}));
|
|
||||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
||||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
||||||
}) : function(o, v) {
|
|
||||||
o["default"] = v;
|
|
||||||
});
|
|
||||||
var __importStar = (this && this.__importStar) || function (mod) {
|
|
||||||
if (mod && mod.__esModule) return mod;
|
|
||||||
var result = {};
|
|
||||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
||||||
__setModuleDefault(result, mod);
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
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 _a;
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.getCmdPath = exports.tryGetExecutablePath = exports.isRooted = exports.isDirectory = exports.exists = exports.READONLY = exports.UV_FS_O_EXLOCK = exports.IS_WINDOWS = exports.unlink = exports.symlink = exports.stat = exports.rmdir = exports.rm = exports.rename = exports.readlink = exports.readdir = exports.open = exports.mkdir = exports.lstat = exports.copyFile = exports.chmod = void 0;
|
|
||||||
const fs = __importStar(__nccwpck_require__(79896));
|
|
||||||
const path = __importStar(__nccwpck_require__(16928));
|
|
||||||
_a = fs.promises
|
|
||||||
// export const {open} = 'fs'
|
|
||||||
, exports.chmod = _a.chmod, exports.copyFile = _a.copyFile, exports.lstat = _a.lstat, exports.mkdir = _a.mkdir, exports.open = _a.open, exports.readdir = _a.readdir, exports.readlink = _a.readlink, exports.rename = _a.rename, exports.rm = _a.rm, exports.rmdir = _a.rmdir, exports.stat = _a.stat, exports.symlink = _a.symlink, exports.unlink = _a.unlink;
|
|
||||||
// export const {open} = 'fs'
|
|
||||||
exports.IS_WINDOWS = process.platform === 'win32';
|
|
||||||
// See https://github.com/nodejs/node/blob/d0153aee367422d0858105abec186da4dff0a0c5/deps/uv/include/uv/win.h#L691
|
|
||||||
exports.UV_FS_O_EXLOCK = 0x10000000;
|
|
||||||
exports.READONLY = fs.constants.O_RDONLY;
|
|
||||||
function exists(fsPath) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
try {
|
|
||||||
yield exports.stat(fsPath);
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
if (err.code === 'ENOENT') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.exists = exists;
|
|
||||||
function isDirectory(fsPath, useStat = false) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
const stats = useStat ? yield exports.stat(fsPath) : yield exports.lstat(fsPath);
|
|
||||||
return stats.isDirectory();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.isDirectory = isDirectory;
|
|
||||||
/**
|
|
||||||
* On OSX/Linux, true if path starts with '/'. On Windows, true for paths like:
|
|
||||||
* \, \hello, \\hello\share, C:, and C:\hello (and corresponding alternate separator cases).
|
|
||||||
*/
|
|
||||||
function isRooted(p) {
|
|
||||||
p = normalizeSeparators(p);
|
|
||||||
if (!p) {
|
|
||||||
throw new Error('isRooted() parameter "p" cannot be empty');
|
|
||||||
}
|
|
||||||
if (exports.IS_WINDOWS) {
|
|
||||||
return (p.startsWith('\\') || /^[A-Z]:/i.test(p) // e.g. \ or \hello or \\hello
|
|
||||||
); // e.g. C: or C:\hello
|
|
||||||
}
|
|
||||||
return p.startsWith('/');
|
|
||||||
}
|
|
||||||
exports.isRooted = isRooted;
|
|
||||||
/**
|
|
||||||
* Best effort attempt to determine whether a file exists and is executable.
|
|
||||||
* @param filePath file path to check
|
|
||||||
* @param extensions additional file extensions to try
|
|
||||||
* @return if file exists and is executable, returns the file path. otherwise empty string.
|
|
||||||
*/
|
|
||||||
function tryGetExecutablePath(filePath, extensions) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
let stats = undefined;
|
|
||||||
try {
|
|
||||||
// test file exists
|
|
||||||
stats = yield exports.stat(filePath);
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
if (err.code !== 'ENOENT') {
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.log(`Unexpected error attempting to determine if executable file exists '${filePath}': ${err}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (stats && stats.isFile()) {
|
|
||||||
if (exports.IS_WINDOWS) {
|
|
||||||
// on Windows, test for valid extension
|
|
||||||
const upperExt = path.extname(filePath).toUpperCase();
|
|
||||||
if (extensions.some(validExt => validExt.toUpperCase() === upperExt)) {
|
|
||||||
return filePath;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (isUnixExecutable(stats)) {
|
|
||||||
return filePath;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// try each extension
|
|
||||||
const originalFilePath = filePath;
|
|
||||||
for (const extension of extensions) {
|
|
||||||
filePath = originalFilePath + extension;
|
|
||||||
stats = undefined;
|
|
||||||
try {
|
|
||||||
stats = yield exports.stat(filePath);
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
if (err.code !== 'ENOENT') {
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.log(`Unexpected error attempting to determine if executable file exists '${filePath}': ${err}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (stats && stats.isFile()) {
|
|
||||||
if (exports.IS_WINDOWS) {
|
|
||||||
// preserve the case of the actual file (since an extension was appended)
|
|
||||||
try {
|
|
||||||
const directory = path.dirname(filePath);
|
|
||||||
const upperName = path.basename(filePath).toUpperCase();
|
|
||||||
for (const actualName of yield exports.readdir(directory)) {
|
|
||||||
if (upperName === actualName.toUpperCase()) {
|
|
||||||
filePath = path.join(directory, actualName);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.log(`Unexpected error attempting to determine the actual case of the file '${filePath}': ${err}`);
|
|
||||||
}
|
|
||||||
return filePath;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (isUnixExecutable(stats)) {
|
|
||||||
return filePath;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.tryGetExecutablePath = tryGetExecutablePath;
|
|
||||||
function normalizeSeparators(p) {
|
|
||||||
p = p || '';
|
|
||||||
if (exports.IS_WINDOWS) {
|
|
||||||
// convert slashes on Windows
|
|
||||||
p = p.replace(/\//g, '\\');
|
|
||||||
// remove redundant slashes
|
|
||||||
return p.replace(/\\\\+/g, '\\');
|
|
||||||
}
|
|
||||||
// remove redundant slashes
|
|
||||||
return p.replace(/\/\/+/g, '/');
|
|
||||||
}
|
|
||||||
// on Mac/Linux, test the execute bit
|
|
||||||
// R W X R W X R W X
|
|
||||||
// 256 128 64 32 16 8 4 2 1
|
|
||||||
function isUnixExecutable(stats) {
|
|
||||||
return ((stats.mode & 1) > 0 ||
|
|
||||||
((stats.mode & 8) > 0 && stats.gid === process.getgid()) ||
|
|
||||||
((stats.mode & 64) > 0 && stats.uid === process.getuid()));
|
|
||||||
}
|
|
||||||
// Get the path of cmd.exe in windows
|
|
||||||
function getCmdPath() {
|
|
||||||
var _a;
|
|
||||||
return (_a = process.env['COMSPEC']) !== null && _a !== void 0 ? _a : `cmd.exe`;
|
|
||||||
}
|
|
||||||
exports.getCmdPath = getCmdPath;
|
|
||||||
//# sourceMappingURL=io-util.js.map
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 42172:
|
|
||||||
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
||||||
}) : (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
o[k2] = m[k];
|
|
||||||
}));
|
|
||||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
||||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
||||||
}) : function(o, v) {
|
|
||||||
o["default"] = v;
|
|
||||||
});
|
|
||||||
var __importStar = (this && this.__importStar) || function (mod) {
|
|
||||||
if (mod && mod.__esModule) return mod;
|
|
||||||
var result = {};
|
|
||||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
||||||
__setModuleDefault(result, mod);
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
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());
|
|
||||||
});
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.findInPath = exports.which = exports.mkdirP = exports.rmRF = exports.mv = exports.cp = void 0;
|
|
||||||
const assert_1 = __nccwpck_require__(42613);
|
|
||||||
const path = __importStar(__nccwpck_require__(16928));
|
|
||||||
const ioUtil = __importStar(__nccwpck_require__(31485));
|
|
||||||
/**
|
|
||||||
* Copies a file or folder.
|
|
||||||
* Based off of shelljs - https://github.com/shelljs/shelljs/blob/9237f66c52e5daa40458f94f9565e18e8132f5a6/src/cp.js
|
|
||||||
*
|
|
||||||
* @param source source path
|
|
||||||
* @param dest destination path
|
|
||||||
* @param options optional. See CopyOptions.
|
|
||||||
*/
|
|
||||||
function cp(source, dest, options = {}) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
const { force, recursive, copySourceDirectory } = readCopyOptions(options);
|
|
||||||
const destStat = (yield ioUtil.exists(dest)) ? yield ioUtil.stat(dest) : null;
|
|
||||||
// Dest is an existing file, but not forcing
|
|
||||||
if (destStat && destStat.isFile() && !force) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// If dest is an existing directory, should copy inside.
|
|
||||||
const newDest = destStat && destStat.isDirectory() && copySourceDirectory
|
|
||||||
? path.join(dest, path.basename(source))
|
|
||||||
: dest;
|
|
||||||
if (!(yield ioUtil.exists(source))) {
|
|
||||||
throw new Error(`no such file or directory: ${source}`);
|
|
||||||
}
|
|
||||||
const sourceStat = yield ioUtil.stat(source);
|
|
||||||
if (sourceStat.isDirectory()) {
|
|
||||||
if (!recursive) {
|
|
||||||
throw new Error(`Failed to copy. ${source} is a directory, but tried to copy without recursive flag.`);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
yield cpDirRecursive(source, newDest, 0, force);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (path.relative(source, newDest) === '') {
|
|
||||||
// a file cannot be copied to itself
|
|
||||||
throw new Error(`'${newDest}' and '${source}' are the same file`);
|
|
||||||
}
|
|
||||||
yield copyFile(source, newDest, force);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.cp = cp;
|
|
||||||
/**
|
|
||||||
* Moves a path.
|
|
||||||
*
|
|
||||||
* @param source source path
|
|
||||||
* @param dest destination path
|
|
||||||
* @param options optional. See MoveOptions.
|
|
||||||
*/
|
|
||||||
function mv(source, dest, options = {}) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
if (yield ioUtil.exists(dest)) {
|
|
||||||
let destExists = true;
|
|
||||||
if (yield ioUtil.isDirectory(dest)) {
|
|
||||||
// If dest is directory copy src into dest
|
|
||||||
dest = path.join(dest, path.basename(source));
|
|
||||||
destExists = yield ioUtil.exists(dest);
|
|
||||||
}
|
|
||||||
if (destExists) {
|
|
||||||
if (options.force == null || options.force) {
|
|
||||||
yield rmRF(dest);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new Error('Destination already exists');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
yield mkdirP(path.dirname(dest));
|
|
||||||
yield ioUtil.rename(source, dest);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.mv = mv;
|
|
||||||
/**
|
|
||||||
* Remove a path recursively with force
|
|
||||||
*
|
|
||||||
* @param inputPath path to remove
|
|
||||||
*/
|
|
||||||
function rmRF(inputPath) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
if (ioUtil.IS_WINDOWS) {
|
|
||||||
// Check for invalid characters
|
|
||||||
// https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file
|
|
||||||
if (/[*"<>|]/.test(inputPath)) {
|
|
||||||
throw new Error('File path must not contain `*`, `"`, `<`, `>` or `|` on Windows');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
// note if path does not exist, error is silent
|
|
||||||
yield ioUtil.rm(inputPath, {
|
|
||||||
force: true,
|
|
||||||
maxRetries: 3,
|
|
||||||
recursive: true,
|
|
||||||
retryDelay: 300
|
|
||||||
});
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
throw new Error(`File was unable to be removed ${err}`);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.rmRF = rmRF;
|
|
||||||
/**
|
|
||||||
* Make a directory. Creates the full path with folders in between
|
|
||||||
* Will throw if it fails
|
|
||||||
*
|
|
||||||
* @param fsPath path to create
|
|
||||||
* @returns Promise<void>
|
|
||||||
*/
|
|
||||||
function mkdirP(fsPath) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
assert_1.ok(fsPath, 'a path argument must be provided');
|
|
||||||
yield ioUtil.mkdir(fsPath, { recursive: true });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.mkdirP = mkdirP;
|
|
||||||
/**
|
|
||||||
* Returns path of a tool had the tool actually been invoked. Resolves via paths.
|
|
||||||
* If you check and the tool does not exist, it will throw.
|
|
||||||
*
|
|
||||||
* @param tool name of the tool
|
|
||||||
* @param check whether to check if tool exists
|
|
||||||
* @returns Promise<string> path to tool
|
|
||||||
*/
|
|
||||||
function which(tool, check) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
if (!tool) {
|
|
||||||
throw new Error("parameter 'tool' is required");
|
|
||||||
}
|
|
||||||
// recursive when check=true
|
|
||||||
if (check) {
|
|
||||||
const result = yield which(tool, false);
|
|
||||||
if (!result) {
|
|
||||||
if (ioUtil.IS_WINDOWS) {
|
|
||||||
throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also verify the file has a valid extension for an executable file.`);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also check the file mode to verify the file is executable.`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
const matches = yield findInPath(tool);
|
|
||||||
if (matches && matches.length > 0) {
|
|
||||||
return matches[0];
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.which = which;
|
|
||||||
/**
|
|
||||||
* Returns a list of all occurrences of the given tool on the system path.
|
|
||||||
*
|
|
||||||
* @returns Promise<string[]> the paths of the tool
|
|
||||||
*/
|
|
||||||
function findInPath(tool) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
if (!tool) {
|
|
||||||
throw new Error("parameter 'tool' is required");
|
|
||||||
}
|
|
||||||
// build the list of extensions to try
|
|
||||||
const extensions = [];
|
|
||||||
if (ioUtil.IS_WINDOWS && process.env['PATHEXT']) {
|
|
||||||
for (const extension of process.env['PATHEXT'].split(path.delimiter)) {
|
|
||||||
if (extension) {
|
|
||||||
extensions.push(extension);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// if it's rooted, return it if exists. otherwise return empty.
|
|
||||||
if (ioUtil.isRooted(tool)) {
|
|
||||||
const filePath = yield ioUtil.tryGetExecutablePath(tool, extensions);
|
|
||||||
if (filePath) {
|
|
||||||
return [filePath];
|
|
||||||
}
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
// if any path separators, return empty
|
|
||||||
if (tool.includes(path.sep)) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
// build the list of directories
|
|
||||||
//
|
|
||||||
// Note, technically "where" checks the current directory on Windows. From a toolkit perspective,
|
|
||||||
// it feels like we should not do this. Checking the current directory seems like more of a use
|
|
||||||
// case of a shell, and the which() function exposed by the toolkit should strive for consistency
|
|
||||||
// across platforms.
|
|
||||||
const directories = [];
|
|
||||||
if (process.env.PATH) {
|
|
||||||
for (const p of process.env.PATH.split(path.delimiter)) {
|
|
||||||
if (p) {
|
|
||||||
directories.push(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// find all matches
|
|
||||||
const matches = [];
|
|
||||||
for (const directory of directories) {
|
|
||||||
const filePath = yield ioUtil.tryGetExecutablePath(path.join(directory, tool), extensions);
|
|
||||||
if (filePath) {
|
|
||||||
matches.push(filePath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return matches;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.findInPath = findInPath;
|
|
||||||
function readCopyOptions(options) {
|
|
||||||
const force = options.force == null ? true : options.force;
|
|
||||||
const recursive = Boolean(options.recursive);
|
|
||||||
const copySourceDirectory = options.copySourceDirectory == null
|
|
||||||
? true
|
|
||||||
: Boolean(options.copySourceDirectory);
|
|
||||||
return { force, recursive, copySourceDirectory };
|
|
||||||
}
|
|
||||||
function cpDirRecursive(sourceDir, destDir, currentDepth, force) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
// Ensure there is not a run away recursive copy
|
|
||||||
if (currentDepth >= 255)
|
|
||||||
return;
|
|
||||||
currentDepth++;
|
|
||||||
yield mkdirP(destDir);
|
|
||||||
const files = yield ioUtil.readdir(sourceDir);
|
|
||||||
for (const fileName of files) {
|
|
||||||
const srcFile = `${sourceDir}/${fileName}`;
|
|
||||||
const destFile = `${destDir}/${fileName}`;
|
|
||||||
const srcFileStat = yield ioUtil.lstat(srcFile);
|
|
||||||
if (srcFileStat.isDirectory()) {
|
|
||||||
// Recurse
|
|
||||||
yield cpDirRecursive(srcFile, destFile, currentDepth, force);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
yield copyFile(srcFile, destFile, force);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Change the mode for the newly created directory
|
|
||||||
yield ioUtil.chmod(destDir, (yield ioUtil.stat(sourceDir)).mode);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// Buffered file copy
|
|
||||||
function copyFile(srcFile, destFile, force) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
if ((yield ioUtil.lstat(srcFile)).isSymbolicLink()) {
|
|
||||||
// unlink/re-link it
|
|
||||||
try {
|
|
||||||
yield ioUtil.lstat(destFile);
|
|
||||||
yield ioUtil.unlink(destFile);
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
// Try to override file permission
|
|
||||||
if (e.code === 'EPERM') {
|
|
||||||
yield ioUtil.chmod(destFile, '0666');
|
|
||||||
yield ioUtil.unlink(destFile);
|
|
||||||
}
|
|
||||||
// other errors = it doesn't exist, no work to do
|
|
||||||
}
|
|
||||||
// Copy over symlink
|
|
||||||
const symlinkFull = yield ioUtil.readlink(srcFile);
|
|
||||||
yield ioUtil.symlink(symlinkFull, destFile, ioUtil.IS_WINDOWS ? 'junction' : null);
|
|
||||||
}
|
|
||||||
else if (!(yield ioUtil.exists(destFile)) || force) {
|
|
||||||
yield ioUtil.copyFile(srcFile, destFile);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
//# sourceMappingURL=io.js.map
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 32231:
|
/***/ 32231:
|
||||||
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4241,7 +4241,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.isLinux = exports.isMacOS = exports.isWindows = exports.arch = exports.platform = void 0;
|
exports.isLinux = exports.isMacOS = exports.isWindows = exports.arch = exports.platform = void 0;
|
||||||
exports.getDetails = getDetails;
|
exports.getDetails = getDetails;
|
||||||
const os_1 = __importDefault(__nccwpck_require__(70857));
|
const os_1 = __importDefault(__nccwpck_require__(70857));
|
||||||
const exec = __importStar(__nccwpck_require__(9966));
|
const exec = __importStar(__nccwpck_require__(32231));
|
||||||
const getWindowsInfo = () => __awaiter(void 0, void 0, void 0, function* () {
|
const getWindowsInfo = () => __awaiter(void 0, void 0, void 0, function* () {
|
||||||
const { stdout: version } = yield exec.getExecOutput('powershell -command "(Get-CimInstance -ClassName Win32_OperatingSystem).Version"', undefined, {
|
const { stdout: version } = yield exec.getExecOutput('powershell -command "(Get-CimInstance -ClassName Win32_OperatingSystem).Version"', undefined, {
|
||||||
silent: true
|
silent: true
|
||||||
|
|
@ -4634,1237 +4634,6 @@ function toCommandProperties(annotationProperties) {
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 9966:
|
|
||||||
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
||||||
}) : (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
o[k2] = m[k];
|
|
||||||
}));
|
|
||||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
||||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
||||||
}) : function(o, v) {
|
|
||||||
o["default"] = v;
|
|
||||||
});
|
|
||||||
var __importStar = (this && this.__importStar) || function (mod) {
|
|
||||||
if (mod && mod.__esModule) return mod;
|
|
||||||
var result = {};
|
|
||||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
||||||
__setModuleDefault(result, mod);
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
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());
|
|
||||||
});
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.getExecOutput = exports.exec = void 0;
|
|
||||||
const string_decoder_1 = __nccwpck_require__(13193);
|
|
||||||
const tr = __importStar(__nccwpck_require__(89063));
|
|
||||||
/**
|
|
||||||
* Exec a command.
|
|
||||||
* Output will be streamed to the live console.
|
|
||||||
* Returns promise with return code
|
|
||||||
*
|
|
||||||
* @param commandLine command to execute (can include additional args). Must be correctly escaped.
|
|
||||||
* @param args optional arguments for tool. Escaping is handled by the lib.
|
|
||||||
* @param options optional exec options. See ExecOptions
|
|
||||||
* @returns Promise<number> exit code
|
|
||||||
*/
|
|
||||||
function exec(commandLine, args, options) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
const commandArgs = tr.argStringToArray(commandLine);
|
|
||||||
if (commandArgs.length === 0) {
|
|
||||||
throw new Error(`Parameter 'commandLine' cannot be null or empty.`);
|
|
||||||
}
|
|
||||||
// Path to tool to execute should be first arg
|
|
||||||
const toolPath = commandArgs[0];
|
|
||||||
args = commandArgs.slice(1).concat(args || []);
|
|
||||||
const runner = new tr.ToolRunner(toolPath, args, options);
|
|
||||||
return runner.exec();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.exec = exec;
|
|
||||||
/**
|
|
||||||
* Exec a command and get the output.
|
|
||||||
* Output will be streamed to the live console.
|
|
||||||
* Returns promise with the exit code and collected stdout and stderr
|
|
||||||
*
|
|
||||||
* @param commandLine command to execute (can include additional args). Must be correctly escaped.
|
|
||||||
* @param args optional arguments for tool. Escaping is handled by the lib.
|
|
||||||
* @param options optional exec options. See ExecOptions
|
|
||||||
* @returns Promise<ExecOutput> exit code, stdout, and stderr
|
|
||||||
*/
|
|
||||||
function getExecOutput(commandLine, args, options) {
|
|
||||||
var _a, _b;
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
let stdout = '';
|
|
||||||
let stderr = '';
|
|
||||||
//Using string decoder covers the case where a mult-byte character is split
|
|
||||||
const stdoutDecoder = new string_decoder_1.StringDecoder('utf8');
|
|
||||||
const stderrDecoder = new string_decoder_1.StringDecoder('utf8');
|
|
||||||
const originalStdoutListener = (_a = options === null || options === void 0 ? void 0 : options.listeners) === null || _a === void 0 ? void 0 : _a.stdout;
|
|
||||||
const originalStdErrListener = (_b = options === null || options === void 0 ? void 0 : options.listeners) === null || _b === void 0 ? void 0 : _b.stderr;
|
|
||||||
const stdErrListener = (data) => {
|
|
||||||
stderr += stderrDecoder.write(data);
|
|
||||||
if (originalStdErrListener) {
|
|
||||||
originalStdErrListener(data);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const stdOutListener = (data) => {
|
|
||||||
stdout += stdoutDecoder.write(data);
|
|
||||||
if (originalStdoutListener) {
|
|
||||||
originalStdoutListener(data);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const listeners = Object.assign(Object.assign({}, options === null || options === void 0 ? void 0 : options.listeners), { stdout: stdOutListener, stderr: stdErrListener });
|
|
||||||
const exitCode = yield exec(commandLine, args, Object.assign(Object.assign({}, options), { listeners }));
|
|
||||||
//flush any remaining characters
|
|
||||||
stdout += stdoutDecoder.end();
|
|
||||||
stderr += stderrDecoder.end();
|
|
||||||
return {
|
|
||||||
exitCode,
|
|
||||||
stdout,
|
|
||||||
stderr
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.getExecOutput = getExecOutput;
|
|
||||||
//# sourceMappingURL=exec.js.map
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 89063:
|
|
||||||
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
||||||
}) : (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
o[k2] = m[k];
|
|
||||||
}));
|
|
||||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
||||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
||||||
}) : function(o, v) {
|
|
||||||
o["default"] = v;
|
|
||||||
});
|
|
||||||
var __importStar = (this && this.__importStar) || function (mod) {
|
|
||||||
if (mod && mod.__esModule) return mod;
|
|
||||||
var result = {};
|
|
||||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
||||||
__setModuleDefault(result, mod);
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
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());
|
|
||||||
});
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.argStringToArray = exports.ToolRunner = void 0;
|
|
||||||
const os = __importStar(__nccwpck_require__(70857));
|
|
||||||
const events = __importStar(__nccwpck_require__(24434));
|
|
||||||
const child = __importStar(__nccwpck_require__(35317));
|
|
||||||
const path = __importStar(__nccwpck_require__(16928));
|
|
||||||
const io = __importStar(__nccwpck_require__(42172));
|
|
||||||
const ioUtil = __importStar(__nccwpck_require__(31485));
|
|
||||||
const timers_1 = __nccwpck_require__(53557);
|
|
||||||
/* eslint-disable @typescript-eslint/unbound-method */
|
|
||||||
const IS_WINDOWS = process.platform === 'win32';
|
|
||||||
/*
|
|
||||||
* Class for running command line tools. Handles quoting and arg parsing in a platform agnostic way.
|
|
||||||
*/
|
|
||||||
class ToolRunner extends events.EventEmitter {
|
|
||||||
constructor(toolPath, args, options) {
|
|
||||||
super();
|
|
||||||
if (!toolPath) {
|
|
||||||
throw new Error("Parameter 'toolPath' cannot be null or empty.");
|
|
||||||
}
|
|
||||||
this.toolPath = toolPath;
|
|
||||||
this.args = args || [];
|
|
||||||
this.options = options || {};
|
|
||||||
}
|
|
||||||
_debug(message) {
|
|
||||||
if (this.options.listeners && this.options.listeners.debug) {
|
|
||||||
this.options.listeners.debug(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_getCommandString(options, noPrefix) {
|
|
||||||
const toolPath = this._getSpawnFileName();
|
|
||||||
const args = this._getSpawnArgs(options);
|
|
||||||
let cmd = noPrefix ? '' : '[command]'; // omit prefix when piped to a second tool
|
|
||||||
if (IS_WINDOWS) {
|
|
||||||
// Windows + cmd file
|
|
||||||
if (this._isCmdFile()) {
|
|
||||||
cmd += toolPath;
|
|
||||||
for (const a of args) {
|
|
||||||
cmd += ` ${a}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Windows + verbatim
|
|
||||||
else if (options.windowsVerbatimArguments) {
|
|
||||||
cmd += `"${toolPath}"`;
|
|
||||||
for (const a of args) {
|
|
||||||
cmd += ` ${a}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Windows (regular)
|
|
||||||
else {
|
|
||||||
cmd += this._windowsQuoteCmdArg(toolPath);
|
|
||||||
for (const a of args) {
|
|
||||||
cmd += ` ${this._windowsQuoteCmdArg(a)}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// OSX/Linux - this can likely be improved with some form of quoting.
|
|
||||||
// creating processes on Unix is fundamentally different than Windows.
|
|
||||||
// on Unix, execvp() takes an arg array.
|
|
||||||
cmd += toolPath;
|
|
||||||
for (const a of args) {
|
|
||||||
cmd += ` ${a}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return cmd;
|
|
||||||
}
|
|
||||||
_processLineBuffer(data, strBuffer, onLine) {
|
|
||||||
try {
|
|
||||||
let s = strBuffer + data.toString();
|
|
||||||
let n = s.indexOf(os.EOL);
|
|
||||||
while (n > -1) {
|
|
||||||
const line = s.substring(0, n);
|
|
||||||
onLine(line);
|
|
||||||
// the rest of the string ...
|
|
||||||
s = s.substring(n + os.EOL.length);
|
|
||||||
n = s.indexOf(os.EOL);
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
// streaming lines to console is best effort. Don't fail a build.
|
|
||||||
this._debug(`error processing line. Failed with error ${err}`);
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_getSpawnFileName() {
|
|
||||||
if (IS_WINDOWS) {
|
|
||||||
if (this._isCmdFile()) {
|
|
||||||
return process.env['COMSPEC'] || 'cmd.exe';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this.toolPath;
|
|
||||||
}
|
|
||||||
_getSpawnArgs(options) {
|
|
||||||
if (IS_WINDOWS) {
|
|
||||||
if (this._isCmdFile()) {
|
|
||||||
let argline = `/D /S /C "${this._windowsQuoteCmdArg(this.toolPath)}`;
|
|
||||||
for (const a of this.args) {
|
|
||||||
argline += ' ';
|
|
||||||
argline += options.windowsVerbatimArguments
|
|
||||||
? a
|
|
||||||
: this._windowsQuoteCmdArg(a);
|
|
||||||
}
|
|
||||||
argline += '"';
|
|
||||||
return [argline];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this.args;
|
|
||||||
}
|
|
||||||
_endsWith(str, end) {
|
|
||||||
return str.endsWith(end);
|
|
||||||
}
|
|
||||||
_isCmdFile() {
|
|
||||||
const upperToolPath = this.toolPath.toUpperCase();
|
|
||||||
return (this._endsWith(upperToolPath, '.CMD') ||
|
|
||||||
this._endsWith(upperToolPath, '.BAT'));
|
|
||||||
}
|
|
||||||
_windowsQuoteCmdArg(arg) {
|
|
||||||
// for .exe, apply the normal quoting rules that libuv applies
|
|
||||||
if (!this._isCmdFile()) {
|
|
||||||
return this._uvQuoteCmdArg(arg);
|
|
||||||
}
|
|
||||||
// otherwise apply quoting rules specific to the cmd.exe command line parser.
|
|
||||||
// the libuv rules are generic and are not designed specifically for cmd.exe
|
|
||||||
// command line parser.
|
|
||||||
//
|
|
||||||
// for a detailed description of the cmd.exe command line parser, refer to
|
|
||||||
// http://stackoverflow.com/questions/4094699/how-does-the-windows-command-interpreter-cmd-exe-parse-scripts/7970912#7970912
|
|
||||||
// need quotes for empty arg
|
|
||||||
if (!arg) {
|
|
||||||
return '""';
|
|
||||||
}
|
|
||||||
// determine whether the arg needs to be quoted
|
|
||||||
const cmdSpecialChars = [
|
|
||||||
' ',
|
|
||||||
'\t',
|
|
||||||
'&',
|
|
||||||
'(',
|
|
||||||
')',
|
|
||||||
'[',
|
|
||||||
']',
|
|
||||||
'{',
|
|
||||||
'}',
|
|
||||||
'^',
|
|
||||||
'=',
|
|
||||||
';',
|
|
||||||
'!',
|
|
||||||
"'",
|
|
||||||
'+',
|
|
||||||
',',
|
|
||||||
'`',
|
|
||||||
'~',
|
|
||||||
'|',
|
|
||||||
'<',
|
|
||||||
'>',
|
|
||||||
'"'
|
|
||||||
];
|
|
||||||
let needsQuotes = false;
|
|
||||||
for (const char of arg) {
|
|
||||||
if (cmdSpecialChars.some(x => x === char)) {
|
|
||||||
needsQuotes = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// short-circuit if quotes not needed
|
|
||||||
if (!needsQuotes) {
|
|
||||||
return arg;
|
|
||||||
}
|
|
||||||
// the following quoting rules are very similar to the rules that by libuv applies.
|
|
||||||
//
|
|
||||||
// 1) wrap the string in quotes
|
|
||||||
//
|
|
||||||
// 2) double-up quotes - i.e. " => ""
|
|
||||||
//
|
|
||||||
// this is different from the libuv quoting rules. libuv replaces " with \", which unfortunately
|
|
||||||
// doesn't work well with a cmd.exe command line.
|
|
||||||
//
|
|
||||||
// note, replacing " with "" also works well if the arg is passed to a downstream .NET console app.
|
|
||||||
// for example, the command line:
|
|
||||||
// foo.exe "myarg:""my val"""
|
|
||||||
// is parsed by a .NET console app into an arg array:
|
|
||||||
// [ "myarg:\"my val\"" ]
|
|
||||||
// which is the same end result when applying libuv quoting rules. although the actual
|
|
||||||
// command line from libuv quoting rules would look like:
|
|
||||||
// foo.exe "myarg:\"my val\""
|
|
||||||
//
|
|
||||||
// 3) double-up slashes that precede a quote,
|
|
||||||
// e.g. hello \world => "hello \world"
|
|
||||||
// hello\"world => "hello\\""world"
|
|
||||||
// hello\\"world => "hello\\\\""world"
|
|
||||||
// hello world\ => "hello world\\"
|
|
||||||
//
|
|
||||||
// technically this is not required for a cmd.exe command line, or the batch argument parser.
|
|
||||||
// the reasons for including this as a .cmd quoting rule are:
|
|
||||||
//
|
|
||||||
// a) this is optimized for the scenario where the argument is passed from the .cmd file to an
|
|
||||||
// external program. many programs (e.g. .NET console apps) rely on the slash-doubling rule.
|
|
||||||
//
|
|
||||||
// b) it's what we've been doing previously (by deferring to node default behavior) and we
|
|
||||||
// haven't heard any complaints about that aspect.
|
|
||||||
//
|
|
||||||
// note, a weakness of the quoting rules chosen here, is that % is not escaped. in fact, % cannot be
|
|
||||||
// escaped when used on the command line directly - even though within a .cmd file % can be escaped
|
|
||||||
// by using %%.
|
|
||||||
//
|
|
||||||
// the saving grace is, on the command line, %var% is left as-is if var is not defined. this contrasts
|
|
||||||
// the line parsing rules within a .cmd file, where if var is not defined it is replaced with nothing.
|
|
||||||
//
|
|
||||||
// one option that was explored was replacing % with ^% - i.e. %var% => ^%var^%. this hack would
|
|
||||||
// often work, since it is unlikely that var^ would exist, and the ^ character is removed when the
|
|
||||||
// variable is used. the problem, however, is that ^ is not removed when %* is used to pass the args
|
|
||||||
// to an external program.
|
|
||||||
//
|
|
||||||
// an unexplored potential solution for the % escaping problem, is to create a wrapper .cmd file.
|
|
||||||
// % can be escaped within a .cmd file.
|
|
||||||
let reverse = '"';
|
|
||||||
let quoteHit = true;
|
|
||||||
for (let i = arg.length; i > 0; i--) {
|
|
||||||
// walk the string in reverse
|
|
||||||
reverse += arg[i - 1];
|
|
||||||
if (quoteHit && arg[i - 1] === '\\') {
|
|
||||||
reverse += '\\'; // double the slash
|
|
||||||
}
|
|
||||||
else if (arg[i - 1] === '"') {
|
|
||||||
quoteHit = true;
|
|
||||||
reverse += '"'; // double the quote
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
quoteHit = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
reverse += '"';
|
|
||||||
return reverse
|
|
||||||
.split('')
|
|
||||||
.reverse()
|
|
||||||
.join('');
|
|
||||||
}
|
|
||||||
_uvQuoteCmdArg(arg) {
|
|
||||||
// Tool runner wraps child_process.spawn() and needs to apply the same quoting as
|
|
||||||
// Node in certain cases where the undocumented spawn option windowsVerbatimArguments
|
|
||||||
// is used.
|
|
||||||
//
|
|
||||||
// Since this function is a port of quote_cmd_arg from Node 4.x (technically, lib UV,
|
|
||||||
// see https://github.com/nodejs/node/blob/v4.x/deps/uv/src/win/process.c for details),
|
|
||||||
// pasting copyright notice from Node within this function:
|
|
||||||
//
|
|
||||||
// Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to
|
|
||||||
// deal in the Software without restriction, including without limitation the
|
|
||||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
||||||
// sell copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in
|
|
||||||
// all copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
||||||
// IN THE SOFTWARE.
|
|
||||||
if (!arg) {
|
|
||||||
// Need double quotation for empty argument
|
|
||||||
return '""';
|
|
||||||
}
|
|
||||||
if (!arg.includes(' ') && !arg.includes('\t') && !arg.includes('"')) {
|
|
||||||
// No quotation needed
|
|
||||||
return arg;
|
|
||||||
}
|
|
||||||
if (!arg.includes('"') && !arg.includes('\\')) {
|
|
||||||
// No embedded double quotes or backslashes, so I can just wrap
|
|
||||||
// quote marks around the whole thing.
|
|
||||||
return `"${arg}"`;
|
|
||||||
}
|
|
||||||
// Expected input/output:
|
|
||||||
// input : hello"world
|
|
||||||
// output: "hello\"world"
|
|
||||||
// input : hello""world
|
|
||||||
// output: "hello\"\"world"
|
|
||||||
// input : hello\world
|
|
||||||
// output: hello\world
|
|
||||||
// input : hello\\world
|
|
||||||
// output: hello\\world
|
|
||||||
// input : hello\"world
|
|
||||||
// output: "hello\\\"world"
|
|
||||||
// input : hello\\"world
|
|
||||||
// output: "hello\\\\\"world"
|
|
||||||
// input : hello world\
|
|
||||||
// output: "hello world\\" - note the comment in libuv actually reads "hello world\"
|
|
||||||
// but it appears the comment is wrong, it should be "hello world\\"
|
|
||||||
let reverse = '"';
|
|
||||||
let quoteHit = true;
|
|
||||||
for (let i = arg.length; i > 0; i--) {
|
|
||||||
// walk the string in reverse
|
|
||||||
reverse += arg[i - 1];
|
|
||||||
if (quoteHit && arg[i - 1] === '\\') {
|
|
||||||
reverse += '\\';
|
|
||||||
}
|
|
||||||
else if (arg[i - 1] === '"') {
|
|
||||||
quoteHit = true;
|
|
||||||
reverse += '\\';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
quoteHit = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
reverse += '"';
|
|
||||||
return reverse
|
|
||||||
.split('')
|
|
||||||
.reverse()
|
|
||||||
.join('');
|
|
||||||
}
|
|
||||||
_cloneExecOptions(options) {
|
|
||||||
options = options || {};
|
|
||||||
const result = {
|
|
||||||
cwd: options.cwd || process.cwd(),
|
|
||||||
env: options.env || process.env,
|
|
||||||
silent: options.silent || false,
|
|
||||||
windowsVerbatimArguments: options.windowsVerbatimArguments || false,
|
|
||||||
failOnStdErr: options.failOnStdErr || false,
|
|
||||||
ignoreReturnCode: options.ignoreReturnCode || false,
|
|
||||||
delay: options.delay || 10000
|
|
||||||
};
|
|
||||||
result.outStream = options.outStream || process.stdout;
|
|
||||||
result.errStream = options.errStream || process.stderr;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
_getSpawnOptions(options, toolPath) {
|
|
||||||
options = options || {};
|
|
||||||
const result = {};
|
|
||||||
result.cwd = options.cwd;
|
|
||||||
result.env = options.env;
|
|
||||||
result['windowsVerbatimArguments'] =
|
|
||||||
options.windowsVerbatimArguments || this._isCmdFile();
|
|
||||||
if (options.windowsVerbatimArguments) {
|
|
||||||
result.argv0 = `"${toolPath}"`;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Exec a tool.
|
|
||||||
* Output will be streamed to the live console.
|
|
||||||
* Returns promise with return code
|
|
||||||
*
|
|
||||||
* @param tool path to tool to exec
|
|
||||||
* @param options optional exec options. See ExecOptions
|
|
||||||
* @returns number
|
|
||||||
*/
|
|
||||||
exec() {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
// root the tool path if it is unrooted and contains relative pathing
|
|
||||||
if (!ioUtil.isRooted(this.toolPath) &&
|
|
||||||
(this.toolPath.includes('/') ||
|
|
||||||
(IS_WINDOWS && this.toolPath.includes('\\')))) {
|
|
||||||
// prefer options.cwd if it is specified, however options.cwd may also need to be rooted
|
|
||||||
this.toolPath = path.resolve(process.cwd(), this.options.cwd || process.cwd(), this.toolPath);
|
|
||||||
}
|
|
||||||
// if the tool is only a file name, then resolve it from the PATH
|
|
||||||
// otherwise verify it exists (add extension on Windows if necessary)
|
|
||||||
this.toolPath = yield io.which(this.toolPath, true);
|
|
||||||
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
|
|
||||||
this._debug(`exec tool: ${this.toolPath}`);
|
|
||||||
this._debug('arguments:');
|
|
||||||
for (const arg of this.args) {
|
|
||||||
this._debug(` ${arg}`);
|
|
||||||
}
|
|
||||||
const optionsNonNull = this._cloneExecOptions(this.options);
|
|
||||||
if (!optionsNonNull.silent && optionsNonNull.outStream) {
|
|
||||||
optionsNonNull.outStream.write(this._getCommandString(optionsNonNull) + os.EOL);
|
|
||||||
}
|
|
||||||
const state = new ExecState(optionsNonNull, this.toolPath);
|
|
||||||
state.on('debug', (message) => {
|
|
||||||
this._debug(message);
|
|
||||||
});
|
|
||||||
if (this.options.cwd && !(yield ioUtil.exists(this.options.cwd))) {
|
|
||||||
return reject(new Error(`The cwd: ${this.options.cwd} does not exist!`));
|
|
||||||
}
|
|
||||||
const fileName = this._getSpawnFileName();
|
|
||||||
const cp = child.spawn(fileName, this._getSpawnArgs(optionsNonNull), this._getSpawnOptions(this.options, fileName));
|
|
||||||
let stdbuffer = '';
|
|
||||||
if (cp.stdout) {
|
|
||||||
cp.stdout.on('data', (data) => {
|
|
||||||
if (this.options.listeners && this.options.listeners.stdout) {
|
|
||||||
this.options.listeners.stdout(data);
|
|
||||||
}
|
|
||||||
if (!optionsNonNull.silent && optionsNonNull.outStream) {
|
|
||||||
optionsNonNull.outStream.write(data);
|
|
||||||
}
|
|
||||||
stdbuffer = this._processLineBuffer(data, stdbuffer, (line) => {
|
|
||||||
if (this.options.listeners && this.options.listeners.stdline) {
|
|
||||||
this.options.listeners.stdline(line);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
let errbuffer = '';
|
|
||||||
if (cp.stderr) {
|
|
||||||
cp.stderr.on('data', (data) => {
|
|
||||||
state.processStderr = true;
|
|
||||||
if (this.options.listeners && this.options.listeners.stderr) {
|
|
||||||
this.options.listeners.stderr(data);
|
|
||||||
}
|
|
||||||
if (!optionsNonNull.silent &&
|
|
||||||
optionsNonNull.errStream &&
|
|
||||||
optionsNonNull.outStream) {
|
|
||||||
const s = optionsNonNull.failOnStdErr
|
|
||||||
? optionsNonNull.errStream
|
|
||||||
: optionsNonNull.outStream;
|
|
||||||
s.write(data);
|
|
||||||
}
|
|
||||||
errbuffer = this._processLineBuffer(data, errbuffer, (line) => {
|
|
||||||
if (this.options.listeners && this.options.listeners.errline) {
|
|
||||||
this.options.listeners.errline(line);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
cp.on('error', (err) => {
|
|
||||||
state.processError = err.message;
|
|
||||||
state.processExited = true;
|
|
||||||
state.processClosed = true;
|
|
||||||
state.CheckComplete();
|
|
||||||
});
|
|
||||||
cp.on('exit', (code) => {
|
|
||||||
state.processExitCode = code;
|
|
||||||
state.processExited = true;
|
|
||||||
this._debug(`Exit code ${code} received from tool '${this.toolPath}'`);
|
|
||||||
state.CheckComplete();
|
|
||||||
});
|
|
||||||
cp.on('close', (code) => {
|
|
||||||
state.processExitCode = code;
|
|
||||||
state.processExited = true;
|
|
||||||
state.processClosed = true;
|
|
||||||
this._debug(`STDIO streams have closed for tool '${this.toolPath}'`);
|
|
||||||
state.CheckComplete();
|
|
||||||
});
|
|
||||||
state.on('done', (error, exitCode) => {
|
|
||||||
if (stdbuffer.length > 0) {
|
|
||||||
this.emit('stdline', stdbuffer);
|
|
||||||
}
|
|
||||||
if (errbuffer.length > 0) {
|
|
||||||
this.emit('errline', errbuffer);
|
|
||||||
}
|
|
||||||
cp.removeAllListeners();
|
|
||||||
if (error) {
|
|
||||||
reject(error);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
resolve(exitCode);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (this.options.input) {
|
|
||||||
if (!cp.stdin) {
|
|
||||||
throw new Error('child process missing stdin');
|
|
||||||
}
|
|
||||||
cp.stdin.end(this.options.input);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.ToolRunner = ToolRunner;
|
|
||||||
/**
|
|
||||||
* Convert an arg string to an array of args. Handles escaping
|
|
||||||
*
|
|
||||||
* @param argString string of arguments
|
|
||||||
* @returns string[] array of arguments
|
|
||||||
*/
|
|
||||||
function argStringToArray(argString) {
|
|
||||||
const args = [];
|
|
||||||
let inQuotes = false;
|
|
||||||
let escaped = false;
|
|
||||||
let arg = '';
|
|
||||||
function append(c) {
|
|
||||||
// we only escape double quotes.
|
|
||||||
if (escaped && c !== '"') {
|
|
||||||
arg += '\\';
|
|
||||||
}
|
|
||||||
arg += c;
|
|
||||||
escaped = false;
|
|
||||||
}
|
|
||||||
for (let i = 0; i < argString.length; i++) {
|
|
||||||
const c = argString.charAt(i);
|
|
||||||
if (c === '"') {
|
|
||||||
if (!escaped) {
|
|
||||||
inQuotes = !inQuotes;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
append(c);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (c === '\\' && escaped) {
|
|
||||||
append(c);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (c === '\\' && inQuotes) {
|
|
||||||
escaped = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (c === ' ' && !inQuotes) {
|
|
||||||
if (arg.length > 0) {
|
|
||||||
args.push(arg);
|
|
||||||
arg = '';
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
append(c);
|
|
||||||
}
|
|
||||||
if (arg.length > 0) {
|
|
||||||
args.push(arg.trim());
|
|
||||||
}
|
|
||||||
return args;
|
|
||||||
}
|
|
||||||
exports.argStringToArray = argStringToArray;
|
|
||||||
class ExecState extends events.EventEmitter {
|
|
||||||
constructor(options, toolPath) {
|
|
||||||
super();
|
|
||||||
this.processClosed = false; // tracks whether the process has exited and stdio is closed
|
|
||||||
this.processError = '';
|
|
||||||
this.processExitCode = 0;
|
|
||||||
this.processExited = false; // tracks whether the process has exited
|
|
||||||
this.processStderr = false; // tracks whether stderr was written to
|
|
||||||
this.delay = 10000; // 10 seconds
|
|
||||||
this.done = false;
|
|
||||||
this.timeout = null;
|
|
||||||
if (!toolPath) {
|
|
||||||
throw new Error('toolPath must not be empty');
|
|
||||||
}
|
|
||||||
this.options = options;
|
|
||||||
this.toolPath = toolPath;
|
|
||||||
if (options.delay) {
|
|
||||||
this.delay = options.delay;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CheckComplete() {
|
|
||||||
if (this.done) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (this.processClosed) {
|
|
||||||
this._setResult();
|
|
||||||
}
|
|
||||||
else if (this.processExited) {
|
|
||||||
this.timeout = timers_1.setTimeout(ExecState.HandleTimeout, this.delay, this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_debug(message) {
|
|
||||||
this.emit('debug', message);
|
|
||||||
}
|
|
||||||
_setResult() {
|
|
||||||
// determine whether there is an error
|
|
||||||
let error;
|
|
||||||
if (this.processExited) {
|
|
||||||
if (this.processError) {
|
|
||||||
error = new Error(`There was an error when attempting to execute the process '${this.toolPath}'. This may indicate the process failed to start. Error: ${this.processError}`);
|
|
||||||
}
|
|
||||||
else if (this.processExitCode !== 0 && !this.options.ignoreReturnCode) {
|
|
||||||
error = new Error(`The process '${this.toolPath}' failed with exit code ${this.processExitCode}`);
|
|
||||||
}
|
|
||||||
else if (this.processStderr && this.options.failOnStdErr) {
|
|
||||||
error = new Error(`The process '${this.toolPath}' failed because one or more lines were written to the STDERR stream`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// clear the timeout
|
|
||||||
if (this.timeout) {
|
|
||||||
clearTimeout(this.timeout);
|
|
||||||
this.timeout = null;
|
|
||||||
}
|
|
||||||
this.done = true;
|
|
||||||
this.emit('done', error, this.processExitCode);
|
|
||||||
}
|
|
||||||
static HandleTimeout(state) {
|
|
||||||
if (state.done) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!state.processClosed && state.processExited) {
|
|
||||||
const message = `The STDIO streams did not close within ${state.delay /
|
|
||||||
1000} seconds of the exit event from process '${state.toolPath}'. This may indicate a child process inherited the STDIO streams and has not yet exited.`;
|
|
||||||
state._debug(message);
|
|
||||||
}
|
|
||||||
state._setResult();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//# sourceMappingURL=toolrunner.js.map
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 31485:
|
|
||||||
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
||||||
}) : (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
o[k2] = m[k];
|
|
||||||
}));
|
|
||||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
||||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
||||||
}) : function(o, v) {
|
|
||||||
o["default"] = v;
|
|
||||||
});
|
|
||||||
var __importStar = (this && this.__importStar) || function (mod) {
|
|
||||||
if (mod && mod.__esModule) return mod;
|
|
||||||
var result = {};
|
|
||||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
||||||
__setModuleDefault(result, mod);
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
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 _a;
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.getCmdPath = exports.tryGetExecutablePath = exports.isRooted = exports.isDirectory = exports.exists = exports.READONLY = exports.UV_FS_O_EXLOCK = exports.IS_WINDOWS = exports.unlink = exports.symlink = exports.stat = exports.rmdir = exports.rm = exports.rename = exports.readlink = exports.readdir = exports.open = exports.mkdir = exports.lstat = exports.copyFile = exports.chmod = void 0;
|
|
||||||
const fs = __importStar(__nccwpck_require__(79896));
|
|
||||||
const path = __importStar(__nccwpck_require__(16928));
|
|
||||||
_a = fs.promises
|
|
||||||
// export const {open} = 'fs'
|
|
||||||
, exports.chmod = _a.chmod, exports.copyFile = _a.copyFile, exports.lstat = _a.lstat, exports.mkdir = _a.mkdir, exports.open = _a.open, exports.readdir = _a.readdir, exports.readlink = _a.readlink, exports.rename = _a.rename, exports.rm = _a.rm, exports.rmdir = _a.rmdir, exports.stat = _a.stat, exports.symlink = _a.symlink, exports.unlink = _a.unlink;
|
|
||||||
// export const {open} = 'fs'
|
|
||||||
exports.IS_WINDOWS = process.platform === 'win32';
|
|
||||||
// See https://github.com/nodejs/node/blob/d0153aee367422d0858105abec186da4dff0a0c5/deps/uv/include/uv/win.h#L691
|
|
||||||
exports.UV_FS_O_EXLOCK = 0x10000000;
|
|
||||||
exports.READONLY = fs.constants.O_RDONLY;
|
|
||||||
function exists(fsPath) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
try {
|
|
||||||
yield exports.stat(fsPath);
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
if (err.code === 'ENOENT') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.exists = exists;
|
|
||||||
function isDirectory(fsPath, useStat = false) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
const stats = useStat ? yield exports.stat(fsPath) : yield exports.lstat(fsPath);
|
|
||||||
return stats.isDirectory();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.isDirectory = isDirectory;
|
|
||||||
/**
|
|
||||||
* On OSX/Linux, true if path starts with '/'. On Windows, true for paths like:
|
|
||||||
* \, \hello, \\hello\share, C:, and C:\hello (and corresponding alternate separator cases).
|
|
||||||
*/
|
|
||||||
function isRooted(p) {
|
|
||||||
p = normalizeSeparators(p);
|
|
||||||
if (!p) {
|
|
||||||
throw new Error('isRooted() parameter "p" cannot be empty');
|
|
||||||
}
|
|
||||||
if (exports.IS_WINDOWS) {
|
|
||||||
return (p.startsWith('\\') || /^[A-Z]:/i.test(p) // e.g. \ or \hello or \\hello
|
|
||||||
); // e.g. C: or C:\hello
|
|
||||||
}
|
|
||||||
return p.startsWith('/');
|
|
||||||
}
|
|
||||||
exports.isRooted = isRooted;
|
|
||||||
/**
|
|
||||||
* Best effort attempt to determine whether a file exists and is executable.
|
|
||||||
* @param filePath file path to check
|
|
||||||
* @param extensions additional file extensions to try
|
|
||||||
* @return if file exists and is executable, returns the file path. otherwise empty string.
|
|
||||||
*/
|
|
||||||
function tryGetExecutablePath(filePath, extensions) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
let stats = undefined;
|
|
||||||
try {
|
|
||||||
// test file exists
|
|
||||||
stats = yield exports.stat(filePath);
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
if (err.code !== 'ENOENT') {
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.log(`Unexpected error attempting to determine if executable file exists '${filePath}': ${err}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (stats && stats.isFile()) {
|
|
||||||
if (exports.IS_WINDOWS) {
|
|
||||||
// on Windows, test for valid extension
|
|
||||||
const upperExt = path.extname(filePath).toUpperCase();
|
|
||||||
if (extensions.some(validExt => validExt.toUpperCase() === upperExt)) {
|
|
||||||
return filePath;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (isUnixExecutable(stats)) {
|
|
||||||
return filePath;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// try each extension
|
|
||||||
const originalFilePath = filePath;
|
|
||||||
for (const extension of extensions) {
|
|
||||||
filePath = originalFilePath + extension;
|
|
||||||
stats = undefined;
|
|
||||||
try {
|
|
||||||
stats = yield exports.stat(filePath);
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
if (err.code !== 'ENOENT') {
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.log(`Unexpected error attempting to determine if executable file exists '${filePath}': ${err}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (stats && stats.isFile()) {
|
|
||||||
if (exports.IS_WINDOWS) {
|
|
||||||
// preserve the case of the actual file (since an extension was appended)
|
|
||||||
try {
|
|
||||||
const directory = path.dirname(filePath);
|
|
||||||
const upperName = path.basename(filePath).toUpperCase();
|
|
||||||
for (const actualName of yield exports.readdir(directory)) {
|
|
||||||
if (upperName === actualName.toUpperCase()) {
|
|
||||||
filePath = path.join(directory, actualName);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.log(`Unexpected error attempting to determine the actual case of the file '${filePath}': ${err}`);
|
|
||||||
}
|
|
||||||
return filePath;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (isUnixExecutable(stats)) {
|
|
||||||
return filePath;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.tryGetExecutablePath = tryGetExecutablePath;
|
|
||||||
function normalizeSeparators(p) {
|
|
||||||
p = p || '';
|
|
||||||
if (exports.IS_WINDOWS) {
|
|
||||||
// convert slashes on Windows
|
|
||||||
p = p.replace(/\//g, '\\');
|
|
||||||
// remove redundant slashes
|
|
||||||
return p.replace(/\\\\+/g, '\\');
|
|
||||||
}
|
|
||||||
// remove redundant slashes
|
|
||||||
return p.replace(/\/\/+/g, '/');
|
|
||||||
}
|
|
||||||
// on Mac/Linux, test the execute bit
|
|
||||||
// R W X R W X R W X
|
|
||||||
// 256 128 64 32 16 8 4 2 1
|
|
||||||
function isUnixExecutable(stats) {
|
|
||||||
return ((stats.mode & 1) > 0 ||
|
|
||||||
((stats.mode & 8) > 0 && stats.gid === process.getgid()) ||
|
|
||||||
((stats.mode & 64) > 0 && stats.uid === process.getuid()));
|
|
||||||
}
|
|
||||||
// Get the path of cmd.exe in windows
|
|
||||||
function getCmdPath() {
|
|
||||||
var _a;
|
|
||||||
return (_a = process.env['COMSPEC']) !== null && _a !== void 0 ? _a : `cmd.exe`;
|
|
||||||
}
|
|
||||||
exports.getCmdPath = getCmdPath;
|
|
||||||
//# sourceMappingURL=io-util.js.map
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 42172:
|
|
||||||
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
||||||
}) : (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
o[k2] = m[k];
|
|
||||||
}));
|
|
||||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
||||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
||||||
}) : function(o, v) {
|
|
||||||
o["default"] = v;
|
|
||||||
});
|
|
||||||
var __importStar = (this && this.__importStar) || function (mod) {
|
|
||||||
if (mod && mod.__esModule) return mod;
|
|
||||||
var result = {};
|
|
||||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
||||||
__setModuleDefault(result, mod);
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
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());
|
|
||||||
});
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.findInPath = exports.which = exports.mkdirP = exports.rmRF = exports.mv = exports.cp = void 0;
|
|
||||||
const assert_1 = __nccwpck_require__(42613);
|
|
||||||
const path = __importStar(__nccwpck_require__(16928));
|
|
||||||
const ioUtil = __importStar(__nccwpck_require__(31485));
|
|
||||||
/**
|
|
||||||
* Copies a file or folder.
|
|
||||||
* Based off of shelljs - https://github.com/shelljs/shelljs/blob/9237f66c52e5daa40458f94f9565e18e8132f5a6/src/cp.js
|
|
||||||
*
|
|
||||||
* @param source source path
|
|
||||||
* @param dest destination path
|
|
||||||
* @param options optional. See CopyOptions.
|
|
||||||
*/
|
|
||||||
function cp(source, dest, options = {}) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
const { force, recursive, copySourceDirectory } = readCopyOptions(options);
|
|
||||||
const destStat = (yield ioUtil.exists(dest)) ? yield ioUtil.stat(dest) : null;
|
|
||||||
// Dest is an existing file, but not forcing
|
|
||||||
if (destStat && destStat.isFile() && !force) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// If dest is an existing directory, should copy inside.
|
|
||||||
const newDest = destStat && destStat.isDirectory() && copySourceDirectory
|
|
||||||
? path.join(dest, path.basename(source))
|
|
||||||
: dest;
|
|
||||||
if (!(yield ioUtil.exists(source))) {
|
|
||||||
throw new Error(`no such file or directory: ${source}`);
|
|
||||||
}
|
|
||||||
const sourceStat = yield ioUtil.stat(source);
|
|
||||||
if (sourceStat.isDirectory()) {
|
|
||||||
if (!recursive) {
|
|
||||||
throw new Error(`Failed to copy. ${source} is a directory, but tried to copy without recursive flag.`);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
yield cpDirRecursive(source, newDest, 0, force);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (path.relative(source, newDest) === '') {
|
|
||||||
// a file cannot be copied to itself
|
|
||||||
throw new Error(`'${newDest}' and '${source}' are the same file`);
|
|
||||||
}
|
|
||||||
yield copyFile(source, newDest, force);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.cp = cp;
|
|
||||||
/**
|
|
||||||
* Moves a path.
|
|
||||||
*
|
|
||||||
* @param source source path
|
|
||||||
* @param dest destination path
|
|
||||||
* @param options optional. See MoveOptions.
|
|
||||||
*/
|
|
||||||
function mv(source, dest, options = {}) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
if (yield ioUtil.exists(dest)) {
|
|
||||||
let destExists = true;
|
|
||||||
if (yield ioUtil.isDirectory(dest)) {
|
|
||||||
// If dest is directory copy src into dest
|
|
||||||
dest = path.join(dest, path.basename(source));
|
|
||||||
destExists = yield ioUtil.exists(dest);
|
|
||||||
}
|
|
||||||
if (destExists) {
|
|
||||||
if (options.force == null || options.force) {
|
|
||||||
yield rmRF(dest);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new Error('Destination already exists');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
yield mkdirP(path.dirname(dest));
|
|
||||||
yield ioUtil.rename(source, dest);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.mv = mv;
|
|
||||||
/**
|
|
||||||
* Remove a path recursively with force
|
|
||||||
*
|
|
||||||
* @param inputPath path to remove
|
|
||||||
*/
|
|
||||||
function rmRF(inputPath) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
if (ioUtil.IS_WINDOWS) {
|
|
||||||
// Check for invalid characters
|
|
||||||
// https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file
|
|
||||||
if (/[*"<>|]/.test(inputPath)) {
|
|
||||||
throw new Error('File path must not contain `*`, `"`, `<`, `>` or `|` on Windows');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
// note if path does not exist, error is silent
|
|
||||||
yield ioUtil.rm(inputPath, {
|
|
||||||
force: true,
|
|
||||||
maxRetries: 3,
|
|
||||||
recursive: true,
|
|
||||||
retryDelay: 300
|
|
||||||
});
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
throw new Error(`File was unable to be removed ${err}`);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.rmRF = rmRF;
|
|
||||||
/**
|
|
||||||
* Make a directory. Creates the full path with folders in between
|
|
||||||
* Will throw if it fails
|
|
||||||
*
|
|
||||||
* @param fsPath path to create
|
|
||||||
* @returns Promise<void>
|
|
||||||
*/
|
|
||||||
function mkdirP(fsPath) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
assert_1.ok(fsPath, 'a path argument must be provided');
|
|
||||||
yield ioUtil.mkdir(fsPath, { recursive: true });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.mkdirP = mkdirP;
|
|
||||||
/**
|
|
||||||
* Returns path of a tool had the tool actually been invoked. Resolves via paths.
|
|
||||||
* If you check and the tool does not exist, it will throw.
|
|
||||||
*
|
|
||||||
* @param tool name of the tool
|
|
||||||
* @param check whether to check if tool exists
|
|
||||||
* @returns Promise<string> path to tool
|
|
||||||
*/
|
|
||||||
function which(tool, check) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
if (!tool) {
|
|
||||||
throw new Error("parameter 'tool' is required");
|
|
||||||
}
|
|
||||||
// recursive when check=true
|
|
||||||
if (check) {
|
|
||||||
const result = yield which(tool, false);
|
|
||||||
if (!result) {
|
|
||||||
if (ioUtil.IS_WINDOWS) {
|
|
||||||
throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also verify the file has a valid extension for an executable file.`);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also check the file mode to verify the file is executable.`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
const matches = yield findInPath(tool);
|
|
||||||
if (matches && matches.length > 0) {
|
|
||||||
return matches[0];
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.which = which;
|
|
||||||
/**
|
|
||||||
* Returns a list of all occurrences of the given tool on the system path.
|
|
||||||
*
|
|
||||||
* @returns Promise<string[]> the paths of the tool
|
|
||||||
*/
|
|
||||||
function findInPath(tool) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
if (!tool) {
|
|
||||||
throw new Error("parameter 'tool' is required");
|
|
||||||
}
|
|
||||||
// build the list of extensions to try
|
|
||||||
const extensions = [];
|
|
||||||
if (ioUtil.IS_WINDOWS && process.env['PATHEXT']) {
|
|
||||||
for (const extension of process.env['PATHEXT'].split(path.delimiter)) {
|
|
||||||
if (extension) {
|
|
||||||
extensions.push(extension);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// if it's rooted, return it if exists. otherwise return empty.
|
|
||||||
if (ioUtil.isRooted(tool)) {
|
|
||||||
const filePath = yield ioUtil.tryGetExecutablePath(tool, extensions);
|
|
||||||
if (filePath) {
|
|
||||||
return [filePath];
|
|
||||||
}
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
// if any path separators, return empty
|
|
||||||
if (tool.includes(path.sep)) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
// build the list of directories
|
|
||||||
//
|
|
||||||
// Note, technically "where" checks the current directory on Windows. From a toolkit perspective,
|
|
||||||
// it feels like we should not do this. Checking the current directory seems like more of a use
|
|
||||||
// case of a shell, and the which() function exposed by the toolkit should strive for consistency
|
|
||||||
// across platforms.
|
|
||||||
const directories = [];
|
|
||||||
if (process.env.PATH) {
|
|
||||||
for (const p of process.env.PATH.split(path.delimiter)) {
|
|
||||||
if (p) {
|
|
||||||
directories.push(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// find all matches
|
|
||||||
const matches = [];
|
|
||||||
for (const directory of directories) {
|
|
||||||
const filePath = yield ioUtil.tryGetExecutablePath(path.join(directory, tool), extensions);
|
|
||||||
if (filePath) {
|
|
||||||
matches.push(filePath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return matches;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.findInPath = findInPath;
|
|
||||||
function readCopyOptions(options) {
|
|
||||||
const force = options.force == null ? true : options.force;
|
|
||||||
const recursive = Boolean(options.recursive);
|
|
||||||
const copySourceDirectory = options.copySourceDirectory == null
|
|
||||||
? true
|
|
||||||
: Boolean(options.copySourceDirectory);
|
|
||||||
return { force, recursive, copySourceDirectory };
|
|
||||||
}
|
|
||||||
function cpDirRecursive(sourceDir, destDir, currentDepth, force) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
// Ensure there is not a run away recursive copy
|
|
||||||
if (currentDepth >= 255)
|
|
||||||
return;
|
|
||||||
currentDepth++;
|
|
||||||
yield mkdirP(destDir);
|
|
||||||
const files = yield ioUtil.readdir(sourceDir);
|
|
||||||
for (const fileName of files) {
|
|
||||||
const srcFile = `${sourceDir}/${fileName}`;
|
|
||||||
const destFile = `${destDir}/${fileName}`;
|
|
||||||
const srcFileStat = yield ioUtil.lstat(srcFile);
|
|
||||||
if (srcFileStat.isDirectory()) {
|
|
||||||
// Recurse
|
|
||||||
yield cpDirRecursive(srcFile, destFile, currentDepth, force);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
yield copyFile(srcFile, destFile, force);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Change the mode for the newly created directory
|
|
||||||
yield ioUtil.chmod(destDir, (yield ioUtil.stat(sourceDir)).mode);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// Buffered file copy
|
|
||||||
function copyFile(srcFile, destFile, force) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
if ((yield ioUtil.lstat(srcFile)).isSymbolicLink()) {
|
|
||||||
// unlink/re-link it
|
|
||||||
try {
|
|
||||||
yield ioUtil.lstat(destFile);
|
|
||||||
yield ioUtil.unlink(destFile);
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
// Try to override file permission
|
|
||||||
if (e.code === 'EPERM') {
|
|
||||||
yield ioUtil.chmod(destFile, '0666');
|
|
||||||
yield ioUtil.unlink(destFile);
|
|
||||||
}
|
|
||||||
// other errors = it doesn't exist, no work to do
|
|
||||||
}
|
|
||||||
// Copy over symlink
|
|
||||||
const symlinkFull = yield ioUtil.readlink(srcFile);
|
|
||||||
yield ioUtil.symlink(symlinkFull, destFile, ioUtil.IS_WINDOWS ? 'junction' : null);
|
|
||||||
}
|
|
||||||
else if (!(yield ioUtil.exists(destFile)) || force) {
|
|
||||||
yield ioUtil.copyFile(srcFile, destFile);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
//# sourceMappingURL=io.js.map
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 32231:
|
/***/ 32231:
|
||||||
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4241,7 +4241,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.isLinux = exports.isMacOS = exports.isWindows = exports.arch = exports.platform = void 0;
|
exports.isLinux = exports.isMacOS = exports.isWindows = exports.arch = exports.platform = void 0;
|
||||||
exports.getDetails = getDetails;
|
exports.getDetails = getDetails;
|
||||||
const os_1 = __importDefault(__nccwpck_require__(70857));
|
const os_1 = __importDefault(__nccwpck_require__(70857));
|
||||||
const exec = __importStar(__nccwpck_require__(9966));
|
const exec = __importStar(__nccwpck_require__(32231));
|
||||||
const getWindowsInfo = () => __awaiter(void 0, void 0, void 0, function* () {
|
const getWindowsInfo = () => __awaiter(void 0, void 0, void 0, function* () {
|
||||||
const { stdout: version } = yield exec.getExecOutput('powershell -command "(Get-CimInstance -ClassName Win32_OperatingSystem).Version"', undefined, {
|
const { stdout: version } = yield exec.getExecOutput('powershell -command "(Get-CimInstance -ClassName Win32_OperatingSystem).Version"', undefined, {
|
||||||
silent: true
|
silent: true
|
||||||
|
|
@ -4634,1237 +4634,6 @@ function toCommandProperties(annotationProperties) {
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 9966:
|
|
||||||
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
||||||
}) : (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
o[k2] = m[k];
|
|
||||||
}));
|
|
||||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
||||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
||||||
}) : function(o, v) {
|
|
||||||
o["default"] = v;
|
|
||||||
});
|
|
||||||
var __importStar = (this && this.__importStar) || function (mod) {
|
|
||||||
if (mod && mod.__esModule) return mod;
|
|
||||||
var result = {};
|
|
||||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
||||||
__setModuleDefault(result, mod);
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
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());
|
|
||||||
});
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.getExecOutput = exports.exec = void 0;
|
|
||||||
const string_decoder_1 = __nccwpck_require__(13193);
|
|
||||||
const tr = __importStar(__nccwpck_require__(89063));
|
|
||||||
/**
|
|
||||||
* Exec a command.
|
|
||||||
* Output will be streamed to the live console.
|
|
||||||
* Returns promise with return code
|
|
||||||
*
|
|
||||||
* @param commandLine command to execute (can include additional args). Must be correctly escaped.
|
|
||||||
* @param args optional arguments for tool. Escaping is handled by the lib.
|
|
||||||
* @param options optional exec options. See ExecOptions
|
|
||||||
* @returns Promise<number> exit code
|
|
||||||
*/
|
|
||||||
function exec(commandLine, args, options) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
const commandArgs = tr.argStringToArray(commandLine);
|
|
||||||
if (commandArgs.length === 0) {
|
|
||||||
throw new Error(`Parameter 'commandLine' cannot be null or empty.`);
|
|
||||||
}
|
|
||||||
// Path to tool to execute should be first arg
|
|
||||||
const toolPath = commandArgs[0];
|
|
||||||
args = commandArgs.slice(1).concat(args || []);
|
|
||||||
const runner = new tr.ToolRunner(toolPath, args, options);
|
|
||||||
return runner.exec();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.exec = exec;
|
|
||||||
/**
|
|
||||||
* Exec a command and get the output.
|
|
||||||
* Output will be streamed to the live console.
|
|
||||||
* Returns promise with the exit code and collected stdout and stderr
|
|
||||||
*
|
|
||||||
* @param commandLine command to execute (can include additional args). Must be correctly escaped.
|
|
||||||
* @param args optional arguments for tool. Escaping is handled by the lib.
|
|
||||||
* @param options optional exec options. See ExecOptions
|
|
||||||
* @returns Promise<ExecOutput> exit code, stdout, and stderr
|
|
||||||
*/
|
|
||||||
function getExecOutput(commandLine, args, options) {
|
|
||||||
var _a, _b;
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
let stdout = '';
|
|
||||||
let stderr = '';
|
|
||||||
//Using string decoder covers the case where a mult-byte character is split
|
|
||||||
const stdoutDecoder = new string_decoder_1.StringDecoder('utf8');
|
|
||||||
const stderrDecoder = new string_decoder_1.StringDecoder('utf8');
|
|
||||||
const originalStdoutListener = (_a = options === null || options === void 0 ? void 0 : options.listeners) === null || _a === void 0 ? void 0 : _a.stdout;
|
|
||||||
const originalStdErrListener = (_b = options === null || options === void 0 ? void 0 : options.listeners) === null || _b === void 0 ? void 0 : _b.stderr;
|
|
||||||
const stdErrListener = (data) => {
|
|
||||||
stderr += stderrDecoder.write(data);
|
|
||||||
if (originalStdErrListener) {
|
|
||||||
originalStdErrListener(data);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const stdOutListener = (data) => {
|
|
||||||
stdout += stdoutDecoder.write(data);
|
|
||||||
if (originalStdoutListener) {
|
|
||||||
originalStdoutListener(data);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const listeners = Object.assign(Object.assign({}, options === null || options === void 0 ? void 0 : options.listeners), { stdout: stdOutListener, stderr: stdErrListener });
|
|
||||||
const exitCode = yield exec(commandLine, args, Object.assign(Object.assign({}, options), { listeners }));
|
|
||||||
//flush any remaining characters
|
|
||||||
stdout += stdoutDecoder.end();
|
|
||||||
stderr += stderrDecoder.end();
|
|
||||||
return {
|
|
||||||
exitCode,
|
|
||||||
stdout,
|
|
||||||
stderr
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.getExecOutput = getExecOutput;
|
|
||||||
//# sourceMappingURL=exec.js.map
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 89063:
|
|
||||||
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
||||||
}) : (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
o[k2] = m[k];
|
|
||||||
}));
|
|
||||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
||||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
||||||
}) : function(o, v) {
|
|
||||||
o["default"] = v;
|
|
||||||
});
|
|
||||||
var __importStar = (this && this.__importStar) || function (mod) {
|
|
||||||
if (mod && mod.__esModule) return mod;
|
|
||||||
var result = {};
|
|
||||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
||||||
__setModuleDefault(result, mod);
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
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());
|
|
||||||
});
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.argStringToArray = exports.ToolRunner = void 0;
|
|
||||||
const os = __importStar(__nccwpck_require__(70857));
|
|
||||||
const events = __importStar(__nccwpck_require__(24434));
|
|
||||||
const child = __importStar(__nccwpck_require__(35317));
|
|
||||||
const path = __importStar(__nccwpck_require__(16928));
|
|
||||||
const io = __importStar(__nccwpck_require__(42172));
|
|
||||||
const ioUtil = __importStar(__nccwpck_require__(31485));
|
|
||||||
const timers_1 = __nccwpck_require__(53557);
|
|
||||||
/* eslint-disable @typescript-eslint/unbound-method */
|
|
||||||
const IS_WINDOWS = process.platform === 'win32';
|
|
||||||
/*
|
|
||||||
* Class for running command line tools. Handles quoting and arg parsing in a platform agnostic way.
|
|
||||||
*/
|
|
||||||
class ToolRunner extends events.EventEmitter {
|
|
||||||
constructor(toolPath, args, options) {
|
|
||||||
super();
|
|
||||||
if (!toolPath) {
|
|
||||||
throw new Error("Parameter 'toolPath' cannot be null or empty.");
|
|
||||||
}
|
|
||||||
this.toolPath = toolPath;
|
|
||||||
this.args = args || [];
|
|
||||||
this.options = options || {};
|
|
||||||
}
|
|
||||||
_debug(message) {
|
|
||||||
if (this.options.listeners && this.options.listeners.debug) {
|
|
||||||
this.options.listeners.debug(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_getCommandString(options, noPrefix) {
|
|
||||||
const toolPath = this._getSpawnFileName();
|
|
||||||
const args = this._getSpawnArgs(options);
|
|
||||||
let cmd = noPrefix ? '' : '[command]'; // omit prefix when piped to a second tool
|
|
||||||
if (IS_WINDOWS) {
|
|
||||||
// Windows + cmd file
|
|
||||||
if (this._isCmdFile()) {
|
|
||||||
cmd += toolPath;
|
|
||||||
for (const a of args) {
|
|
||||||
cmd += ` ${a}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Windows + verbatim
|
|
||||||
else if (options.windowsVerbatimArguments) {
|
|
||||||
cmd += `"${toolPath}"`;
|
|
||||||
for (const a of args) {
|
|
||||||
cmd += ` ${a}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Windows (regular)
|
|
||||||
else {
|
|
||||||
cmd += this._windowsQuoteCmdArg(toolPath);
|
|
||||||
for (const a of args) {
|
|
||||||
cmd += ` ${this._windowsQuoteCmdArg(a)}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// OSX/Linux - this can likely be improved with some form of quoting.
|
|
||||||
// creating processes on Unix is fundamentally different than Windows.
|
|
||||||
// on Unix, execvp() takes an arg array.
|
|
||||||
cmd += toolPath;
|
|
||||||
for (const a of args) {
|
|
||||||
cmd += ` ${a}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return cmd;
|
|
||||||
}
|
|
||||||
_processLineBuffer(data, strBuffer, onLine) {
|
|
||||||
try {
|
|
||||||
let s = strBuffer + data.toString();
|
|
||||||
let n = s.indexOf(os.EOL);
|
|
||||||
while (n > -1) {
|
|
||||||
const line = s.substring(0, n);
|
|
||||||
onLine(line);
|
|
||||||
// the rest of the string ...
|
|
||||||
s = s.substring(n + os.EOL.length);
|
|
||||||
n = s.indexOf(os.EOL);
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
// streaming lines to console is best effort. Don't fail a build.
|
|
||||||
this._debug(`error processing line. Failed with error ${err}`);
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_getSpawnFileName() {
|
|
||||||
if (IS_WINDOWS) {
|
|
||||||
if (this._isCmdFile()) {
|
|
||||||
return process.env['COMSPEC'] || 'cmd.exe';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this.toolPath;
|
|
||||||
}
|
|
||||||
_getSpawnArgs(options) {
|
|
||||||
if (IS_WINDOWS) {
|
|
||||||
if (this._isCmdFile()) {
|
|
||||||
let argline = `/D /S /C "${this._windowsQuoteCmdArg(this.toolPath)}`;
|
|
||||||
for (const a of this.args) {
|
|
||||||
argline += ' ';
|
|
||||||
argline += options.windowsVerbatimArguments
|
|
||||||
? a
|
|
||||||
: this._windowsQuoteCmdArg(a);
|
|
||||||
}
|
|
||||||
argline += '"';
|
|
||||||
return [argline];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this.args;
|
|
||||||
}
|
|
||||||
_endsWith(str, end) {
|
|
||||||
return str.endsWith(end);
|
|
||||||
}
|
|
||||||
_isCmdFile() {
|
|
||||||
const upperToolPath = this.toolPath.toUpperCase();
|
|
||||||
return (this._endsWith(upperToolPath, '.CMD') ||
|
|
||||||
this._endsWith(upperToolPath, '.BAT'));
|
|
||||||
}
|
|
||||||
_windowsQuoteCmdArg(arg) {
|
|
||||||
// for .exe, apply the normal quoting rules that libuv applies
|
|
||||||
if (!this._isCmdFile()) {
|
|
||||||
return this._uvQuoteCmdArg(arg);
|
|
||||||
}
|
|
||||||
// otherwise apply quoting rules specific to the cmd.exe command line parser.
|
|
||||||
// the libuv rules are generic and are not designed specifically for cmd.exe
|
|
||||||
// command line parser.
|
|
||||||
//
|
|
||||||
// for a detailed description of the cmd.exe command line parser, refer to
|
|
||||||
// http://stackoverflow.com/questions/4094699/how-does-the-windows-command-interpreter-cmd-exe-parse-scripts/7970912#7970912
|
|
||||||
// need quotes for empty arg
|
|
||||||
if (!arg) {
|
|
||||||
return '""';
|
|
||||||
}
|
|
||||||
// determine whether the arg needs to be quoted
|
|
||||||
const cmdSpecialChars = [
|
|
||||||
' ',
|
|
||||||
'\t',
|
|
||||||
'&',
|
|
||||||
'(',
|
|
||||||
')',
|
|
||||||
'[',
|
|
||||||
']',
|
|
||||||
'{',
|
|
||||||
'}',
|
|
||||||
'^',
|
|
||||||
'=',
|
|
||||||
';',
|
|
||||||
'!',
|
|
||||||
"'",
|
|
||||||
'+',
|
|
||||||
',',
|
|
||||||
'`',
|
|
||||||
'~',
|
|
||||||
'|',
|
|
||||||
'<',
|
|
||||||
'>',
|
|
||||||
'"'
|
|
||||||
];
|
|
||||||
let needsQuotes = false;
|
|
||||||
for (const char of arg) {
|
|
||||||
if (cmdSpecialChars.some(x => x === char)) {
|
|
||||||
needsQuotes = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// short-circuit if quotes not needed
|
|
||||||
if (!needsQuotes) {
|
|
||||||
return arg;
|
|
||||||
}
|
|
||||||
// the following quoting rules are very similar to the rules that by libuv applies.
|
|
||||||
//
|
|
||||||
// 1) wrap the string in quotes
|
|
||||||
//
|
|
||||||
// 2) double-up quotes - i.e. " => ""
|
|
||||||
//
|
|
||||||
// this is different from the libuv quoting rules. libuv replaces " with \", which unfortunately
|
|
||||||
// doesn't work well with a cmd.exe command line.
|
|
||||||
//
|
|
||||||
// note, replacing " with "" also works well if the arg is passed to a downstream .NET console app.
|
|
||||||
// for example, the command line:
|
|
||||||
// foo.exe "myarg:""my val"""
|
|
||||||
// is parsed by a .NET console app into an arg array:
|
|
||||||
// [ "myarg:\"my val\"" ]
|
|
||||||
// which is the same end result when applying libuv quoting rules. although the actual
|
|
||||||
// command line from libuv quoting rules would look like:
|
|
||||||
// foo.exe "myarg:\"my val\""
|
|
||||||
//
|
|
||||||
// 3) double-up slashes that precede a quote,
|
|
||||||
// e.g. hello \world => "hello \world"
|
|
||||||
// hello\"world => "hello\\""world"
|
|
||||||
// hello\\"world => "hello\\\\""world"
|
|
||||||
// hello world\ => "hello world\\"
|
|
||||||
//
|
|
||||||
// technically this is not required for a cmd.exe command line, or the batch argument parser.
|
|
||||||
// the reasons for including this as a .cmd quoting rule are:
|
|
||||||
//
|
|
||||||
// a) this is optimized for the scenario where the argument is passed from the .cmd file to an
|
|
||||||
// external program. many programs (e.g. .NET console apps) rely on the slash-doubling rule.
|
|
||||||
//
|
|
||||||
// b) it's what we've been doing previously (by deferring to node default behavior) and we
|
|
||||||
// haven't heard any complaints about that aspect.
|
|
||||||
//
|
|
||||||
// note, a weakness of the quoting rules chosen here, is that % is not escaped. in fact, % cannot be
|
|
||||||
// escaped when used on the command line directly - even though within a .cmd file % can be escaped
|
|
||||||
// by using %%.
|
|
||||||
//
|
|
||||||
// the saving grace is, on the command line, %var% is left as-is if var is not defined. this contrasts
|
|
||||||
// the line parsing rules within a .cmd file, where if var is not defined it is replaced with nothing.
|
|
||||||
//
|
|
||||||
// one option that was explored was replacing % with ^% - i.e. %var% => ^%var^%. this hack would
|
|
||||||
// often work, since it is unlikely that var^ would exist, and the ^ character is removed when the
|
|
||||||
// variable is used. the problem, however, is that ^ is not removed when %* is used to pass the args
|
|
||||||
// to an external program.
|
|
||||||
//
|
|
||||||
// an unexplored potential solution for the % escaping problem, is to create a wrapper .cmd file.
|
|
||||||
// % can be escaped within a .cmd file.
|
|
||||||
let reverse = '"';
|
|
||||||
let quoteHit = true;
|
|
||||||
for (let i = arg.length; i > 0; i--) {
|
|
||||||
// walk the string in reverse
|
|
||||||
reverse += arg[i - 1];
|
|
||||||
if (quoteHit && arg[i - 1] === '\\') {
|
|
||||||
reverse += '\\'; // double the slash
|
|
||||||
}
|
|
||||||
else if (arg[i - 1] === '"') {
|
|
||||||
quoteHit = true;
|
|
||||||
reverse += '"'; // double the quote
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
quoteHit = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
reverse += '"';
|
|
||||||
return reverse
|
|
||||||
.split('')
|
|
||||||
.reverse()
|
|
||||||
.join('');
|
|
||||||
}
|
|
||||||
_uvQuoteCmdArg(arg) {
|
|
||||||
// Tool runner wraps child_process.spawn() and needs to apply the same quoting as
|
|
||||||
// Node in certain cases where the undocumented spawn option windowsVerbatimArguments
|
|
||||||
// is used.
|
|
||||||
//
|
|
||||||
// Since this function is a port of quote_cmd_arg from Node 4.x (technically, lib UV,
|
|
||||||
// see https://github.com/nodejs/node/blob/v4.x/deps/uv/src/win/process.c for details),
|
|
||||||
// pasting copyright notice from Node within this function:
|
|
||||||
//
|
|
||||||
// Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to
|
|
||||||
// deal in the Software without restriction, including without limitation the
|
|
||||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
||||||
// sell copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in
|
|
||||||
// all copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
||||||
// IN THE SOFTWARE.
|
|
||||||
if (!arg) {
|
|
||||||
// Need double quotation for empty argument
|
|
||||||
return '""';
|
|
||||||
}
|
|
||||||
if (!arg.includes(' ') && !arg.includes('\t') && !arg.includes('"')) {
|
|
||||||
// No quotation needed
|
|
||||||
return arg;
|
|
||||||
}
|
|
||||||
if (!arg.includes('"') && !arg.includes('\\')) {
|
|
||||||
// No embedded double quotes or backslashes, so I can just wrap
|
|
||||||
// quote marks around the whole thing.
|
|
||||||
return `"${arg}"`;
|
|
||||||
}
|
|
||||||
// Expected input/output:
|
|
||||||
// input : hello"world
|
|
||||||
// output: "hello\"world"
|
|
||||||
// input : hello""world
|
|
||||||
// output: "hello\"\"world"
|
|
||||||
// input : hello\world
|
|
||||||
// output: hello\world
|
|
||||||
// input : hello\\world
|
|
||||||
// output: hello\\world
|
|
||||||
// input : hello\"world
|
|
||||||
// output: "hello\\\"world"
|
|
||||||
// input : hello\\"world
|
|
||||||
// output: "hello\\\\\"world"
|
|
||||||
// input : hello world\
|
|
||||||
// output: "hello world\\" - note the comment in libuv actually reads "hello world\"
|
|
||||||
// but it appears the comment is wrong, it should be "hello world\\"
|
|
||||||
let reverse = '"';
|
|
||||||
let quoteHit = true;
|
|
||||||
for (let i = arg.length; i > 0; i--) {
|
|
||||||
// walk the string in reverse
|
|
||||||
reverse += arg[i - 1];
|
|
||||||
if (quoteHit && arg[i - 1] === '\\') {
|
|
||||||
reverse += '\\';
|
|
||||||
}
|
|
||||||
else if (arg[i - 1] === '"') {
|
|
||||||
quoteHit = true;
|
|
||||||
reverse += '\\';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
quoteHit = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
reverse += '"';
|
|
||||||
return reverse
|
|
||||||
.split('')
|
|
||||||
.reverse()
|
|
||||||
.join('');
|
|
||||||
}
|
|
||||||
_cloneExecOptions(options) {
|
|
||||||
options = options || {};
|
|
||||||
const result = {
|
|
||||||
cwd: options.cwd || process.cwd(),
|
|
||||||
env: options.env || process.env,
|
|
||||||
silent: options.silent || false,
|
|
||||||
windowsVerbatimArguments: options.windowsVerbatimArguments || false,
|
|
||||||
failOnStdErr: options.failOnStdErr || false,
|
|
||||||
ignoreReturnCode: options.ignoreReturnCode || false,
|
|
||||||
delay: options.delay || 10000
|
|
||||||
};
|
|
||||||
result.outStream = options.outStream || process.stdout;
|
|
||||||
result.errStream = options.errStream || process.stderr;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
_getSpawnOptions(options, toolPath) {
|
|
||||||
options = options || {};
|
|
||||||
const result = {};
|
|
||||||
result.cwd = options.cwd;
|
|
||||||
result.env = options.env;
|
|
||||||
result['windowsVerbatimArguments'] =
|
|
||||||
options.windowsVerbatimArguments || this._isCmdFile();
|
|
||||||
if (options.windowsVerbatimArguments) {
|
|
||||||
result.argv0 = `"${toolPath}"`;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Exec a tool.
|
|
||||||
* Output will be streamed to the live console.
|
|
||||||
* Returns promise with return code
|
|
||||||
*
|
|
||||||
* @param tool path to tool to exec
|
|
||||||
* @param options optional exec options. See ExecOptions
|
|
||||||
* @returns number
|
|
||||||
*/
|
|
||||||
exec() {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
// root the tool path if it is unrooted and contains relative pathing
|
|
||||||
if (!ioUtil.isRooted(this.toolPath) &&
|
|
||||||
(this.toolPath.includes('/') ||
|
|
||||||
(IS_WINDOWS && this.toolPath.includes('\\')))) {
|
|
||||||
// prefer options.cwd if it is specified, however options.cwd may also need to be rooted
|
|
||||||
this.toolPath = path.resolve(process.cwd(), this.options.cwd || process.cwd(), this.toolPath);
|
|
||||||
}
|
|
||||||
// if the tool is only a file name, then resolve it from the PATH
|
|
||||||
// otherwise verify it exists (add extension on Windows if necessary)
|
|
||||||
this.toolPath = yield io.which(this.toolPath, true);
|
|
||||||
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
|
|
||||||
this._debug(`exec tool: ${this.toolPath}`);
|
|
||||||
this._debug('arguments:');
|
|
||||||
for (const arg of this.args) {
|
|
||||||
this._debug(` ${arg}`);
|
|
||||||
}
|
|
||||||
const optionsNonNull = this._cloneExecOptions(this.options);
|
|
||||||
if (!optionsNonNull.silent && optionsNonNull.outStream) {
|
|
||||||
optionsNonNull.outStream.write(this._getCommandString(optionsNonNull) + os.EOL);
|
|
||||||
}
|
|
||||||
const state = new ExecState(optionsNonNull, this.toolPath);
|
|
||||||
state.on('debug', (message) => {
|
|
||||||
this._debug(message);
|
|
||||||
});
|
|
||||||
if (this.options.cwd && !(yield ioUtil.exists(this.options.cwd))) {
|
|
||||||
return reject(new Error(`The cwd: ${this.options.cwd} does not exist!`));
|
|
||||||
}
|
|
||||||
const fileName = this._getSpawnFileName();
|
|
||||||
const cp = child.spawn(fileName, this._getSpawnArgs(optionsNonNull), this._getSpawnOptions(this.options, fileName));
|
|
||||||
let stdbuffer = '';
|
|
||||||
if (cp.stdout) {
|
|
||||||
cp.stdout.on('data', (data) => {
|
|
||||||
if (this.options.listeners && this.options.listeners.stdout) {
|
|
||||||
this.options.listeners.stdout(data);
|
|
||||||
}
|
|
||||||
if (!optionsNonNull.silent && optionsNonNull.outStream) {
|
|
||||||
optionsNonNull.outStream.write(data);
|
|
||||||
}
|
|
||||||
stdbuffer = this._processLineBuffer(data, stdbuffer, (line) => {
|
|
||||||
if (this.options.listeners && this.options.listeners.stdline) {
|
|
||||||
this.options.listeners.stdline(line);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
let errbuffer = '';
|
|
||||||
if (cp.stderr) {
|
|
||||||
cp.stderr.on('data', (data) => {
|
|
||||||
state.processStderr = true;
|
|
||||||
if (this.options.listeners && this.options.listeners.stderr) {
|
|
||||||
this.options.listeners.stderr(data);
|
|
||||||
}
|
|
||||||
if (!optionsNonNull.silent &&
|
|
||||||
optionsNonNull.errStream &&
|
|
||||||
optionsNonNull.outStream) {
|
|
||||||
const s = optionsNonNull.failOnStdErr
|
|
||||||
? optionsNonNull.errStream
|
|
||||||
: optionsNonNull.outStream;
|
|
||||||
s.write(data);
|
|
||||||
}
|
|
||||||
errbuffer = this._processLineBuffer(data, errbuffer, (line) => {
|
|
||||||
if (this.options.listeners && this.options.listeners.errline) {
|
|
||||||
this.options.listeners.errline(line);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
cp.on('error', (err) => {
|
|
||||||
state.processError = err.message;
|
|
||||||
state.processExited = true;
|
|
||||||
state.processClosed = true;
|
|
||||||
state.CheckComplete();
|
|
||||||
});
|
|
||||||
cp.on('exit', (code) => {
|
|
||||||
state.processExitCode = code;
|
|
||||||
state.processExited = true;
|
|
||||||
this._debug(`Exit code ${code} received from tool '${this.toolPath}'`);
|
|
||||||
state.CheckComplete();
|
|
||||||
});
|
|
||||||
cp.on('close', (code) => {
|
|
||||||
state.processExitCode = code;
|
|
||||||
state.processExited = true;
|
|
||||||
state.processClosed = true;
|
|
||||||
this._debug(`STDIO streams have closed for tool '${this.toolPath}'`);
|
|
||||||
state.CheckComplete();
|
|
||||||
});
|
|
||||||
state.on('done', (error, exitCode) => {
|
|
||||||
if (stdbuffer.length > 0) {
|
|
||||||
this.emit('stdline', stdbuffer);
|
|
||||||
}
|
|
||||||
if (errbuffer.length > 0) {
|
|
||||||
this.emit('errline', errbuffer);
|
|
||||||
}
|
|
||||||
cp.removeAllListeners();
|
|
||||||
if (error) {
|
|
||||||
reject(error);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
resolve(exitCode);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (this.options.input) {
|
|
||||||
if (!cp.stdin) {
|
|
||||||
throw new Error('child process missing stdin');
|
|
||||||
}
|
|
||||||
cp.stdin.end(this.options.input);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.ToolRunner = ToolRunner;
|
|
||||||
/**
|
|
||||||
* Convert an arg string to an array of args. Handles escaping
|
|
||||||
*
|
|
||||||
* @param argString string of arguments
|
|
||||||
* @returns string[] array of arguments
|
|
||||||
*/
|
|
||||||
function argStringToArray(argString) {
|
|
||||||
const args = [];
|
|
||||||
let inQuotes = false;
|
|
||||||
let escaped = false;
|
|
||||||
let arg = '';
|
|
||||||
function append(c) {
|
|
||||||
// we only escape double quotes.
|
|
||||||
if (escaped && c !== '"') {
|
|
||||||
arg += '\\';
|
|
||||||
}
|
|
||||||
arg += c;
|
|
||||||
escaped = false;
|
|
||||||
}
|
|
||||||
for (let i = 0; i < argString.length; i++) {
|
|
||||||
const c = argString.charAt(i);
|
|
||||||
if (c === '"') {
|
|
||||||
if (!escaped) {
|
|
||||||
inQuotes = !inQuotes;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
append(c);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (c === '\\' && escaped) {
|
|
||||||
append(c);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (c === '\\' && inQuotes) {
|
|
||||||
escaped = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (c === ' ' && !inQuotes) {
|
|
||||||
if (arg.length > 0) {
|
|
||||||
args.push(arg);
|
|
||||||
arg = '';
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
append(c);
|
|
||||||
}
|
|
||||||
if (arg.length > 0) {
|
|
||||||
args.push(arg.trim());
|
|
||||||
}
|
|
||||||
return args;
|
|
||||||
}
|
|
||||||
exports.argStringToArray = argStringToArray;
|
|
||||||
class ExecState extends events.EventEmitter {
|
|
||||||
constructor(options, toolPath) {
|
|
||||||
super();
|
|
||||||
this.processClosed = false; // tracks whether the process has exited and stdio is closed
|
|
||||||
this.processError = '';
|
|
||||||
this.processExitCode = 0;
|
|
||||||
this.processExited = false; // tracks whether the process has exited
|
|
||||||
this.processStderr = false; // tracks whether stderr was written to
|
|
||||||
this.delay = 10000; // 10 seconds
|
|
||||||
this.done = false;
|
|
||||||
this.timeout = null;
|
|
||||||
if (!toolPath) {
|
|
||||||
throw new Error('toolPath must not be empty');
|
|
||||||
}
|
|
||||||
this.options = options;
|
|
||||||
this.toolPath = toolPath;
|
|
||||||
if (options.delay) {
|
|
||||||
this.delay = options.delay;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CheckComplete() {
|
|
||||||
if (this.done) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (this.processClosed) {
|
|
||||||
this._setResult();
|
|
||||||
}
|
|
||||||
else if (this.processExited) {
|
|
||||||
this.timeout = timers_1.setTimeout(ExecState.HandleTimeout, this.delay, this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_debug(message) {
|
|
||||||
this.emit('debug', message);
|
|
||||||
}
|
|
||||||
_setResult() {
|
|
||||||
// determine whether there is an error
|
|
||||||
let error;
|
|
||||||
if (this.processExited) {
|
|
||||||
if (this.processError) {
|
|
||||||
error = new Error(`There was an error when attempting to execute the process '${this.toolPath}'. This may indicate the process failed to start. Error: ${this.processError}`);
|
|
||||||
}
|
|
||||||
else if (this.processExitCode !== 0 && !this.options.ignoreReturnCode) {
|
|
||||||
error = new Error(`The process '${this.toolPath}' failed with exit code ${this.processExitCode}`);
|
|
||||||
}
|
|
||||||
else if (this.processStderr && this.options.failOnStdErr) {
|
|
||||||
error = new Error(`The process '${this.toolPath}' failed because one or more lines were written to the STDERR stream`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// clear the timeout
|
|
||||||
if (this.timeout) {
|
|
||||||
clearTimeout(this.timeout);
|
|
||||||
this.timeout = null;
|
|
||||||
}
|
|
||||||
this.done = true;
|
|
||||||
this.emit('done', error, this.processExitCode);
|
|
||||||
}
|
|
||||||
static HandleTimeout(state) {
|
|
||||||
if (state.done) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!state.processClosed && state.processExited) {
|
|
||||||
const message = `The STDIO streams did not close within ${state.delay /
|
|
||||||
1000} seconds of the exit event from process '${state.toolPath}'. This may indicate a child process inherited the STDIO streams and has not yet exited.`;
|
|
||||||
state._debug(message);
|
|
||||||
}
|
|
||||||
state._setResult();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//# sourceMappingURL=toolrunner.js.map
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 31485:
|
|
||||||
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
||||||
}) : (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
o[k2] = m[k];
|
|
||||||
}));
|
|
||||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
||||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
||||||
}) : function(o, v) {
|
|
||||||
o["default"] = v;
|
|
||||||
});
|
|
||||||
var __importStar = (this && this.__importStar) || function (mod) {
|
|
||||||
if (mod && mod.__esModule) return mod;
|
|
||||||
var result = {};
|
|
||||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
||||||
__setModuleDefault(result, mod);
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
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 _a;
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.getCmdPath = exports.tryGetExecutablePath = exports.isRooted = exports.isDirectory = exports.exists = exports.READONLY = exports.UV_FS_O_EXLOCK = exports.IS_WINDOWS = exports.unlink = exports.symlink = exports.stat = exports.rmdir = exports.rm = exports.rename = exports.readlink = exports.readdir = exports.open = exports.mkdir = exports.lstat = exports.copyFile = exports.chmod = void 0;
|
|
||||||
const fs = __importStar(__nccwpck_require__(79896));
|
|
||||||
const path = __importStar(__nccwpck_require__(16928));
|
|
||||||
_a = fs.promises
|
|
||||||
// export const {open} = 'fs'
|
|
||||||
, exports.chmod = _a.chmod, exports.copyFile = _a.copyFile, exports.lstat = _a.lstat, exports.mkdir = _a.mkdir, exports.open = _a.open, exports.readdir = _a.readdir, exports.readlink = _a.readlink, exports.rename = _a.rename, exports.rm = _a.rm, exports.rmdir = _a.rmdir, exports.stat = _a.stat, exports.symlink = _a.symlink, exports.unlink = _a.unlink;
|
|
||||||
// export const {open} = 'fs'
|
|
||||||
exports.IS_WINDOWS = process.platform === 'win32';
|
|
||||||
// See https://github.com/nodejs/node/blob/d0153aee367422d0858105abec186da4dff0a0c5/deps/uv/include/uv/win.h#L691
|
|
||||||
exports.UV_FS_O_EXLOCK = 0x10000000;
|
|
||||||
exports.READONLY = fs.constants.O_RDONLY;
|
|
||||||
function exists(fsPath) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
try {
|
|
||||||
yield exports.stat(fsPath);
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
if (err.code === 'ENOENT') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.exists = exists;
|
|
||||||
function isDirectory(fsPath, useStat = false) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
const stats = useStat ? yield exports.stat(fsPath) : yield exports.lstat(fsPath);
|
|
||||||
return stats.isDirectory();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.isDirectory = isDirectory;
|
|
||||||
/**
|
|
||||||
* On OSX/Linux, true if path starts with '/'. On Windows, true for paths like:
|
|
||||||
* \, \hello, \\hello\share, C:, and C:\hello (and corresponding alternate separator cases).
|
|
||||||
*/
|
|
||||||
function isRooted(p) {
|
|
||||||
p = normalizeSeparators(p);
|
|
||||||
if (!p) {
|
|
||||||
throw new Error('isRooted() parameter "p" cannot be empty');
|
|
||||||
}
|
|
||||||
if (exports.IS_WINDOWS) {
|
|
||||||
return (p.startsWith('\\') || /^[A-Z]:/i.test(p) // e.g. \ or \hello or \\hello
|
|
||||||
); // e.g. C: or C:\hello
|
|
||||||
}
|
|
||||||
return p.startsWith('/');
|
|
||||||
}
|
|
||||||
exports.isRooted = isRooted;
|
|
||||||
/**
|
|
||||||
* Best effort attempt to determine whether a file exists and is executable.
|
|
||||||
* @param filePath file path to check
|
|
||||||
* @param extensions additional file extensions to try
|
|
||||||
* @return if file exists and is executable, returns the file path. otherwise empty string.
|
|
||||||
*/
|
|
||||||
function tryGetExecutablePath(filePath, extensions) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
let stats = undefined;
|
|
||||||
try {
|
|
||||||
// test file exists
|
|
||||||
stats = yield exports.stat(filePath);
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
if (err.code !== 'ENOENT') {
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.log(`Unexpected error attempting to determine if executable file exists '${filePath}': ${err}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (stats && stats.isFile()) {
|
|
||||||
if (exports.IS_WINDOWS) {
|
|
||||||
// on Windows, test for valid extension
|
|
||||||
const upperExt = path.extname(filePath).toUpperCase();
|
|
||||||
if (extensions.some(validExt => validExt.toUpperCase() === upperExt)) {
|
|
||||||
return filePath;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (isUnixExecutable(stats)) {
|
|
||||||
return filePath;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// try each extension
|
|
||||||
const originalFilePath = filePath;
|
|
||||||
for (const extension of extensions) {
|
|
||||||
filePath = originalFilePath + extension;
|
|
||||||
stats = undefined;
|
|
||||||
try {
|
|
||||||
stats = yield exports.stat(filePath);
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
if (err.code !== 'ENOENT') {
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.log(`Unexpected error attempting to determine if executable file exists '${filePath}': ${err}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (stats && stats.isFile()) {
|
|
||||||
if (exports.IS_WINDOWS) {
|
|
||||||
// preserve the case of the actual file (since an extension was appended)
|
|
||||||
try {
|
|
||||||
const directory = path.dirname(filePath);
|
|
||||||
const upperName = path.basename(filePath).toUpperCase();
|
|
||||||
for (const actualName of yield exports.readdir(directory)) {
|
|
||||||
if (upperName === actualName.toUpperCase()) {
|
|
||||||
filePath = path.join(directory, actualName);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.log(`Unexpected error attempting to determine the actual case of the file '${filePath}': ${err}`);
|
|
||||||
}
|
|
||||||
return filePath;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (isUnixExecutable(stats)) {
|
|
||||||
return filePath;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.tryGetExecutablePath = tryGetExecutablePath;
|
|
||||||
function normalizeSeparators(p) {
|
|
||||||
p = p || '';
|
|
||||||
if (exports.IS_WINDOWS) {
|
|
||||||
// convert slashes on Windows
|
|
||||||
p = p.replace(/\//g, '\\');
|
|
||||||
// remove redundant slashes
|
|
||||||
return p.replace(/\\\\+/g, '\\');
|
|
||||||
}
|
|
||||||
// remove redundant slashes
|
|
||||||
return p.replace(/\/\/+/g, '/');
|
|
||||||
}
|
|
||||||
// on Mac/Linux, test the execute bit
|
|
||||||
// R W X R W X R W X
|
|
||||||
// 256 128 64 32 16 8 4 2 1
|
|
||||||
function isUnixExecutable(stats) {
|
|
||||||
return ((stats.mode & 1) > 0 ||
|
|
||||||
((stats.mode & 8) > 0 && stats.gid === process.getgid()) ||
|
|
||||||
((stats.mode & 64) > 0 && stats.uid === process.getuid()));
|
|
||||||
}
|
|
||||||
// Get the path of cmd.exe in windows
|
|
||||||
function getCmdPath() {
|
|
||||||
var _a;
|
|
||||||
return (_a = process.env['COMSPEC']) !== null && _a !== void 0 ? _a : `cmd.exe`;
|
|
||||||
}
|
|
||||||
exports.getCmdPath = getCmdPath;
|
|
||||||
//# sourceMappingURL=io-util.js.map
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 42172:
|
|
||||||
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
||||||
}) : (function(o, m, k, k2) {
|
|
||||||
if (k2 === undefined) k2 = k;
|
|
||||||
o[k2] = m[k];
|
|
||||||
}));
|
|
||||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
||||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
||||||
}) : function(o, v) {
|
|
||||||
o["default"] = v;
|
|
||||||
});
|
|
||||||
var __importStar = (this && this.__importStar) || function (mod) {
|
|
||||||
if (mod && mod.__esModule) return mod;
|
|
||||||
var result = {};
|
|
||||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
||||||
__setModuleDefault(result, mod);
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
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());
|
|
||||||
});
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.findInPath = exports.which = exports.mkdirP = exports.rmRF = exports.mv = exports.cp = void 0;
|
|
||||||
const assert_1 = __nccwpck_require__(42613);
|
|
||||||
const path = __importStar(__nccwpck_require__(16928));
|
|
||||||
const ioUtil = __importStar(__nccwpck_require__(31485));
|
|
||||||
/**
|
|
||||||
* Copies a file or folder.
|
|
||||||
* Based off of shelljs - https://github.com/shelljs/shelljs/blob/9237f66c52e5daa40458f94f9565e18e8132f5a6/src/cp.js
|
|
||||||
*
|
|
||||||
* @param source source path
|
|
||||||
* @param dest destination path
|
|
||||||
* @param options optional. See CopyOptions.
|
|
||||||
*/
|
|
||||||
function cp(source, dest, options = {}) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
const { force, recursive, copySourceDirectory } = readCopyOptions(options);
|
|
||||||
const destStat = (yield ioUtil.exists(dest)) ? yield ioUtil.stat(dest) : null;
|
|
||||||
// Dest is an existing file, but not forcing
|
|
||||||
if (destStat && destStat.isFile() && !force) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// If dest is an existing directory, should copy inside.
|
|
||||||
const newDest = destStat && destStat.isDirectory() && copySourceDirectory
|
|
||||||
? path.join(dest, path.basename(source))
|
|
||||||
: dest;
|
|
||||||
if (!(yield ioUtil.exists(source))) {
|
|
||||||
throw new Error(`no such file or directory: ${source}`);
|
|
||||||
}
|
|
||||||
const sourceStat = yield ioUtil.stat(source);
|
|
||||||
if (sourceStat.isDirectory()) {
|
|
||||||
if (!recursive) {
|
|
||||||
throw new Error(`Failed to copy. ${source} is a directory, but tried to copy without recursive flag.`);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
yield cpDirRecursive(source, newDest, 0, force);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (path.relative(source, newDest) === '') {
|
|
||||||
// a file cannot be copied to itself
|
|
||||||
throw new Error(`'${newDest}' and '${source}' are the same file`);
|
|
||||||
}
|
|
||||||
yield copyFile(source, newDest, force);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.cp = cp;
|
|
||||||
/**
|
|
||||||
* Moves a path.
|
|
||||||
*
|
|
||||||
* @param source source path
|
|
||||||
* @param dest destination path
|
|
||||||
* @param options optional. See MoveOptions.
|
|
||||||
*/
|
|
||||||
function mv(source, dest, options = {}) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
if (yield ioUtil.exists(dest)) {
|
|
||||||
let destExists = true;
|
|
||||||
if (yield ioUtil.isDirectory(dest)) {
|
|
||||||
// If dest is directory copy src into dest
|
|
||||||
dest = path.join(dest, path.basename(source));
|
|
||||||
destExists = yield ioUtil.exists(dest);
|
|
||||||
}
|
|
||||||
if (destExists) {
|
|
||||||
if (options.force == null || options.force) {
|
|
||||||
yield rmRF(dest);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new Error('Destination already exists');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
yield mkdirP(path.dirname(dest));
|
|
||||||
yield ioUtil.rename(source, dest);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.mv = mv;
|
|
||||||
/**
|
|
||||||
* Remove a path recursively with force
|
|
||||||
*
|
|
||||||
* @param inputPath path to remove
|
|
||||||
*/
|
|
||||||
function rmRF(inputPath) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
if (ioUtil.IS_WINDOWS) {
|
|
||||||
// Check for invalid characters
|
|
||||||
// https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file
|
|
||||||
if (/[*"<>|]/.test(inputPath)) {
|
|
||||||
throw new Error('File path must not contain `*`, `"`, `<`, `>` or `|` on Windows');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
// note if path does not exist, error is silent
|
|
||||||
yield ioUtil.rm(inputPath, {
|
|
||||||
force: true,
|
|
||||||
maxRetries: 3,
|
|
||||||
recursive: true,
|
|
||||||
retryDelay: 300
|
|
||||||
});
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
throw new Error(`File was unable to be removed ${err}`);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.rmRF = rmRF;
|
|
||||||
/**
|
|
||||||
* Make a directory. Creates the full path with folders in between
|
|
||||||
* Will throw if it fails
|
|
||||||
*
|
|
||||||
* @param fsPath path to create
|
|
||||||
* @returns Promise<void>
|
|
||||||
*/
|
|
||||||
function mkdirP(fsPath) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
assert_1.ok(fsPath, 'a path argument must be provided');
|
|
||||||
yield ioUtil.mkdir(fsPath, { recursive: true });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.mkdirP = mkdirP;
|
|
||||||
/**
|
|
||||||
* Returns path of a tool had the tool actually been invoked. Resolves via paths.
|
|
||||||
* If you check and the tool does not exist, it will throw.
|
|
||||||
*
|
|
||||||
* @param tool name of the tool
|
|
||||||
* @param check whether to check if tool exists
|
|
||||||
* @returns Promise<string> path to tool
|
|
||||||
*/
|
|
||||||
function which(tool, check) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
if (!tool) {
|
|
||||||
throw new Error("parameter 'tool' is required");
|
|
||||||
}
|
|
||||||
// recursive when check=true
|
|
||||||
if (check) {
|
|
||||||
const result = yield which(tool, false);
|
|
||||||
if (!result) {
|
|
||||||
if (ioUtil.IS_WINDOWS) {
|
|
||||||
throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also verify the file has a valid extension for an executable file.`);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also check the file mode to verify the file is executable.`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
const matches = yield findInPath(tool);
|
|
||||||
if (matches && matches.length > 0) {
|
|
||||||
return matches[0];
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.which = which;
|
|
||||||
/**
|
|
||||||
* Returns a list of all occurrences of the given tool on the system path.
|
|
||||||
*
|
|
||||||
* @returns Promise<string[]> the paths of the tool
|
|
||||||
*/
|
|
||||||
function findInPath(tool) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
if (!tool) {
|
|
||||||
throw new Error("parameter 'tool' is required");
|
|
||||||
}
|
|
||||||
// build the list of extensions to try
|
|
||||||
const extensions = [];
|
|
||||||
if (ioUtil.IS_WINDOWS && process.env['PATHEXT']) {
|
|
||||||
for (const extension of process.env['PATHEXT'].split(path.delimiter)) {
|
|
||||||
if (extension) {
|
|
||||||
extensions.push(extension);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// if it's rooted, return it if exists. otherwise return empty.
|
|
||||||
if (ioUtil.isRooted(tool)) {
|
|
||||||
const filePath = yield ioUtil.tryGetExecutablePath(tool, extensions);
|
|
||||||
if (filePath) {
|
|
||||||
return [filePath];
|
|
||||||
}
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
// if any path separators, return empty
|
|
||||||
if (tool.includes(path.sep)) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
// build the list of directories
|
|
||||||
//
|
|
||||||
// Note, technically "where" checks the current directory on Windows. From a toolkit perspective,
|
|
||||||
// it feels like we should not do this. Checking the current directory seems like more of a use
|
|
||||||
// case of a shell, and the which() function exposed by the toolkit should strive for consistency
|
|
||||||
// across platforms.
|
|
||||||
const directories = [];
|
|
||||||
if (process.env.PATH) {
|
|
||||||
for (const p of process.env.PATH.split(path.delimiter)) {
|
|
||||||
if (p) {
|
|
||||||
directories.push(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// find all matches
|
|
||||||
const matches = [];
|
|
||||||
for (const directory of directories) {
|
|
||||||
const filePath = yield ioUtil.tryGetExecutablePath(path.join(directory, tool), extensions);
|
|
||||||
if (filePath) {
|
|
||||||
matches.push(filePath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return matches;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.findInPath = findInPath;
|
|
||||||
function readCopyOptions(options) {
|
|
||||||
const force = options.force == null ? true : options.force;
|
|
||||||
const recursive = Boolean(options.recursive);
|
|
||||||
const copySourceDirectory = options.copySourceDirectory == null
|
|
||||||
? true
|
|
||||||
: Boolean(options.copySourceDirectory);
|
|
||||||
return { force, recursive, copySourceDirectory };
|
|
||||||
}
|
|
||||||
function cpDirRecursive(sourceDir, destDir, currentDepth, force) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
// Ensure there is not a run away recursive copy
|
|
||||||
if (currentDepth >= 255)
|
|
||||||
return;
|
|
||||||
currentDepth++;
|
|
||||||
yield mkdirP(destDir);
|
|
||||||
const files = yield ioUtil.readdir(sourceDir);
|
|
||||||
for (const fileName of files) {
|
|
||||||
const srcFile = `${sourceDir}/${fileName}`;
|
|
||||||
const destFile = `${destDir}/${fileName}`;
|
|
||||||
const srcFileStat = yield ioUtil.lstat(srcFile);
|
|
||||||
if (srcFileStat.isDirectory()) {
|
|
||||||
// Recurse
|
|
||||||
yield cpDirRecursive(srcFile, destFile, currentDepth, force);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
yield copyFile(srcFile, destFile, force);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Change the mode for the newly created directory
|
|
||||||
yield ioUtil.chmod(destDir, (yield ioUtil.stat(sourceDir)).mode);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// Buffered file copy
|
|
||||||
function copyFile(srcFile, destFile, force) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
if ((yield ioUtil.lstat(srcFile)).isSymbolicLink()) {
|
|
||||||
// unlink/re-link it
|
|
||||||
try {
|
|
||||||
yield ioUtil.lstat(destFile);
|
|
||||||
yield ioUtil.unlink(destFile);
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
// Try to override file permission
|
|
||||||
if (e.code === 'EPERM') {
|
|
||||||
yield ioUtil.chmod(destFile, '0666');
|
|
||||||
yield ioUtil.unlink(destFile);
|
|
||||||
}
|
|
||||||
// other errors = it doesn't exist, no work to do
|
|
||||||
}
|
|
||||||
// Copy over symlink
|
|
||||||
const symlinkFull = yield ioUtil.readlink(srcFile);
|
|
||||||
yield ioUtil.symlink(symlinkFull, destFile, ioUtil.IS_WINDOWS ? 'junction' : null);
|
|
||||||
}
|
|
||||||
else if (!(yield ioUtil.exists(destFile)) || force) {
|
|
||||||
yield ioUtil.copyFile(srcFile, destFile);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
//# sourceMappingURL=io.js.map
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 32231:
|
/***/ 32231:
|
||||||
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue