azure-pipelines-task-lib 5.0.0-preview.0 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Strings/resources.resjson/de-DE/resources.resjson +35 -34
- package/Strings/resources.resjson/en-US/resources.resjson +24 -20
- package/Strings/resources.resjson/es-ES/resources.resjson +35 -34
- package/Strings/resources.resjson/fr-FR/resources.resjson +35 -34
- package/Strings/resources.resjson/it-IT/resources.resjson +2 -1
- package/Strings/resources.resjson/ja-JP/resources.resjson +35 -34
- package/Strings/resources.resjson/ko-KR/resources.resjson +2 -1
- package/Strings/resources.resjson/ru-RU/resources.resjson +2 -1
- package/Strings/resources.resjson/zh-CN/resources.resjson +2 -1
- package/Strings/resources.resjson/zh-TW/resources.resjson +2 -1
- package/ThirdPartyNotice.txt +5 -3
- package/internal.d.ts +13 -2
- package/internal.js +73 -20
- package/lib.json +26 -22
- package/mock-answer.d.ts +4 -1
- package/mock-answer.js +2 -2
- package/mock-task.d.ts +3 -0
- package/mock-task.js +20 -2
- package/mock-test.d.ts +3 -2
- package/mock-test.js +296 -166
- package/mock-toolrunner.d.ts +7 -0
- package/mock-toolrunner.js +95 -1
- package/package.json +4 -3
- package/task.d.ts +121 -33
- package/task.js +565 -262
- package/toolrunner.d.ts +15 -1
- package/toolrunner.js +360 -43
package/toolrunner.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
3
|
+
/// <reference types="node" />
|
|
2
4
|
import Q = require('q');
|
|
3
5
|
import events = require('events');
|
|
4
6
|
/**
|
|
@@ -94,6 +96,7 @@ export declare class ToolRunner extends events.EventEmitter {
|
|
|
94
96
|
private _cloneExecOptions;
|
|
95
97
|
private _getSpawnOptions;
|
|
96
98
|
private _getSpawnSyncOptions;
|
|
99
|
+
private execWithPipingAsync;
|
|
97
100
|
private execWithPiping;
|
|
98
101
|
/**
|
|
99
102
|
* Add argument
|
|
@@ -139,6 +142,17 @@ export declare class ToolRunner extends events.EventEmitter {
|
|
|
139
142
|
* @param options optional exec options. See IExecOptions
|
|
140
143
|
* @returns number
|
|
141
144
|
*/
|
|
145
|
+
execAsync(options?: IExecOptions): Promise<number>;
|
|
146
|
+
/**
|
|
147
|
+
* Exec a tool.
|
|
148
|
+
* Output will be streamed to the live console.
|
|
149
|
+
* Returns promise with return code
|
|
150
|
+
*
|
|
151
|
+
* @deprecated Use the `execAsync` method that returns a native Javascript promise instead
|
|
152
|
+
* @param tool path to tool to exec
|
|
153
|
+
* @param options optional exec options. See IExecOptions
|
|
154
|
+
* @returns number
|
|
155
|
+
*/
|
|
142
156
|
exec(options?: IExecOptions): Q.Promise<number>;
|
|
143
157
|
/**
|
|
144
158
|
* Exec a tool synchronously.
|
|
@@ -155,5 +169,5 @@ export declare class ToolRunner extends events.EventEmitter {
|
|
|
155
169
|
* Used to close child process by sending SIGNINT signal.
|
|
156
170
|
* It allows executed script to have some additional logic on SIGINT, before exiting.
|
|
157
171
|
*/
|
|
158
|
-
killChildProcess(): void;
|
|
172
|
+
killChildProcess(signal?: number | NodeJS.Signals): void;
|
|
159
173
|
}
|
package/toolrunner.js
CHANGED
|
@@ -7,6 +7,8 @@ var __extends = (this && this.__extends) || (function () {
|
|
|
7
7
|
return extendStatics(d, b);
|
|
8
8
|
};
|
|
9
9
|
return function (d, b) {
|
|
10
|
+
if (typeof b !== "function" && b !== null)
|
|
11
|
+
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
10
12
|
extendStatics(d, b);
|
|
11
13
|
function __() { this.constructor = d; }
|
|
12
14
|
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
@@ -107,7 +109,7 @@ var ToolRunner = /** @class */ (function (_super) {
|
|
|
107
109
|
}
|
|
108
110
|
// Windows + verbatim
|
|
109
111
|
else if (options.windowsVerbatimArguments) {
|
|
110
|
-
commandParts.push("\""
|
|
112
|
+
commandParts.push("\"".concat(toolPath, "\""));
|
|
111
113
|
commandParts = commandParts.concat(args);
|
|
112
114
|
}
|
|
113
115
|
else if (options.shell) {
|
|
@@ -134,23 +136,23 @@ var ToolRunner = /** @class */ (function (_super) {
|
|
|
134
136
|
}
|
|
135
137
|
return cmd;
|
|
136
138
|
};
|
|
137
|
-
ToolRunner.prototype._processLineBuffer = function (data,
|
|
139
|
+
ToolRunner.prototype._processLineBuffer = function (data, buffer, onLine) {
|
|
140
|
+
var newBuffer = buffer + data.toString();
|
|
138
141
|
try {
|
|
139
|
-
var
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
var line = s.substring(0, n);
|
|
142
|
+
var eolIndex = newBuffer.indexOf(os.EOL);
|
|
143
|
+
while (eolIndex > -1) {
|
|
144
|
+
var line = newBuffer.substring(0, eolIndex);
|
|
143
145
|
onLine(line);
|
|
144
146
|
// the rest of the string ...
|
|
145
|
-
|
|
146
|
-
|
|
147
|
+
newBuffer = newBuffer.substring(eolIndex + os.EOL.length);
|
|
148
|
+
eolIndex = newBuffer.indexOf(os.EOL);
|
|
147
149
|
}
|
|
148
|
-
strBuffer = s;
|
|
149
150
|
}
|
|
150
151
|
catch (err) {
|
|
151
152
|
// streaming lines to console is best effort. Don't fail a build.
|
|
152
153
|
this._debug('error processing line');
|
|
153
154
|
}
|
|
155
|
+
return newBuffer;
|
|
154
156
|
};
|
|
155
157
|
/**
|
|
156
158
|
* Wraps an arg string with specified char if it's not already wrapped
|
|
@@ -160,7 +162,7 @@ var ToolRunner = /** @class */ (function (_super) {
|
|
|
160
162
|
*/
|
|
161
163
|
ToolRunner.prototype._wrapArg = function (arg, wrapChar) {
|
|
162
164
|
if (!this._isWrapped(arg, wrapChar)) {
|
|
163
|
-
return ""
|
|
165
|
+
return "".concat(wrapChar).concat(arg).concat(wrapChar);
|
|
164
166
|
}
|
|
165
167
|
return arg;
|
|
166
168
|
};
|
|
@@ -171,7 +173,7 @@ var ToolRunner = /** @class */ (function (_super) {
|
|
|
171
173
|
*/
|
|
172
174
|
ToolRunner.prototype._unwrapArg = function (arg, wrapChar) {
|
|
173
175
|
if (this._isWrapped(arg, wrapChar)) {
|
|
174
|
-
var pattern = new RegExp("(^\\\\?"
|
|
176
|
+
var pattern = new RegExp("(^\\\\?".concat(wrapChar, ")|(\\\\?").concat(wrapChar, "$)"), 'g');
|
|
175
177
|
return arg.trim().replace(pattern, '');
|
|
176
178
|
}
|
|
177
179
|
return arg;
|
|
@@ -181,7 +183,7 @@ var ToolRunner = /** @class */ (function (_super) {
|
|
|
181
183
|
* @param arg Input arg string
|
|
182
184
|
*/
|
|
183
185
|
ToolRunner.prototype._isWrapped = function (arg, wrapChar) {
|
|
184
|
-
var pattern = new RegExp("^\\\\?"
|
|
186
|
+
var pattern = new RegExp("^\\\\?".concat(wrapChar, ".+\\\\?").concat(wrapChar, "$"));
|
|
185
187
|
return pattern.test(arg.trim());
|
|
186
188
|
};
|
|
187
189
|
ToolRunner.prototype._getSpawnFileName = function (options) {
|
|
@@ -199,7 +201,7 @@ var ToolRunner = /** @class */ (function (_super) {
|
|
|
199
201
|
var _this = this;
|
|
200
202
|
if (process.platform == 'win32') {
|
|
201
203
|
if (this._isCmdFile()) {
|
|
202
|
-
var argline = "/D /S /C \""
|
|
204
|
+
var argline = "/D /S /C \"".concat(this._windowsQuoteCmdArg(this.toolPath));
|
|
203
205
|
for (var i = 0; i < this.args.length; i++) {
|
|
204
206
|
argline += ' ';
|
|
205
207
|
argline += options.windowsVerbatimArguments ? this.args[i] : this._windowsQuoteCmdArg(this.args[i]);
|
|
@@ -243,7 +245,7 @@ var ToolRunner = /** @class */ (function (_super) {
|
|
|
243
245
|
if (arguments.length != 1) {
|
|
244
246
|
throw new Error('Unexpected arguments passed to args.unshift when windowsVerbatimArguments flag is set.');
|
|
245
247
|
}
|
|
246
|
-
return Array.prototype.unshift.call(args_1, "\""
|
|
248
|
+
return Array.prototype.unshift.call(args_1, "\"".concat(arguments[0], "\"")); // quote the file name
|
|
247
249
|
};
|
|
248
250
|
return args_1;
|
|
249
251
|
}
|
|
@@ -447,7 +449,7 @@ var ToolRunner = /** @class */ (function (_super) {
|
|
|
447
449
|
if (arg.indexOf('"') < 0 && arg.indexOf('\\') < 0) {
|
|
448
450
|
// No embedded double quotes or backslashes, so I can just wrap
|
|
449
451
|
// quote marks around the whole thing.
|
|
450
|
-
return "\""
|
|
452
|
+
return "\"".concat(arg, "\"");
|
|
451
453
|
}
|
|
452
454
|
// Expected input/output:
|
|
453
455
|
// input : hello"world
|
|
@@ -516,6 +518,186 @@ var ToolRunner = /** @class */ (function (_super) {
|
|
|
516
518
|
result['windowsVerbatimArguments'] = options.windowsVerbatimArguments || this._isCmdFile();
|
|
517
519
|
return result;
|
|
518
520
|
};
|
|
521
|
+
ToolRunner.prototype.execWithPipingAsync = function (pipeOutputToTool, options) {
|
|
522
|
+
var _this = this;
|
|
523
|
+
this._debug('exec tool: ' + this.toolPath);
|
|
524
|
+
this._debug('arguments:');
|
|
525
|
+
this.args.forEach(function (arg) {
|
|
526
|
+
_this._debug(' ' + arg);
|
|
527
|
+
});
|
|
528
|
+
var success = true;
|
|
529
|
+
var optionsNonNull = this._cloneExecOptions(options);
|
|
530
|
+
if (!optionsNonNull.silent) {
|
|
531
|
+
optionsNonNull.outStream.write(this._getCommandString(optionsNonNull) + os.EOL);
|
|
532
|
+
}
|
|
533
|
+
var cp;
|
|
534
|
+
var toolPath = pipeOutputToTool.toolPath;
|
|
535
|
+
var toolPathFirst;
|
|
536
|
+
var successFirst = true;
|
|
537
|
+
var returnCodeFirst;
|
|
538
|
+
var fileStream;
|
|
539
|
+
var waitingEvents = 0; // number of process or stream events we are waiting on to complete
|
|
540
|
+
var returnCode = 0;
|
|
541
|
+
var error;
|
|
542
|
+
toolPathFirst = this.toolPath;
|
|
543
|
+
// Following node documentation example from this link on how to pipe output of one process to another
|
|
544
|
+
// https://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options
|
|
545
|
+
//start the child process for both tools
|
|
546
|
+
waitingEvents++;
|
|
547
|
+
var cpFirst = child.spawn(this._getSpawnFileName(optionsNonNull), this._getSpawnArgs(optionsNonNull), this._getSpawnOptions(optionsNonNull));
|
|
548
|
+
waitingEvents++;
|
|
549
|
+
cp = child.spawn(pipeOutputToTool._getSpawnFileName(optionsNonNull), pipeOutputToTool._getSpawnArgs(optionsNonNull), pipeOutputToTool._getSpawnOptions(optionsNonNull));
|
|
550
|
+
fileStream = this.pipeOutputToFile ? fs.createWriteStream(this.pipeOutputToFile) : null;
|
|
551
|
+
return new Promise(function (resolve, reject) {
|
|
552
|
+
var _a, _b, _c, _d;
|
|
553
|
+
if (fileStream) {
|
|
554
|
+
waitingEvents++;
|
|
555
|
+
fileStream.on('finish', function () {
|
|
556
|
+
waitingEvents--; //file write is complete
|
|
557
|
+
fileStream = null;
|
|
558
|
+
if (waitingEvents == 0) {
|
|
559
|
+
if (error) {
|
|
560
|
+
reject(error);
|
|
561
|
+
}
|
|
562
|
+
else {
|
|
563
|
+
resolve(returnCode);
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
});
|
|
567
|
+
fileStream.on('error', function (err) {
|
|
568
|
+
waitingEvents--; //there were errors writing to the file, write is done
|
|
569
|
+
_this._debug("Failed to pipe output of ".concat(toolPathFirst, " to file ").concat(_this.pipeOutputToFile, ". Error = ").concat(err));
|
|
570
|
+
fileStream = null;
|
|
571
|
+
if (waitingEvents == 0) {
|
|
572
|
+
if (error) {
|
|
573
|
+
reject(error);
|
|
574
|
+
}
|
|
575
|
+
else {
|
|
576
|
+
resolve(returnCode);
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
});
|
|
580
|
+
}
|
|
581
|
+
//pipe stdout of first tool to stdin of second tool
|
|
582
|
+
(_a = cpFirst.stdout) === null || _a === void 0 ? void 0 : _a.on('data', function (data) {
|
|
583
|
+
var _a, _b;
|
|
584
|
+
try {
|
|
585
|
+
if (fileStream) {
|
|
586
|
+
fileStream.write(data);
|
|
587
|
+
}
|
|
588
|
+
if (!((_a = cp.stdin) === null || _a === void 0 ? void 0 : _a.destroyed)) {
|
|
589
|
+
(_b = cp.stdin) === null || _b === void 0 ? void 0 : _b.write(data);
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
catch (err) {
|
|
593
|
+
_this._debug('Failed to pipe output of ' + toolPathFirst + ' to ' + toolPath);
|
|
594
|
+
_this._debug(toolPath + ' might have exited due to errors prematurely. Verify the arguments passed are valid.');
|
|
595
|
+
}
|
|
596
|
+
});
|
|
597
|
+
(_b = cpFirst.stderr) === null || _b === void 0 ? void 0 : _b.on('data', function (data) {
|
|
598
|
+
if (fileStream) {
|
|
599
|
+
fileStream.write(data);
|
|
600
|
+
}
|
|
601
|
+
successFirst = !optionsNonNull.failOnStdErr;
|
|
602
|
+
if (!optionsNonNull.silent) {
|
|
603
|
+
var s = optionsNonNull.failOnStdErr ? optionsNonNull.errStream : optionsNonNull.outStream;
|
|
604
|
+
s.write(data);
|
|
605
|
+
}
|
|
606
|
+
});
|
|
607
|
+
cpFirst.on('error', function (err) {
|
|
608
|
+
var _a;
|
|
609
|
+
waitingEvents--; //first process is complete with errors
|
|
610
|
+
if (fileStream) {
|
|
611
|
+
fileStream.end();
|
|
612
|
+
}
|
|
613
|
+
(_a = cp.stdin) === null || _a === void 0 ? void 0 : _a.end();
|
|
614
|
+
error = new Error(toolPathFirst + ' failed. ' + err.message);
|
|
615
|
+
if (waitingEvents == 0) {
|
|
616
|
+
reject(error);
|
|
617
|
+
}
|
|
618
|
+
});
|
|
619
|
+
cpFirst.on('close', function (code, signal) {
|
|
620
|
+
var _a;
|
|
621
|
+
waitingEvents--; //first process is complete
|
|
622
|
+
if (code != 0 && !optionsNonNull.ignoreReturnCode) {
|
|
623
|
+
successFirst = false;
|
|
624
|
+
returnCodeFirst = code;
|
|
625
|
+
returnCode = returnCodeFirst;
|
|
626
|
+
}
|
|
627
|
+
_this._debug('success of first tool:' + successFirst);
|
|
628
|
+
if (fileStream) {
|
|
629
|
+
fileStream.end();
|
|
630
|
+
}
|
|
631
|
+
(_a = cp.stdin) === null || _a === void 0 ? void 0 : _a.end();
|
|
632
|
+
if (waitingEvents == 0) {
|
|
633
|
+
if (error) {
|
|
634
|
+
reject(error);
|
|
635
|
+
}
|
|
636
|
+
else {
|
|
637
|
+
resolve(returnCode);
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
});
|
|
641
|
+
var stdLineBuffer = '';
|
|
642
|
+
(_c = cp.stdout) === null || _c === void 0 ? void 0 : _c.on('data', function (data) {
|
|
643
|
+
_this.emit('stdout', data);
|
|
644
|
+
if (!optionsNonNull.silent) {
|
|
645
|
+
optionsNonNull.outStream.write(data);
|
|
646
|
+
}
|
|
647
|
+
stdLineBuffer = _this._processLineBuffer(data, stdLineBuffer, function (line) {
|
|
648
|
+
_this.emit('stdline', line);
|
|
649
|
+
});
|
|
650
|
+
});
|
|
651
|
+
var errLineBuffer = '';
|
|
652
|
+
(_d = cp.stderr) === null || _d === void 0 ? void 0 : _d.on('data', function (data) {
|
|
653
|
+
_this.emit('stderr', data);
|
|
654
|
+
success = !optionsNonNull.failOnStdErr;
|
|
655
|
+
if (!optionsNonNull.silent) {
|
|
656
|
+
var s = optionsNonNull.failOnStdErr ? optionsNonNull.errStream : optionsNonNull.outStream;
|
|
657
|
+
s.write(data);
|
|
658
|
+
}
|
|
659
|
+
errLineBuffer = _this._processLineBuffer(data, errLineBuffer, function (line) {
|
|
660
|
+
_this.emit('errline', line);
|
|
661
|
+
});
|
|
662
|
+
});
|
|
663
|
+
cp.on('error', function (err) {
|
|
664
|
+
waitingEvents--; //process is done with errors
|
|
665
|
+
error = new Error(toolPath + ' failed. ' + err.message);
|
|
666
|
+
if (waitingEvents == 0) {
|
|
667
|
+
reject(error);
|
|
668
|
+
}
|
|
669
|
+
});
|
|
670
|
+
cp.on('close', function (code, signal) {
|
|
671
|
+
waitingEvents--; //process is complete
|
|
672
|
+
_this._debug('rc:' + code);
|
|
673
|
+
returnCode = code;
|
|
674
|
+
if (stdLineBuffer.length > 0) {
|
|
675
|
+
_this.emit('stdline', stdLineBuffer);
|
|
676
|
+
}
|
|
677
|
+
if (errLineBuffer.length > 0) {
|
|
678
|
+
_this.emit('errline', errLineBuffer);
|
|
679
|
+
}
|
|
680
|
+
if (code != 0 && !optionsNonNull.ignoreReturnCode) {
|
|
681
|
+
success = false;
|
|
682
|
+
}
|
|
683
|
+
_this._debug('success:' + success);
|
|
684
|
+
if (!successFirst) { //in the case output is piped to another tool, check exit code of both tools
|
|
685
|
+
error = new Error(toolPathFirst + ' failed with return code: ' + returnCodeFirst);
|
|
686
|
+
}
|
|
687
|
+
else if (!success) {
|
|
688
|
+
error = new Error(toolPath + ' failed with return code: ' + code);
|
|
689
|
+
}
|
|
690
|
+
if (waitingEvents == 0) {
|
|
691
|
+
if (error) {
|
|
692
|
+
reject(error);
|
|
693
|
+
}
|
|
694
|
+
else {
|
|
695
|
+
resolve(returnCode);
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
});
|
|
699
|
+
});
|
|
700
|
+
};
|
|
519
701
|
ToolRunner.prototype.execWithPiping = function (pipeOutputToTool, options) {
|
|
520
702
|
var _this = this;
|
|
521
703
|
var _a, _b, _c, _d;
|
|
@@ -564,7 +746,7 @@ var ToolRunner = /** @class */ (function (_super) {
|
|
|
564
746
|
});
|
|
565
747
|
fileStream.on('error', function (err) {
|
|
566
748
|
waitingEvents--; //there were errors writing to the file, write is done
|
|
567
|
-
_this._debug("Failed to pipe output of "
|
|
749
|
+
_this._debug("Failed to pipe output of ".concat(toolPathFirst, " to file ").concat(_this.pipeOutputToFile, ". Error = ").concat(err));
|
|
568
750
|
fileStream = null;
|
|
569
751
|
if (waitingEvents == 0) {
|
|
570
752
|
if (error) {
|
|
@@ -634,17 +816,17 @@ var ToolRunner = /** @class */ (function (_super) {
|
|
|
634
816
|
}
|
|
635
817
|
}
|
|
636
818
|
});
|
|
637
|
-
var
|
|
819
|
+
var stdLineBuffer = '';
|
|
638
820
|
(_c = cp.stdout) === null || _c === void 0 ? void 0 : _c.on('data', function (data) {
|
|
639
821
|
_this.emit('stdout', data);
|
|
640
822
|
if (!optionsNonNull.silent) {
|
|
641
823
|
optionsNonNull.outStream.write(data);
|
|
642
824
|
}
|
|
643
|
-
_this._processLineBuffer(data,
|
|
825
|
+
stdLineBuffer = _this._processLineBuffer(data, stdLineBuffer, function (line) {
|
|
644
826
|
_this.emit('stdline', line);
|
|
645
827
|
});
|
|
646
828
|
});
|
|
647
|
-
var
|
|
829
|
+
var errLineBuffer = '';
|
|
648
830
|
(_d = cp.stderr) === null || _d === void 0 ? void 0 : _d.on('data', function (data) {
|
|
649
831
|
_this.emit('stderr', data);
|
|
650
832
|
success = !optionsNonNull.failOnStdErr;
|
|
@@ -652,7 +834,7 @@ var ToolRunner = /** @class */ (function (_super) {
|
|
|
652
834
|
var s = optionsNonNull.failOnStdErr ? optionsNonNull.errStream : optionsNonNull.outStream;
|
|
653
835
|
s.write(data);
|
|
654
836
|
}
|
|
655
|
-
_this._processLineBuffer(data,
|
|
837
|
+
errLineBuffer = _this._processLineBuffer(data, errLineBuffer, function (line) {
|
|
656
838
|
_this.emit('errline', line);
|
|
657
839
|
});
|
|
658
840
|
});
|
|
@@ -667,11 +849,11 @@ var ToolRunner = /** @class */ (function (_super) {
|
|
|
667
849
|
waitingEvents--; //process is complete
|
|
668
850
|
_this._debug('rc:' + code);
|
|
669
851
|
returnCode = code;
|
|
670
|
-
if (
|
|
671
|
-
_this.emit('stdline',
|
|
852
|
+
if (stdLineBuffer.length > 0) {
|
|
853
|
+
_this.emit('stdline', stdLineBuffer);
|
|
672
854
|
}
|
|
673
|
-
if (
|
|
674
|
-
_this.emit('errline',
|
|
855
|
+
if (errLineBuffer.length > 0) {
|
|
856
|
+
_this.emit('errline', errLineBuffer);
|
|
675
857
|
}
|
|
676
858
|
if (code != 0 && !optionsNonNull.ignoreReturnCode) {
|
|
677
859
|
success = false;
|
|
@@ -767,13 +949,12 @@ var ToolRunner = /** @class */ (function (_super) {
|
|
|
767
949
|
* @param options optional exec options. See IExecOptions
|
|
768
950
|
* @returns number
|
|
769
951
|
*/
|
|
770
|
-
ToolRunner.prototype.
|
|
952
|
+
ToolRunner.prototype.execAsync = function (options) {
|
|
771
953
|
var _this = this;
|
|
772
954
|
var _a, _b, _c;
|
|
773
955
|
if (this.pipeOutputToTool) {
|
|
774
|
-
return this.
|
|
956
|
+
return this.execWithPipingAsync(this.pipeOutputToTool, options);
|
|
775
957
|
}
|
|
776
|
-
var defer = Q.defer();
|
|
777
958
|
this._debug('exec tool: ' + this.toolPath);
|
|
778
959
|
this._debug('arguments:');
|
|
779
960
|
this.args.forEach(function (arg) {
|
|
@@ -787,7 +968,41 @@ var ToolRunner = /** @class */ (function (_super) {
|
|
|
787
968
|
state.on('debug', function (message) {
|
|
788
969
|
_this._debug(message);
|
|
789
970
|
});
|
|
790
|
-
var
|
|
971
|
+
var stdLineBuffer = '';
|
|
972
|
+
var errLineBuffer = '';
|
|
973
|
+
var emitDoneEvent = function (resolve, reject) {
|
|
974
|
+
state.on('done', function (error, exitCode) {
|
|
975
|
+
if (stdLineBuffer.length > 0) {
|
|
976
|
+
_this.emit('stdline', stdLineBuffer);
|
|
977
|
+
}
|
|
978
|
+
if (errLineBuffer.length > 0) {
|
|
979
|
+
_this.emit('errline', errLineBuffer);
|
|
980
|
+
}
|
|
981
|
+
if (cp) {
|
|
982
|
+
cp.removeAllListeners();
|
|
983
|
+
}
|
|
984
|
+
if (error) {
|
|
985
|
+
reject(error);
|
|
986
|
+
}
|
|
987
|
+
else {
|
|
988
|
+
resolve(exitCode);
|
|
989
|
+
}
|
|
990
|
+
});
|
|
991
|
+
};
|
|
992
|
+
// Edge case when the node itself cant's spawn and emit event
|
|
993
|
+
var cp;
|
|
994
|
+
try {
|
|
995
|
+
cp = child.spawn(this._getSpawnFileName(options), this._getSpawnArgs(optionsNonNull), this._getSpawnOptions(options));
|
|
996
|
+
}
|
|
997
|
+
catch (error) {
|
|
998
|
+
return new Promise(function (resolve, reject) {
|
|
999
|
+
emitDoneEvent(resolve, reject);
|
|
1000
|
+
state.processError = error.message;
|
|
1001
|
+
state.processExited = true;
|
|
1002
|
+
state.processClosed = true;
|
|
1003
|
+
state.CheckComplete();
|
|
1004
|
+
});
|
|
1005
|
+
}
|
|
791
1006
|
this.childProcess = cp;
|
|
792
1007
|
// it is possible for the child process to end its last line without a new line.
|
|
793
1008
|
// because stdout is buffered, this causes the last line to not get sent to the parent
|
|
@@ -797,17 +1012,15 @@ var ToolRunner = /** @class */ (function (_super) {
|
|
|
797
1012
|
optionsNonNull.outStream.write(os.EOL);
|
|
798
1013
|
}
|
|
799
1014
|
});
|
|
800
|
-
var stdbuffer = '';
|
|
801
1015
|
(_b = cp.stdout) === null || _b === void 0 ? void 0 : _b.on('data', function (data) {
|
|
802
1016
|
_this.emit('stdout', data);
|
|
803
1017
|
if (!optionsNonNull.silent) {
|
|
804
1018
|
optionsNonNull.outStream.write(data);
|
|
805
1019
|
}
|
|
806
|
-
_this._processLineBuffer(data,
|
|
1020
|
+
stdLineBuffer = _this._processLineBuffer(data, stdLineBuffer, function (line) {
|
|
807
1021
|
_this.emit('stdline', line);
|
|
808
1022
|
});
|
|
809
1023
|
});
|
|
810
|
-
var errbuffer = '';
|
|
811
1024
|
(_c = cp.stderr) === null || _c === void 0 ? void 0 : _c.on('data', function (data) {
|
|
812
1025
|
state.processStderr = true;
|
|
813
1026
|
_this.emit('stderr', data);
|
|
@@ -815,7 +1028,7 @@ var ToolRunner = /** @class */ (function (_super) {
|
|
|
815
1028
|
var s = optionsNonNull.failOnStdErr ? optionsNonNull.errStream : optionsNonNull.outStream;
|
|
816
1029
|
s.write(data);
|
|
817
1030
|
}
|
|
818
|
-
_this._processLineBuffer(data,
|
|
1031
|
+
errLineBuffer = _this._processLineBuffer(data, errLineBuffer, function (line) {
|
|
819
1032
|
_this.emit('errline', line);
|
|
820
1033
|
});
|
|
821
1034
|
});
|
|
@@ -825,27 +1038,64 @@ var ToolRunner = /** @class */ (function (_super) {
|
|
|
825
1038
|
state.processClosed = true;
|
|
826
1039
|
state.CheckComplete();
|
|
827
1040
|
});
|
|
1041
|
+
// Do not write debug logs here. Sometimes stdio not closed yet and you can damage user output commands.
|
|
828
1042
|
cp.on('exit', function (code, signal) {
|
|
829
1043
|
state.processExitCode = code;
|
|
1044
|
+
state.processExitSignal = signal;
|
|
830
1045
|
state.processExited = true;
|
|
831
|
-
_this._debug("Exit code " + code + " received from tool '" + _this.toolPath + "'");
|
|
832
1046
|
state.CheckComplete();
|
|
833
1047
|
});
|
|
834
1048
|
cp.on('close', function (code, signal) {
|
|
835
|
-
state.
|
|
836
|
-
state.
|
|
1049
|
+
state.processCloseCode = code;
|
|
1050
|
+
state.processCloseSignal = signal;
|
|
837
1051
|
state.processClosed = true;
|
|
838
|
-
|
|
1052
|
+
state.processExited = true;
|
|
839
1053
|
state.CheckComplete();
|
|
840
1054
|
});
|
|
1055
|
+
return new Promise(emitDoneEvent);
|
|
1056
|
+
};
|
|
1057
|
+
/**
|
|
1058
|
+
* Exec a tool.
|
|
1059
|
+
* Output will be streamed to the live console.
|
|
1060
|
+
* Returns promise with return code
|
|
1061
|
+
*
|
|
1062
|
+
* @deprecated Use the `execAsync` method that returns a native Javascript promise instead
|
|
1063
|
+
* @param tool path to tool to exec
|
|
1064
|
+
* @param options optional exec options. See IExecOptions
|
|
1065
|
+
* @returns number
|
|
1066
|
+
*/
|
|
1067
|
+
ToolRunner.prototype.exec = function (options) {
|
|
1068
|
+
var _this = this;
|
|
1069
|
+
var _a, _b, _c;
|
|
1070
|
+
if (this.pipeOutputToTool) {
|
|
1071
|
+
return this.execWithPiping(this.pipeOutputToTool, options);
|
|
1072
|
+
}
|
|
1073
|
+
var defer = Q.defer();
|
|
1074
|
+
this._debug('exec tool: ' + this.toolPath);
|
|
1075
|
+
this._debug('arguments:');
|
|
1076
|
+
this.args.forEach(function (arg) {
|
|
1077
|
+
_this._debug(' ' + arg);
|
|
1078
|
+
});
|
|
1079
|
+
var optionsNonNull = this._cloneExecOptions(options);
|
|
1080
|
+
if (!optionsNonNull.silent) {
|
|
1081
|
+
optionsNonNull.outStream.write(this._getCommandString(optionsNonNull) + os.EOL);
|
|
1082
|
+
}
|
|
1083
|
+
var state = new ExecState(optionsNonNull, this.toolPath);
|
|
1084
|
+
state.on('debug', function (message) {
|
|
1085
|
+
_this._debug(message);
|
|
1086
|
+
});
|
|
1087
|
+
var stdLineBuffer = '';
|
|
1088
|
+
var errLineBuffer = '';
|
|
841
1089
|
state.on('done', function (error, exitCode) {
|
|
842
|
-
if (
|
|
843
|
-
_this.emit('stdline',
|
|
1090
|
+
if (stdLineBuffer.length > 0) {
|
|
1091
|
+
_this.emit('stdline', stdLineBuffer);
|
|
844
1092
|
}
|
|
845
|
-
if (
|
|
846
|
-
_this.emit('errline',
|
|
1093
|
+
if (errLineBuffer.length > 0) {
|
|
1094
|
+
_this.emit('errline', errLineBuffer);
|
|
1095
|
+
}
|
|
1096
|
+
if (cp) {
|
|
1097
|
+
cp.removeAllListeners();
|
|
847
1098
|
}
|
|
848
|
-
cp.removeAllListeners();
|
|
849
1099
|
if (error) {
|
|
850
1100
|
defer.reject(error);
|
|
851
1101
|
}
|
|
@@ -853,6 +1103,67 @@ var ToolRunner = /** @class */ (function (_super) {
|
|
|
853
1103
|
defer.resolve(exitCode);
|
|
854
1104
|
}
|
|
855
1105
|
});
|
|
1106
|
+
// Edge case when the node itself cant's spawn and emit event
|
|
1107
|
+
var cp;
|
|
1108
|
+
try {
|
|
1109
|
+
cp = child.spawn(this._getSpawnFileName(options), this._getSpawnArgs(optionsNonNull), this._getSpawnOptions(options));
|
|
1110
|
+
}
|
|
1111
|
+
catch (error) {
|
|
1112
|
+
state.processError = error.message;
|
|
1113
|
+
state.processExited = true;
|
|
1114
|
+
state.processClosed = true;
|
|
1115
|
+
state.CheckComplete();
|
|
1116
|
+
return defer.promise;
|
|
1117
|
+
}
|
|
1118
|
+
this.childProcess = cp;
|
|
1119
|
+
// it is possible for the child process to end its last line without a new line.
|
|
1120
|
+
// because stdout is buffered, this causes the last line to not get sent to the parent
|
|
1121
|
+
// stream. Adding this event forces a flush before the child streams are closed.
|
|
1122
|
+
(_a = cp.stdout) === null || _a === void 0 ? void 0 : _a.on('finish', function () {
|
|
1123
|
+
if (!optionsNonNull.silent) {
|
|
1124
|
+
optionsNonNull.outStream.write(os.EOL);
|
|
1125
|
+
}
|
|
1126
|
+
});
|
|
1127
|
+
(_b = cp.stdout) === null || _b === void 0 ? void 0 : _b.on('data', function (data) {
|
|
1128
|
+
_this.emit('stdout', data);
|
|
1129
|
+
if (!optionsNonNull.silent) {
|
|
1130
|
+
optionsNonNull.outStream.write(data);
|
|
1131
|
+
}
|
|
1132
|
+
stdLineBuffer = _this._processLineBuffer(data, stdLineBuffer, function (line) {
|
|
1133
|
+
_this.emit('stdline', line);
|
|
1134
|
+
});
|
|
1135
|
+
});
|
|
1136
|
+
(_c = cp.stderr) === null || _c === void 0 ? void 0 : _c.on('data', function (data) {
|
|
1137
|
+
state.processStderr = true;
|
|
1138
|
+
_this.emit('stderr', data);
|
|
1139
|
+
if (!optionsNonNull.silent) {
|
|
1140
|
+
var s = optionsNonNull.failOnStdErr ? optionsNonNull.errStream : optionsNonNull.outStream;
|
|
1141
|
+
s.write(data);
|
|
1142
|
+
}
|
|
1143
|
+
errLineBuffer = _this._processLineBuffer(data, errLineBuffer, function (line) {
|
|
1144
|
+
_this.emit('errline', line);
|
|
1145
|
+
});
|
|
1146
|
+
});
|
|
1147
|
+
cp.on('error', function (err) {
|
|
1148
|
+
state.processError = err.message;
|
|
1149
|
+
state.processExited = true;
|
|
1150
|
+
state.processClosed = true;
|
|
1151
|
+
state.CheckComplete();
|
|
1152
|
+
});
|
|
1153
|
+
// Do not write debug logs here. Sometimes stdio not closed yet and you can damage user output commands.
|
|
1154
|
+
cp.on('exit', function (code, signal) {
|
|
1155
|
+
state.processExitCode = code;
|
|
1156
|
+
state.processExitSignal = signal;
|
|
1157
|
+
state.processExited = true;
|
|
1158
|
+
state.CheckComplete();
|
|
1159
|
+
});
|
|
1160
|
+
cp.on('close', function (code, signal) {
|
|
1161
|
+
state.processCloseCode = code;
|
|
1162
|
+
state.processCloseSignal = signal;
|
|
1163
|
+
state.processClosed = true;
|
|
1164
|
+
state.processExited = true;
|
|
1165
|
+
state.CheckComplete();
|
|
1166
|
+
});
|
|
856
1167
|
return defer.promise;
|
|
857
1168
|
};
|
|
858
1169
|
/**
|
|
@@ -893,9 +1204,11 @@ var ToolRunner = /** @class */ (function (_super) {
|
|
|
893
1204
|
* Used to close child process by sending SIGNINT signal.
|
|
894
1205
|
* It allows executed script to have some additional logic on SIGINT, before exiting.
|
|
895
1206
|
*/
|
|
896
|
-
ToolRunner.prototype.killChildProcess = function () {
|
|
1207
|
+
ToolRunner.prototype.killChildProcess = function (signal) {
|
|
1208
|
+
if (signal === void 0) { signal = "SIGTERM"; }
|
|
897
1209
|
if (this.childProcess) {
|
|
898
|
-
this.
|
|
1210
|
+
this._debug("[killChildProcess] Signal ".concat(signal, " received"));
|
|
1211
|
+
this.childProcess.kill(signal);
|
|
899
1212
|
}
|
|
900
1213
|
};
|
|
901
1214
|
return ToolRunner;
|
|
@@ -936,6 +1249,7 @@ var ExecState = /** @class */ (function (_super) {
|
|
|
936
1249
|
// determine whether there is an error
|
|
937
1250
|
var error;
|
|
938
1251
|
if (this.processExited) {
|
|
1252
|
+
this._debug("Process exited with code ".concat(this.processExitCode, " and signal ").concat(this.processExitSignal, " for tool '").concat(this.toolPath, "'"));
|
|
939
1253
|
if (this.processError) {
|
|
940
1254
|
error = new Error(im._loc('LIB_ProcessError', this.toolPath, this.processError));
|
|
941
1255
|
}
|
|
@@ -946,6 +1260,9 @@ var ExecState = /** @class */ (function (_super) {
|
|
|
946
1260
|
error = new Error(im._loc('LIB_ProcessStderr', this.toolPath));
|
|
947
1261
|
}
|
|
948
1262
|
}
|
|
1263
|
+
if (this.processClosed) {
|
|
1264
|
+
this._debug("STDIO streams have closed and received exit code ".concat(this.processCloseCode, " and signal ").concat(this.processCloseSignal, " for tool '").concat(this.toolPath, "'"));
|
|
1265
|
+
}
|
|
949
1266
|
// clear the timeout
|
|
950
1267
|
if (this.timeout) {
|
|
951
1268
|
clearTimeout(this.timeout);
|