Use core.setOutput to set output

df1bc16 · Jonathan Clem · 2020-08-05 14:52

4 files +737 -56

Files changed

modified dist/index.js
+1477 −796
@@ -19,13 +19,7 @@ module.exports =
19 19 /******/ };
20 20 /******/
21 21 /******/ // Execute the module function
22 −/******/ var threw = true;
23 −/******/ try {
24 −/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
25 −/******/ threw = false;
26 −/******/ } finally {
27 −/******/ if(threw) delete installedModules[moduleId];
28 −/******/ }
22 +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
29 23 /******/
30 24 /******/ // Flag the module as loaded
31 25 /******/ module.l = true;
@@ -53,578 +47,605 @@ module.exports =
53 47 /***/ (function(__unusedmodule, exports, __webpack_require__) {
54 48
55 49 "use strict";
56 −
57 −var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
58 − return new (P || (P = Promise))(function (resolve, reject) {
59 − function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
60 − function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
61 − function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
62 − step((generator = generator.apply(thisArg, _arguments || [])).next());
63 − });
64 −};
65 −Object.defineProperty(exports, "__esModule", { value: true });
66 −const os = __webpack_require__(87);
67 −const events = __webpack_require__(614);
68 −const child = __webpack_require__(129);
69 −/* eslint-disable @typescript-eslint/unbound-method */
70 −const IS_WINDOWS = process.platform === 'win32';
71 −/*
72 − * Class for running command line tools. Handles quoting and arg parsing in a platform agnostic way.
73 − */
74 −class ToolRunner extends events.EventEmitter {
75 − constructor(toolPath, args, options) {
76 − super();
77 − if (!toolPath) {
78 − throw new Error("Parameter 'toolPath' cannot be null or empty.");
79 − }
80 − this.toolPath = toolPath;
81 − this.args = args || [];
82 − this.options = options || {};
83 − }
84 − _debug(message) {
85 − if (this.options.listeners && this.options.listeners.debug) {
86 − this.options.listeners.debug(message);
87 − }
88 − }
89 − _getCommandString(options, noPrefix) {
90 − const toolPath = this._getSpawnFileName();
91 − const args = this._getSpawnArgs(options);
92 − let cmd = noPrefix ? '' : '[command]'; // omit prefix when piped to a second tool
93 − if (IS_WINDOWS) {
94 − // Windows + cmd file
95 − if (this._isCmdFile()) {
96 − cmd += toolPath;
97 − for (const a of args) {
98 − cmd += ` ${a}`;
99 − }
100 − }
101 − // Windows + verbatim
102 − else if (options.windowsVerbatimArguments) {
103 − cmd += `"${toolPath}"`;
104 − for (const a of args) {
105 − cmd += ` ${a}`;
106 − }
107 − }
108 − // Windows (regular)
109 − else {
110 − cmd += this._windowsQuoteCmdArg(toolPath);
111 − for (const a of args) {
112 − cmd += ` ${this._windowsQuoteCmdArg(a)}`;
113 − }
114 − }
115 − }
116 − else {
117 − // OSX/Linux - this can likely be improved with some form of quoting.
118 − // creating processes on Unix is fundamentally different than Windows.
119 − // on Unix, execvp() takes an arg array.
120 − cmd += toolPath;
121 − for (const a of args) {
122 − cmd += ` ${a}`;
123 − }
124 − }
125 − return cmd;
126 − }
127 − _processLineBuffer(data, strBuffer, onLine) {
128 − try {
129 − let s = strBuffer + data.toString();
130 − let n = s.indexOf(os.EOL);
131 − while (n > -1) {
132 − const line = s.substring(0, n);
133 − onLine(line);
134 − // the rest of the string ...
135 − s = s.substring(n + os.EOL.length);
136 − n = s.indexOf(os.EOL);
137 − }
138 − strBuffer = s;
139 − }
140 − catch (err) {
141 − // streaming lines to console is best effort. Don't fail a build.
142 − this._debug(`error processing line. Failed with error ${err}`);
143 − }
144 − }
145 − _getSpawnFileName() {
146 − if (IS_WINDOWS) {
147 − if (this._isCmdFile()) {
148 − return process.env['COMSPEC'] || 'cmd.exe';
149 − }
150 − }
151 − return this.toolPath;
152 − }
153 − _getSpawnArgs(options) {
154 − if (IS_WINDOWS) {
155 − if (this._isCmdFile()) {
156 − let argline = `/D /S /C "${this._windowsQuoteCmdArg(this.toolPath)}`;
157 − for (const a of this.args) {
158 − argline += ' ';
159 − argline += options.windowsVerbatimArguments
160 − ? a
161 − : this._windowsQuoteCmdArg(a);
162 − }
163 − argline += '"';
164 − return [argline];
165 − }
166 − }
167 − return this.args;
168 − }
169 − _endsWith(str, end) {
170 − return str.endsWith(end);
171 − }
172 − _isCmdFile() {
173 − const upperToolPath = this.toolPath.toUpperCase();
174 − return (this._endsWith(upperToolPath, '.CMD') ||
175 − this._endsWith(upperToolPath, '.BAT'));
176 − }
177 − _windowsQuoteCmdArg(arg) {
178 − // for .exe, apply the normal quoting rules that libuv applies
179 − if (!this._isCmdFile()) {
180 − return this._uvQuoteCmdArg(arg);
181 − }
182 − // otherwise apply quoting rules specific to the cmd.exe command line parser.
183 − // the libuv rules are generic and are not designed specifically for cmd.exe
184 − // command line parser.
185 − //
186 − // for a detailed description of the cmd.exe command line parser, refer to
187 − // http://stackoverflow.com/questions/4094699/how-does-the-windows-command-interpreter-cmd-exe-parse-scripts/7970912#7970912
188 − // need quotes for empty arg
189 − if (!arg) {
190 − return '""';
191 − }
192 − // determine whether the arg needs to be quoted
193 − const cmdSpecialChars = [
194 − ' ',
195 − '\t',
196 − '&',
197 − '(',
198 − ')',
199 − '[',
200 − ']',
201 − '{',
202 − '}',
203 − '^',
204 − '=',
205 − ';',
206 − '!',
207 − "'",
208 − '+',
209 − ',',
210 − '`',
211 − '~',
212 − '|',
213 − '<',
214 − '>',
215 − '"'
216 − ];
217 − let needsQuotes = false;
218 − for (const char of arg) {
219 − if (cmdSpecialChars.some(x => x === char)) {
220 − needsQuotes = true;
221 − break;
222 − }
223 − }
224 − // short-circuit if quotes not needed
225 − if (!needsQuotes) {
226 − return arg;
227 − }
228 − // the following quoting rules are very similar to the rules that by libuv applies.
229 − //
230 − // 1) wrap the string in quotes
231 − //
232 − // 2) double-up quotes - i.e. " => ""
233 − //
234 − // this is different from the libuv quoting rules. libuv replaces " with \", which unfortunately
235 − // doesn't work well with a cmd.exe command line.
236 − //
237 − // note, replacing " with "" also works well if the arg is passed to a downstream .NET console app.
238 − // for example, the command line:
239 − // foo.exe "myarg:""my val"""
240 − // is parsed by a .NET console app into an arg array:
241 − // [ "myarg:\"my val\"" ]
242 − // which is the same end result when applying libuv quoting rules. although the actual
243 − // command line from libuv quoting rules would look like:
244 − // foo.exe "myarg:\"my val\""
245 − //
246 − // 3) double-up slashes that preceed a quote,
247 − // e.g. hello \world => "hello \world"
248 − // hello\"world => "hello\\""world"
249 − // hello\\"world => "hello\\\\""world"
250 − // hello world\ => "hello world\\"
251 − //
252 − // technically this is not required for a cmd.exe command line, or the batch argument parser.
253 − // the reasons for including this as a .cmd quoting rule are:
254 − //
255 − // a) this is optimized for the scenario where the argument is passed from the .cmd file to an
256 − // external program. many programs (e.g. .NET console apps) rely on the slash-doubling rule.
257 − //
258 − // b) it's what we've been doing previously (by deferring to node default behavior) and we
259 − // haven't heard any complaints about that aspect.
260 − //
261 − // note, a weakness of the quoting rules chosen here, is that % is not escaped. in fact, % cannot be
262 − // escaped when used on the command line directly - even though within a .cmd file % can be escaped
263 − // by using %%.
264 − //
265 − // the saving grace is, on the command line, %var% is left as-is if var is not defined. this contrasts
266 − // the line parsing rules within a .cmd file, where if var is not defined it is replaced with nothing.
267 − //
268 − // one option that was explored was replacing % with ^% - i.e. %var% => ^%var^%. this hack would
269 − // often work, since it is unlikely that var^ would exist, and the ^ character is removed when the
270 − // variable is used. the problem, however, is that ^ is not removed when %* is used to pass the args
271 − // to an external program.
272 − //
273 − // an unexplored potential solution for the % escaping problem, is to create a wrapper .cmd file.
274 − // % can be escaped within a .cmd file.
275 − let reverse = '"';
276 − let quoteHit = true;
277 − for (let i = arg.length; i > 0; i--) {
278 − // walk the string in reverse
279 − reverse += arg[i - 1];
280 − if (quoteHit && arg[i - 1] === '\\') {
281 − reverse += '\\'; // double the slash
282 − }
283 − else if (arg[i - 1] === '"') {
284 − quoteHit = true;
285 − reverse += '"'; // double the quote
286 − }
287 − else {
288 − quoteHit = false;
289 − }
290 − }
291 − reverse += '"';
292 − return reverse
293 − .split('')
294 − .reverse()
295 − .join('');
296 − }
297 − _uvQuoteCmdArg(arg) {
298 − // Tool runner wraps child_process.spawn() and needs to apply the same quoting as
299 − // Node in certain cases where the undocumented spawn option windowsVerbatimArguments
300 − // is used.
301 − //
302 − // Since this function is a port of quote_cmd_arg from Node 4.x (technically, lib UV,
303 − // see https://github.com/nodejs/node/blob/v4.x/deps/uv/src/win/process.c for details),
304 − // pasting copyright notice from Node within this function:
305 − //
306 − // Copyright Joyent, Inc. and other Node contributors. All rights reserved.
307 − //
308 − // Permission is hereby granted, free of charge, to any person obtaining a copy
309 − // of this software and associated documentation files (the "Software"), to
310 − // deal in the Software without restriction, including without limitation the
311 − // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
312 − // sell copies of the Software, and to permit persons to whom the Software is
313 − // furnished to do so, subject to the following conditions:
314 − //
315 − // The above copyright notice and this permission notice shall be included in
316 − // all copies or substantial portions of the Software.
317 − //
318 − // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
319 − // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
320 − // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
321 − // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
322 − // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
323 − // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
324 − // IN THE SOFTWARE.
325 − if (!arg) {
326 − // Need double quotation for empty argument
327 − return '""';
328 − }
329 − if (!arg.includes(' ') && !arg.includes('\t') && !arg.includes('"')) {
330 − // No quotation needed
331 − return arg;
332 − }
333 − if (!arg.includes('"') && !arg.includes('\\')) {
334 − // No embedded double quotes or backslashes, so I can just wrap
335 − // quote marks around the whole thing.
336 − return `"${arg}"`;
337 − }
338 − // Expected input/output:
339 − // input : hello"world
340 − // output: "hello\"world"
341 − // input : hello""world
342 − // output: "hello\"\"world"
343 − // input : hello\world
344 − // output: hello\world
345 − // input : hello\\world
346 − // output: hello\\world
347 − // input : hello\"world
348 − // output: "hello\\\"world"
349 − // input : hello\\"world
350 − // output: "hello\\\\\"world"
351 − // input : hello world\
352 − // output: "hello world\\" - note the comment in libuv actually reads "hello world\"
353 − // but it appears the comment is wrong, it should be "hello world\\"
354 − let reverse = '"';
355 − let quoteHit = true;
356 − for (let i = arg.length; i > 0; i--) {
357 − // walk the string in reverse
358 − reverse += arg[i - 1];
359 − if (quoteHit && arg[i - 1] === '\\') {
360 − reverse += '\\';
361 − }
362 − else if (arg[i - 1] === '"') {
363 − quoteHit = true;
364 − reverse += '\\';
365 − }
366 − else {
367 − quoteHit = false;
368 − }
369 − }
370 − reverse += '"';
371 − return reverse
372 − .split('')
373 − .reverse()
374 − .join('');
375 − }
376 − _cloneExecOptions(options) {
377 − options = options || {};
378 − const result = {
379 − cwd: options.cwd || process.cwd(),
380 − env: options.env || process.env,
381 − silent: options.silent || false,
382 − windowsVerbatimArguments: options.windowsVerbatimArguments || false,
383 − failOnStdErr: options.failOnStdErr || false,
384 − ignoreReturnCode: options.ignoreReturnCode || false,
385 − delay: options.delay || 10000
386 − };
387 − result.outStream = options.outStream || process.stdout;
388 − result.errStream = options.errStream || process.stderr;
389 − return result;
390 − }
391 − _getSpawnOptions(options, toolPath) {
392 − options = options || {};
393 − const result = {};
394 − result.cwd = options.cwd;
395 − result.env = options.env;
396 − result['windowsVerbatimArguments'] =
397 − options.windowsVerbatimArguments || this._isCmdFile();
398 − if (options.windowsVerbatimArguments) {
399 − result.argv0 = `"${toolPath}"`;
400 − }
401 − return result;
402 − }
403 − /**
404 − * Exec a tool.
405 − * Output will be streamed to the live console.
406 − * Returns promise with return code
407 − *
408 − * @param tool path to tool to exec
409 − * @param options optional exec options. See ExecOptions
410 − * @returns number
411 − */
412 − exec() {
413 − return __awaiter(this, void 0, void 0, function* () {
414 − return new Promise((resolve, reject) => {
415 − this._debug(`exec tool: ${this.toolPath}`);
416 − this._debug('arguments:');
417 − for (const arg of this.args) {
418 − this._debug(` ${arg}`);
419 − }
420 − const optionsNonNull = this._cloneExecOptions(this.options);
421 − if (!optionsNonNull.silent && optionsNonNull.outStream) {
422 − optionsNonNull.outStream.write(this._getCommandString(optionsNonNull) + os.EOL);
423 − }
424 − const state = new ExecState(optionsNonNull, this.toolPath);
425 − state.on('debug', (message) => {
426 − this._debug(message);
427 − });
428 − const fileName = this._getSpawnFileName();
429 − const cp = child.spawn(fileName, this._getSpawnArgs(optionsNonNull), this._getSpawnOptions(this.options, fileName));
430 − const stdbuffer = '';
431 − if (cp.stdout) {
432 − cp.stdout.on('data', (data) => {
433 − if (this.options.listeners && this.options.listeners.stdout) {
434 − this.options.listeners.stdout(data);
435 − }
436 − if (!optionsNonNull.silent && optionsNonNull.outStream) {
437 − optionsNonNull.outStream.write(data);
438 − }
439 − this._processLineBuffer(data, stdbuffer, (line) => {
440 − if (this.options.listeners && this.options.listeners.stdline) {
441 − this.options.listeners.stdline(line);
442 − }
443 − });
444 − });
445 − }
446 − const errbuffer = '';
447 − if (cp.stderr) {
448 − cp.stderr.on('data', (data) => {
449 − state.processStderr = true;
450 − if (this.options.listeners && this.options.listeners.stderr) {
451 − this.options.listeners.stderr(data);
452 − }
453 − if (!optionsNonNull.silent &&
454 − optionsNonNull.errStream &&
455 − optionsNonNull.outStream) {
456 − const s = optionsNonNull.failOnStdErr
457 − ? optionsNonNull.errStream
458 − : optionsNonNull.outStream;
459 − s.write(data);
460 − }
461 − this._processLineBuffer(data, errbuffer, (line) => {
462 − if (this.options.listeners && this.options.listeners.errline) {
463 − this.options.listeners.errline(line);
464 − }
465 − });
466 − });
467 − }
468 − cp.on('error', (err) => {
469 − state.processError = err.message;
470 − state.processExited = true;
471 − state.processClosed = true;
472 − state.CheckComplete();
473 − });
474 − cp.on('exit', (code) => {
475 − state.processExitCode = code;
476 − state.processExited = true;
477 − this._debug(`Exit code ${code} received from tool '${this.toolPath}'`);
478 − state.CheckComplete();
479 − });
480 − cp.on('close', (code) => {
481 − state.processExitCode = code;
482 − state.processExited = true;
483 − state.processClosed = true;
484 − this._debug(`STDIO streams have closed for tool '${this.toolPath}'`);
485 − state.CheckComplete();
486 − });
487 − state.on('done', (error, exitCode) => {
488 − if (stdbuffer.length > 0) {
489 − this.emit('stdline', stdbuffer);
490 − }
491 − if (errbuffer.length > 0) {
492 − this.emit('errline', errbuffer);
493 − }
494 − cp.removeAllListeners();
495 − if (error) {
496 − reject(error);
497 − }
498 − else {
499 − resolve(exitCode);
500 − }
501 − });
502 − });
503 − });
504 − }
505 −}
506 −exports.ToolRunner = ToolRunner;
507 −/**
508 − * Convert an arg string to an array of args. Handles escaping
509 − *
510 − * @param argString string of arguments
511 − * @returns string[] array of arguments
512 − */
513 −function argStringToArray(argString) {
514 − const args = [];
515 − let inQuotes = false;
516 − let escaped = false;
517 − let arg = '';
518 − function append(c) {
519 − // we only escape double quotes.
520 − if (escaped && c !== '"') {
521 − arg += '\\';
522 − }
523 − arg += c;
524 − escaped = false;
525 − }
526 − for (let i = 0; i < argString.length; i++) {
527 − const c = argString.charAt(i);
528 − if (c === '"') {
529 − if (!escaped) {
530 − inQuotes = !inQuotes;
531 − }
532 − else {
533 − append(c);
534 − }
535 − continue;
536 − }
537 − if (c === '\\' && escaped) {
538 − append(c);
539 − continue;
540 − }
541 − if (c === '\\' && inQuotes) {
542 − escaped = true;
543 − continue;
544 − }
545 − if (c === ' ' && !inQuotes) {
546 − if (arg.length > 0) {
547 − args.push(arg);
548 − arg = '';
549 − }
550 − continue;
551 − }
552 − append(c);
553 − }
554 − if (arg.length > 0) {
555 − args.push(arg.trim());
556 − }
557 − return args;
558 −}
559 −exports.argStringToArray = argStringToArray;
560 −class ExecState extends events.EventEmitter {
561 − constructor(options, toolPath) {
562 − super();
563 − this.processClosed = false; // tracks whether the process has exited and stdio is closed
564 − this.processError = '';
565 − this.processExitCode = 0;
566 − this.processExited = false; // tracks whether the process has exited
567 − this.processStderr = false; // tracks whether stderr was written to
568 − this.delay = 10000; // 10 seconds
569 − this.done = false;
570 − this.timeout = null;
571 − if (!toolPath) {
572 − throw new Error('toolPath must not be empty');
573 − }
574 − this.options = options;
575 − this.toolPath = toolPath;
576 − if (options.delay) {
577 − this.delay = options.delay;
578 − }
579 − }
580 − CheckComplete() {
581 − if (this.done) {
582 − return;
583 − }
584 − if (this.processClosed) {
585 − this._setResult();
586 − }
587 − else if (this.processExited) {
588 − this.timeout = setTimeout(ExecState.HandleTimeout, this.delay, this);
589 − }
590 − }
591 − _debug(message) {
592 − this.emit('debug', message);
593 − }
594 − _setResult() {
595 − // determine whether there is an error
596 − let error;
597 − if (this.processExited) {
598 − if (this.processError) {
599 − 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}`);
600 − }
601 − else if (this.processExitCode !== 0 && !this.options.ignoreReturnCode) {
602 − error = new Error(`The process '${this.toolPath}' failed with exit code ${this.processExitCode}`);
603 − }
604 − else if (this.processStderr && this.options.failOnStdErr) {
605 − error = new Error(`The process '${this.toolPath}' failed because one or more lines were written to the STDERR stream`);
606 − }
607 − }
608 − // clear the timeout
609 − if (this.timeout) {
610 − clearTimeout(this.timeout);
611 − this.timeout = null;
612 − }
613 − this.done = true;
614 − this.emit('done', error, this.processExitCode);
615 − }
616 − static HandleTimeout(state) {
617 − if (state.done) {
618 − return;
619 − }
620 − if (!state.processClosed && state.processExited) {
621 − const message = `The STDIO streams did not close within ${state.delay /
622 − 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.`;
623 − state._debug(message);
624 − }
625 − state._setResult();
626 − }
627 −}
50 +
51 +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
52 + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
53 + return new (P || (P = Promise))(function (resolve, reject) {
54 + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
55 + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
56 + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
57 + step((generator = generator.apply(thisArg, _arguments || [])).next());
58 + });
59 +};
60 +var __importStar = (this && this.__importStar) || function (mod) {
61 + if (mod && mod.__esModule) return mod;
62 + var result = {};
63 + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
64 + result["default"] = mod;
65 + return result;
66 +};
67 +Object.defineProperty(exports, "__esModule", { value: true });
68 +const os = __importStar(__webpack_require__(87));
69 +const events = __importStar(__webpack_require__(614));
70 +const child = __importStar(__webpack_require__(129));
71 +const path = __importStar(__webpack_require__(622));
72 +const io = __importStar(__webpack_require__(194));
73 +const ioUtil = __importStar(__webpack_require__(408));
74 +/* eslint-disable @typescript-eslint/unbound-method */
75 +const IS_WINDOWS = process.platform === 'win32';
76 +/*
77 + * Class for running command line tools. Handles quoting and arg parsing in a platform agnostic way.
78 + */
79 +class ToolRunner extends events.EventEmitter {
80 + constructor(toolPath, args, options) {
81 + super();
82 + if (!toolPath) {
83 + throw new Error("Parameter 'toolPath' cannot be null or empty.");
84 + }
85 + this.toolPath = toolPath;
86 + this.args = args || [];
87 + this.options = options || {};
88 + }
89 + _debug(message) {
90 + if (this.options.listeners && this.options.listeners.debug) {
91 + this.options.listeners.debug(message);
92 + }
93 + }
94 + _getCommandString(options, noPrefix) {
95 + const toolPath = this._getSpawnFileName();
96 + const args = this._getSpawnArgs(options);
97 + let cmd = noPrefix ? '' : '[command]'; // omit prefix when piped to a second tool
98 + if (IS_WINDOWS) {
99 + // Windows + cmd file
100 + if (this._isCmdFile()) {
101 + cmd += toolPath;
102 + for (const a of args) {
103 + cmd += ` ${a}`;
104 + }
105 + }
106 + // Windows + verbatim
107 + else if (options.windowsVerbatimArguments) {
108 + cmd += `"${toolPath}"`;
109 + for (const a of args) {
110 + cmd += ` ${a}`;
111 + }
112 + }
113 + // Windows (regular)
114 + else {
115 + cmd += this._windowsQuoteCmdArg(toolPath);
116 + for (const a of args) {
117 + cmd += ` ${this._windowsQuoteCmdArg(a)}`;
118 + }
119 + }
120 + }
121 + else {
122 + // OSX/Linux - this can likely be improved with some form of quoting.
123 + // creating processes on Unix is fundamentally different than Windows.
124 + // on Unix, execvp() takes an arg array.
125 + cmd += toolPath;
126 + for (const a of args) {
127 + cmd += ` ${a}`;
128 + }
129 + }
130 + return cmd;
131 + }
132 + _processLineBuffer(data, strBuffer, onLine) {
133 + try {
134 + let s = strBuffer + data.toString();
135 + let n = s.indexOf(os.EOL);
136 + while (n > -1) {
137 + const line = s.substring(0, n);
138 + onLine(line);
139 + // the rest of the string ...
140 + s = s.substring(n + os.EOL.length);
141 + n = s.indexOf(os.EOL);
142 + }
143 + strBuffer = s;
144 + }
145 + catch (err) {
146 + // streaming lines to console is best effort. Don't fail a build.
147 + this._debug(`error processing line. Failed with error ${err}`);
148 + }
149 + }
150 + _getSpawnFileName() {
151 + if (IS_WINDOWS) {
152 + if (this._isCmdFile()) {
153 + return process.env['COMSPEC'] || 'cmd.exe';
154 + }
155 + }
156 + return this.toolPath;
157 + }
158 + _getSpawnArgs(options) {
159 + if (IS_WINDOWS) {
160 + if (this._isCmdFile()) {
161 + let argline = `/D /S /C "${this._windowsQuoteCmdArg(this.toolPath)}`;
162 + for (const a of this.args) {
163 + argline += ' ';
164 + argline += options.windowsVerbatimArguments
165 + ? a
166 + : this._windowsQuoteCmdArg(a);
167 + }
168 + argline += '"';
169 + return [argline];
170 + }
171 + }
172 + return this.args;
173 + }
174 + _endsWith(str, end) {
175 + return str.endsWith(end);
176 + }
177 + _isCmdFile() {
178 + const upperToolPath = this.toolPath.toUpperCase();
179 + return (this._endsWith(upperToolPath, '.CMD') ||
180 + this._endsWith(upperToolPath, '.BAT'));
181 + }
182 + _windowsQuoteCmdArg(arg) {
183 + // for .exe, apply the normal quoting rules that libuv applies
184 + if (!this._isCmdFile()) {
185 + return this._uvQuoteCmdArg(arg);
186 + }
187 + // otherwise apply quoting rules specific to the cmd.exe command line parser.
188 + // the libuv rules are generic and are not designed specifically for cmd.exe
189 + // command line parser.
190 + //
191 + // for a detailed description of the cmd.exe command line parser, refer to
192 + // http://stackoverflow.com/questions/4094699/how-does-the-windows-command-interpreter-cmd-exe-parse-scripts/7970912#7970912
193 + // need quotes for empty arg
194 + if (!arg) {
195 + return '""';
196 + }
197 + // determine whether the arg needs to be quoted
198 + const cmdSpecialChars = [
199 + ' ',
200 + '\t',
201 + '&',
202 + '(',
203 + ')',
204 + '[',
205 + ']',
206 + '{',
207 + '}',
208 + '^',
209 + '=',
210 + ';',
211 + '!',
212 + "'",
213 + '+',
214 + ',',
215 + '`',
216 + '~',
217 + '|',
218 + '<',
219 + '>',
220 + '"'
221 + ];
222 + let needsQuotes = false;
223 + for (const char of arg) {
224 + if (cmdSpecialChars.some(x => x === char)) {
225 + needsQuotes = true;
226 + break;
227 + }
228 + }
229 + // short-circuit if quotes not needed
230 + if (!needsQuotes) {
231 + return arg;
232 + }
233 + // the following quoting rules are very similar to the rules that by libuv applies.
234 + //
235 + // 1) wrap the string in quotes
236 + //
237 + // 2) double-up quotes - i.e. " => ""
238 + //
239 + // this is different from the libuv quoting rules. libuv replaces " with \", which unfortunately
240 + // doesn't work well with a cmd.exe command line.
241 + //
242 + // note, replacing " with "" also works well if the arg is passed to a downstream .NET console app.
243 + // for example, the command line:
244 + // foo.exe "myarg:""my val"""
245 + // is parsed by a .NET console app into an arg array:
246 + // [ "myarg:\"my val\"" ]
247 + // which is the same end result when applying libuv quoting rules. although the actual
248 + // command line from libuv quoting rules would look like:
249 + // foo.exe "myarg:\"my val\""
250 + //
251 + // 3) double-up slashes that precede a quote,
252 + // e.g. hello \world => "hello \world"
253 + // hello\"world => "hello\\""world"
254 + // hello\\"world => "hello\\\\""world"
255 + // hello world\ => "hello world\\"
256 + //
257 + // technically this is not required for a cmd.exe command line, or the batch argument parser.
258 + // the reasons for including this as a .cmd quoting rule are:
259 + //
260 + // a) this is optimized for the scenario where the argument is passed from the .cmd file to an
261 + // external program. many programs (e.g. .NET console apps) rely on the slash-doubling rule.
262 + //
263 + // b) it's what we've been doing previously (by deferring to node default behavior) and we
264 + // haven't heard any complaints about that aspect.
265 + //
266 + // note, a weakness of the quoting rules chosen here, is that % is not escaped. in fact, % cannot be
267 + // escaped when used on the command line directly - even though within a .cmd file % can be escaped
268 + // by using %%.
269 + //
270 + // the saving grace is, on the command line, %var% is left as-is if var is not defined. this contrasts
271 + // the line parsing rules within a .cmd file, where if var is not defined it is replaced with nothing.
272 + //
273 + // one option that was explored was replacing % with ^% - i.e. %var% => ^%var^%. this hack would
274 + // often work, since it is unlikely that var^ would exist, and the ^ character is removed when the
275 + // variable is used. the problem, however, is that ^ is not removed when %* is used to pass the args
276 + // to an external program.
277 + //
278 + // an unexplored potential solution for the % escaping problem, is to create a wrapper .cmd file.
279 + // % can be escaped within a .cmd file.
280 + let reverse = '"';
281 + let quoteHit = true;
282 + for (let i = arg.length; i > 0; i--) {
283 + // walk the string in reverse
284 + reverse += arg[i - 1];
285 + if (quoteHit && arg[i - 1] === '\\') {
286 + reverse += '\\'; // double the slash
287 + }
288 + else if (arg[i - 1] === '"') {
289 + quoteHit = true;
290 + reverse += '"'; // double the quote
291 + }
292 + else {
293 + quoteHit = false;
294 + }
295 + }
296 + reverse += '"';
297 + return reverse
298 + .split('')
299 + .reverse()
300 + .join('');
301 + }
302 + _uvQuoteCmdArg(arg) {
303 + // Tool runner wraps child_process.spawn() and needs to apply the same quoting as
304 + // Node in certain cases where the undocumented spawn option windowsVerbatimArguments
305 + // is used.
306 + //
307 + // Since this function is a port of quote_cmd_arg from Node 4.x (technically, lib UV,
308 + // see https://github.com/nodejs/node/blob/v4.x/deps/uv/src/win/process.c for details),
309 + // pasting copyright notice from Node within this function:
310 + //
311 + // Copyright Joyent, Inc. and other Node contributors. All rights reserved.
312 + //
313 + // Permission is hereby granted, free of charge, to any person obtaining a copy
314 + // of this software and associated documentation files (the "Software"), to
315 + // deal in the Software without restriction, including without limitation the
316 + // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
317 + // sell copies of the Software, and to permit persons to whom the Software is
318 + // furnished to do so, subject to the following conditions:
319 + //
320 + // The above copyright notice and this permission notice shall be included in
321 + // all copies or substantial portions of the Software.
322 + //
323 + // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
324 + // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
325 + // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
326 + // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
327 + // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
328 + // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
329 + // IN THE SOFTWARE.
330 + if (!arg) {
331 + // Need double quotation for empty argument
332 + return '""';
333 + }
334 + if (!arg.includes(' ') && !arg.includes('\t') && !arg.includes('"')) {
335 + // No quotation needed
336 + return arg;
337 + }
338 + if (!arg.includes('"') && !arg.includes('\\')) {
339 + // No embedded double quotes or backslashes, so I can just wrap
340 + // quote marks around the whole thing.
341 + return `"${arg}"`;
342 + }
343 + // Expected input/output:
344 + // input : hello"world
345 + // output: "hello\"world"
346 + // input : hello""world
347 + // output: "hello\"\"world"
348 + // input : hello\world
349 + // output: hello\world
350 + // input : hello\\world
351 + // output: hello\\world
352 + // input : hello\"world
353 + // output: "hello\\\"world"
354 + // input : hello\\"world
355 + // output: "hello\\\\\"world"
356 + // input : hello world\
357 + // output: "hello world\\" - note the comment in libuv actually reads "hello world\"
358 + // but it appears the comment is wrong, it should be "hello world\\"
359 + let reverse = '"';
360 + let quoteHit = true;
361 + for (let i = arg.length; i > 0; i--) {
362 + // walk the string in reverse
363 + reverse += arg[i - 1];
364 + if (quoteHit && arg[i - 1] === '\\') {
365 + reverse += '\\';
366 + }
367 + else if (arg[i - 1] === '"') {
368 + quoteHit = true;
369 + reverse += '\\';
370 + }
371 + else {
372 + quoteHit = false;
373 + }
374 + }
375 + reverse += '"';
376 + return reverse
377 + .split('')
378 + .reverse()
379 + .join('');
380 + }
381 + _cloneExecOptions(options) {
382 + options = options || {};
383 + const result = {
384 + cwd: options.cwd || process.cwd(),
385 + env: options.env || process.env,
386 + silent: options.silent || false,
387 + windowsVerbatimArguments: options.windowsVerbatimArguments || false,
388 + failOnStdErr: options.failOnStdErr || false,
389 + ignoreReturnCode: options.ignoreReturnCode || false,
390 + delay: options.delay || 10000
391 + };
392 + result.outStream = options.outStream || process.stdout;
393 + result.errStream = options.errStream || process.stderr;
394 + return result;
395 + }
396 + _getSpawnOptions(options, toolPath) {
397 + options = options || {};
398 + const result = {};
399 + result.cwd = options.cwd;
400 + result.env = options.env;
401 + result['windowsVerbatimArguments'] =
402 + options.windowsVerbatimArguments || this._isCmdFile();
403 + if (options.windowsVerbatimArguments) {
404 + result.argv0 = `"${toolPath}"`;
405 + }
406 + return result;
407 + }
408 + /**
409 + * Exec a tool.
410 + * Output will be streamed to the live console.
411 + * Returns promise with return code
412 + *
413 + * @param tool path to tool to exec
414 + * @param options optional exec options. See ExecOptions
415 + * @returns number
416 + */
417 + exec() {
418 + return __awaiter(this, void 0, void 0, function* () {
419 + // root the tool path if it is unrooted and contains relative pathing
420 + if (!ioUtil.isRooted(this.toolPath) &&
421 + (this.toolPath.includes('/') ||
422 + (IS_WINDOWS && this.toolPath.includes('\\')))) {
423 + // prefer options.cwd if it is specified, however options.cwd may also need to be rooted
424 + this.toolPath = path.resolve(process.cwd(), this.options.cwd || process.cwd(), this.toolPath);
425 + }
426 + // if the tool is only a file name, then resolve it from the PATH
427 + // otherwise verify it exists (add extension on Windows if necessary)
428 + this.toolPath = yield io.which(this.toolPath, true);
429 + return new Promise((resolve, reject) => {
430 + this._debug(`exec tool: ${this.toolPath}`);
431 + this._debug('arguments:');
432 + for (const arg of this.args) {
433 + this._debug(` ${arg}`);
434 + }
435 + const optionsNonNull = this._cloneExecOptions(this.options);
436 + if (!optionsNonNull.silent && optionsNonNull.outStream) {
437 + optionsNonNull.outStream.write(this._getCommandString(optionsNonNull) + os.EOL);
438 + }
439 + const state = new ExecState(optionsNonNull, this.toolPath);
440 + state.on('debug', (message) => {
441 + this._debug(message);
442 + });
443 + const fileName = this._getSpawnFileName();
444 + const cp = child.spawn(fileName, this._getSpawnArgs(optionsNonNull), this._getSpawnOptions(this.options, fileName));
445 + const stdbuffer = '';
446 + if (cp.stdout) {
447 + cp.stdout.on('data', (data) => {
448 + if (this.options.listeners && this.options.listeners.stdout) {
449 + this.options.listeners.stdout(data);
450 + }
451 + if (!optionsNonNull.silent && optionsNonNull.outStream) {
452 + optionsNonNull.outStream.write(data);
453 + }
454 + this._processLineBuffer(data, stdbuffer, (line) => {
455 + if (this.options.listeners && this.options.listeners.stdline) {
456 + this.options.listeners.stdline(line);
457 + }
458 + });
459 + });
460 + }
461 + const errbuffer = '';
462 + if (cp.stderr) {
463 + cp.stderr.on('data', (data) => {
464 + state.processStderr = true;
465 + if (this.options.listeners && this.options.listeners.stderr) {
466 + this.options.listeners.stderr(data);
467 + }
468 + if (!optionsNonNull.silent &&
469 + optionsNonNull.errStream &&
470 + optionsNonNull.outStream) {
471 + const s = optionsNonNull.failOnStdErr
472 + ? optionsNonNull.errStream
473 + : optionsNonNull.outStream;
474 + s.write(data);
475 + }
476 + this._processLineBuffer(data, errbuffer, (line) => {
477 + if (this.options.listeners && this.options.listeners.errline) {
478 + this.options.listeners.errline(line);
479 + }
480 + });
481 + });
482 + }
483 + cp.on('error', (err) => {
484 + state.processError = err.message;
485 + state.processExited = true;
486 + state.processClosed = true;
487 + state.CheckComplete();
488 + });
489 + cp.on('exit', (code) => {
490 + state.processExitCode = code;
491 + state.processExited = true;
492 + this._debug(`Exit code ${code} received from tool '${this.toolPath}'`);
493 + state.CheckComplete();
494 + });
495 + cp.on('close', (code) => {
496 + state.processExitCode = code;
497 + state.processExited = true;
498 + state.processClosed = true;
499 + this._debug(`STDIO streams have closed for tool '${this.toolPath}'`);
500 + state.CheckComplete();
501 + });
502 + state.on('done', (error, exitCode) => {
503 + if (stdbuffer.length > 0) {
504 + this.emit('stdline', stdbuffer);
505 + }
506 + if (errbuffer.length > 0) {
507 + this.emit('errline', errbuffer);
508 + }
509 + cp.removeAllListeners();
510 + if (error) {
511 + reject(error);
512 + }
513 + else {
514 + resolve(exitCode);
515 + }
516 + });
517 + if (this.options.input) {
518 + if (!cp.stdin) {
519 + throw new Error('child process missing stdin');
520 + }
521 + cp.stdin.end(this.options.input);
522 + }
523 + });
524 + });
525 + }
526 +}
527 +exports.ToolRunner = ToolRunner;
528 +/**
529 + * Convert an arg string to an array of args. Handles escaping
530 + *
531 + * @param argString string of arguments
532 + * @returns string[] array of arguments
533 + */
534 +function argStringToArray(argString) {
535 + const args = [];
536 + let inQuotes = false;
537 + let escaped = false;
538 + let arg = '';
539 + function append(c) {
540 + // we only escape double quotes.
541 + if (escaped && c !== '"') {
542 + arg += '\\';
543 + }
544 + arg += c;
545 + escaped = false;
546 + }
547 + for (let i = 0; i < argString.length; i++) {
548 + const c = argString.charAt(i);
549 + if (c === '"') {
550 + if (!escaped) {
551 + inQuotes = !inQuotes;
552 + }
553 + else {
554 + append(c);
555 + }
556 + continue;
557 + }
558 + if (c === '\\' && escaped) {
559 + append(c);
560 + continue;
561 + }
562 + if (c === '\\' && inQuotes) {
563 + escaped = true;
564 + continue;
565 + }
566 + if (c === ' ' && !inQuotes) {
567 + if (arg.length > 0) {
568 + args.push(arg);
569 + arg = '';
570 + }
571 + continue;
572 + }
573 + append(c);
574 + }
575 + if (arg.length > 0) {
576 + args.push(arg.trim());
577 + }
578 + return args;
579 +}
580 +exports.argStringToArray = argStringToArray;
581 +class ExecState extends events.EventEmitter {
582 + constructor(options, toolPath) {
583 + super();
584 + this.processClosed = false; // tracks whether the process has exited and stdio is closed
585 + this.processError = '';
586 + this.processExitCode = 0;
587 + this.processExited = false; // tracks whether the process has exited
588 + this.processStderr = false; // tracks whether stderr was written to
589 + this.delay = 10000; // 10 seconds
590 + this.done = false;
591 + this.timeout = null;
592 + if (!toolPath) {
593 + throw new Error('toolPath must not be empty');
594 + }
595 + this.options = options;
596 + this.toolPath = toolPath;
597 + if (options.delay) {
598 + this.delay = options.delay;
599 + }
600 + }
601 + CheckComplete() {
602 + if (this.done) {
603 + return;
604 + }
605 + if (this.processClosed) {
606 + this._setResult();
607 + }
608 + else if (this.processExited) {
609 + this.timeout = setTimeout(ExecState.HandleTimeout, this.delay, this);
610 + }
611 + }
612 + _debug(message) {
613 + this.emit('debug', message);
614 + }
615 + _setResult() {
616 + // determine whether there is an error
617 + let error;
618 + if (this.processExited) {
619 + if (this.processError) {
620 + 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}`);
621 + }
622 + else if (this.processExitCode !== 0 && !this.options.ignoreReturnCode) {
623 + error = new Error(`The process '${this.toolPath}' failed with exit code ${this.processExitCode}`);
624 + }
625 + else if (this.processStderr && this.options.failOnStdErr) {
626 + error = new Error(`The process '${this.toolPath}' failed because one or more lines were written to the STDERR stream`);
627 + }
628 + }
629 + // clear the timeout
630 + if (this.timeout) {
631 + clearTimeout(this.timeout);
632 + this.timeout = null;
633 + }
634 + this.done = true;
635 + this.emit('done', error, this.processExitCode);
636 + }
637 + static HandleTimeout(state) {
638 + if (state.done) {
639 + return;
640 + }
641 + if (!state.processClosed && state.processExited) {
642 + const message = `The STDIO streams did not close within ${state.delay /
643 + 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.`;
644 + state._debug(message);
645 + }
646 + state._setResult();
647 + }
648 +}
628 649 //# sourceMappingURL=toolrunner.js.map
629 650
630 651 /***/ }),
@@ -643,6 +664,303 @@ module.exports = require("child_process");
643 664
644 665 /***/ }),
645 666
667 +/***/ 194:
668 +/***/ (function(__unusedmodule, exports, __webpack_require__) {
669 +
670 +"use strict";
671 +
672 +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
673 + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
674 + return new (P || (P = Promise))(function (resolve, reject) {
675 + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
676 + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
677 + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
678 + step((generator = generator.apply(thisArg, _arguments || [])).next());
679 + });
680 +};
681 +Object.defineProperty(exports, "__esModule", { value: true });
682 +const childProcess = __webpack_require__(129);
683 +const path = __webpack_require__(622);
684 +const util_1 = __webpack_require__(669);
685 +const ioUtil = __webpack_require__(408);
686 +const exec = util_1.promisify(childProcess.exec);
687 +/**
688 + * Copies a file or folder.
689 + * Based off of shelljs - https://github.com/shelljs/shelljs/blob/9237f66c52e5daa40458f94f9565e18e8132f5a6/src/cp.js
690 + *
691 + * @param source source path
692 + * @param dest destination path
693 + * @param options optional. See CopyOptions.
694 + */
695 +function cp(source, dest, options = {}) {
696 + return __awaiter(this, void 0, void 0, function* () {
697 + const { force, recursive } = readCopyOptions(options);
698 + const destStat = (yield ioUtil.exists(dest)) ? yield ioUtil.stat(dest) : null;
699 + // Dest is an existing file, but not forcing
700 + if (destStat && destStat.isFile() && !force) {
701 + return;
702 + }
703 + // If dest is an existing directory, should copy inside.
704 + const newDest = destStat && destStat.isDirectory()
705 + ? path.join(dest, path.basename(source))
706 + : dest;
707 + if (!(yield ioUtil.exists(source))) {
708 + throw new Error(`no such file or directory: ${source}`);
709 + }
710 + const sourceStat = yield ioUtil.stat(source);
711 + if (sourceStat.isDirectory()) {
712 + if (!recursive) {
713 + throw new Error(`Failed to copy. ${source} is a directory, but tried to copy without recursive flag.`);
714 + }
715 + else {
716 + yield cpDirRecursive(source, newDest, 0, force);
717 + }
718 + }
719 + else {
720 + if (path.relative(source, newDest) === '') {
721 + // a file cannot be copied to itself
722 + throw new Error(`'${newDest}' and '${source}' are the same file`);
723 + }
724 + yield copyFile(source, newDest, force);
725 + }
726 + });
727 +}
728 +exports.cp = cp;
729 +/**
730 + * Moves a path.
731 + *
732 + * @param source source path
733 + * @param dest destination path
734 + * @param options optional. See MoveOptions.
735 + */
736 +function mv(source, dest, options = {}) {
737 + return __awaiter(this, void 0, void 0, function* () {
738 + if (yield ioUtil.exists(dest)) {
739 + let destExists = true;
740 + if (yield ioUtil.isDirectory(dest)) {
741 + // If dest is directory copy src into dest
742 + dest = path.join(dest, path.basename(source));
743 + destExists = yield ioUtil.exists(dest);
744 + }
745 + if (destExists) {
746 + if (options.force == null || options.force) {
747 + yield rmRF(dest);
748 + }
749 + else {
750 + throw new Error('Destination already exists');
751 + }
752 + }
753 + }
754 + yield mkdirP(path.dirname(dest));
755 + yield ioUtil.rename(source, dest);
756 + });
757 +}
758 +exports.mv = mv;
759 +/**
760 + * Remove a path recursively with force
761 + *
762 + * @param inputPath path to remove
763 + */
764 +function rmRF(inputPath) {
765 + return __awaiter(this, void 0, void 0, function* () {
766 + if (ioUtil.IS_WINDOWS) {
767 + // Node doesn't provide a delete operation, only an unlink function. This means that if the file is being used by another
768 + // program (e.g. antivirus), it won't be deleted. To address this, we shell out the work to rd/del.
769 + try {
770 + if (yield ioUtil.isDirectory(inputPath, true)) {
771 + yield exec(`rd /s /q "${inputPath}"`);
772 + }
773 + else {
774 + yield exec(`del /f /a "${inputPath}"`);
775 + }
776 + }
777 + catch (err) {
778 + // if you try to delete a file that doesn't exist, desired result is achieved
779 + // other errors are valid
780 + if (err.code !== 'ENOENT')
781 + throw err;
782 + }
783 + // Shelling out fails to remove a symlink folder with missing source, this unlink catches that
784 + try {
785 + yield ioUtil.unlink(inputPath);
786 + }
787 + catch (err) {
788 + // if you try to delete a file that doesn't exist, desired result is achieved
789 + // other errors are valid
790 + if (err.code !== 'ENOENT')
791 + throw err;
792 + }
793 + }
794 + else {
795 + let isDir = false;
796 + try {
797 + isDir = yield ioUtil.isDirectory(inputPath);
798 + }
799 + catch (err) {
800 + // if you try to delete a file that doesn't exist, desired result is achieved
801 + // other errors are valid
802 + if (err.code !== 'ENOENT')
803 + throw err;
804 + return;
805 + }
806 + if (isDir) {
807 + yield exec(`rm -rf "${inputPath}"`);
808 + }
809 + else {
810 + yield ioUtil.unlink(inputPath);
811 + }
812 + }
813 + });
814 +}
815 +exports.rmRF = rmRF;
816 +/**
817 + * Make a directory. Creates the full path with folders in between
818 + * Will throw if it fails
819 + *
820 + * @param fsPath path to create
821 + * @returns Promise<void>
822 + */
823 +function mkdirP(fsPath) {
824 + return __awaiter(this, void 0, void 0, function* () {
825 + yield ioUtil.mkdirP(fsPath);
826 + });
827 +}
828 +exports.mkdirP = mkdirP;
829 +/**
830 + * Returns path of a tool had the tool actually been invoked. Resolves via paths.
831 + * If you check and the tool does not exist, it will throw.
832 + *
833 + * @param tool name of the tool
834 + * @param check whether to check if tool exists
835 + * @returns Promise<string> path to tool
836 + */
837 +function which(tool, check) {
838 + return __awaiter(this, void 0, void 0, function* () {
839 + if (!tool) {
840 + throw new Error("parameter 'tool' is required");
841 + }
842 + // recursive when check=true
843 + if (check) {
844 + const result = yield which(tool, false);
845 + if (!result) {
846 + if (ioUtil.IS_WINDOWS) {
847 + 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.`);
848 + }
849 + else {
850 + 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.`);
851 + }
852 + }
853 + }
854 + try {
855 + // build the list of extensions to try
856 + const extensions = [];
857 + if (ioUtil.IS_WINDOWS && process.env.PATHEXT) {
858 + for (const extension of process.env.PATHEXT.split(path.delimiter)) {
859 + if (extension) {
860 + extensions.push(extension);
861 + }
862 + }
863 + }
864 + // if it's rooted, return it if exists. otherwise return empty.
865 + if (ioUtil.isRooted(tool)) {
866 + const filePath = yield ioUtil.tryGetExecutablePath(tool, extensions);
867 + if (filePath) {
868 + return filePath;
869 + }
870 + return '';
871 + }
872 + // if any path separators, return empty
873 + if (tool.includes('/') || (ioUtil.IS_WINDOWS && tool.includes('\\'))) {
874 + return '';
875 + }
876 + // build the list of directories
877 + //
878 + // Note, technically "where" checks the current directory on Windows. From a toolkit perspective,
879 + // it feels like we should not do this. Checking the current directory seems like more of a use
880 + // case of a shell, and the which() function exposed by the toolkit should strive for consistency
881 + // across platforms.
882 + const directories = [];
883 + if (process.env.PATH) {
884 + for (const p of process.env.PATH.split(path.delimiter)) {
885 + if (p) {
886 + directories.push(p);
887 + }
888 + }
889 + }
890 + // return the first match
891 + for (const directory of directories) {
892 + const filePath = yield ioUtil.tryGetExecutablePath(directory + path.sep + tool, extensions);
893 + if (filePath) {
894 + return filePath;
895 + }
896 + }
897 + return '';
898 + }
899 + catch (err) {
900 + throw new Error(`which failed with message ${err.message}`);
901 + }
902 + });
903 +}
904 +exports.which = which;
905 +function readCopyOptions(options) {
906 + const force = options.force == null ? true : options.force;
907 + const recursive = Boolean(options.recursive);
908 + return { force, recursive };
909 +}
910 +function cpDirRecursive(sourceDir, destDir, currentDepth, force) {
911 + return __awaiter(this, void 0, void 0, function* () {
912 + // Ensure there is not a run away recursive copy
913 + if (currentDepth >= 255)
914 + return;
915 + currentDepth++;
916 + yield mkdirP(destDir);
917 + const files = yield ioUtil.readdir(sourceDir);
918 + for (const fileName of files) {
919 + const srcFile = `${sourceDir}/${fileName}`;
920 + const destFile = `${destDir}/${fileName}`;
921 + const srcFileStat = yield ioUtil.lstat(srcFile);
922 + if (srcFileStat.isDirectory()) {
923 + // Recurse
924 + yield cpDirRecursive(srcFile, destFile, currentDepth, force);
925 + }
926 + else {
927 + yield copyFile(srcFile, destFile, force);
928 + }
929 + }
930 + // Change the mode for the newly created directory
931 + yield ioUtil.chmod(destDir, (yield ioUtil.stat(sourceDir)).mode);
932 + });
933 +}
934 +// Buffered file copy
935 +function copyFile(srcFile, destFile, force) {
936 + return __awaiter(this, void 0, void 0, function* () {
937 + if ((yield ioUtil.lstat(srcFile)).isSymbolicLink()) {
938 + // unlink/re-link it
939 + try {
940 + yield ioUtil.lstat(destFile);
941 + yield ioUtil.unlink(destFile);
942 + }
943 + catch (e) {
944 + // Try to override file permission
945 + if (e.code === 'EPERM') {
946 + yield ioUtil.chmod(destFile, '0666');
947 + yield ioUtil.unlink(destFile);
948 + }
949 + // other errors = it doesn't exist, no work to do
950 + }
951 + // Copy over symlink
952 + const symlinkFull = yield ioUtil.readlink(srcFile);
953 + yield ioUtil.symlink(symlinkFull, destFile, ioUtil.IS_WINDOWS ? 'junction' : null);
954 + }
955 + else if (!(yield ioUtil.exists(destFile)) || force) {
956 + yield ioUtil.copyFile(srcFile, destFile);
957 + }
958 + });
959 +}
960 +//# sourceMappingURL=io.js.map
961 +
962 +/***/ }),
963 +
646 964 /***/ 211:
647 965 /***/ (function(module) {
648 966
@@ -2251,77 +2569,312 @@ function coerce (version, options) {
2251 2569 }
2252 2570
2253 2571
2572 +/***/ }),
2573 +
2574 +/***/ 357:
2575 +/***/ (function(module) {
2576 +
2577 +module.exports = require("assert");
2578 +
2579 +/***/ }),
2580 +
2581 +/***/ 408:
2582 +/***/ (function(__unusedmodule, exports, __webpack_require__) {
2583 +
2584 +"use strict";
2585 +
2586 +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2587 + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
2588 + return new (P || (P = Promise))(function (resolve, reject) {
2589 + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
2590 + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
2591 + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
2592 + step((generator = generator.apply(thisArg, _arguments || [])).next());
2593 + });
2594 +};
2595 +var _a;
2596 +Object.defineProperty(exports, "__esModule", { value: true });
2597 +const assert_1 = __webpack_require__(357);
2598 +const fs = __webpack_require__(747);
2599 +const path = __webpack_require__(622);
2600 +_a = fs.promises, exports.chmod = _a.chmod, exports.copyFile = _a.copyFile, exports.lstat = _a.lstat, exports.mkdir = _a.mkdir, exports.readdir = _a.readdir, exports.readlink = _a.readlink, exports.rename = _a.rename, exports.rmdir = _a.rmdir, exports.stat = _a.stat, exports.symlink = _a.symlink, exports.unlink = _a.unlink;
2601 +exports.IS_WINDOWS = process.platform === 'win32';
2602 +function exists(fsPath) {
2603 + return __awaiter(this, void 0, void 0, function* () {
2604 + try {
2605 + yield exports.stat(fsPath);
2606 + }
2607 + catch (err) {
2608 + if (err.code === 'ENOENT') {
2609 + return false;
2610 + }
2611 + throw err;
2612 + }
2613 + return true;
2614 + });
2615 +}
2616 +exports.exists = exists;
2617 +function isDirectory(fsPath, useStat = false) {
2618 + return __awaiter(this, void 0, void 0, function* () {
2619 + const stats = useStat ? yield exports.stat(fsPath) : yield exports.lstat(fsPath);
2620 + return stats.isDirectory();
2621 + });
2622 +}
2623 +exports.isDirectory = isDirectory;
2624 +/**
2625 + * On OSX/Linux, true if path starts with '/'. On Windows, true for paths like:
2626 + * \, \hello, \\hello\share, C:, and C:\hello (and corresponding alternate separator cases).
2627 + */
2628 +function isRooted(p) {
2629 + p = normalizeSeparators(p);
2630 + if (!p) {
2631 + throw new Error('isRooted() parameter "p" cannot be empty');
2632 + }
2633 + if (exports.IS_WINDOWS) {
2634 + return (p.startsWith('\\') || /^[A-Z]:/i.test(p) // e.g. \ or \hello or \\hello
2635 + ); // e.g. C: or C:\hello
2636 + }
2637 + return p.startsWith('/');
2638 +}
2639 +exports.isRooted = isRooted;
2640 +/**
2641 + * Recursively create a directory at `fsPath`.
2642 + *
2643 + * This implementation is optimistic, meaning it attempts to create the full
2644 + * path first, and backs up the path stack from there.
2645 + *
2646 + * @param fsPath The path to create
2647 + * @param maxDepth The maximum recursion depth
2648 + * @param depth The current recursion depth
2649 + */
2650 +function mkdirP(fsPath, maxDepth = 1000, depth = 1) {
2651 + return __awaiter(this, void 0, void 0, function* () {
2652 + assert_1.ok(fsPath, 'a path argument must be provided');
2653 + fsPath = path.resolve(fsPath);
2654 + if (depth >= maxDepth)
2655 + return exports.mkdir(fsPath);
2656 + try {
2657 + yield exports.mkdir(fsPath);
2658 + return;
2659 + }
2660 + catch (err) {
2661 + switch (err.code) {
2662 + case 'ENOENT': {
2663 + yield mkdirP(path.dirname(fsPath), maxDepth, depth + 1);
2664 + yield exports.mkdir(fsPath);
2665 + return;
2666 + }
2667 + default: {
2668 + let stats;
2669 + try {
2670 + stats = yield exports.stat(fsPath);
2671 + }
2672 + catch (err2) {
2673 + throw err;
2674 + }
2675 + if (!stats.isDirectory())
2676 + throw err;
2677 + }
2678 + }
2679 + }
2680 + });
2681 +}
2682 +exports.mkdirP = mkdirP;
2683 +/**
2684 + * Best effort attempt to determine whether a file exists and is executable.
2685 + * @param filePath file path to check
2686 + * @param extensions additional file extensions to try
2687 + * @return if file exists and is executable, returns the file path. otherwise empty string.
2688 + */
2689 +function tryGetExecutablePath(filePath, extensions) {
2690 + return __awaiter(this, void 0, void 0, function* () {
2691 + let stats = undefined;
2692 + try {
2693 + // test file exists
2694 + stats = yield exports.stat(filePath);
2695 + }
2696 + catch (err) {
2697 + if (err.code !== 'ENOENT') {
2698 + // eslint-disable-next-line no-console
2699 + console.log(`Unexpected error attempting to determine if executable file exists '${filePath}': ${err}`);
2700 + }
2701 + }
2702 + if (stats && stats.isFile()) {
2703 + if (exports.IS_WINDOWS) {
2704 + // on Windows, test for valid extension
2705 + const upperExt = path.extname(filePath).toUpperCase();
2706 + if (extensions.some(validExt => validExt.toUpperCase() === upperExt)) {
2707 + return filePath;
2708 + }
2709 + }
2710 + else {
2711 + if (isUnixExecutable(stats)) {
2712 + return filePath;
2713 + }
2714 + }
2715 + }
2716 + // try each extension
2717 + const originalFilePath = filePath;
2718 + for (const extension of extensions) {
2719 + filePath = originalFilePath + extension;
2720 + stats = undefined;
2721 + try {
2722 + stats = yield exports.stat(filePath);
2723 + }
2724 + catch (err) {
2725 + if (err.code !== 'ENOENT') {
2726 + // eslint-disable-next-line no-console
2727 + console.log(`Unexpected error attempting to determine if executable file exists '${filePath}': ${err}`);
2728 + }
2729 + }
2730 + if (stats && stats.isFile()) {
2731 + if (exports.IS_WINDOWS) {
2732 + // preserve the case of the actual file (since an extension was appended)
2733 + try {
2734 + const directory = path.dirname(filePath);
2735 + const upperName = path.basename(filePath).toUpperCase();
2736 + for (const actualName of yield exports.readdir(directory)) {
2737 + if (upperName === actualName.toUpperCase()) {
2738 + filePath = path.join(directory, actualName);
2739 + break;
2740 + }
2741 + }
2742 + }
2743 + catch (err) {
2744 + // eslint-disable-next-line no-console
2745 + console.log(`Unexpected error attempting to determine the actual case of the file '${filePath}': ${err}`);
2746 + }
2747 + return filePath;
2748 + }
2749 + else {
2750 + if (isUnixExecutable(stats)) {
2751 + return filePath;
2752 + }
2753 + }
2754 + }
2755 + }
2756 + return '';
2757 + });
2758 +}
2759 +exports.tryGetExecutablePath = tryGetExecutablePath;
2760 +function normalizeSeparators(p) {
2761 + p = p || '';
2762 + if (exports.IS_WINDOWS) {
2763 + // convert slashes on Windows
2764 + p = p.replace(/\//g, '\\');
2765 + // remove redundant slashes
2766 + return p.replace(/\\\\+/g, '\\');
2767 + }
2768 + // remove redundant slashes
2769 + return p.replace(/\/\/+/g, '/');
2770 +}
2771 +// on Mac/Linux, test the execute bit
2772 +// R W X R W X R W X
2773 +// 256 128 64 32 16 8 4 2 1
2774 +function isUnixExecutable(stats) {
2775 + return ((stats.mode & 1) > 0 ||
2776 + ((stats.mode & 8) > 0 && stats.gid === process.getgid()) ||
2777 + ((stats.mode & 64) > 0 && stats.uid === process.getuid()));
2778 +}
2779 +//# sourceMappingURL=io-util.js.map
2780 +
2254 2781 /***/ }),
2255 2782
2256 2783 /***/ 431:
2257 2784 /***/ (function(__unusedmodule, exports, __webpack_require__) {
2258 2785
2259 2786 "use strict";
2260 −
2261 −Object.defineProperty(exports, "__esModule", { value: true });
2262 −const os = __webpack_require__(87);
2263 −/**
2264 − * Commands
2265 − *
2266 − * Command Format:
2267 − * ##[name key=value;key=value]message
2268 − *
2269 − * Examples:
2270 − * ##[warning]This is the user warning message
2271 − * ##[set-secret name=mypassword]definatelyNotAPassword!
2272 − */
2273 −function issueCommand(command, properties, message) {
2274 − const cmd = new Command(command, properties, message);
2275 − process.stdout.write(cmd.toString() + os.EOL);
2276 −}
2277 −exports.issueCommand = issueCommand;
2278 −function issue(name, message) {
2279 − issueCommand(name, {}, message);
2280 −}
2281 −exports.issue = issue;
2282 −const CMD_PREFIX = '##[';
2283 −class Command {
2284 − constructor(command, properties, message) {
2285 − if (!command) {
2286 − command = 'missing.command';
2287 − }
2288 − this.command = command;
2289 − this.properties = properties;
2290 − this.message = message;
2291 − }
2292 − toString() {
2293 − let cmdStr = CMD_PREFIX + this.command;
2294 − if (this.properties && Object.keys(this.properties).length > 0) {
2295 − cmdStr += ' ';
2296 − for (const key in this.properties) {
2297 − if (this.properties.hasOwnProperty(key)) {
2298 − const val = this.properties[key];
2299 − if (val) {
2300 − // safely append the val - avoid blowing up when attempting to
2301 − // call .replace() if message is not a string for some reason
2302 − cmdStr += `${key}=${escape(`${val || ''}`)};`;
2303 − }
2304 − }
2305 − }
2306 − }
2307 − cmdStr += ']';
2308 − // safely append the message - avoid blowing up when attempting to
2309 − // call .replace() if message is not a string for some reason
2310 − const message = `${this.message || ''}`;
2311 − cmdStr += escapeData(message);
2312 − return cmdStr;
2313 − }
2314 −}
2315 −function escapeData(s) {
2316 − return s.replace(/\r/g, '%0D').replace(/\n/g, '%0A');
2317 −}
2318 −function escape(s) {
2319 − return s
2320 − .replace(/\r/g, '%0D')
2321 − .replace(/\n/g, '%0A')
2322 − .replace(/]/g, '%5D')
2323 − .replace(/;/g, '%3B');
2324 −}
2787 +
2788 +var __importStar = (this && this.__importStar) || function (mod) {
2789 + if (mod && mod.__esModule) return mod;
2790 + var result = {};
2791 + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
2792 + result["default"] = mod;
2793 + return result;
2794 +};
2795 +Object.defineProperty(exports, "__esModule", { value: true });
2796 +const os = __importStar(__webpack_require__(87));
2797 +/**
2798 + * Commands
2799 + *
2800 + * Command Format:
2801 + * ::name key=value,key=value::message
2802 + *
2803 + * Examples:
2804 + * ::warning::This is the message
2805 + * ::set-env name=MY_VAR::some value
2806 + */
2807 +function issueCommand(command, properties, message) {
2808 + const cmd = new Command(command, properties, message);
2809 + process.stdout.write(cmd.toString() + os.EOL);
2810 +}
2811 +exports.issueCommand = issueCommand;
2812 +function issue(name, message = '') {
2813 + issueCommand(name, {}, message);
2814 +}
2815 +exports.issue = issue;
2816 +const CMD_STRING = '::';
2817 +class Command {
2818 + constructor(command, properties, message) {
2819 + if (!command) {
2820 + command = 'missing.command';
2821 + }
2822 + this.command = command;
2823 + this.properties = properties;
2824 + this.message = message;
2825 + }
2826 + toString() {
2827 + let cmdStr = CMD_STRING + this.command;
2828 + if (this.properties && Object.keys(this.properties).length > 0) {
2829 + cmdStr += ' ';
2830 + let first = true;
2831 + for (const key in this.properties) {
2832 + if (this.properties.hasOwnProperty(key)) {
2833 + const val = this.properties[key];
2834 + if (val) {
2835 + if (first) {
2836 + first = false;
2837 + }
2838 + else {
2839 + cmdStr += ',';
2840 + }
2841 + cmdStr += `${key}=${escapeProperty(val)}`;
2842 + }
2843 + }
2844 + }
2845 + }
2846 + cmdStr += `${CMD_STRING}${escapeData(this.message)}`;
2847 + return cmdStr;
2848 + }
2849 +}
2850 +/**
2851 + * Sanitizes an input into a string so it can be passed into issueCommand safely
2852 + * @param input input to sanitize into a string
2853 + */
2854 +function toCommandValue(input) {
2855 + if (input === null || input === undefined) {
2856 + return '';
2857 + }
2858 + else if (typeof input === 'string' || input instanceof String) {
2859 + return input;
2860 + }
2861 + return JSON.stringify(input);
2862 +}
2863 +exports.toCommandValue = toCommandValue;
2864 +function escapeData(s) {
2865 + return toCommandValue(s)
2866 + .replace(/%/g, '%25')
2867 + .replace(/\r/g, '%0D')
2868 + .replace(/\n/g, '%0A');
2869 +}
2870 +function escapeProperty(s) {
2871 + return toCommandValue(s)
2872 + .replace(/%/g, '%25')
2873 + .replace(/\r/g, '%0D')
2874 + .replace(/\n/g, '%0A')
2875 + .replace(/:/g, '%3A')
2876 + .replace(/,/g, '%2C');
2877 +}
2325 2878 //# sourceMappingURL=command.js.map
2326 2879
2327 2880 /***/ }),
@@ -2371,121 +2924,227 @@ async function installOTP(version) {
2371 2924 /***/ (function(__unusedmodule, exports, __webpack_require__) {
2372 2925
2373 2926 "use strict";
2374 −
2375 −Object.defineProperty(exports, "__esModule", { value: true });
2376 −const command_1 = __webpack_require__(431);
2377 −const path = __webpack_require__(622);
2378 −/**
2379 − * The code to exit an action
2380 − */
2381 −var ExitCode;
2382 −(function (ExitCode) {
2383 − /**
2384 − * A code indicating that the action was successful
2385 − */
2386 − ExitCode[ExitCode["Success"] = 0] = "Success";
2387 − /**
2388 − * A code indicating that the action was a failure
2389 − */
2390 − ExitCode[ExitCode["Failure"] = 1] = "Failure";
2391 −})(ExitCode = exports.ExitCode || (exports.ExitCode = {}));
2392 −//-----------------------------------------------------------------------
2393 −// Variables
2394 −//-----------------------------------------------------------------------
2395 −/**
2396 − * sets env variable for this action and future actions in the job
2397 − * @param name the name of the variable to set
2398 − * @param val the value of the variable
2399 − */
2400 −function exportVariable(name, val) {
2401 − process.env[name] = val;
2402 − command_1.issueCommand('set-env', { name }, val);
2403 −}
2404 −exports.exportVariable = exportVariable;
2405 −/**
2406 − * exports the variable and registers a secret which will get masked from logs
2407 − * @param name the name of the variable to set
2408 − * @param val value of the secret
2409 − */
2410 −function exportSecret(name, val) {
2411 − exportVariable(name, val);
2412 − command_1.issueCommand('set-secret', {}, val);
2413 −}
2414 −exports.exportSecret = exportSecret;
2415 −/**
2416 − * Prepends inputPath to the PATH (for this action and future actions)
2417 − * @param inputPath
2418 − */
2419 −function addPath(inputPath) {
2420 − command_1.issueCommand('add-path', {}, inputPath);
2421 − process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`;
2422 −}
2423 −exports.addPath = addPath;
2424 −/**
2425 − * Gets the value of an input. The value is also trimmed.
2426 − *
2427 − * @param name name of the input to get
2428 − * @param options optional. See InputOptions.
2429 − * @returns string
2430 − */
2431 −function getInput(name, options) {
2432 − const val = process.env[`INPUT_${name.replace(' ', '_').toUpperCase()}`] || '';
2433 − if (options && options.required && !val) {
2434 − throw new Error(`Input required and not supplied: ${name}`);
2435 − }
2436 − return val.trim();
2437 −}
2438 −exports.getInput = getInput;
2439 −/**
2440 − * Sets the value of an output.
2441 − *
2442 − * @param name name of the output to set
2443 − * @param value value to store
2444 − */
2445 −function setOutput(name, value) {
2446 − command_1.issueCommand('set-output', { name }, value);
2447 −}
2448 −exports.setOutput = setOutput;
2449 −//-----------------------------------------------------------------------
2450 −// Results
2451 −//-----------------------------------------------------------------------
2452 −/**
2453 − * Sets the action status to failed.
2454 − * When the action exits it will be with an exit code of 1
2455 − * @param message add error issue message
2456 − */
2457 −function setFailed(message) {
2458 − process.exitCode = ExitCode.Failure;
2459 − error(message);
2460 −}
2461 −exports.setFailed = setFailed;
2462 −//-----------------------------------------------------------------------
2463 −// Logging Commands
2464 −//-----------------------------------------------------------------------
2465 −/**
2466 − * Writes debug message to user log
2467 − * @param message debug message
2468 − */
2469 −function debug(message) {
2470 − command_1.issueCommand('debug', {}, message);
2471 −}
2472 −exports.debug = debug;
2473 −/**
2474 − * Adds an error issue
2475 − * @param message error issue message
2476 − */
2477 −function error(message) {
2478 − command_1.issue('error', message);
2479 −}
2480 −exports.error = error;
2481 −/**
2482 − * Adds an warning issue
2483 − * @param message warning issue message
2484 − */
2485 −function warning(message) {
2486 − command_1.issue('warning', message);
2487 −}
2488 −exports.warning = warning;
2927 +
2928 +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2929 + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
2930 + return new (P || (P = Promise))(function (resolve, reject) {
2931 + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
2932 + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
2933 + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
2934 + step((generator = generator.apply(thisArg, _arguments || [])).next());
2935 + });
2936 +};
2937 +var __importStar = (this && this.__importStar) || function (mod) {
2938 + if (mod && mod.__esModule) return mod;
2939 + var result = {};
2940 + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
2941 + result["default"] = mod;
2942 + return result;
2943 +};
2944 +Object.defineProperty(exports, "__esModule", { value: true });
2945 +const command_1 = __webpack_require__(431);
2946 +const os = __importStar(__webpack_require__(87));
2947 +const path = __importStar(__webpack_require__(622));
2948 +/**
2949 + * The code to exit an action
2950 + */
2951 +var ExitCode;
2952 +(function (ExitCode) {
2953 + /**
2954 + * A code indicating that the action was successful
2955 + */
2956 + ExitCode[ExitCode["Success"] = 0] = "Success";
2957 + /**
2958 + * A code indicating that the action was a failure
2959 + */
2960 + ExitCode[ExitCode["Failure"] = 1] = "Failure";
2961 +})(ExitCode = exports.ExitCode || (exports.ExitCode = {}));
2962 +//-----------------------------------------------------------------------
2963 +// Variables
2964 +//-----------------------------------------------------------------------
2965 +/**
2966 + * Sets env variable for this action and future actions in the job
2967 + * @param name the name of the variable to set
2968 + * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify
2969 + */
2970 +// eslint-disable-next-line @typescript-eslint/no-explicit-any
2971 +function exportVariable(name, val) {
2972 + const convertedVal = command_1.toCommandValue(val);
2973 + process.env[name] = convertedVal;
2974 + command_1.issueCommand('set-env', { name }, convertedVal);
2975 +}
2976 +exports.exportVariable = exportVariable;
2977 +/**
2978 + * Registers a secret which will get masked from logs
2979 + * @param secret value of the secret
2980 + */
2981 +function setSecret(secret) {
2982 + command_1.issueCommand('add-mask', {}, secret);
2983 +}
2984 +exports.setSecret = setSecret;
2985 +/**
2986 + * Prepends inputPath to the PATH (for this action and future actions)
2987 + * @param inputPath
2988 + */
2989 +function addPath(inputPath) {
2990 + command_1.issueCommand('add-path', {}, inputPath);
2991 + process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`;
2992 +}
2993 +exports.addPath = addPath;
2994 +/**
2995 + * Gets the value of an input. The value is also trimmed.
2996 + *
2997 + * @param name name of the input to get
2998 + * @param options optional. See InputOptions.
2999 + * @returns string
3000 + */
3001 +function getInput(name, options) {
3002 + const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || '';
3003 + if (options && options.required && !val) {
3004 + throw new Error(`Input required and not supplied: ${name}`);
3005 + }
3006 + return val.trim();
3007 +}
3008 +exports.getInput = getInput;
3009 +/**
3010 + * Sets the value of an output.
3011 + *
3012 + * @param name name of the output to set
3013 + * @param value value to store. Non-string values will be converted to a string via JSON.stringify
3014 + */
3015 +// eslint-disable-next-line @typescript-eslint/no-explicit-any
3016 +function setOutput(name, value) {
3017 + command_1.issueCommand('set-output', { name }, value);
3018 +}
3019 +exports.setOutput = setOutput;
3020 +/**
3021 + * Enables or disables the echoing of commands into stdout for the rest of the step.
3022 + * Echoing is disabled by default if ACTIONS_STEP_DEBUG is not set.
3023 + *
3024 + */
3025 +function setCommandEcho(enabled) {
3026 + command_1.issue('echo', enabled ? 'on' : 'off');
3027 +}
3028 +exports.setCommandEcho = setCommandEcho;
3029 +//-----------------------------------------------------------------------
3030 +// Results
3031 +//-----------------------------------------------------------------------
3032 +/**
3033 + * Sets the action status to failed.
3034 + * When the action exits it will be with an exit code of 1
3035 + * @param message add error issue message
3036 + */
3037 +function setFailed(message) {
3038 + process.exitCode = ExitCode.Failure;
3039 + error(message);
3040 +}
3041 +exports.setFailed = setFailed;
3042 +//-----------------------------------------------------------------------
3043 +// Logging Commands
3044 +//-----------------------------------------------------------------------
3045 +/**
3046 + * Gets whether Actions Step Debug is on or not
3047 + */
3048 +function isDebug() {
3049 + return process.env['RUNNER_DEBUG'] === '1';
3050 +}
3051 +exports.isDebug = isDebug;
3052 +/**
3053 + * Writes debug message to user log
3054 + * @param message debug message
3055 + */
3056 +function debug(message) {
3057 + command_1.issueCommand('debug', {}, message);
3058 +}
3059 +exports.debug = debug;
3060 +/**
3061 + * Adds an error issue
3062 + * @param message error issue message. Errors will be converted to string via toString()
3063 + */
3064 +function error(message) {
3065 + command_1.issue('error', message instanceof Error ? message.toString() : message);
3066 +}
3067 +exports.error = error;
3068 +/**
3069 + * Adds an warning issue
3070 + * @param message warning issue message. Errors will be converted to string via toString()
3071 + */
3072 +function warning(message) {
3073 + command_1.issue('warning', message instanceof Error ? message.toString() : message);
3074 +}
3075 +exports.warning = warning;
3076 +/**
3077 + * Writes info to log with console.log.
3078 + * @param message info message
3079 + */
3080 +function info(message) {
3081 + process.stdout.write(message + os.EOL);
3082 +}
3083 +exports.info = info;
3084 +/**
3085 + * Begin an output group.
3086 + *
3087 + * Output until the next `groupEnd` will be foldable in this group
3088 + *
3089 + * @param name The name of the output group
3090 + */
3091 +function startGroup(name) {
3092 + command_1.issue('group', name);
3093 +}
3094 +exports.startGroup = startGroup;
3095 +/**
3096 + * End an output group.
3097 + */
3098 +function endGroup() {
3099 + command_1.issue('endgroup');
3100 +}
3101 +exports.endGroup = endGroup;
3102 +/**
3103 + * Wrap an asynchronous function call in a group.
3104 + *
3105 + * Returns the same type as the function itself.
3106 + *
3107 + * @param name The name of the group
3108 + * @param fn The function to wrap in the group
3109 + */
3110 +function group(name, fn) {
3111 + return __awaiter(this, void 0, void 0, function* () {
3112 + startGroup(name);
3113 + let result;
3114 + try {
3115 + result = yield fn();
3116 + }
3117 + finally {
3118 + endGroup();
3119 + }
3120 + return result;
3121 + });
3122 +}
3123 +exports.group = group;
3124 +//-----------------------------------------------------------------------
3125 +// Wrapper action state
3126 +//-----------------------------------------------------------------------
3127 +/**
3128 + * Saves state for current action, the state can only be retrieved by this action's post job execution.
3129 + *
3130 + * @param name name of the state to store
3131 + * @param value value to store. Non-string values will be converted to a string via JSON.stringify
3132 + */
3133 +// eslint-disable-next-line @typescript-eslint/no-explicit-any
3134 +function saveState(name, value) {
3135 + command_1.issueCommand('save-state', { name }, value);
3136 +}
3137 +exports.saveState = saveState;
3138 +/**
3139 + * Gets the value of an state set by this action's main execution.
3140 + *
3141 + * @param name name of the state to get
3142 + * @returns string
3143 + */
3144 +function getState(name) {
3145 + return process.env[`STATE_${name}`] || '';
3146 +}
3147 +exports.getState = getState;
2489 3148 //# sourceMappingURL=core.js.map
2490 3149
2491 3150 /***/ }),
@@ -2504,45 +3163,67 @@ module.exports = require("path");
2504 3163
2505 3164 /***/ }),
2506 3165
3166 +/***/ 669:
3167 +/***/ (function(module) {
3168 +
3169 +module.exports = require("util");
3170 +
3171 +/***/ }),
3172 +
3173 +/***/ 747:
3174 +/***/ (function(module) {
3175 +
3176 +module.exports = require("fs");
3177 +
3178 +/***/ }),
3179 +
2507 3180 /***/ 917:
2508 3181 /***/ (function(__unusedmodule, exports, __webpack_require__) {
2509 3182
2510 3183 "use strict";
2511 −
2512 −var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2513 − return new (P || (P = Promise))(function (resolve, reject) {
2514 − function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
2515 − function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
2516 − function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
2517 − step((generator = generator.apply(thisArg, _arguments || [])).next());
2518 − });
2519 −};
2520 −Object.defineProperty(exports, "__esModule", { value: true });
2521 −const tr = __webpack_require__(9);
2522 −/**
2523 − * Exec a command.
2524 − * Output will be streamed to the live console.
2525 − * Returns promise with return code
2526 − *
2527 − * @param commandLine command to execute (can include additional args). Must be correctly escaped.
2528 − * @param args optional arguments for tool. Escaping is handled by the lib.
2529 − * @param options optional exec options. See ExecOptions
2530 − * @returns Promise<number> exit code
2531 − */
2532 −function exec(commandLine, args, options) {
2533 − return __awaiter(this, void 0, void 0, function* () {
2534 − const commandArgs = tr.argStringToArray(commandLine);
2535 − if (commandArgs.length === 0) {
2536 − throw new Error(`Parameter 'commandLine' cannot be null or empty.`);
2537 − }
2538 − // Path to tool to execute should be first arg
2539 − const toolPath = commandArgs[0];
2540 − args = commandArgs.slice(1).concat(args || []);
2541 − const runner = new tr.ToolRunner(toolPath, args, options);
2542 − return runner.exec();
2543 − });
2544 −}
2545 −exports.exec = exec;
3184 +
3185 +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3186 + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3187 + return new (P || (P = Promise))(function (resolve, reject) {
3188 + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
3189 + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
3190 + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
3191 + step((generator = generator.apply(thisArg, _arguments || [])).next());
3192 + });
3193 +};
3194 +var __importStar = (this && this.__importStar) || function (mod) {
3195 + if (mod && mod.__esModule) return mod;
3196 + var result = {};
3197 + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
3198 + result["default"] = mod;
3199 + return result;
3200 +};
3201 +Object.defineProperty(exports, "__esModule", { value: true });
3202 +const tr = __importStar(__webpack_require__(9));
3203 +/**
3204 + * Exec a command.
3205 + * Output will be streamed to the live console.
3206 + * Returns promise with return code
3207 + *
3208 + * @param commandLine command to execute (can include additional args). Must be correctly escaped.
3209 + * @param args optional arguments for tool. Escaping is handled by the lib.
3210 + * @param options optional exec options. See ExecOptions
3211 + * @returns Promise<number> exit code
3212 + */
3213 +function exec(commandLine, args, options) {
3214 + return __awaiter(this, void 0, void 0, function* () {
3215 + const commandArgs = tr.argStringToArray(commandLine);
3216 + if (commandArgs.length === 0) {
3217 + throw new Error(`Parameter 'commandLine' cannot be null or empty.`);
3218 + }
3219 + // Path to tool to execute should be first arg
3220 + const toolPath = commandArgs[0];
3221 + args = commandArgs.slice(1).concat(args || []);
3222 + const runner = new tr.ToolRunner(toolPath, args, options);
3223 + return runner.exec();
3224 + });
3225 +}
3226 +exports.exec = exec;
2546 3227 //# sourceMappingURL=exec.js.map
2547 3228
2548 3229 /***/ }),
@@ -2592,8 +3273,8 @@ async function main() {
2592 3273
2593 3274 const matchersPath = __webpack_require__.ab + ".github"
2594 3275 console.log(`##[add-matcher]${path.join(matchersPath, 'elixir.json')}`)
2595 − console.log(`::set-output name=otp-version::${otpVersion}`)
2596 − console.log(`::set-output name=elixir-version::${elixirVersion}`)
3276 + core.setOutput('otp-version', otpVersion)
3277 + core.setOutput('elixir-version', elixirVersion)
2597 3278 }
2598 3279
2599 3280 function checkPlatform() {
modified src/setup-elixir.js
+2 −2
@@ -40,8 +40,8 @@ async function main() {
40 40
41 41 const matchersPath = path.join(__dirname, '..', '.github')
42 42 console.log(`##[add-matcher]${path.join(matchersPath, 'elixir.json')}`)
43 − console.log(`::set-output name=otp-version::${otpVersion}`)
44 − console.log(`::set-output name=elixir-version::${elixirVersion}`)
43 + core.setOutput('otp-version', otpVersion)
44 + core.setOutput('elixir-version', elixirVersion)
45 45 }
46 46
47 47 function checkPlatform() {

Parents: 24f06ac