azure-pipelines-task-lib 4.4.0 → 4.5.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/mock-task.d.ts +1 -0
- package/mock-task.js +13 -1
- package/mock-toolrunner.d.ts +6 -0
- package/mock-toolrunner.js +93 -1
- package/package.json +2 -2
- package/task.d.ts +14 -1
- package/task.js +28 -17
- package/toolrunner.d.ts +12 -0
- package/toolrunner.js +276 -0
package/mock-task.d.ts
CHANGED
|
@@ -74,6 +74,7 @@ export declare function find(findPath: string): string[];
|
|
|
74
74
|
export declare function rmRF(path: string): void;
|
|
75
75
|
export declare function mv(source: string, dest: string, force: boolean, continueOnError?: boolean): boolean;
|
|
76
76
|
export declare function exec(tool: string, args: any, options?: trm.IExecOptions): Q.Promise<number>;
|
|
77
|
+
export declare function execAsync(tool: string, args: any, options?: trm.IExecOptions): Promise<number>;
|
|
77
78
|
export declare function execSync(tool: string, args: any, options?: trm.IExecSyncOptions): trm.IExecSyncResult;
|
|
78
79
|
export declare function tool(tool: string): trm.ToolRunner;
|
|
79
80
|
export interface MatchOptions {
|
package/mock-task.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getHttpCertConfiguration = exports.getHttpProxyConfiguration = exports.CodeCoverageEnabler = exports.CodeCoveragePublisher = exports.TestPublisher = exports.legacyFindFiles = exports.findMatch = exports.tool = exports.execSync = exports.exec = exports.mv = exports.rmRF = exports.find = exports.retry = exports.cp = exports.ls = exports.which = exports.resolve = exports.mkdirP = exports.checkPath = exports.popd = exports.pushd = exports.cd = exports.cwd = exports.getAgentMode = exports.getPlatform = exports.osType = exports.writeFile = exports.exist = exports.stats = exports.FsStats = exports.loc = exports.setResourcePath = exports.setAnswers = void 0;
|
|
3
|
+
exports.getHttpCertConfiguration = exports.getHttpProxyConfiguration = exports.CodeCoverageEnabler = exports.CodeCoveragePublisher = exports.TestPublisher = exports.legacyFindFiles = exports.findMatch = exports.tool = exports.execSync = exports.execAsync = exports.exec = exports.mv = exports.rmRF = exports.find = exports.retry = exports.cp = exports.ls = exports.which = exports.resolve = exports.mkdirP = exports.checkPath = exports.popd = exports.pushd = exports.cd = exports.cwd = exports.getAgentMode = exports.getPlatform = exports.osType = exports.writeFile = exports.exist = exports.stats = exports.FsStats = exports.loc = exports.setResourcePath = exports.setAnswers = void 0;
|
|
4
4
|
var path = require("path");
|
|
5
5
|
var task = require("./task");
|
|
6
6
|
var tcm = require("./taskcommand");
|
|
@@ -299,6 +299,18 @@ function exec(tool, args, options) {
|
|
|
299
299
|
return tr.exec(options);
|
|
300
300
|
}
|
|
301
301
|
exports.exec = exec;
|
|
302
|
+
//-----------------------------------------------------
|
|
303
|
+
// Exec convenience wrapper
|
|
304
|
+
//-----------------------------------------------------
|
|
305
|
+
function execAsync(tool, args, options) {
|
|
306
|
+
var toolPath = which(tool, true);
|
|
307
|
+
var tr = this.tool(toolPath);
|
|
308
|
+
if (args) {
|
|
309
|
+
tr.arg(args);
|
|
310
|
+
}
|
|
311
|
+
return tr.execAsync(options);
|
|
312
|
+
}
|
|
313
|
+
exports.execAsync = execAsync;
|
|
302
314
|
function execSync(tool, args, options) {
|
|
303
315
|
var toolPath = which(tool, true);
|
|
304
316
|
var tr = this.tool(toolPath);
|
package/mock-toolrunner.d.ts
CHANGED
|
@@ -36,6 +36,12 @@ export declare class ToolRunner extends events.EventEmitter {
|
|
|
36
36
|
line(val: string): ToolRunner;
|
|
37
37
|
pipeExecOutputToTool(tool: ToolRunner): ToolRunner;
|
|
38
38
|
private ignoreTempPath;
|
|
39
|
+
execAsync(options?: IExecOptions): Promise<number>;
|
|
40
|
+
/**
|
|
41
|
+
* Exec - use for long running tools where you need to stream live output as it runs
|
|
42
|
+
* @deprecated use `execAsync` instead
|
|
43
|
+
* @returns a promise with return code.
|
|
44
|
+
*/
|
|
39
45
|
exec(options?: IExecOptions): Q.Promise<number>;
|
|
40
46
|
execSync(options?: IExecSyncOptions): IExecSyncResult;
|
|
41
47
|
}
|
package/mock-toolrunner.js
CHANGED
|
@@ -130,6 +130,99 @@ var ToolRunner = /** @class */ (function (_super) {
|
|
|
130
130
|
// Exec - use for long running tools where you need to stream live output as it runs
|
|
131
131
|
// returns a promise with return code.
|
|
132
132
|
//
|
|
133
|
+
ToolRunner.prototype.execAsync = function (options) {
|
|
134
|
+
var _this = this;
|
|
135
|
+
this._debug('exec tool: ' + this.toolPath);
|
|
136
|
+
this._debug('Arguments:');
|
|
137
|
+
this.args.forEach(function (arg) {
|
|
138
|
+
_this._debug(' ' + arg);
|
|
139
|
+
});
|
|
140
|
+
var success = true;
|
|
141
|
+
options = options || {};
|
|
142
|
+
var ops = {
|
|
143
|
+
cwd: options.cwd || process.cwd(),
|
|
144
|
+
env: options.env || process.env,
|
|
145
|
+
silent: options.silent || false,
|
|
146
|
+
outStream: options.outStream || process.stdout,
|
|
147
|
+
errStream: options.errStream || process.stderr,
|
|
148
|
+
failOnStdErr: options.failOnStdErr || false,
|
|
149
|
+
ignoreReturnCode: options.ignoreReturnCode || false,
|
|
150
|
+
windowsVerbatimArguments: options.windowsVerbatimArguments
|
|
151
|
+
};
|
|
152
|
+
var argString = this.args.join(' ') || '';
|
|
153
|
+
var cmdString = this.toolPath;
|
|
154
|
+
if (argString) {
|
|
155
|
+
cmdString += (' ' + argString);
|
|
156
|
+
}
|
|
157
|
+
// Using split/join to replace the temp path
|
|
158
|
+
cmdString = this.ignoreTempPath(cmdString);
|
|
159
|
+
if (!ops.silent) {
|
|
160
|
+
if (this.pipeOutputToTool) {
|
|
161
|
+
var pipeToolArgString = this.pipeOutputToTool.args.join(' ') || '';
|
|
162
|
+
var pipeToolCmdString = this.ignoreTempPath(this.pipeOutputToTool.toolPath);
|
|
163
|
+
if (pipeToolArgString) {
|
|
164
|
+
pipeToolCmdString += (' ' + pipeToolArgString);
|
|
165
|
+
}
|
|
166
|
+
cmdString += ' | ' + pipeToolCmdString;
|
|
167
|
+
}
|
|
168
|
+
ops.outStream.write('[command]' + cmdString + os.EOL);
|
|
169
|
+
}
|
|
170
|
+
// TODO: filter process.env
|
|
171
|
+
var res = mock.getResponse('exec', cmdString, debug);
|
|
172
|
+
if (res.stdout) {
|
|
173
|
+
this.emit('stdout', res.stdout);
|
|
174
|
+
if (!ops.silent) {
|
|
175
|
+
ops.outStream.write(res.stdout + os.EOL);
|
|
176
|
+
}
|
|
177
|
+
var stdLineArray = res.stdout.split(os.EOL);
|
|
178
|
+
for (var _i = 0, _a = stdLineArray.slice(0, -1); _i < _a.length; _i++) {
|
|
179
|
+
var line = _a[_i];
|
|
180
|
+
this.emit('stdline', line);
|
|
181
|
+
}
|
|
182
|
+
if (stdLineArray.length > 0 && stdLineArray[stdLineArray.length - 1].length > 0) {
|
|
183
|
+
this.emit('stdline', stdLineArray[stdLineArray.length - 1]);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
if (res.stderr) {
|
|
187
|
+
this.emit('stderr', res.stderr);
|
|
188
|
+
success = !ops.failOnStdErr;
|
|
189
|
+
if (!ops.silent) {
|
|
190
|
+
var s = ops.failOnStdErr ? ops.errStream : ops.outStream;
|
|
191
|
+
s.write(res.stderr + os.EOL);
|
|
192
|
+
}
|
|
193
|
+
var stdErrArray = res.stderr.split(os.EOL);
|
|
194
|
+
for (var _b = 0, _c = stdErrArray.slice(0, -1); _b < _c.length; _b++) {
|
|
195
|
+
var line = _c[_b];
|
|
196
|
+
this.emit('errline', line);
|
|
197
|
+
}
|
|
198
|
+
if (stdErrArray.length > 0 && stdErrArray[stdErrArray.length - 1].length > 0) {
|
|
199
|
+
this.emit('errline', stdErrArray[stdErrArray.length - 1]);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
var code = res.code;
|
|
203
|
+
if (!ops.silent) {
|
|
204
|
+
ops.outStream.write('rc:' + res.code + os.EOL);
|
|
205
|
+
}
|
|
206
|
+
if (code != 0 && !ops.ignoreReturnCode) {
|
|
207
|
+
success = false;
|
|
208
|
+
}
|
|
209
|
+
if (!ops.silent) {
|
|
210
|
+
ops.outStream.write('success:' + success + os.EOL);
|
|
211
|
+
}
|
|
212
|
+
return new Promise(function (resolve, reject) {
|
|
213
|
+
if (success) {
|
|
214
|
+
resolve(code);
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
reject(new Error(_this.toolPath + ' failed with return code: ' + code));
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
};
|
|
221
|
+
/**
|
|
222
|
+
* Exec - use for long running tools where you need to stream live output as it runs
|
|
223
|
+
* @deprecated use `execAsync` instead
|
|
224
|
+
* @returns a promise with return code.
|
|
225
|
+
*/
|
|
133
226
|
ToolRunner.prototype.exec = function (options) {
|
|
134
227
|
var _this = this;
|
|
135
228
|
var defer = Q.defer();
|
|
@@ -224,7 +317,6 @@ var ToolRunner = /** @class */ (function (_super) {
|
|
|
224
317
|
//
|
|
225
318
|
ToolRunner.prototype.execSync = function (options) {
|
|
226
319
|
var _this = this;
|
|
227
|
-
var defer = Q.defer();
|
|
228
320
|
this._debug('exec tool: ' + this.toolPath);
|
|
229
321
|
this._debug('Arguments:');
|
|
230
322
|
this.args.forEach(function (arg) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "azure-pipelines-task-lib",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.5.0",
|
|
4
4
|
"description": "Azure Pipelines Task SDK",
|
|
5
5
|
"main": "./task.js",
|
|
6
6
|
"typings": "./task.d.ts",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"@types/minimatch": "3.0.3",
|
|
40
40
|
"@types/mocha": "^9.1.1",
|
|
41
41
|
"@types/mockery": "^1.4.29",
|
|
42
|
-
"@types/node": "^
|
|
42
|
+
"@types/node": "^10.17.0",
|
|
43
43
|
"@types/q": "^1.5.4",
|
|
44
44
|
"@types/semver": "^7.3.4",
|
|
45
45
|
"@types/shelljs": "^0.8.8",
|
package/task.d.ts
CHANGED
|
@@ -58,7 +58,8 @@ export declare const setErrStream: typeof im._setErrStream;
|
|
|
58
58
|
* from agent version 2.142.0 or higher (otherwise will no-op).
|
|
59
59
|
* @returns void
|
|
60
60
|
*/
|
|
61
|
-
export declare function setResult(result: TaskResult, message
|
|
61
|
+
export declare function setResult(result: TaskResult.Succeeded, message?: string, done?: boolean): void;
|
|
62
|
+
export declare function setResult(result: Exclude<TaskResult, 'Succeeded'>, message: string, done?: boolean): void;
|
|
62
63
|
export declare const setResourcePath: typeof im._setResourcePath;
|
|
63
64
|
export declare const loc: typeof im._loc;
|
|
64
65
|
export declare const getVariable: typeof im._getVariable;
|
|
@@ -485,6 +486,18 @@ export declare function rmRF(inputPath: string): void;
|
|
|
485
486
|
* @param options optional exec options. See IExecOptions
|
|
486
487
|
* @returns number
|
|
487
488
|
*/
|
|
489
|
+
export declare function execAsync(tool: string, args: any, options?: trm.IExecOptions): Promise<number>;
|
|
490
|
+
/**
|
|
491
|
+
* Exec a tool. Convenience wrapper over ToolRunner to exec with args in one call.
|
|
492
|
+
* Output will be streamed to the live console.
|
|
493
|
+
* Returns promise with return code
|
|
494
|
+
*
|
|
495
|
+
* @deprecated Use the {@link execAsync} method that returns a native Javascript Promise instead
|
|
496
|
+
* @param tool path to tool to exec
|
|
497
|
+
* @param args an arg string or array of args
|
|
498
|
+
* @param options optional exec options. See IExecOptions
|
|
499
|
+
* @returns number
|
|
500
|
+
*/
|
|
488
501
|
export declare function exec(tool: string, args: any, options?: trm.IExecOptions): Q.Promise<number>;
|
|
489
502
|
/**
|
|
490
503
|
* Exec a tool synchronously. Convenience wrapper over ToolRunner to execSync with args in one call.
|
package/task.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.updateReleaseName = exports.addBuildTag = exports.updateBuildNumber = exports.uploadBuildLog = exports.associateArtifact = exports.uploadArtifact = exports.logIssue = exports.logDetail = exports.setProgress = exports.setEndpoint = exports.addAttachment = exports.uploadSummary = exports.prependPath = exports.uploadFile = exports.CodeCoverageEnabler = exports.CodeCoveragePublisher = exports.TestPublisher = exports.getHttpCertConfiguration = exports.getHttpProxyConfiguration = exports.findMatch = exports.filter = exports.match = exports.tool = exports.execSync = exports.exec = exports.rmRF = exports.legacyFindFiles = exports.find = exports.retry = exports.mv = exports.cp = exports.ls = exports.which = exports.resolve = exports.mkdirP = exports.popd = exports.pushd = exports.cd = exports.checkPath = exports.cwd = exports.getAgentMode = exports.getPlatform = exports.osType = exports.writeFile = exports.exist = exports.stats = exports.debug = exports.error = exports.warning = exports.command = exports.setTaskVariable = exports.getTaskVariable = exports.getSecureFileTicket = exports.getSecureFileName = exports.getEndpointAuthorization = exports.getEndpointAuthorizationParameterRequired = exports.getEndpointAuthorizationParameter = exports.getEndpointAuthorizationSchemeRequired = exports.getEndpointAuthorizationScheme = exports.getEndpointDataParameterRequired = exports.getEndpointDataParameter = exports.getEndpointUrlRequired = exports.getEndpointUrl = exports.getPathInputRequired = exports.getPathInput = exports.filePathSupplied = exports.getDelimitedInput = exports.getBoolFeatureFlag = exports.getBoolInput = exports.getInputRequired = exports.getInput = exports.setSecret = exports.setVariable = exports.getVariables = exports.assertAgent = exports.getVariable = exports.loc = exports.setResourcePath = exports.setResult = exports.setErrStream = exports.setStdStream = exports.AgentHostedMode = exports.Platform = exports.FieldType = exports.ArtifactType = exports.IssueType = exports.TaskState = exports.TaskResult = void 0;
|
|
3
|
+
exports.updateReleaseName = exports.addBuildTag = exports.updateBuildNumber = exports.uploadBuildLog = exports.associateArtifact = exports.uploadArtifact = exports.logIssue = exports.logDetail = exports.setProgress = exports.setEndpoint = exports.addAttachment = exports.uploadSummary = exports.prependPath = exports.uploadFile = exports.CodeCoverageEnabler = exports.CodeCoveragePublisher = exports.TestPublisher = exports.getHttpCertConfiguration = exports.getHttpProxyConfiguration = exports.findMatch = exports.filter = exports.match = exports.tool = exports.execSync = exports.exec = exports.execAsync = exports.rmRF = exports.legacyFindFiles = exports.find = exports.retry = exports.mv = exports.cp = exports.ls = exports.which = exports.resolve = exports.mkdirP = exports.popd = exports.pushd = exports.cd = exports.checkPath = exports.cwd = exports.getAgentMode = exports.getPlatform = exports.osType = exports.writeFile = exports.exist = exports.stats = exports.debug = exports.error = exports.warning = exports.command = exports.setTaskVariable = exports.getTaskVariable = exports.getSecureFileTicket = exports.getSecureFileName = exports.getEndpointAuthorization = exports.getEndpointAuthorizationParameterRequired = exports.getEndpointAuthorizationParameter = exports.getEndpointAuthorizationSchemeRequired = exports.getEndpointAuthorizationScheme = exports.getEndpointDataParameterRequired = exports.getEndpointDataParameter = exports.getEndpointUrlRequired = exports.getEndpointUrl = exports.getPathInputRequired = exports.getPathInput = exports.filePathSupplied = exports.getDelimitedInput = exports.getBoolFeatureFlag = exports.getBoolInput = exports.getInputRequired = exports.getInput = exports.setSecret = exports.setVariable = exports.getVariables = exports.assertAgent = exports.getVariable = exports.loc = exports.setResourcePath = exports.setResult = exports.setErrStream = exports.setStdStream = exports.AgentHostedMode = exports.Platform = exports.FieldType = exports.ArtifactType = exports.IssueType = exports.TaskState = exports.TaskResult = void 0;
|
|
4
4
|
var shell = require("shelljs");
|
|
5
5
|
var childProcess = require("child_process");
|
|
6
6
|
var fs = require("fs");
|
|
@@ -63,22 +63,6 @@ var AgentHostedMode;
|
|
|
63
63
|
//-----------------------------------------------------
|
|
64
64
|
exports.setStdStream = im._setStdStream;
|
|
65
65
|
exports.setErrStream = im._setErrStream;
|
|
66
|
-
//-----------------------------------------------------
|
|
67
|
-
// Results
|
|
68
|
-
//-----------------------------------------------------
|
|
69
|
-
/**
|
|
70
|
-
* Sets the result of the task.
|
|
71
|
-
* Execution will continue.
|
|
72
|
-
* If not set, task will be Succeeded.
|
|
73
|
-
* If multiple calls are made to setResult the most pessimistic call wins (Failed) regardless of the order of calls.
|
|
74
|
-
*
|
|
75
|
-
* @param result TaskResult enum of Succeeded, SucceededWithIssues, Failed, Cancelled or Skipped.
|
|
76
|
-
* @param message A message which will be logged as an error issue if the result is Failed.
|
|
77
|
-
* @param done Optional. Instructs the agent the task is done. This is helpful when child processes
|
|
78
|
-
* may still be running and prevent node from fully exiting. This argument is supported
|
|
79
|
-
* from agent version 2.142.0 or higher (otherwise will no-op).
|
|
80
|
-
* @returns void
|
|
81
|
-
*/
|
|
82
66
|
function setResult(result, message, done) {
|
|
83
67
|
exports.debug('task result: ' + TaskResult[result]);
|
|
84
68
|
// add an error issue
|
|
@@ -1280,6 +1264,33 @@ exports.rmRF = rmRF;
|
|
|
1280
1264
|
* @param options optional exec options. See IExecOptions
|
|
1281
1265
|
* @returns number
|
|
1282
1266
|
*/
|
|
1267
|
+
function execAsync(tool, args, options) {
|
|
1268
|
+
var tr = this.tool(tool);
|
|
1269
|
+
tr.on('debug', function (data) {
|
|
1270
|
+
exports.debug(data);
|
|
1271
|
+
});
|
|
1272
|
+
if (args) {
|
|
1273
|
+
if (args instanceof Array) {
|
|
1274
|
+
tr.arg(args);
|
|
1275
|
+
}
|
|
1276
|
+
else if (typeof (args) === 'string') {
|
|
1277
|
+
tr.line(args);
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1280
|
+
return tr.execAsync(options);
|
|
1281
|
+
}
|
|
1282
|
+
exports.execAsync = execAsync;
|
|
1283
|
+
/**
|
|
1284
|
+
* Exec a tool. Convenience wrapper over ToolRunner to exec with args in one call.
|
|
1285
|
+
* Output will be streamed to the live console.
|
|
1286
|
+
* Returns promise with return code
|
|
1287
|
+
*
|
|
1288
|
+
* @deprecated Use the {@link execAsync} method that returns a native Javascript Promise instead
|
|
1289
|
+
* @param tool path to tool to exec
|
|
1290
|
+
* @param args an arg string or array of args
|
|
1291
|
+
* @param options optional exec options. See IExecOptions
|
|
1292
|
+
* @returns number
|
|
1293
|
+
*/
|
|
1283
1294
|
function exec(tool, args, options) {
|
|
1284
1295
|
var tr = this.tool(tool);
|
|
1285
1296
|
tr.on('debug', function (data) {
|
package/toolrunner.d.ts
CHANGED
|
@@ -94,6 +94,7 @@ export declare class ToolRunner extends events.EventEmitter {
|
|
|
94
94
|
private _cloneExecOptions;
|
|
95
95
|
private _getSpawnOptions;
|
|
96
96
|
private _getSpawnSyncOptions;
|
|
97
|
+
private execWithPipingAsync;
|
|
97
98
|
private execWithPiping;
|
|
98
99
|
/**
|
|
99
100
|
* Add argument
|
|
@@ -139,6 +140,17 @@ export declare class ToolRunner extends events.EventEmitter {
|
|
|
139
140
|
* @param options optional exec options. See IExecOptions
|
|
140
141
|
* @returns number
|
|
141
142
|
*/
|
|
143
|
+
execAsync(options?: IExecOptions): Promise<number>;
|
|
144
|
+
/**
|
|
145
|
+
* Exec a tool.
|
|
146
|
+
* Output will be streamed to the live console.
|
|
147
|
+
* Returns promise with return code
|
|
148
|
+
*
|
|
149
|
+
* @deprecated Use the `execAsync` method that returns a native Javascript promise instead
|
|
150
|
+
* @param tool path to tool to exec
|
|
151
|
+
* @param options optional exec options. See IExecOptions
|
|
152
|
+
* @returns number
|
|
153
|
+
*/
|
|
142
154
|
exec(options?: IExecOptions): Q.Promise<number>;
|
|
143
155
|
/**
|
|
144
156
|
* Exec a tool synchronously.
|
package/toolrunner.js
CHANGED
|
@@ -516,6 +516,184 @@ var ToolRunner = /** @class */ (function (_super) {
|
|
|
516
516
|
result['windowsVerbatimArguments'] = options.windowsVerbatimArguments || this._isCmdFile();
|
|
517
517
|
return result;
|
|
518
518
|
};
|
|
519
|
+
ToolRunner.prototype.execWithPipingAsync = function (pipeOutputToTool, options) {
|
|
520
|
+
var _this = this;
|
|
521
|
+
this._debug('exec tool: ' + this.toolPath);
|
|
522
|
+
this._debug('arguments:');
|
|
523
|
+
this.args.forEach(function (arg) {
|
|
524
|
+
_this._debug(' ' + arg);
|
|
525
|
+
});
|
|
526
|
+
var success = true;
|
|
527
|
+
var optionsNonNull = this._cloneExecOptions(options);
|
|
528
|
+
if (!optionsNonNull.silent) {
|
|
529
|
+
optionsNonNull.outStream.write(this._getCommandString(optionsNonNull) + os.EOL);
|
|
530
|
+
}
|
|
531
|
+
var cp;
|
|
532
|
+
var toolPath = pipeOutputToTool.toolPath;
|
|
533
|
+
var toolPathFirst;
|
|
534
|
+
var successFirst = true;
|
|
535
|
+
var returnCodeFirst;
|
|
536
|
+
var fileStream;
|
|
537
|
+
var waitingEvents = 0; // number of process or stream events we are waiting on to complete
|
|
538
|
+
var returnCode = 0;
|
|
539
|
+
var error;
|
|
540
|
+
toolPathFirst = this.toolPath;
|
|
541
|
+
// Following node documentation example from this link on how to pipe output of one process to another
|
|
542
|
+
// https://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options
|
|
543
|
+
//start the child process for both tools
|
|
544
|
+
waitingEvents++;
|
|
545
|
+
var cpFirst = child.spawn(this._getSpawnFileName(optionsNonNull), this._getSpawnArgs(optionsNonNull), this._getSpawnOptions(optionsNonNull));
|
|
546
|
+
waitingEvents++;
|
|
547
|
+
cp = child.spawn(pipeOutputToTool._getSpawnFileName(optionsNonNull), pipeOutputToTool._getSpawnArgs(optionsNonNull), pipeOutputToTool._getSpawnOptions(optionsNonNull));
|
|
548
|
+
fileStream = this.pipeOutputToFile ? fs.createWriteStream(this.pipeOutputToFile) : null;
|
|
549
|
+
return new Promise(function (resolve, reject) {
|
|
550
|
+
var _a, _b, _c, _d;
|
|
551
|
+
if (fileStream) {
|
|
552
|
+
waitingEvents++;
|
|
553
|
+
fileStream.on('finish', function () {
|
|
554
|
+
waitingEvents--; //file write is complete
|
|
555
|
+
fileStream = null;
|
|
556
|
+
if (waitingEvents == 0) {
|
|
557
|
+
if (error) {
|
|
558
|
+
reject(error);
|
|
559
|
+
}
|
|
560
|
+
else {
|
|
561
|
+
resolve(returnCode);
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
});
|
|
565
|
+
fileStream.on('error', function (err) {
|
|
566
|
+
waitingEvents--; //there were errors writing to the file, write is done
|
|
567
|
+
_this._debug("Failed to pipe output of " + toolPathFirst + " to file " + _this.pipeOutputToFile + ". Error = " + err);
|
|
568
|
+
fileStream = null;
|
|
569
|
+
if (waitingEvents == 0) {
|
|
570
|
+
if (error) {
|
|
571
|
+
reject(error);
|
|
572
|
+
}
|
|
573
|
+
else {
|
|
574
|
+
resolve(returnCode);
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
});
|
|
578
|
+
}
|
|
579
|
+
//pipe stdout of first tool to stdin of second tool
|
|
580
|
+
(_a = cpFirst.stdout) === null || _a === void 0 ? void 0 : _a.on('data', function (data) {
|
|
581
|
+
var _a;
|
|
582
|
+
try {
|
|
583
|
+
if (fileStream) {
|
|
584
|
+
fileStream.write(data);
|
|
585
|
+
}
|
|
586
|
+
(_a = cp.stdin) === null || _a === void 0 ? void 0 : _a.write(data);
|
|
587
|
+
}
|
|
588
|
+
catch (err) {
|
|
589
|
+
_this._debug('Failed to pipe output of ' + toolPathFirst + ' to ' + toolPath);
|
|
590
|
+
_this._debug(toolPath + ' might have exited due to errors prematurely. Verify the arguments passed are valid.');
|
|
591
|
+
}
|
|
592
|
+
});
|
|
593
|
+
(_b = cpFirst.stderr) === null || _b === void 0 ? void 0 : _b.on('data', function (data) {
|
|
594
|
+
if (fileStream) {
|
|
595
|
+
fileStream.write(data);
|
|
596
|
+
}
|
|
597
|
+
successFirst = !optionsNonNull.failOnStdErr;
|
|
598
|
+
if (!optionsNonNull.silent) {
|
|
599
|
+
var s = optionsNonNull.failOnStdErr ? optionsNonNull.errStream : optionsNonNull.outStream;
|
|
600
|
+
s.write(data);
|
|
601
|
+
}
|
|
602
|
+
});
|
|
603
|
+
cpFirst.on('error', function (err) {
|
|
604
|
+
var _a;
|
|
605
|
+
waitingEvents--; //first process is complete with errors
|
|
606
|
+
if (fileStream) {
|
|
607
|
+
fileStream.end();
|
|
608
|
+
}
|
|
609
|
+
(_a = cp.stdin) === null || _a === void 0 ? void 0 : _a.end();
|
|
610
|
+
error = new Error(toolPathFirst + ' failed. ' + err.message);
|
|
611
|
+
if (waitingEvents == 0) {
|
|
612
|
+
reject(error);
|
|
613
|
+
}
|
|
614
|
+
});
|
|
615
|
+
cpFirst.on('close', function (code, signal) {
|
|
616
|
+
var _a;
|
|
617
|
+
waitingEvents--; //first process is complete
|
|
618
|
+
if (code != 0 && !optionsNonNull.ignoreReturnCode) {
|
|
619
|
+
successFirst = false;
|
|
620
|
+
returnCodeFirst = code;
|
|
621
|
+
returnCode = returnCodeFirst;
|
|
622
|
+
}
|
|
623
|
+
_this._debug('success of first tool:' + successFirst);
|
|
624
|
+
if (fileStream) {
|
|
625
|
+
fileStream.end();
|
|
626
|
+
}
|
|
627
|
+
(_a = cp.stdin) === null || _a === void 0 ? void 0 : _a.end();
|
|
628
|
+
if (waitingEvents == 0) {
|
|
629
|
+
if (error) {
|
|
630
|
+
reject(error);
|
|
631
|
+
}
|
|
632
|
+
else {
|
|
633
|
+
resolve(returnCode);
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
});
|
|
637
|
+
var stdbuffer = '';
|
|
638
|
+
(_c = cp.stdout) === null || _c === void 0 ? void 0 : _c.on('data', function (data) {
|
|
639
|
+
_this.emit('stdout', data);
|
|
640
|
+
if (!optionsNonNull.silent) {
|
|
641
|
+
optionsNonNull.outStream.write(data);
|
|
642
|
+
}
|
|
643
|
+
_this._processLineBuffer(data, stdbuffer, function (line) {
|
|
644
|
+
_this.emit('stdline', line);
|
|
645
|
+
});
|
|
646
|
+
});
|
|
647
|
+
var errbuffer = '';
|
|
648
|
+
(_d = cp.stderr) === null || _d === void 0 ? void 0 : _d.on('data', function (data) {
|
|
649
|
+
_this.emit('stderr', data);
|
|
650
|
+
success = !optionsNonNull.failOnStdErr;
|
|
651
|
+
if (!optionsNonNull.silent) {
|
|
652
|
+
var s = optionsNonNull.failOnStdErr ? optionsNonNull.errStream : optionsNonNull.outStream;
|
|
653
|
+
s.write(data);
|
|
654
|
+
}
|
|
655
|
+
_this._processLineBuffer(data, errbuffer, function (line) {
|
|
656
|
+
_this.emit('errline', line);
|
|
657
|
+
});
|
|
658
|
+
});
|
|
659
|
+
cp.on('error', function (err) {
|
|
660
|
+
waitingEvents--; //process is done with errors
|
|
661
|
+
error = new Error(toolPath + ' failed. ' + err.message);
|
|
662
|
+
if (waitingEvents == 0) {
|
|
663
|
+
reject(error);
|
|
664
|
+
}
|
|
665
|
+
});
|
|
666
|
+
cp.on('close', function (code, signal) {
|
|
667
|
+
waitingEvents--; //process is complete
|
|
668
|
+
_this._debug('rc:' + code);
|
|
669
|
+
returnCode = code;
|
|
670
|
+
if (stdbuffer.length > 0) {
|
|
671
|
+
_this.emit('stdline', stdbuffer);
|
|
672
|
+
}
|
|
673
|
+
if (errbuffer.length > 0) {
|
|
674
|
+
_this.emit('errline', errbuffer);
|
|
675
|
+
}
|
|
676
|
+
if (code != 0 && !optionsNonNull.ignoreReturnCode) {
|
|
677
|
+
success = false;
|
|
678
|
+
}
|
|
679
|
+
_this._debug('success:' + success);
|
|
680
|
+
if (!successFirst) { //in the case output is piped to another tool, check exit code of both tools
|
|
681
|
+
error = new Error(toolPathFirst + ' failed with return code: ' + returnCodeFirst);
|
|
682
|
+
}
|
|
683
|
+
else if (!success) {
|
|
684
|
+
error = new Error(toolPath + ' failed with return code: ' + code);
|
|
685
|
+
}
|
|
686
|
+
if (waitingEvents == 0) {
|
|
687
|
+
if (error) {
|
|
688
|
+
reject(error);
|
|
689
|
+
}
|
|
690
|
+
else {
|
|
691
|
+
resolve(returnCode);
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
});
|
|
695
|
+
});
|
|
696
|
+
};
|
|
519
697
|
ToolRunner.prototype.execWithPiping = function (pipeOutputToTool, options) {
|
|
520
698
|
var _this = this;
|
|
521
699
|
var _a, _b, _c, _d;
|
|
@@ -767,6 +945,104 @@ var ToolRunner = /** @class */ (function (_super) {
|
|
|
767
945
|
* @param options optional exec options. See IExecOptions
|
|
768
946
|
* @returns number
|
|
769
947
|
*/
|
|
948
|
+
ToolRunner.prototype.execAsync = function (options) {
|
|
949
|
+
var _this = this;
|
|
950
|
+
var _a, _b, _c;
|
|
951
|
+
if (this.pipeOutputToTool) {
|
|
952
|
+
return this.execWithPipingAsync(this.pipeOutputToTool, options);
|
|
953
|
+
}
|
|
954
|
+
this._debug('exec tool: ' + this.toolPath);
|
|
955
|
+
this._debug('arguments:');
|
|
956
|
+
this.args.forEach(function (arg) {
|
|
957
|
+
_this._debug(' ' + arg);
|
|
958
|
+
});
|
|
959
|
+
var optionsNonNull = this._cloneExecOptions(options);
|
|
960
|
+
if (!optionsNonNull.silent) {
|
|
961
|
+
optionsNonNull.outStream.write(this._getCommandString(optionsNonNull) + os.EOL);
|
|
962
|
+
}
|
|
963
|
+
var state = new ExecState(optionsNonNull, this.toolPath);
|
|
964
|
+
state.on('debug', function (message) {
|
|
965
|
+
_this._debug(message);
|
|
966
|
+
});
|
|
967
|
+
var cp = child.spawn(this._getSpawnFileName(options), this._getSpawnArgs(optionsNonNull), this._getSpawnOptions(options));
|
|
968
|
+
this.childProcess = cp;
|
|
969
|
+
// it is possible for the child process to end its last line without a new line.
|
|
970
|
+
// because stdout is buffered, this causes the last line to not get sent to the parent
|
|
971
|
+
// stream. Adding this event forces a flush before the child streams are closed.
|
|
972
|
+
(_a = cp.stdout) === null || _a === void 0 ? void 0 : _a.on('finish', function () {
|
|
973
|
+
if (!optionsNonNull.silent) {
|
|
974
|
+
optionsNonNull.outStream.write(os.EOL);
|
|
975
|
+
}
|
|
976
|
+
});
|
|
977
|
+
var stdbuffer = '';
|
|
978
|
+
(_b = cp.stdout) === null || _b === void 0 ? void 0 : _b.on('data', function (data) {
|
|
979
|
+
_this.emit('stdout', data);
|
|
980
|
+
if (!optionsNonNull.silent) {
|
|
981
|
+
optionsNonNull.outStream.write(data);
|
|
982
|
+
}
|
|
983
|
+
_this._processLineBuffer(data, stdbuffer, function (line) {
|
|
984
|
+
_this.emit('stdline', line);
|
|
985
|
+
});
|
|
986
|
+
});
|
|
987
|
+
var errbuffer = '';
|
|
988
|
+
(_c = cp.stderr) === null || _c === void 0 ? void 0 : _c.on('data', function (data) {
|
|
989
|
+
state.processStderr = true;
|
|
990
|
+
_this.emit('stderr', data);
|
|
991
|
+
if (!optionsNonNull.silent) {
|
|
992
|
+
var s = optionsNonNull.failOnStdErr ? optionsNonNull.errStream : optionsNonNull.outStream;
|
|
993
|
+
s.write(data);
|
|
994
|
+
}
|
|
995
|
+
_this._processLineBuffer(data, errbuffer, function (line) {
|
|
996
|
+
_this.emit('errline', line);
|
|
997
|
+
});
|
|
998
|
+
});
|
|
999
|
+
cp.on('error', function (err) {
|
|
1000
|
+
state.processError = err.message;
|
|
1001
|
+
state.processExited = true;
|
|
1002
|
+
state.processClosed = true;
|
|
1003
|
+
state.CheckComplete();
|
|
1004
|
+
});
|
|
1005
|
+
cp.on('exit', function (code, signal) {
|
|
1006
|
+
state.processExitCode = code;
|
|
1007
|
+
state.processExited = true;
|
|
1008
|
+
_this._debug("Exit code " + code + " received from tool '" + _this.toolPath + "'");
|
|
1009
|
+
state.CheckComplete();
|
|
1010
|
+
});
|
|
1011
|
+
cp.on('close', function (code, signal) {
|
|
1012
|
+
state.processExitCode = code;
|
|
1013
|
+
state.processExited = true;
|
|
1014
|
+
state.processClosed = true;
|
|
1015
|
+
_this._debug("STDIO streams have closed for tool '" + _this.toolPath + "'");
|
|
1016
|
+
state.CheckComplete();
|
|
1017
|
+
});
|
|
1018
|
+
return new Promise(function (resolve, reject) {
|
|
1019
|
+
state.on('done', function (error, exitCode) {
|
|
1020
|
+
if (stdbuffer.length > 0) {
|
|
1021
|
+
_this.emit('stdline', stdbuffer);
|
|
1022
|
+
}
|
|
1023
|
+
if (errbuffer.length > 0) {
|
|
1024
|
+
_this.emit('errline', errbuffer);
|
|
1025
|
+
}
|
|
1026
|
+
cp.removeAllListeners();
|
|
1027
|
+
if (error) {
|
|
1028
|
+
reject(error);
|
|
1029
|
+
}
|
|
1030
|
+
else {
|
|
1031
|
+
resolve(exitCode);
|
|
1032
|
+
}
|
|
1033
|
+
});
|
|
1034
|
+
});
|
|
1035
|
+
};
|
|
1036
|
+
/**
|
|
1037
|
+
* Exec a tool.
|
|
1038
|
+
* Output will be streamed to the live console.
|
|
1039
|
+
* Returns promise with return code
|
|
1040
|
+
*
|
|
1041
|
+
* @deprecated Use the `execAsync` method that returns a native Javascript promise instead
|
|
1042
|
+
* @param tool path to tool to exec
|
|
1043
|
+
* @param options optional exec options. See IExecOptions
|
|
1044
|
+
* @returns number
|
|
1045
|
+
*/
|
|
770
1046
|
ToolRunner.prototype.exec = function (options) {
|
|
771
1047
|
var _this = this;
|
|
772
1048
|
var _a, _b, _c;
|