azure-pipelines-task-lib 4.0.1-preview → 4.0.2

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/task.js CHANGED
@@ -1,2003 +1,2003 @@
1
- "use strict";
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.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.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.Platform = exports.FieldType = exports.ArtifactType = exports.IssueType = exports.TaskState = exports.TaskResult = void 0;
4
- var shell = require("shelljs");
5
- var childProcess = require("child_process");
6
- var fs = require("fs");
7
- var path = require("path");
8
- var os = require("os");
9
- var minimatch = require("minimatch");
10
- var im = require("./internal");
11
- var tcm = require("./taskcommand");
12
- var trm = require("./toolrunner");
13
- var semver = require("semver");
14
- var TaskResult;
15
- (function (TaskResult) {
16
- TaskResult[TaskResult["Succeeded"] = 0] = "Succeeded";
17
- TaskResult[TaskResult["SucceededWithIssues"] = 1] = "SucceededWithIssues";
18
- TaskResult[TaskResult["Failed"] = 2] = "Failed";
19
- TaskResult[TaskResult["Cancelled"] = 3] = "Cancelled";
20
- TaskResult[TaskResult["Skipped"] = 4] = "Skipped";
21
- })(TaskResult = exports.TaskResult || (exports.TaskResult = {}));
22
- var TaskState;
23
- (function (TaskState) {
24
- TaskState[TaskState["Unknown"] = 0] = "Unknown";
25
- TaskState[TaskState["Initialized"] = 1] = "Initialized";
26
- TaskState[TaskState["InProgress"] = 2] = "InProgress";
27
- TaskState[TaskState["Completed"] = 3] = "Completed";
28
- })(TaskState = exports.TaskState || (exports.TaskState = {}));
29
- var IssueType;
30
- (function (IssueType) {
31
- IssueType[IssueType["Error"] = 0] = "Error";
32
- IssueType[IssueType["Warning"] = 1] = "Warning";
33
- })(IssueType = exports.IssueType || (exports.IssueType = {}));
34
- var ArtifactType;
35
- (function (ArtifactType) {
36
- ArtifactType[ArtifactType["Container"] = 0] = "Container";
37
- ArtifactType[ArtifactType["FilePath"] = 1] = "FilePath";
38
- ArtifactType[ArtifactType["VersionControl"] = 2] = "VersionControl";
39
- ArtifactType[ArtifactType["GitRef"] = 3] = "GitRef";
40
- ArtifactType[ArtifactType["TfvcLabel"] = 4] = "TfvcLabel";
41
- })(ArtifactType = exports.ArtifactType || (exports.ArtifactType = {}));
42
- var FieldType;
43
- (function (FieldType) {
44
- FieldType[FieldType["AuthParameter"] = 0] = "AuthParameter";
45
- FieldType[FieldType["DataParameter"] = 1] = "DataParameter";
46
- FieldType[FieldType["Url"] = 2] = "Url";
47
- })(FieldType = exports.FieldType || (exports.FieldType = {}));
48
- /** Platforms supported by our build agent */
49
- var Platform;
50
- (function (Platform) {
51
- Platform[Platform["Windows"] = 0] = "Windows";
52
- Platform[Platform["MacOS"] = 1] = "MacOS";
53
- Platform[Platform["Linux"] = 2] = "Linux";
54
- })(Platform = exports.Platform || (exports.Platform = {}));
55
- //-----------------------------------------------------
56
- // General Helpers
57
- //-----------------------------------------------------
58
- exports.setStdStream = im._setStdStream;
59
- exports.setErrStream = im._setErrStream;
60
- //-----------------------------------------------------
61
- // Results
62
- //-----------------------------------------------------
63
- /**
64
- * Sets the result of the task.
65
- * Execution will continue.
66
- * If not set, task will be Succeeded.
67
- * If multiple calls are made to setResult the most pessimistic call wins (Failed) regardless of the order of calls.
68
- *
69
- * @param result TaskResult enum of Succeeded, SucceededWithIssues, Failed, Cancelled or Skipped.
70
- * @param message A message which will be logged as an error issue if the result is Failed.
71
- * @param done Optional. Instructs the agent the task is done. This is helpful when child processes
72
- * may still be running and prevent node from fully exiting. This argument is supported
73
- * from agent version 2.142.0 or higher (otherwise will no-op).
74
- * @returns void
75
- */
76
- function setResult(result, message, done) {
77
- exports.debug('task result: ' + TaskResult[result]);
78
- // add an error issue
79
- if (result == TaskResult.Failed && message) {
80
- exports.error(message);
81
- }
82
- else if (result == TaskResult.SucceededWithIssues && message) {
83
- exports.warning(message);
84
- }
85
- // task.complete
86
- var properties = { 'result': TaskResult[result] };
87
- if (done) {
88
- properties['done'] = 'true';
89
- }
90
- exports.command('task.complete', properties, message);
91
- }
92
- exports.setResult = setResult;
93
- //
94
- // Catching all exceptions
95
- //
96
- process.on('uncaughtException', function (err) {
97
- setResult(TaskResult.Failed, exports.loc('LIB_UnhandledEx', err.message));
98
- });
99
- //-----------------------------------------------------
100
- // Loc Helpers
101
- //-----------------------------------------------------
102
- exports.setResourcePath = im._setResourcePath;
103
- exports.loc = im._loc;
104
- //-----------------------------------------------------
105
- // Input Helpers
106
- //-----------------------------------------------------
107
- exports.getVariable = im._getVariable;
108
- /**
109
- * Asserts the agent version is at least the specified minimum.
110
- *
111
- * @param minimum minimum version version - must be 2.104.1 or higher
112
- */
113
- function assertAgent(minimum) {
114
- if (semver.lt(minimum, '2.104.1')) {
115
- throw new Error('assertAgent() requires the parameter to be 2.104.1 or higher');
116
- }
117
- var agent = exports.getVariable('Agent.Version');
118
- if (agent && semver.lt(agent, minimum)) {
119
- throw new Error("Agent version " + minimum + " or higher is required");
120
- }
121
- }
122
- exports.assertAgent = assertAgent;
123
- /**
124
- * Gets a snapshot of the current state of all job variables available to the task.
125
- * Requires a 2.104.1 agent or higher for full functionality.
126
- *
127
- * Limitations on an agent prior to 2.104.1:
128
- * 1) The return value does not include all public variables. Only public variables
129
- * that have been added using setVariable are returned.
130
- * 2) The name returned for each secret variable is the formatted environment variable
131
- * name, not the actual variable name (unless it was set explicitly at runtime using
132
- * setVariable).
133
- *
134
- * @returns VariableInfo[]
135
- */
136
- function getVariables() {
137
- return Object.keys(im._knownVariableMap)
138
- .map(function (key) {
139
- var info = im._knownVariableMap[key];
140
- return { name: info.name, value: exports.getVariable(info.name), secret: info.secret };
141
- });
142
- }
143
- exports.getVariables = getVariables;
144
- /**
145
- * Sets a variable which will be available to subsequent tasks as well.
146
- *
147
- * @param name name of the variable to set
148
- * @param val value to set
149
- * @param secret whether variable is secret. Multi-line secrets are not allowed. Optional, defaults to false
150
- * @param isOutput whether variable is an output variable. Optional, defaults to false
151
- * @returns void
152
- */
153
- function setVariable(name, val, secret, isOutput) {
154
- if (secret === void 0) { secret = false; }
155
- if (isOutput === void 0) { isOutput = false; }
156
- // once a secret always a secret
157
- var key = im._getVariableKey(name);
158
- if (im._knownVariableMap.hasOwnProperty(key)) {
159
- secret = secret || im._knownVariableMap[key].secret;
160
- }
161
- // store the value
162
- var varValue = val || '';
163
- exports.debug('set ' + name + '=' + (secret && varValue ? '********' : varValue));
164
- if (secret) {
165
- if (varValue && varValue.match(/\r|\n/) && ("" + process.env['SYSTEM_UNSAFEALLOWMULTILINESECRET']).toUpperCase() != 'TRUE') {
166
- throw new Error(exports.loc('LIB_MultilineSecret'));
167
- }
168
- im._vault.storeSecret('SECRET_' + key, varValue);
169
- delete process.env[key];
170
- }
171
- else {
172
- process.env[key] = varValue;
173
- }
174
- // store the metadata
175
- im._knownVariableMap[key] = { name: name, secret: secret };
176
- // write the setvariable command
177
- exports.command('task.setvariable', { 'variable': name || '', isOutput: (isOutput || false).toString(), 'issecret': (secret || false).toString() }, varValue);
178
- }
179
- exports.setVariable = setVariable;
180
- /**
181
- * Registers a value with the logger, so the value will be masked from the logs. Multi-line secrets are not allowed.
182
- *
183
- * @param val value to register
184
- */
185
- function setSecret(val) {
186
- if (val) {
187
- if (val.match(/\r|\n/) && ("" + process.env['SYSTEM_UNSAFEALLOWMULTILINESECRET']).toUpperCase() !== 'TRUE') {
188
- throw new Error(exports.loc('LIB_MultilineSecret'));
189
- }
190
- exports.command('task.setsecret', {}, val);
191
- }
192
- }
193
- exports.setSecret = setSecret;
194
- /**
195
- * Gets the value of an input.
196
- * If required is true and the value is not set, it will throw.
197
- *
198
- * @param name name of the input to get
199
- * @param required whether input is required. optional, defaults to false
200
- * @returns string
201
- */
202
- function getInput(name, required) {
203
- var inval = im._vault.retrieveSecret('INPUT_' + im._getVariableKey(name));
204
- if (required && !inval) {
205
- throw new Error(exports.loc('LIB_InputRequired', name));
206
- }
207
- exports.debug(name + '=' + inval);
208
- return inval;
209
- }
210
- exports.getInput = getInput;
211
- /**
212
- * Gets the value of an input.
213
- * If the value is not set, it will throw.
214
- *
215
- * @param name name of the input to get
216
- * @returns string
217
- */
218
- function getInputRequired(name) {
219
- return getInput(name, true);
220
- }
221
- exports.getInputRequired = getInputRequired;
222
- /**
223
- * Gets the value of an input and converts to a bool. Convenience.
224
- * If required is true and the value is not set, it will throw.
225
- * If required is false and the value is not set, returns false.
226
- *
227
- * @param name name of the bool input to get
228
- * @param required whether input is required. optional, defaults to false
229
- * @returns boolean
230
- */
231
- function getBoolInput(name, required) {
232
- return (getInput(name, required) || '').toUpperCase() == "TRUE";
233
- }
234
- exports.getBoolInput = getBoolInput;
235
- /**
236
- * Gets the value of an input and splits the value using a delimiter (space, comma, etc).
237
- * Empty values are removed. This function is useful for splitting an input containing a simple
238
- * list of items - such as build targets.
239
- * IMPORTANT: Do not use this function for splitting additional args! Instead use argString(), which
240
- * follows normal argument splitting rules and handles values encapsulated by quotes.
241
- * If required is true and the value is not set, it will throw.
242
- *
243
- * @param name name of the input to get
244
- * @param delim delimiter to split on
245
- * @param required whether input is required. optional, defaults to false
246
- * @returns string[]
247
- */
248
- function getDelimitedInput(name, delim, required) {
249
- var inputVal = getInput(name, required);
250
- if (!inputVal) {
251
- return [];
252
- }
253
- var result = [];
254
- inputVal.split(delim).forEach(function (x) {
255
- if (x) {
256
- result.push(x);
257
- }
258
- });
259
- return result;
260
- }
261
- exports.getDelimitedInput = getDelimitedInput;
262
- /**
263
- * Checks whether a path inputs value was supplied by the user
264
- * File paths are relative with a picker, so an empty path is the root of the repo.
265
- * Useful if you need to condition work (like append an arg) if a value was supplied
266
- *
267
- * @param name name of the path input to check
268
- * @returns boolean
269
- */
270
- function filePathSupplied(name) {
271
- // normalize paths
272
- var pathValue = this.resolve(this.getPathInput(name) || '');
273
- var repoRoot = this.resolve(exports.getVariable('build.sourcesDirectory') || exports.getVariable('system.defaultWorkingDirectory') || '');
274
- var supplied = pathValue !== repoRoot;
275
- exports.debug(name + 'path supplied :' + supplied);
276
- return supplied;
277
- }
278
- exports.filePathSupplied = filePathSupplied;
279
- /**
280
- * Gets the value of a path input
281
- * It will be quoted for you if it isn't already and contains spaces
282
- * If required is true and the value is not set, it will throw.
283
- * If check is true and the path does not exist, it will throw.
284
- *
285
- * @param name name of the input to get
286
- * @param required whether input is required. optional, defaults to false
287
- * @param check whether path is checked. optional, defaults to false
288
- * @returns string
289
- */
290
- function getPathInput(name, required, check) {
291
- var inval = getInput(name, required);
292
- if (inval) {
293
- if (check) {
294
- exports.checkPath(inval, name);
295
- }
296
- }
297
- return inval;
298
- }
299
- exports.getPathInput = getPathInput;
300
- /**
301
- * Gets the value of a path input
302
- * It will be quoted for you if it isn't already and contains spaces
303
- * If the value is not set, it will throw.
304
- * If check is true and the path does not exist, it will throw.
305
- *
306
- * @param name name of the input to get
307
- * @param check whether path is checked. optional, defaults to false
308
- * @returns string
309
- */
310
- function getPathInputRequired(name, check) {
311
- return getPathInput(name, true, check);
312
- }
313
- exports.getPathInputRequired = getPathInputRequired;
314
- //-----------------------------------------------------
315
- // Endpoint Helpers
316
- //-----------------------------------------------------
317
- /**
318
- * Gets the url for a service endpoint
319
- * If the url was not set and is not optional, it will throw.
320
- *
321
- * @param id name of the service endpoint
322
- * @param optional whether the url is optional
323
- * @returns string
324
- */
325
- function getEndpointUrl(id, optional) {
326
- var urlval = process.env['ENDPOINT_URL_' + id];
327
- if (!optional && !urlval) {
328
- throw new Error(exports.loc('LIB_EndpointNotExist', id));
329
- }
330
- exports.debug(id + '=' + urlval);
331
- return urlval;
332
- }
333
- exports.getEndpointUrl = getEndpointUrl;
334
- /**
335
- * Gets the url for a service endpoint
336
- * If the url was not set, it will throw.
337
- *
338
- * @param id name of the service endpoint
339
- * @returns string
340
- */
341
- function getEndpointUrlRequired(id) {
342
- return getEndpointUrl(id, false);
343
- }
344
- exports.getEndpointUrlRequired = getEndpointUrlRequired;
345
- /*
346
- * Gets the endpoint data parameter value with specified key for a service endpoint
347
- * If the endpoint data parameter was not set and is not optional, it will throw.
348
- *
349
- * @param id name of the service endpoint
350
- * @param key of the parameter
351
- * @param optional whether the endpoint data is optional
352
- * @returns {string} value of the endpoint data parameter
353
- */
354
- function getEndpointDataParameter(id, key, optional) {
355
- var dataParamVal = process.env['ENDPOINT_DATA_' + id + '_' + key.toUpperCase()];
356
- if (!optional && !dataParamVal) {
357
- throw new Error(exports.loc('LIB_EndpointDataNotExist', id, key));
358
- }
359
- exports.debug(id + ' data ' + key + ' = ' + dataParamVal);
360
- return dataParamVal;
361
- }
362
- exports.getEndpointDataParameter = getEndpointDataParameter;
363
- /*
364
- * Gets the endpoint data parameter value with specified key for a service endpoint
365
- * If the endpoint data parameter was not set, it will throw.
366
- *
367
- * @param id name of the service endpoint
368
- * @param key of the parameter
369
- * @returns {string} value of the endpoint data parameter
370
- */
371
- function getEndpointDataParameterRequired(id, key) {
372
- return getEndpointDataParameter(id, key, false);
373
- }
374
- exports.getEndpointDataParameterRequired = getEndpointDataParameterRequired;
375
- /**
376
- * Gets the endpoint authorization scheme for a service endpoint
377
- * If the endpoint authorization scheme is not set and is not optional, it will throw.
378
- *
379
- * @param id name of the service endpoint
380
- * @param optional whether the endpoint authorization scheme is optional
381
- * @returns {string} value of the endpoint authorization scheme
382
- */
383
- function getEndpointAuthorizationScheme(id, optional) {
384
- var authScheme = im._vault.retrieveSecret('ENDPOINT_AUTH_SCHEME_' + id);
385
- if (!optional && !authScheme) {
386
- throw new Error(exports.loc('LIB_EndpointAuthNotExist', id));
387
- }
388
- exports.debug(id + ' auth scheme = ' + authScheme);
389
- return authScheme;
390
- }
391
- exports.getEndpointAuthorizationScheme = getEndpointAuthorizationScheme;
392
- /**
393
- * Gets the endpoint authorization scheme for a service endpoint
394
- * If the endpoint authorization scheme is not set, it will throw.
395
- *
396
- * @param id name of the service endpoint
397
- * @returns {string} value of the endpoint authorization scheme
398
- */
399
- function getEndpointAuthorizationSchemeRequired(id) {
400
- return getEndpointAuthorizationScheme(id, false);
401
- }
402
- exports.getEndpointAuthorizationSchemeRequired = getEndpointAuthorizationSchemeRequired;
403
- /**
404
- * Gets the endpoint authorization parameter value for a service endpoint with specified key
405
- * If the endpoint authorization parameter is not set and is not optional, it will throw.
406
- *
407
- * @param id name of the service endpoint
408
- * @param key key to find the endpoint authorization parameter
409
- * @param optional optional whether the endpoint authorization scheme is optional
410
- * @returns {string} value of the endpoint authorization parameter value
411
- */
412
- function getEndpointAuthorizationParameter(id, key, optional) {
413
- var authParam = im._vault.retrieveSecret('ENDPOINT_AUTH_PARAMETER_' + id + '_' + key.toUpperCase());
414
- if (!optional && !authParam) {
415
- throw new Error(exports.loc('LIB_EndpointAuthNotExist', id));
416
- }
417
- exports.debug(id + ' auth param ' + key + ' = ' + authParam);
418
- return authParam;
419
- }
420
- exports.getEndpointAuthorizationParameter = getEndpointAuthorizationParameter;
421
- /**
422
- * Gets the endpoint authorization parameter value for a service endpoint with specified key
423
- * If the endpoint authorization parameter is not set, it will throw.
424
- *
425
- * @param id name of the service endpoint
426
- * @param key key to find the endpoint authorization parameter
427
- * @returns {string} value of the endpoint authorization parameter value
428
- */
429
- function getEndpointAuthorizationParameterRequired(id, key) {
430
- return getEndpointAuthorizationParameter(id, key, false);
431
- }
432
- exports.getEndpointAuthorizationParameterRequired = getEndpointAuthorizationParameterRequired;
433
- /**
434
- * Gets the authorization details for a service endpoint
435
- * If the authorization was not set and is not optional, it will set the task result to Failed.
436
- *
437
- * @param id name of the service endpoint
438
- * @param optional whether the url is optional
439
- * @returns string
440
- */
441
- function getEndpointAuthorization(id, optional) {
442
- var aval = im._vault.retrieveSecret('ENDPOINT_AUTH_' + id);
443
- if (!optional && !aval) {
444
- setResult(TaskResult.Failed, exports.loc('LIB_EndpointAuthNotExist', id));
445
- }
446
- exports.debug(id + ' exists ' + (!!aval));
447
- var auth;
448
- try {
449
- if (aval) {
450
- auth = JSON.parse(aval);
451
- }
452
- }
453
- catch (err) {
454
- throw new Error(exports.loc('LIB_InvalidEndpointAuth', aval));
455
- }
456
- return auth;
457
- }
458
- exports.getEndpointAuthorization = getEndpointAuthorization;
459
- //-----------------------------------------------------
460
- // SecureFile Helpers
461
- //-----------------------------------------------------
462
- /**
463
- * Gets the name for a secure file
464
- *
465
- * @param id secure file id
466
- * @returns string
467
- */
468
- function getSecureFileName(id) {
469
- var name = process.env['SECUREFILE_NAME_' + id];
470
- exports.debug('secure file name for id ' + id + ' = ' + name);
471
- return name;
472
- }
473
- exports.getSecureFileName = getSecureFileName;
474
- /**
475
- * Gets the secure file ticket that can be used to download the secure file contents
476
- *
477
- * @param id name of the secure file
478
- * @returns {string} secure file ticket
479
- */
480
- function getSecureFileTicket(id) {
481
- var ticket = im._vault.retrieveSecret('SECUREFILE_TICKET_' + id);
482
- exports.debug('secure file ticket for id ' + id + ' = ' + ticket);
483
- return ticket;
484
- }
485
- exports.getSecureFileTicket = getSecureFileTicket;
486
- //-----------------------------------------------------
487
- // Task Variable Helpers
488
- //-----------------------------------------------------
489
- /**
490
- * Gets a variable value that is set by previous step from the same wrapper task.
491
- * Requires a 2.115.0 agent or higher.
492
- *
493
- * @param name name of the variable to get
494
- * @returns string
495
- */
496
- function getTaskVariable(name) {
497
- assertAgent('2.115.0');
498
- var inval = im._vault.retrieveSecret('VSTS_TASKVARIABLE_' + im._getVariableKey(name));
499
- if (inval) {
500
- inval = inval.trim();
501
- }
502
- exports.debug('task variable: ' + name + '=' + inval);
503
- return inval;
504
- }
505
- exports.getTaskVariable = getTaskVariable;
506
- /**
507
- * Sets a task variable which will only be available to subsequent steps belong to the same wrapper task.
508
- * Requires a 2.115.0 agent or higher.
509
- *
510
- * @param name name of the variable to set
511
- * @param val value to set
512
- * @param secret whether variable is secret. optional, defaults to false
513
- * @returns void
514
- */
515
- function setTaskVariable(name, val, secret) {
516
- if (secret === void 0) { secret = false; }
517
- assertAgent('2.115.0');
518
- var key = im._getVariableKey(name);
519
- // store the value
520
- var varValue = val || '';
521
- exports.debug('set task variable: ' + name + '=' + (secret && varValue ? '********' : varValue));
522
- im._vault.storeSecret('VSTS_TASKVARIABLE_' + key, varValue);
523
- delete process.env[key];
524
- // write the command
525
- exports.command('task.settaskvariable', { 'variable': name || '', 'issecret': (secret || false).toString() }, varValue);
526
- }
527
- exports.setTaskVariable = setTaskVariable;
528
- //-----------------------------------------------------
529
- // Cmd Helpers
530
- //-----------------------------------------------------
531
- exports.command = im._command;
532
- exports.warning = im._warning;
533
- exports.error = im._error;
534
- exports.debug = im._debug;
535
- //-----------------------------------------------------
536
- // Disk Functions
537
- //-----------------------------------------------------
538
- function _checkShell(cmd, continueOnError) {
539
- var se = shell.error();
540
- if (se) {
541
- exports.debug(cmd + ' failed');
542
- var errMsg = exports.loc('LIB_OperationFailed', cmd, se);
543
- exports.debug(errMsg);
544
- if (!continueOnError) {
545
- throw new Error(errMsg);
546
- }
547
- }
548
- }
549
- /**
550
- * Get's stat on a path.
551
- * Useful for checking whether a file or directory. Also getting created, modified and accessed time.
552
- * see [fs.stat](https://nodejs.org/api/fs.html#fs_class_fs_stats)
553
- *
554
- * @param path path to check
555
- * @returns fsStat
556
- */
557
- function stats(path) {
558
- return fs.statSync(path);
559
- }
560
- exports.stats = stats;
561
- exports.exist = im._exist;
562
- function writeFile(file, data, options) {
563
- if (typeof (options) === 'string') {
564
- fs.writeFileSync(file, data, { encoding: options });
565
- }
566
- else {
567
- fs.writeFileSync(file, data, options);
568
- }
569
- }
570
- exports.writeFile = writeFile;
571
- /**
572
- * @deprecated Use `getPlatform`
573
- * Useful for determining the host operating system.
574
- * see [os.type](https://nodejs.org/api/os.html#os_os_type)
575
- *
576
- * @return the name of the operating system
577
- */
578
- function osType() {
579
- return os.type();
580
- }
581
- exports.osType = osType;
582
- /**
583
- * Determine the operating system the build agent is running on.
584
- * @returns {Platform}
585
- * @throws {Error} Platform is not supported by our agent
586
- */
587
- function getPlatform() {
588
- switch (process.platform) {
589
- case 'win32': return Platform.Windows;
590
- case 'darwin': return Platform.MacOS;
591
- case 'linux': return Platform.Linux;
592
- default: throw Error(exports.loc('LIB_PlatformNotSupported', process.platform));
593
- }
594
- }
595
- exports.getPlatform = getPlatform;
596
- /**
597
- * Returns the process's current working directory.
598
- * see [process.cwd](https://nodejs.org/api/process.html#process_process_cwd)
599
- *
600
- * @return the path to the current working directory of the process
601
- */
602
- function cwd() {
603
- return process.cwd();
604
- }
605
- exports.cwd = cwd;
606
- exports.checkPath = im._checkPath;
607
- /**
608
- * Change working directory.
609
- *
610
- * @param path new working directory path
611
- * @returns void
612
- */
613
- function cd(path) {
614
- if (path) {
615
- shell.cd(path);
616
- _checkShell('cd');
617
- }
618
- }
619
- exports.cd = cd;
620
- /**
621
- * Change working directory and push it on the stack
622
- *
623
- * @param path new working directory path
624
- * @returns void
625
- */
626
- function pushd(path) {
627
- shell.pushd(path);
628
- _checkShell('pushd');
629
- }
630
- exports.pushd = pushd;
631
- /**
632
- * Change working directory back to previously pushed directory
633
- *
634
- * @returns void
635
- */
636
- function popd() {
637
- shell.popd();
638
- _checkShell('popd');
639
- }
640
- exports.popd = popd;
641
- /**
642
- * Make a directory. Creates the full path with folders in between
643
- * Will throw if it fails
644
- *
645
- * @param p path to create
646
- * @returns void
647
- */
648
- function mkdirP(p) {
649
- if (!p) {
650
- throw new Error(exports.loc('LIB_ParameterIsRequired', 'p'));
651
- }
652
- // build a stack of directories to create
653
- var stack = [];
654
- var testDir = p;
655
- while (true) {
656
- // validate the loop is not out of control
657
- if (stack.length >= (process.env['TASKLIB_TEST_MKDIRP_FAILSAFE'] || 1000)) {
658
- // let the framework throw
659
- exports.debug('loop is out of control');
660
- fs.mkdirSync(p);
661
- return;
662
- }
663
- exports.debug("testing directory '" + testDir + "'");
664
- var stats_1 = void 0;
665
- try {
666
- stats_1 = fs.statSync(testDir);
667
- }
668
- catch (err) {
669
- if (err.code == 'ENOENT') {
670
- // validate the directory is not the drive root
671
- var parentDir = path.dirname(testDir);
672
- if (testDir == parentDir) {
673
- throw new Error(exports.loc('LIB_MkdirFailedInvalidDriveRoot', p, testDir)); // Unable to create directory '{p}'. Root directory does not exist: '{testDir}'
674
- }
675
- // push the dir and test the parent
676
- stack.push(testDir);
677
- testDir = parentDir;
678
- continue;
679
- }
680
- else if (err.code == 'UNKNOWN') {
681
- throw new Error(exports.loc('LIB_MkdirFailedInvalidShare', p, testDir)); // Unable to create directory '{p}'. Unable to verify the directory exists: '{testDir}'. If directory is a file share, please verify the share name is correct, the share is online, and the current process has permission to access the share.
682
- }
683
- else {
684
- throw err;
685
- }
686
- }
687
- if (!stats_1.isDirectory()) {
688
- throw new Error(exports.loc('LIB_MkdirFailedFileExists', p, testDir)); // Unable to create directory '{p}'. Conflicting file exists: '{testDir}'
689
- }
690
- // testDir exists
691
- break;
692
- }
693
- // create each directory
694
- while (stack.length) {
695
- var dir = stack.pop(); // non-null because `stack.length` was truthy
696
- exports.debug("mkdir '" + dir + "'");
697
- try {
698
- fs.mkdirSync(dir);
699
- }
700
- catch (err) {
701
- throw new Error(exports.loc('LIB_MkdirFailed', p, err.message)); // Unable to create directory '{p}'. {err.message}
702
- }
703
- }
704
- }
705
- exports.mkdirP = mkdirP;
706
- /**
707
- * Resolves a sequence of paths or path segments into an absolute path.
708
- * Calls node.js path.resolve()
709
- * Allows L0 testing with consistent path formats on Mac/Linux and Windows in the mock implementation
710
- * @param pathSegments
711
- * @returns {string}
712
- */
713
- function resolve() {
714
- var pathSegments = [];
715
- for (var _i = 0; _i < arguments.length; _i++) {
716
- pathSegments[_i] = arguments[_i];
717
- }
718
- var absolutePath = path.resolve.apply(this, pathSegments);
719
- exports.debug('Absolute path for pathSegments: ' + pathSegments + ' = ' + absolutePath);
720
- return absolutePath;
721
- }
722
- exports.resolve = resolve;
723
- exports.which = im._which;
724
- /**
725
- * Returns array of files in the given path, or in current directory if no path provided. See shelljs.ls
726
- * @param {string} options Available options: -R (recursive), -A (all files, include files beginning with ., except for . and ..)
727
- * @param {string[]} paths Paths to search.
728
- * @return {string[]} An array of files in the given path(s).
729
- */
730
- function ls(options, paths) {
731
- if (options) {
732
- return shell.ls(options, paths);
733
- }
734
- else {
735
- return shell.ls(paths);
736
- }
737
- }
738
- exports.ls = ls;
739
- /**
740
- * Copies a file or folder.
741
- *
742
- * @param source source path
743
- * @param dest destination path
744
- * @param options string -r, -f or -rf for recursive and force
745
- * @param continueOnError optional. whether to continue on error
746
- * @param retryCount optional. Retry count to copy the file. It might help to resolve intermittent issues e.g. with UNC target paths on a remote host.
747
- */
748
- function cp(source, dest, options, continueOnError, retryCount) {
749
- if (retryCount === void 0) { retryCount = 0; }
750
- while (retryCount >= 0) {
751
- try {
752
- if (options) {
753
- shell.cp(options, source, dest);
754
- }
755
- else {
756
- shell.cp(source, dest);
757
- }
758
- _checkShell('cp', false);
759
- break;
760
- }
761
- catch (e) {
762
- if (retryCount <= 0) {
763
- if (continueOnError) {
764
- exports.warning(e);
765
- break;
766
- }
767
- else {
768
- throw e;
769
- }
770
- }
771
- else {
772
- console.log(exports.loc('LIB_CopyFileFailed', retryCount));
773
- retryCount--;
774
- }
775
- }
776
- }
777
- }
778
- exports.cp = cp;
779
- /**
780
- * Moves a path.
781
- *
782
- * @param source source path
783
- * @param dest destination path
784
- * @param options string -f or -n for force and no clobber
785
- * @param continueOnError optional. whether to continue on error
786
- */
787
- function mv(source, dest, options, continueOnError) {
788
- if (options) {
789
- shell.mv(options, source, dest);
790
- }
791
- else {
792
- shell.mv(source, dest);
793
- }
794
- _checkShell('mv', continueOnError);
795
- }
796
- exports.mv = mv;
797
- /**
798
- * Tries to execute a function a specified number of times.
799
- *
800
- * @param func a function to be executed.
801
- * @param args executed function arguments array.
802
- * @param retryOptions optional. Defaults to { continueOnError: false, retryCount: 0 }.
803
- * @returns the same as the usual function.
804
- */
805
- function retry(func, args, retryOptions) {
806
- if (retryOptions === void 0) { retryOptions = { continueOnError: false, retryCount: 0 }; }
807
- while (retryOptions.retryCount >= 0) {
808
- try {
809
- return func.apply(void 0, args);
810
- }
811
- catch (e) {
812
- if (retryOptions.retryCount <= 0) {
813
- if (retryOptions.continueOnError) {
814
- exports.warning(e);
815
- break;
816
- }
817
- else {
818
- throw e;
819
- }
820
- }
821
- else {
822
- exports.debug("Attempt to execute function \"" + (func === null || func === void 0 ? void 0 : func.name) + "\" failed, retries left: " + retryOptions.retryCount);
823
- retryOptions.retryCount--;
824
- }
825
- }
826
- }
827
- }
828
- exports.retry = retry;
829
- /**
830
- * Gets info about item stats.
831
- *
832
- * @param path a path to the item to be processed.
833
- * @param followSymbolicLink indicates whether to traverse descendants of symbolic link directories.
834
- * @param allowBrokenSymbolicLinks when true, broken symbolic link will not cause an error.
835
- * @returns fs.Stats
836
- */
837
- function _getStats(path, followSymbolicLink, allowBrokenSymbolicLinks) {
838
- // stat returns info about the target of a symlink (or symlink chain),
839
- // lstat returns info about a symlink itself
840
- var stats;
841
- if (followSymbolicLink) {
842
- try {
843
- // use stat (following symlinks)
844
- stats = fs.statSync(path);
845
- }
846
- catch (err) {
847
- if (err.code == 'ENOENT' && allowBrokenSymbolicLinks) {
848
- // fallback to lstat (broken symlinks allowed)
849
- stats = fs.lstatSync(path);
850
- exports.debug(" " + path + " (broken symlink)");
851
- }
852
- else {
853
- throw err;
854
- }
855
- }
856
- }
857
- else {
858
- // use lstat (not following symlinks)
859
- stats = fs.lstatSync(path);
860
- }
861
- return stats;
862
- }
863
- /**
864
- * Recursively finds all paths a given path. Returns an array of paths.
865
- *
866
- * @param findPath path to search
867
- * @param options optional. defaults to { followSymbolicLinks: true }. following soft links is generally appropriate unless deleting files.
868
- * @returns string[]
869
- */
870
- function find(findPath, options) {
871
- if (!findPath) {
872
- exports.debug('no path specified');
873
- return [];
874
- }
875
- // normalize the path, otherwise the first result is inconsistently formatted from the rest of the results
876
- // because path.join() performs normalization.
877
- findPath = path.normalize(findPath);
878
- // debug trace the parameters
879
- exports.debug("findPath: '" + findPath + "'");
880
- options = options || _getDefaultFindOptions();
881
- _debugFindOptions(options);
882
- // return empty if not exists
883
- try {
884
- fs.lstatSync(findPath);
885
- }
886
- catch (err) {
887
- if (err.code == 'ENOENT') {
888
- exports.debug('0 results');
889
- return [];
890
- }
891
- throw err;
892
- }
893
- try {
894
- var result = [];
895
- // push the first item
896
- var stack = [new _FindItem(findPath, 1)];
897
- var traversalChain = []; // used to detect cycles
898
- var _loop_1 = function () {
899
- // pop the next item and push to the result array
900
- var item = stack.pop(); // non-null because `stack.length` was truthy
901
- var stats_2 = void 0;
902
- try {
903
- // `item.path` equals `findPath` for the first item to be processed, when the `result` array is empty
904
- var isPathToSearch = !result.length;
905
- // following specified symlinks only if current path equals specified path
906
- var followSpecifiedSymbolicLink = options.followSpecifiedSymbolicLink && isPathToSearch;
907
- // following all symlinks or following symlink for the specified path
908
- var followSymbolicLink = options.followSymbolicLinks || followSpecifiedSymbolicLink;
909
- // stat the item. The stat info is used further below to determine whether to traverse deeper
910
- stats_2 = _getStats(item.path, followSymbolicLink, options.allowBrokenSymbolicLinks);
911
- }
912
- catch (err) {
913
- if (err.code == 'ENOENT' && options.skipMissingFiles) {
914
- exports.warning("No such file or directory: \"" + item.path + "\" - skipping.");
915
- return "continue";
916
- }
917
- throw err;
918
- }
919
- result.push(item.path);
920
- // note, isDirectory() returns false for the lstat of a symlink
921
- if (stats_2.isDirectory()) {
922
- exports.debug(" " + item.path + " (directory)");
923
- if (options.followSymbolicLinks) {
924
- // get the realpath
925
- var realPath_1;
926
- if (im._isUncPath(item.path)) {
927
- // Sometimes there are spontaneous issues when working with unc-paths, so retries have been added for them.
928
- realPath_1 = retry(fs.realpathSync, [item.path], { continueOnError: false, retryCount: 5 });
929
- }
930
- else {
931
- realPath_1 = fs.realpathSync(item.path);
932
- }
933
- // fixup the traversal chain to match the item level
934
- while (traversalChain.length >= item.level) {
935
- traversalChain.pop();
936
- }
937
- // test for a cycle
938
- if (traversalChain.some(function (x) { return x == realPath_1; })) {
939
- exports.debug(' cycle detected');
940
- return "continue";
941
- }
942
- // update the traversal chain
943
- traversalChain.push(realPath_1);
944
- }
945
- // push the child items in reverse onto the stack
946
- var childLevel_1 = item.level + 1;
947
- var childItems = fs.readdirSync(item.path)
948
- .map(function (childName) { return new _FindItem(path.join(item.path, childName), childLevel_1); });
949
- for (var i = childItems.length - 1; i >= 0; i--) {
950
- stack.push(childItems[i]);
951
- }
952
- }
953
- else {
954
- exports.debug(" " + item.path + " (file)");
955
- }
956
- };
957
- while (stack.length) {
958
- _loop_1();
959
- }
960
- exports.debug(result.length + " results");
961
- return result;
962
- }
963
- catch (err) {
964
- throw new Error(exports.loc('LIB_OperationFailed', 'find', err.message));
965
- }
966
- }
967
- exports.find = find;
968
- var _FindItem = /** @class */ (function () {
969
- function _FindItem(path, level) {
970
- this.path = path;
971
- this.level = level;
972
- }
973
- return _FindItem;
974
- }());
975
- function _debugFindOptions(options) {
976
- exports.debug("findOptions.allowBrokenSymbolicLinks: '" + options.allowBrokenSymbolicLinks + "'");
977
- exports.debug("findOptions.followSpecifiedSymbolicLink: '" + options.followSpecifiedSymbolicLink + "'");
978
- exports.debug("findOptions.followSymbolicLinks: '" + options.followSymbolicLinks + "'");
979
- exports.debug("findOptions.skipMissingFiles: '" + options.skipMissingFiles + "'");
980
- }
981
- function _getDefaultFindOptions() {
982
- return {
983
- allowBrokenSymbolicLinks: false,
984
- followSpecifiedSymbolicLink: true,
985
- followSymbolicLinks: true,
986
- skipMissingFiles: false
987
- };
988
- }
989
- /**
990
- * Prefer tl.find() and tl.match() instead. This function is for backward compatibility
991
- * when porting tasks to Node from the PowerShell or PowerShell3 execution handler.
992
- *
993
- * @param rootDirectory path to root unrooted patterns with
994
- * @param pattern include and exclude patterns
995
- * @param includeFiles whether to include files in the result. defaults to true when includeFiles and includeDirectories are both false
996
- * @param includeDirectories whether to include directories in the result
997
- * @returns string[]
998
- */
999
- function legacyFindFiles(rootDirectory, pattern, includeFiles, includeDirectories) {
1000
- if (!pattern) {
1001
- throw new Error('pattern parameter cannot be empty');
1002
- }
1003
- exports.debug("legacyFindFiles rootDirectory: '" + rootDirectory + "'");
1004
- exports.debug("pattern: '" + pattern + "'");
1005
- exports.debug("includeFiles: '" + includeFiles + "'");
1006
- exports.debug("includeDirectories: '" + includeDirectories + "'");
1007
- if (!includeFiles && !includeDirectories) {
1008
- includeFiles = true;
1009
- }
1010
- // organize the patterns into include patterns and exclude patterns
1011
- var includePatterns = [];
1012
- var excludePatterns = [];
1013
- pattern = pattern.replace(/;;/g, '\0');
1014
- for (var _i = 0, _a = pattern.split(';'); _i < _a.length; _i++) {
1015
- var pat = _a[_i];
1016
- if (!pat) {
1017
- continue;
1018
- }
1019
- pat = pat.replace(/\0/g, ';');
1020
- // determine whether include pattern and remove any include/exclude prefix.
1021
- // include patterns start with +: or anything other than -:
1022
- // exclude patterns start with -:
1023
- var isIncludePattern = void 0;
1024
- if (im._startsWith(pat, '+:')) {
1025
- pat = pat.substring(2);
1026
- isIncludePattern = true;
1027
- }
1028
- else if (im._startsWith(pat, '-:')) {
1029
- pat = pat.substring(2);
1030
- isIncludePattern = false;
1031
- }
1032
- else {
1033
- isIncludePattern = true;
1034
- }
1035
- // validate pattern does not end with a slash
1036
- if (im._endsWith(pat, '/') || (process.platform == 'win32' && im._endsWith(pat, '\\'))) {
1037
- throw new Error(exports.loc('LIB_InvalidPattern', pat));
1038
- }
1039
- // root the pattern
1040
- if (rootDirectory && !path.isAbsolute(pat)) {
1041
- pat = path.join(rootDirectory, pat);
1042
- // remove trailing slash sometimes added by path.join() on Windows, e.g.
1043
- // path.join('\\\\hello', 'world') => '\\\\hello\\world\\'
1044
- // path.join('//hello', 'world') => '\\\\hello\\world\\'
1045
- if (im._endsWith(pat, '\\')) {
1046
- pat = pat.substring(0, pat.length - 1);
1047
- }
1048
- }
1049
- if (isIncludePattern) {
1050
- includePatterns.push(pat);
1051
- }
1052
- else {
1053
- excludePatterns.push(im._legacyFindFiles_convertPatternToRegExp(pat));
1054
- }
1055
- }
1056
- // find and apply patterns
1057
- var count = 0;
1058
- var result = _legacyFindFiles_getMatchingItems(includePatterns, excludePatterns, !!includeFiles, !!includeDirectories);
1059
- exports.debug('all matches:');
1060
- for (var _b = 0, result_1 = result; _b < result_1.length; _b++) {
1061
- var resultItem = result_1[_b];
1062
- exports.debug(' ' + resultItem);
1063
- }
1064
- exports.debug('total matched: ' + result.length);
1065
- return result;
1066
- }
1067
- exports.legacyFindFiles = legacyFindFiles;
1068
- function _legacyFindFiles_getMatchingItems(includePatterns, excludePatterns, includeFiles, includeDirectories) {
1069
- exports.debug('getMatchingItems()');
1070
- for (var _i = 0, includePatterns_1 = includePatterns; _i < includePatterns_1.length; _i++) {
1071
- var pattern = includePatterns_1[_i];
1072
- exports.debug("includePattern: '" + pattern + "'");
1073
- }
1074
- for (var _a = 0, excludePatterns_1 = excludePatterns; _a < excludePatterns_1.length; _a++) {
1075
- var pattern = excludePatterns_1[_a];
1076
- exports.debug("excludePattern: " + pattern);
1077
- }
1078
- exports.debug('includeFiles: ' + includeFiles);
1079
- exports.debug('includeDirectories: ' + includeDirectories);
1080
- var allFiles = {};
1081
- var _loop_2 = function (pattern) {
1082
- // determine the directory to search
1083
- //
1084
- // note, getDirectoryName removes redundant path separators
1085
- var findPath = void 0;
1086
- var starIndex = pattern.indexOf('*');
1087
- var questionIndex = pattern.indexOf('?');
1088
- if (starIndex < 0 && questionIndex < 0) {
1089
- // if no wildcards are found, use the directory name portion of the path.
1090
- // if there is no directory name (file name only in pattern or drive root),
1091
- // this will return empty string.
1092
- findPath = im._getDirectoryName(pattern);
1093
- }
1094
- else {
1095
- // extract the directory prior to the first wildcard
1096
- var index = Math.min(starIndex >= 0 ? starIndex : questionIndex, questionIndex >= 0 ? questionIndex : starIndex);
1097
- findPath = im._getDirectoryName(pattern.substring(0, index));
1098
- }
1099
- // note, due to this short-circuit and the above usage of getDirectoryName, this
1100
- // function has the same limitations regarding drive roots as the powershell
1101
- // implementation.
1102
- //
1103
- // also note, since getDirectoryName eliminates slash redundancies, some additional
1104
- // work may be required if removal of this limitation is attempted.
1105
- if (!findPath) {
1106
- return "continue";
1107
- }
1108
- var patternRegex = im._legacyFindFiles_convertPatternToRegExp(pattern);
1109
- // find files/directories
1110
- var items = find(findPath, { followSymbolicLinks: true })
1111
- .filter(function (item) {
1112
- if (includeFiles && includeDirectories) {
1113
- return true;
1114
- }
1115
- var isDir = fs.statSync(item).isDirectory();
1116
- return (includeFiles && !isDir) || (includeDirectories && isDir);
1117
- })
1118
- .forEach(function (item) {
1119
- var normalizedPath = process.platform == 'win32' ? item.replace(/\\/g, '/') : item; // normalize separators
1120
- // **/times/** will not match C:/fun/times because there isn't a trailing slash
1121
- // so try both if including directories
1122
- var alternatePath = normalizedPath + "/"; // potential bug: it looks like this will result in a false
1123
- // positive if the item is a regular file and not a directory
1124
- var isMatch = false;
1125
- if (patternRegex.test(normalizedPath) || (includeDirectories && patternRegex.test(alternatePath))) {
1126
- isMatch = true;
1127
- // test whether the path should be excluded
1128
- for (var _i = 0, excludePatterns_2 = excludePatterns; _i < excludePatterns_2.length; _i++) {
1129
- var regex = excludePatterns_2[_i];
1130
- if (regex.test(normalizedPath) || (includeDirectories && regex.test(alternatePath))) {
1131
- isMatch = false;
1132
- break;
1133
- }
1134
- }
1135
- }
1136
- if (isMatch) {
1137
- allFiles[item] = item;
1138
- }
1139
- });
1140
- };
1141
- for (var _b = 0, includePatterns_2 = includePatterns; _b < includePatterns_2.length; _b++) {
1142
- var pattern = includePatterns_2[_b];
1143
- _loop_2(pattern);
1144
- }
1145
- return Object.keys(allFiles).sort();
1146
- }
1147
- /**
1148
- * Remove a path recursively with force
1149
- *
1150
- * @param inputPath path to remove
1151
- * @throws when the file or directory exists but could not be deleted.
1152
- */
1153
- function rmRF(inputPath) {
1154
- exports.debug('rm -rf ' + inputPath);
1155
- if (getPlatform() == Platform.Windows) {
1156
- // Node doesn't provide a delete operation, only an unlink function. This means that if the file is being used by another
1157
- // program (e.g. antivirus), it won't be deleted. To address this, we shell out the work to rd/del.
1158
- try {
1159
- if (fs.statSync(inputPath).isDirectory()) {
1160
- exports.debug('removing directory ' + inputPath);
1161
- childProcess.execSync("rd /s /q \"" + inputPath + "\"");
1162
- }
1163
- else {
1164
- exports.debug('removing file ' + inputPath);
1165
- childProcess.execSync("del /f /a \"" + inputPath + "\"");
1166
- }
1167
- }
1168
- catch (err) {
1169
- // if you try to delete a file that doesn't exist, desired result is achieved
1170
- // other errors are valid
1171
- if (err.code != 'ENOENT') {
1172
- throw new Error(exports.loc('LIB_OperationFailed', 'rmRF', err.message));
1173
- }
1174
- }
1175
- // Shelling out fails to remove a symlink folder with missing source, this unlink catches that
1176
- try {
1177
- fs.unlinkSync(inputPath);
1178
- }
1179
- catch (err) {
1180
- // if you try to delete a file that doesn't exist, desired result is achieved
1181
- // other errors are valid
1182
- if (err.code != 'ENOENT') {
1183
- throw new Error(exports.loc('LIB_OperationFailed', 'rmRF', err.message));
1184
- }
1185
- }
1186
- }
1187
- else {
1188
- // get the lstats in order to workaround a bug in shelljs@0.3.0 where symlinks
1189
- // with missing targets are not handled correctly by "rm('-rf', path)"
1190
- var lstats = void 0;
1191
- try {
1192
- lstats = fs.lstatSync(inputPath);
1193
- }
1194
- catch (err) {
1195
- // if you try to delete a file that doesn't exist, desired result is achieved
1196
- // other errors are valid
1197
- if (err.code == 'ENOENT') {
1198
- return;
1199
- }
1200
- throw new Error(exports.loc('LIB_OperationFailed', 'rmRF', err.message));
1201
- }
1202
- if (lstats.isDirectory()) {
1203
- exports.debug('removing directory');
1204
- shell.rm('-rf', inputPath);
1205
- var errMsg = shell.error();
1206
- if (errMsg) {
1207
- throw new Error(exports.loc('LIB_OperationFailed', 'rmRF', errMsg));
1208
- }
1209
- return;
1210
- }
1211
- exports.debug('removing file');
1212
- try {
1213
- fs.unlinkSync(inputPath);
1214
- }
1215
- catch (err) {
1216
- throw new Error(exports.loc('LIB_OperationFailed', 'rmRF', err.message));
1217
- }
1218
- }
1219
- }
1220
- exports.rmRF = rmRF;
1221
- /**
1222
- * Exec a tool. Convenience wrapper over ToolRunner to exec with args in one call.
1223
- * Output will be streamed to the live console.
1224
- * Returns promise with return code
1225
- *
1226
- * @param tool path to tool to exec
1227
- * @param args an arg string or array of args
1228
- * @param options optional exec options. See IExecOptions
1229
- * @returns number
1230
- */
1231
- function exec(tool, args, options) {
1232
- var tr = this.tool(tool);
1233
- tr.on('debug', function (data) {
1234
- exports.debug(data);
1235
- });
1236
- if (args) {
1237
- if (args instanceof Array) {
1238
- tr.arg(args);
1239
- }
1240
- else if (typeof (args) === 'string') {
1241
- tr.line(args);
1242
- }
1243
- }
1244
- return tr.exec(options);
1245
- }
1246
- exports.exec = exec;
1247
- /**
1248
- * Exec a tool synchronously. Convenience wrapper over ToolRunner to execSync with args in one call.
1249
- * Output will be *not* be streamed to the live console. It will be returned after execution is complete.
1250
- * Appropriate for short running tools
1251
- * Returns IExecResult with output and return code
1252
- *
1253
- * @param tool path to tool to exec
1254
- * @param args an arg string or array of args
1255
- * @param options optional exec options. See IExecSyncOptions
1256
- * @returns IExecSyncResult
1257
- */
1258
- function execSync(tool, args, options) {
1259
- var tr = this.tool(tool);
1260
- tr.on('debug', function (data) {
1261
- exports.debug(data);
1262
- });
1263
- if (args) {
1264
- if (args instanceof Array) {
1265
- tr.arg(args);
1266
- }
1267
- else if (typeof (args) === 'string') {
1268
- tr.line(args);
1269
- }
1270
- }
1271
- return tr.execSync(options);
1272
- }
1273
- exports.execSync = execSync;
1274
- /**
1275
- * Convenience factory to create a ToolRunner.
1276
- *
1277
- * @param tool path to tool to exec
1278
- * @returns ToolRunner
1279
- */
1280
- function tool(tool) {
1281
- var tr = new trm.ToolRunner(tool);
1282
- tr.on('debug', function (message) {
1283
- exports.debug(message);
1284
- });
1285
- return tr;
1286
- }
1287
- exports.tool = tool;
1288
- /**
1289
- * Applies glob patterns to a list of paths. Supports interleaved exclude patterns.
1290
- *
1291
- * @param list array of paths
1292
- * @param patterns patterns to apply. supports interleaved exclude patterns.
1293
- * @param patternRoot optional. default root to apply to unrooted patterns. not applied to basename-only patterns when matchBase:true.
1294
- * @param options optional. defaults to { dot: true, nobrace: true, nocase: process.platform == 'win32' }.
1295
- */
1296
- function match(list, patterns, patternRoot, options) {
1297
- // trace parameters
1298
- exports.debug("patternRoot: '" + patternRoot + "'");
1299
- options = options || _getDefaultMatchOptions(); // default match options
1300
- _debugMatchOptions(options);
1301
- // convert pattern to an array
1302
- if (typeof patterns == 'string') {
1303
- patterns = [patterns];
1304
- }
1305
- // hashtable to keep track of matches
1306
- var map = {};
1307
- var originalOptions = options;
1308
- for (var _i = 0, patterns_1 = patterns; _i < patterns_1.length; _i++) {
1309
- var pattern = patterns_1[_i];
1310
- exports.debug("pattern: '" + pattern + "'");
1311
- // trim and skip empty
1312
- pattern = (pattern || '').trim();
1313
- if (!pattern) {
1314
- exports.debug('skipping empty pattern');
1315
- continue;
1316
- }
1317
- // clone match options
1318
- var options_1 = im._cloneMatchOptions(originalOptions);
1319
- // skip comments
1320
- if (!options_1.nocomment && im._startsWith(pattern, '#')) {
1321
- exports.debug('skipping comment');
1322
- continue;
1323
- }
1324
- // set nocomment - brace expansion could result in a leading '#'
1325
- options_1.nocomment = true;
1326
- // determine whether pattern is include or exclude
1327
- var negateCount = 0;
1328
- if (!options_1.nonegate) {
1329
- while (pattern.charAt(negateCount) == '!') {
1330
- negateCount++;
1331
- }
1332
- pattern = pattern.substring(negateCount); // trim leading '!'
1333
- if (negateCount) {
1334
- exports.debug("trimmed leading '!'. pattern: '" + pattern + "'");
1335
- }
1336
- }
1337
- var isIncludePattern = negateCount == 0 ||
1338
- (negateCount % 2 == 0 && !options_1.flipNegate) ||
1339
- (negateCount % 2 == 1 && options_1.flipNegate);
1340
- // set nonegate - brace expansion could result in a leading '!'
1341
- options_1.nonegate = true;
1342
- options_1.flipNegate = false;
1343
- // expand braces - required to accurately root patterns
1344
- var expanded = void 0;
1345
- var preExpanded = pattern;
1346
- if (options_1.nobrace) {
1347
- expanded = [pattern];
1348
- }
1349
- else {
1350
- // convert slashes on Windows before calling braceExpand(). unfortunately this means braces cannot
1351
- // be escaped on Windows, this limitation is consistent with current limitations of minimatch (3.0.3).
1352
- exports.debug('expanding braces');
1353
- var convertedPattern = process.platform == 'win32' ? pattern.replace(/\\/g, '/') : pattern;
1354
- expanded = minimatch.braceExpand(convertedPattern);
1355
- }
1356
- // set nobrace
1357
- options_1.nobrace = true;
1358
- for (var _a = 0, expanded_1 = expanded; _a < expanded_1.length; _a++) {
1359
- var pattern_1 = expanded_1[_a];
1360
- if (expanded.length != 1 || pattern_1 != preExpanded) {
1361
- exports.debug("pattern: '" + pattern_1 + "'");
1362
- }
1363
- // trim and skip empty
1364
- pattern_1 = (pattern_1 || '').trim();
1365
- if (!pattern_1) {
1366
- exports.debug('skipping empty pattern');
1367
- continue;
1368
- }
1369
- // root the pattern when all of the following conditions are true:
1370
- if (patternRoot && // patternRoot supplied
1371
- !im._isRooted(pattern_1) && // AND pattern not rooted
1372
- // AND matchBase:false or not basename only
1373
- (!options_1.matchBase || (process.platform == 'win32' ? pattern_1.replace(/\\/g, '/') : pattern_1).indexOf('/') >= 0)) {
1374
- pattern_1 = im._ensureRooted(patternRoot, pattern_1);
1375
- exports.debug("rooted pattern: '" + pattern_1 + "'");
1376
- }
1377
- if (isIncludePattern) {
1378
- // apply the pattern
1379
- exports.debug('applying include pattern against original list');
1380
- var matchResults = minimatch.match(list, pattern_1, options_1);
1381
- exports.debug(matchResults.length + ' matches');
1382
- // union the results
1383
- for (var _b = 0, matchResults_1 = matchResults; _b < matchResults_1.length; _b++) {
1384
- var matchResult = matchResults_1[_b];
1385
- map[matchResult] = true;
1386
- }
1387
- }
1388
- else {
1389
- // apply the pattern
1390
- exports.debug('applying exclude pattern against original list');
1391
- var matchResults = minimatch.match(list, pattern_1, options_1);
1392
- exports.debug(matchResults.length + ' matches');
1393
- // substract the results
1394
- for (var _c = 0, matchResults_2 = matchResults; _c < matchResults_2.length; _c++) {
1395
- var matchResult = matchResults_2[_c];
1396
- delete map[matchResult];
1397
- }
1398
- }
1399
- }
1400
- }
1401
- // return a filtered version of the original list (preserves order and prevents duplication)
1402
- var result = list.filter(function (item) { return map.hasOwnProperty(item); });
1403
- exports.debug(result.length + ' final results');
1404
- return result;
1405
- }
1406
- exports.match = match;
1407
- /**
1408
- * Filter to apply glob patterns
1409
- *
1410
- * @param pattern pattern to apply
1411
- * @param options optional. defaults to { dot: true, nobrace: true, nocase: process.platform == 'win32' }.
1412
- */
1413
- function filter(pattern, options) {
1414
- options = options || _getDefaultMatchOptions();
1415
- return minimatch.filter(pattern, options);
1416
- }
1417
- exports.filter = filter;
1418
- function _debugMatchOptions(options) {
1419
- exports.debug("matchOptions.debug: '" + options.debug + "'");
1420
- exports.debug("matchOptions.nobrace: '" + options.nobrace + "'");
1421
- exports.debug("matchOptions.noglobstar: '" + options.noglobstar + "'");
1422
- exports.debug("matchOptions.dot: '" + options.dot + "'");
1423
- exports.debug("matchOptions.noext: '" + options.noext + "'");
1424
- exports.debug("matchOptions.nocase: '" + options.nocase + "'");
1425
- exports.debug("matchOptions.nonull: '" + options.nonull + "'");
1426
- exports.debug("matchOptions.matchBase: '" + options.matchBase + "'");
1427
- exports.debug("matchOptions.nocomment: '" + options.nocomment + "'");
1428
- exports.debug("matchOptions.nonegate: '" + options.nonegate + "'");
1429
- exports.debug("matchOptions.flipNegate: '" + options.flipNegate + "'");
1430
- }
1431
- function _getDefaultMatchOptions() {
1432
- return {
1433
- debug: false,
1434
- nobrace: true,
1435
- noglobstar: false,
1436
- dot: true,
1437
- noext: false,
1438
- nocase: process.platform == 'win32',
1439
- nonull: false,
1440
- matchBase: false,
1441
- nocomment: false,
1442
- nonegate: false,
1443
- flipNegate: false
1444
- };
1445
- }
1446
- /**
1447
- * Determines the find root from a list of patterns. Performs the find and then applies the glob patterns.
1448
- * Supports interleaved exclude patterns. Unrooted patterns are rooted using defaultRoot, unless
1449
- * matchOptions.matchBase is specified and the pattern is a basename only. For matchBase cases, the
1450
- * defaultRoot is used as the find root.
1451
- *
1452
- * @param defaultRoot default path to root unrooted patterns. falls back to System.DefaultWorkingDirectory or process.cwd().
1453
- * @param patterns pattern or array of patterns to apply
1454
- * @param findOptions defaults to { followSymbolicLinks: true }. following soft links is generally appropriate unless deleting files.
1455
- * @param matchOptions defaults to { dot: true, nobrace: true, nocase: process.platform == 'win32' }
1456
- */
1457
- function findMatch(defaultRoot, patterns, findOptions, matchOptions) {
1458
- // apply defaults for parameters and trace
1459
- defaultRoot = defaultRoot || this.getVariable('system.defaultWorkingDirectory') || process.cwd();
1460
- exports.debug("defaultRoot: '" + defaultRoot + "'");
1461
- patterns = patterns || [];
1462
- patterns = typeof patterns == 'string' ? [patterns] : patterns;
1463
- findOptions = findOptions || _getDefaultFindOptions();
1464
- _debugFindOptions(findOptions);
1465
- matchOptions = matchOptions || _getDefaultMatchOptions();
1466
- _debugMatchOptions(matchOptions);
1467
- // normalize slashes for root dir
1468
- defaultRoot = im._normalizeSeparators(defaultRoot);
1469
- var results = {};
1470
- var originalMatchOptions = matchOptions;
1471
- for (var _i = 0, _a = (patterns || []); _i < _a.length; _i++) {
1472
- var pattern = _a[_i];
1473
- exports.debug("pattern: '" + pattern + "'");
1474
- // trim and skip empty
1475
- pattern = (pattern || '').trim();
1476
- if (!pattern) {
1477
- exports.debug('skipping empty pattern');
1478
- continue;
1479
- }
1480
- // clone match options
1481
- var matchOptions_1 = im._cloneMatchOptions(originalMatchOptions);
1482
- // skip comments
1483
- if (!matchOptions_1.nocomment && im._startsWith(pattern, '#')) {
1484
- exports.debug('skipping comment');
1485
- continue;
1486
- }
1487
- // set nocomment - brace expansion could result in a leading '#'
1488
- matchOptions_1.nocomment = true;
1489
- // determine whether pattern is include or exclude
1490
- var negateCount = 0;
1491
- if (!matchOptions_1.nonegate) {
1492
- while (pattern.charAt(negateCount) == '!') {
1493
- negateCount++;
1494
- }
1495
- pattern = pattern.substring(negateCount); // trim leading '!'
1496
- if (negateCount) {
1497
- exports.debug("trimmed leading '!'. pattern: '" + pattern + "'");
1498
- }
1499
- }
1500
- var isIncludePattern = negateCount == 0 ||
1501
- (negateCount % 2 == 0 && !matchOptions_1.flipNegate) ||
1502
- (negateCount % 2 == 1 && matchOptions_1.flipNegate);
1503
- // set nonegate - brace expansion could result in a leading '!'
1504
- matchOptions_1.nonegate = true;
1505
- matchOptions_1.flipNegate = false;
1506
- // expand braces - required to accurately interpret findPath
1507
- var expanded = void 0;
1508
- var preExpanded = pattern;
1509
- if (matchOptions_1.nobrace) {
1510
- expanded = [pattern];
1511
- }
1512
- else {
1513
- // convert slashes on Windows before calling braceExpand(). unfortunately this means braces cannot
1514
- // be escaped on Windows, this limitation is consistent with current limitations of minimatch (3.0.3).
1515
- exports.debug('expanding braces');
1516
- var convertedPattern = process.platform == 'win32' ? pattern.replace(/\\/g, '/') : pattern;
1517
- expanded = minimatch.braceExpand(convertedPattern);
1518
- }
1519
- // set nobrace
1520
- matchOptions_1.nobrace = true;
1521
- for (var _b = 0, expanded_2 = expanded; _b < expanded_2.length; _b++) {
1522
- var pattern_2 = expanded_2[_b];
1523
- if (expanded.length != 1 || pattern_2 != preExpanded) {
1524
- exports.debug("pattern: '" + pattern_2 + "'");
1525
- }
1526
- // trim and skip empty
1527
- pattern_2 = (pattern_2 || '').trim();
1528
- if (!pattern_2) {
1529
- exports.debug('skipping empty pattern');
1530
- continue;
1531
- }
1532
- if (isIncludePattern) {
1533
- // determine the findPath
1534
- var findInfo = im._getFindInfoFromPattern(defaultRoot, pattern_2, matchOptions_1);
1535
- var findPath = findInfo.findPath;
1536
- exports.debug("findPath: '" + findPath + "'");
1537
- if (!findPath) {
1538
- exports.debug('skipping empty path');
1539
- continue;
1540
- }
1541
- // perform the find
1542
- exports.debug("statOnly: '" + findInfo.statOnly + "'");
1543
- var findResults = [];
1544
- if (findInfo.statOnly) {
1545
- // simply stat the path - all path segments were used to build the path
1546
- try {
1547
- fs.statSync(findPath);
1548
- findResults.push(findPath);
1549
- }
1550
- catch (err) {
1551
- if (err.code != 'ENOENT') {
1552
- throw err;
1553
- }
1554
- exports.debug('ENOENT');
1555
- }
1556
- }
1557
- else {
1558
- findResults = find(findPath, findOptions);
1559
- }
1560
- exports.debug("found " + findResults.length + " paths");
1561
- // apply the pattern
1562
- exports.debug('applying include pattern');
1563
- if (findInfo.adjustedPattern != pattern_2) {
1564
- exports.debug("adjustedPattern: '" + findInfo.adjustedPattern + "'");
1565
- pattern_2 = findInfo.adjustedPattern;
1566
- }
1567
- var matchResults = minimatch.match(findResults, pattern_2, matchOptions_1);
1568
- exports.debug(matchResults.length + ' matches');
1569
- // union the results
1570
- for (var _c = 0, matchResults_3 = matchResults; _c < matchResults_3.length; _c++) {
1571
- var matchResult = matchResults_3[_c];
1572
- var key = process.platform == 'win32' ? matchResult.toUpperCase() : matchResult;
1573
- results[key] = matchResult;
1574
- }
1575
- }
1576
- else {
1577
- // check if basename only and matchBase=true
1578
- if (matchOptions_1.matchBase &&
1579
- !im._isRooted(pattern_2) &&
1580
- (process.platform == 'win32' ? pattern_2.replace(/\\/g, '/') : pattern_2).indexOf('/') < 0) {
1581
- // do not root the pattern
1582
- exports.debug('matchBase and basename only');
1583
- }
1584
- else {
1585
- // root the exclude pattern
1586
- pattern_2 = im._ensurePatternRooted(defaultRoot, pattern_2);
1587
- exports.debug("after ensurePatternRooted, pattern: '" + pattern_2 + "'");
1588
- }
1589
- // apply the pattern
1590
- exports.debug('applying exclude pattern');
1591
- var matchResults = minimatch.match(Object.keys(results).map(function (key) { return results[key]; }), pattern_2, matchOptions_1);
1592
- exports.debug(matchResults.length + ' matches');
1593
- // substract the results
1594
- for (var _d = 0, matchResults_4 = matchResults; _d < matchResults_4.length; _d++) {
1595
- var matchResult = matchResults_4[_d];
1596
- var key = process.platform == 'win32' ? matchResult.toUpperCase() : matchResult;
1597
- delete results[key];
1598
- }
1599
- }
1600
- }
1601
- }
1602
- var finalResult = Object.keys(results)
1603
- .map(function (key) { return results[key]; })
1604
- .sort();
1605
- exports.debug(finalResult.length + ' final results');
1606
- return finalResult;
1607
- }
1608
- exports.findMatch = findMatch;
1609
- /**
1610
- * Build Proxy URL in the following format: protocol://username:password@hostname:port
1611
- * @param proxyUrl Url address of the proxy server (eg: http://example.com)
1612
- * @param proxyUsername Proxy username (optional)
1613
- * @param proxyPassword Proxy password (optional)
1614
- * @returns string
1615
- */
1616
- function getProxyFormattedUrl(proxyUrl, proxyUsername, proxyPassword) {
1617
- var parsedUrl = new URL(proxyUrl);
1618
- var proxyAddress = parsedUrl.protocol + "//" + parsedUrl.host;
1619
- if (proxyUsername) {
1620
- proxyAddress = parsedUrl.protocol + "//" + proxyUsername + ":" + proxyPassword + "@" + parsedUrl.host;
1621
- }
1622
- return proxyAddress;
1623
- }
1624
- /**
1625
- * Gets http proxy configuration used by Build/Release agent
1626
- *
1627
- * @return ProxyConfiguration
1628
- */
1629
- function getHttpProxyConfiguration(requestUrl) {
1630
- var proxyUrl = exports.getVariable('Agent.ProxyUrl');
1631
- if (proxyUrl && proxyUrl.length > 0) {
1632
- var proxyUsername = exports.getVariable('Agent.ProxyUsername');
1633
- var proxyPassword = exports.getVariable('Agent.ProxyPassword');
1634
- var proxyBypassHosts = JSON.parse(exports.getVariable('Agent.ProxyBypassList') || '[]');
1635
- var bypass_1 = false;
1636
- if (requestUrl) {
1637
- proxyBypassHosts.forEach(function (bypassHost) {
1638
- if (new RegExp(bypassHost, 'i').test(requestUrl)) {
1639
- bypass_1 = true;
1640
- }
1641
- });
1642
- }
1643
- if (bypass_1) {
1644
- return null;
1645
- }
1646
- else {
1647
- var proxyAddress = getProxyFormattedUrl(proxyUrl, proxyUsername, proxyPassword);
1648
- return {
1649
- proxyUrl: proxyUrl,
1650
- proxyUsername: proxyUsername,
1651
- proxyPassword: proxyPassword,
1652
- proxyBypassHosts: proxyBypassHosts,
1653
- proxyFormattedUrl: proxyAddress
1654
- };
1655
- }
1656
- }
1657
- else {
1658
- return null;
1659
- }
1660
- }
1661
- exports.getHttpProxyConfiguration = getHttpProxyConfiguration;
1662
- /**
1663
- * Gets http certificate configuration used by Build/Release agent
1664
- *
1665
- * @return CertConfiguration
1666
- */
1667
- function getHttpCertConfiguration() {
1668
- var ca = exports.getVariable('Agent.CAInfo');
1669
- var clientCert = exports.getVariable('Agent.ClientCert');
1670
- if (ca || clientCert) {
1671
- var certConfig = {};
1672
- certConfig.caFile = ca;
1673
- certConfig.certFile = clientCert;
1674
- if (clientCert) {
1675
- var clientCertKey = exports.getVariable('Agent.ClientCertKey');
1676
- var clientCertArchive = exports.getVariable('Agent.ClientCertArchive');
1677
- var clientCertPassword = exports.getVariable('Agent.ClientCertPassword');
1678
- certConfig.keyFile = clientCertKey;
1679
- certConfig.certArchiveFile = clientCertArchive;
1680
- certConfig.passphrase = clientCertPassword;
1681
- }
1682
- return certConfig;
1683
- }
1684
- else {
1685
- return null;
1686
- }
1687
- }
1688
- exports.getHttpCertConfiguration = getHttpCertConfiguration;
1689
- //-----------------------------------------------------
1690
- // Test Publisher
1691
- //-----------------------------------------------------
1692
- var TestPublisher = /** @class */ (function () {
1693
- function TestPublisher(testRunner) {
1694
- this.testRunner = testRunner;
1695
- }
1696
- TestPublisher.prototype.publish = function (resultFiles, mergeResults, platform, config, runTitle, publishRunAttachments, testRunSystem) {
1697
- // Could have used an initializer, but wanted to avoid reordering parameters when converting to strict null checks
1698
- // (A parameter cannot both be optional and have an initializer)
1699
- testRunSystem = testRunSystem || "VSTSTask";
1700
- var properties = {};
1701
- properties['type'] = this.testRunner;
1702
- if (mergeResults) {
1703
- properties['mergeResults'] = mergeResults;
1704
- }
1705
- if (platform) {
1706
- properties['platform'] = platform;
1707
- }
1708
- if (config) {
1709
- properties['config'] = config;
1710
- }
1711
- if (runTitle) {
1712
- properties['runTitle'] = runTitle;
1713
- }
1714
- if (publishRunAttachments) {
1715
- properties['publishRunAttachments'] = publishRunAttachments;
1716
- }
1717
- if (resultFiles) {
1718
- properties['resultFiles'] = Array.isArray(resultFiles) ? resultFiles.join() : resultFiles;
1719
- }
1720
- properties['testRunSystem'] = testRunSystem;
1721
- exports.command('results.publish', properties, '');
1722
- };
1723
- return TestPublisher;
1724
- }());
1725
- exports.TestPublisher = TestPublisher;
1726
- //-----------------------------------------------------
1727
- // Code coverage Publisher
1728
- //-----------------------------------------------------
1729
- var CodeCoveragePublisher = /** @class */ (function () {
1730
- function CodeCoveragePublisher() {
1731
- }
1732
- CodeCoveragePublisher.prototype.publish = function (codeCoverageTool, summaryFileLocation, reportDirectory, additionalCodeCoverageFiles) {
1733
- var properties = {};
1734
- if (codeCoverageTool) {
1735
- properties['codecoveragetool'] = codeCoverageTool;
1736
- }
1737
- if (summaryFileLocation) {
1738
- properties['summaryfile'] = summaryFileLocation;
1739
- }
1740
- if (reportDirectory) {
1741
- properties['reportdirectory'] = reportDirectory;
1742
- }
1743
- if (additionalCodeCoverageFiles) {
1744
- properties['additionalcodecoveragefiles'] = Array.isArray(additionalCodeCoverageFiles) ? additionalCodeCoverageFiles.join() : additionalCodeCoverageFiles;
1745
- }
1746
- exports.command('codecoverage.publish', properties, "");
1747
- };
1748
- return CodeCoveragePublisher;
1749
- }());
1750
- exports.CodeCoveragePublisher = CodeCoveragePublisher;
1751
- //-----------------------------------------------------
1752
- // Code coverage Publisher
1753
- //-----------------------------------------------------
1754
- var CodeCoverageEnabler = /** @class */ (function () {
1755
- function CodeCoverageEnabler(buildTool, ccTool) {
1756
- this.buildTool = buildTool;
1757
- this.ccTool = ccTool;
1758
- }
1759
- CodeCoverageEnabler.prototype.enableCodeCoverage = function (buildProps) {
1760
- buildProps['buildtool'] = this.buildTool;
1761
- buildProps['codecoveragetool'] = this.ccTool;
1762
- exports.command('codecoverage.enable', buildProps, "");
1763
- };
1764
- return CodeCoverageEnabler;
1765
- }());
1766
- exports.CodeCoverageEnabler = CodeCoverageEnabler;
1767
- //-----------------------------------------------------
1768
- // Task Logging Commands
1769
- //-----------------------------------------------------
1770
- /**
1771
- * Upload user interested file as additional log information
1772
- * to the current timeline record.
1773
- *
1774
- * The file shall be available for download along with task logs.
1775
- *
1776
- * @param path Path to the file that should be uploaded.
1777
- * @returns void
1778
- */
1779
- function uploadFile(path) {
1780
- exports.command("task.uploadfile", null, path);
1781
- }
1782
- exports.uploadFile = uploadFile;
1783
- /**
1784
- * Instruction for the agent to update the PATH environment variable.
1785
- * The specified directory is prepended to the PATH.
1786
- * The updated environment variable will be reflected in subsequent tasks.
1787
- *
1788
- * @param path Local directory path.
1789
- * @returns void
1790
- */
1791
- function prependPath(path) {
1792
- assertAgent("2.115.0");
1793
- exports.command("task.prependpath", null, path);
1794
- }
1795
- exports.prependPath = prependPath;
1796
- /**
1797
- * Upload and attach summary markdown to current timeline record.
1798
- * This summary shall be added to the build/release summary and
1799
- * not available for download with logs.
1800
- *
1801
- * @param path Local directory path.
1802
- * @returns void
1803
- */
1804
- function uploadSummary(path) {
1805
- exports.command("task.uploadsummary", null, path);
1806
- }
1807
- exports.uploadSummary = uploadSummary;
1808
- /**
1809
- * Upload and attach attachment to current timeline record.
1810
- * These files are not available for download with logs.
1811
- * These can only be referred to by extensions using the type or name values.
1812
- *
1813
- * @param type Attachment type.
1814
- * @param name Attachment name.
1815
- * @param path Attachment path.
1816
- * @returns void
1817
- */
1818
- function addAttachment(type, name, path) {
1819
- exports.command("task.addattachment", { "type": type, "name": name }, path);
1820
- }
1821
- exports.addAttachment = addAttachment;
1822
- /**
1823
- * Set an endpoint field with given value.
1824
- * Value updated will be retained in the endpoint for
1825
- * the subsequent tasks that execute within the same job.
1826
- *
1827
- * @param id Endpoint id.
1828
- * @param field FieldType enum of AuthParameter, DataParameter or Url.
1829
- * @param key Key.
1830
- * @param value Value for key or url.
1831
- * @returns void
1832
- */
1833
- function setEndpoint(id, field, key, value) {
1834
- exports.command("task.setendpoint", { "id": id, "field": FieldType[field].toLowerCase(), "key": key }, value);
1835
- }
1836
- exports.setEndpoint = setEndpoint;
1837
- /**
1838
- * Set progress and current operation for current task.
1839
- *
1840
- * @param percent Percentage of completion.
1841
- * @param currentOperation Current pperation.
1842
- * @returns void
1843
- */
1844
- function setProgress(percent, currentOperation) {
1845
- exports.command("task.setprogress", { "value": "" + percent }, currentOperation);
1846
- }
1847
- exports.setProgress = setProgress;
1848
- /**
1849
- * Indicates whether to write the logging command directly to the host or to the output pipeline.
1850
- *
1851
- * @param id Timeline record Guid.
1852
- * @param parentId Parent timeline record Guid.
1853
- * @param recordType Record type.
1854
- * @param recordName Record name.
1855
- * @param order Order of timeline record.
1856
- * @param startTime Start time.
1857
- * @param finishTime End time.
1858
- * @param progress Percentage of completion.
1859
- * @param state TaskState enum of Unknown, Initialized, InProgress or Completed.
1860
- * @param result TaskResult enum of Succeeded, SucceededWithIssues, Failed, Cancelled or Skipped.
1861
- * @param message current operation
1862
- * @returns void
1863
- */
1864
- function logDetail(id, message, parentId, recordType, recordName, order, startTime, finishTime, progress, state, result) {
1865
- var properties = {
1866
- "id": id,
1867
- "parentid": parentId,
1868
- "type": recordType,
1869
- "name": recordName,
1870
- "order": order ? order.toString() : undefined,
1871
- "starttime": startTime,
1872
- "finishtime": finishTime,
1873
- "progress": progress ? progress.toString() : undefined,
1874
- "state": state ? TaskState[state] : undefined,
1875
- "result": result ? TaskResult[result] : undefined
1876
- };
1877
- exports.command("task.logdetail", properties, message);
1878
- }
1879
- exports.logDetail = logDetail;
1880
- /**
1881
- * Log error or warning issue to timeline record of current task.
1882
- *
1883
- * @param type IssueType enum of Error or Warning.
1884
- * @param sourcePath Source file location.
1885
- * @param lineNumber Line number.
1886
- * @param columnNumber Column number.
1887
- * @param code Error or warning code.
1888
- * @param message Error or warning message.
1889
- * @returns void
1890
- */
1891
- function logIssue(type, message, sourcePath, lineNumber, columnNumber, errorCode) {
1892
- var properties = {
1893
- "type": IssueType[type].toLowerCase(),
1894
- "code": errorCode,
1895
- "sourcepath": sourcePath,
1896
- "linenumber": lineNumber ? lineNumber.toString() : undefined,
1897
- "columnnumber": columnNumber ? columnNumber.toString() : undefined,
1898
- };
1899
- exports.command("task.logissue", properties, message);
1900
- }
1901
- exports.logIssue = logIssue;
1902
- //-----------------------------------------------------
1903
- // Artifact Logging Commands
1904
- //-----------------------------------------------------
1905
- /**
1906
- * Upload user interested file as additional log information
1907
- * to the current timeline record.
1908
- *
1909
- * The file shall be available for download along with task logs.
1910
- *
1911
- * @param containerFolder Folder that the file will upload to, folder will be created if needed.
1912
- * @param path Path to the file that should be uploaded.
1913
- * @param name Artifact name.
1914
- * @returns void
1915
- */
1916
- function uploadArtifact(containerFolder, path, name) {
1917
- exports.command("artifact.upload", { "containerfolder": containerFolder, "artifactname": name }, path);
1918
- }
1919
- exports.uploadArtifact = uploadArtifact;
1920
- /**
1921
- * Create an artifact link, artifact location is required to be
1922
- * a file container path, VC path or UNC share path.
1923
- *
1924
- * The file shall be available for download along with task logs.
1925
- *
1926
- * @param name Artifact name.
1927
- * @param path Path to the file that should be associated.
1928
- * @param artifactType ArtifactType enum of Container, FilePath, VersionControl, GitRef or TfvcLabel.
1929
- * @returns void
1930
- */
1931
- function associateArtifact(name, path, artifactType) {
1932
- exports.command("artifact.associate", { "type": ArtifactType[artifactType].toLowerCase(), "artifactname": name }, path);
1933
- }
1934
- exports.associateArtifact = associateArtifact;
1935
- //-----------------------------------------------------
1936
- // Build Logging Commands
1937
- //-----------------------------------------------------
1938
- /**
1939
- * Upload user interested log to build’s container “logs\tool” folder.
1940
- *
1941
- * @param path Path to the file that should be uploaded.
1942
- * @returns void
1943
- */
1944
- function uploadBuildLog(path) {
1945
- exports.command("build.uploadlog", null, path);
1946
- }
1947
- exports.uploadBuildLog = uploadBuildLog;
1948
- /**
1949
- * Update build number for current build.
1950
- *
1951
- * @param value Value to be assigned as the build number.
1952
- * @returns void
1953
- */
1954
- function updateBuildNumber(value) {
1955
- exports.command("build.updatebuildnumber", null, value);
1956
- }
1957
- exports.updateBuildNumber = updateBuildNumber;
1958
- /**
1959
- * Add a tag for current build.
1960
- *
1961
- * @param value Tag value.
1962
- * @returns void
1963
- */
1964
- function addBuildTag(value) {
1965
- exports.command("build.addbuildtag", null, value);
1966
- }
1967
- exports.addBuildTag = addBuildTag;
1968
- //-----------------------------------------------------
1969
- // Release Logging Commands
1970
- //-----------------------------------------------------
1971
- /**
1972
- * Update release name for current release.
1973
- *
1974
- * @param value Value to be assigned as the release name.
1975
- * @returns void
1976
- */
1977
- function updateReleaseName(name) {
1978
- assertAgent("2.132.0");
1979
- exports.command("release.updatereleasename", null, name);
1980
- }
1981
- exports.updateReleaseName = updateReleaseName;
1982
- //-----------------------------------------------------
1983
- // Tools
1984
- //-----------------------------------------------------
1985
- exports.TaskCommand = tcm.TaskCommand;
1986
- exports.commandFromString = tcm.commandFromString;
1987
- exports.ToolRunner = trm.ToolRunner;
1988
- //-----------------------------------------------------
1989
- // Validation Checks
1990
- //-----------------------------------------------------
1991
- // async await needs generators in node 4.x+
1992
- if (semver.lt(process.versions.node, '4.2.0')) {
1993
- exports.warning('Tasks require a new agent. Upgrade your agent or node to 4.2.0 or later');
1994
- }
1995
- //-------------------------------------------------------------------
1996
- // Populate the vault with sensitive data. Inputs and Endpoints
1997
- //-------------------------------------------------------------------
1998
- // avoid loading twice (overwrites .taskkey)
1999
- if (!global['_vsts_task_lib_loaded']) {
2000
- im._loadData();
2001
- im._exposeProxySettings();
2002
- im._exposeCertSettings();
2003
- }
1
+ "use strict";
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.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.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.Platform = exports.FieldType = exports.ArtifactType = exports.IssueType = exports.TaskState = exports.TaskResult = void 0;
4
+ var shell = require("shelljs");
5
+ var childProcess = require("child_process");
6
+ var fs = require("fs");
7
+ var path = require("path");
8
+ var os = require("os");
9
+ var minimatch = require("minimatch");
10
+ var im = require("./internal");
11
+ var tcm = require("./taskcommand");
12
+ var trm = require("./toolrunner");
13
+ var semver = require("semver");
14
+ var TaskResult;
15
+ (function (TaskResult) {
16
+ TaskResult[TaskResult["Succeeded"] = 0] = "Succeeded";
17
+ TaskResult[TaskResult["SucceededWithIssues"] = 1] = "SucceededWithIssues";
18
+ TaskResult[TaskResult["Failed"] = 2] = "Failed";
19
+ TaskResult[TaskResult["Cancelled"] = 3] = "Cancelled";
20
+ TaskResult[TaskResult["Skipped"] = 4] = "Skipped";
21
+ })(TaskResult = exports.TaskResult || (exports.TaskResult = {}));
22
+ var TaskState;
23
+ (function (TaskState) {
24
+ TaskState[TaskState["Unknown"] = 0] = "Unknown";
25
+ TaskState[TaskState["Initialized"] = 1] = "Initialized";
26
+ TaskState[TaskState["InProgress"] = 2] = "InProgress";
27
+ TaskState[TaskState["Completed"] = 3] = "Completed";
28
+ })(TaskState = exports.TaskState || (exports.TaskState = {}));
29
+ var IssueType;
30
+ (function (IssueType) {
31
+ IssueType[IssueType["Error"] = 0] = "Error";
32
+ IssueType[IssueType["Warning"] = 1] = "Warning";
33
+ })(IssueType = exports.IssueType || (exports.IssueType = {}));
34
+ var ArtifactType;
35
+ (function (ArtifactType) {
36
+ ArtifactType[ArtifactType["Container"] = 0] = "Container";
37
+ ArtifactType[ArtifactType["FilePath"] = 1] = "FilePath";
38
+ ArtifactType[ArtifactType["VersionControl"] = 2] = "VersionControl";
39
+ ArtifactType[ArtifactType["GitRef"] = 3] = "GitRef";
40
+ ArtifactType[ArtifactType["TfvcLabel"] = 4] = "TfvcLabel";
41
+ })(ArtifactType = exports.ArtifactType || (exports.ArtifactType = {}));
42
+ var FieldType;
43
+ (function (FieldType) {
44
+ FieldType[FieldType["AuthParameter"] = 0] = "AuthParameter";
45
+ FieldType[FieldType["DataParameter"] = 1] = "DataParameter";
46
+ FieldType[FieldType["Url"] = 2] = "Url";
47
+ })(FieldType = exports.FieldType || (exports.FieldType = {}));
48
+ /** Platforms supported by our build agent */
49
+ var Platform;
50
+ (function (Platform) {
51
+ Platform[Platform["Windows"] = 0] = "Windows";
52
+ Platform[Platform["MacOS"] = 1] = "MacOS";
53
+ Platform[Platform["Linux"] = 2] = "Linux";
54
+ })(Platform = exports.Platform || (exports.Platform = {}));
55
+ //-----------------------------------------------------
56
+ // General Helpers
57
+ //-----------------------------------------------------
58
+ exports.setStdStream = im._setStdStream;
59
+ exports.setErrStream = im._setErrStream;
60
+ //-----------------------------------------------------
61
+ // Results
62
+ //-----------------------------------------------------
63
+ /**
64
+ * Sets the result of the task.
65
+ * Execution will continue.
66
+ * If not set, task will be Succeeded.
67
+ * If multiple calls are made to setResult the most pessimistic call wins (Failed) regardless of the order of calls.
68
+ *
69
+ * @param result TaskResult enum of Succeeded, SucceededWithIssues, Failed, Cancelled or Skipped.
70
+ * @param message A message which will be logged as an error issue if the result is Failed.
71
+ * @param done Optional. Instructs the agent the task is done. This is helpful when child processes
72
+ * may still be running and prevent node from fully exiting. This argument is supported
73
+ * from agent version 2.142.0 or higher (otherwise will no-op).
74
+ * @returns void
75
+ */
76
+ function setResult(result, message, done) {
77
+ exports.debug('task result: ' + TaskResult[result]);
78
+ // add an error issue
79
+ if (result == TaskResult.Failed && message) {
80
+ exports.error(message);
81
+ }
82
+ else if (result == TaskResult.SucceededWithIssues && message) {
83
+ exports.warning(message);
84
+ }
85
+ // task.complete
86
+ var properties = { 'result': TaskResult[result] };
87
+ if (done) {
88
+ properties['done'] = 'true';
89
+ }
90
+ exports.command('task.complete', properties, message);
91
+ }
92
+ exports.setResult = setResult;
93
+ //
94
+ // Catching all exceptions
95
+ //
96
+ process.on('uncaughtException', function (err) {
97
+ setResult(TaskResult.Failed, exports.loc('LIB_UnhandledEx', err.message));
98
+ });
99
+ //-----------------------------------------------------
100
+ // Loc Helpers
101
+ //-----------------------------------------------------
102
+ exports.setResourcePath = im._setResourcePath;
103
+ exports.loc = im._loc;
104
+ //-----------------------------------------------------
105
+ // Input Helpers
106
+ //-----------------------------------------------------
107
+ exports.getVariable = im._getVariable;
108
+ /**
109
+ * Asserts the agent version is at least the specified minimum.
110
+ *
111
+ * @param minimum minimum version version - must be 2.104.1 or higher
112
+ */
113
+ function assertAgent(minimum) {
114
+ if (semver.lt(minimum, '2.104.1')) {
115
+ throw new Error('assertAgent() requires the parameter to be 2.104.1 or higher');
116
+ }
117
+ var agent = exports.getVariable('Agent.Version');
118
+ if (agent && semver.lt(agent, minimum)) {
119
+ throw new Error("Agent version " + minimum + " or higher is required");
120
+ }
121
+ }
122
+ exports.assertAgent = assertAgent;
123
+ /**
124
+ * Gets a snapshot of the current state of all job variables available to the task.
125
+ * Requires a 2.104.1 agent or higher for full functionality.
126
+ *
127
+ * Limitations on an agent prior to 2.104.1:
128
+ * 1) The return value does not include all public variables. Only public variables
129
+ * that have been added using setVariable are returned.
130
+ * 2) The name returned for each secret variable is the formatted environment variable
131
+ * name, not the actual variable name (unless it was set explicitly at runtime using
132
+ * setVariable).
133
+ *
134
+ * @returns VariableInfo[]
135
+ */
136
+ function getVariables() {
137
+ return Object.keys(im._knownVariableMap)
138
+ .map(function (key) {
139
+ var info = im._knownVariableMap[key];
140
+ return { name: info.name, value: exports.getVariable(info.name), secret: info.secret };
141
+ });
142
+ }
143
+ exports.getVariables = getVariables;
144
+ /**
145
+ * Sets a variable which will be available to subsequent tasks as well.
146
+ *
147
+ * @param name name of the variable to set
148
+ * @param val value to set
149
+ * @param secret whether variable is secret. Multi-line secrets are not allowed. Optional, defaults to false
150
+ * @param isOutput whether variable is an output variable. Optional, defaults to false
151
+ * @returns void
152
+ */
153
+ function setVariable(name, val, secret, isOutput) {
154
+ if (secret === void 0) { secret = false; }
155
+ if (isOutput === void 0) { isOutput = false; }
156
+ // once a secret always a secret
157
+ var key = im._getVariableKey(name);
158
+ if (im._knownVariableMap.hasOwnProperty(key)) {
159
+ secret = secret || im._knownVariableMap[key].secret;
160
+ }
161
+ // store the value
162
+ var varValue = val || '';
163
+ exports.debug('set ' + name + '=' + (secret && varValue ? '********' : varValue));
164
+ if (secret) {
165
+ if (varValue && varValue.match(/\r|\n/) && ("" + process.env['SYSTEM_UNSAFEALLOWMULTILINESECRET']).toUpperCase() != 'TRUE') {
166
+ throw new Error(exports.loc('LIB_MultilineSecret'));
167
+ }
168
+ im._vault.storeSecret('SECRET_' + key, varValue);
169
+ delete process.env[key];
170
+ }
171
+ else {
172
+ process.env[key] = varValue;
173
+ }
174
+ // store the metadata
175
+ im._knownVariableMap[key] = { name: name, secret: secret };
176
+ // write the setvariable command
177
+ exports.command('task.setvariable', { 'variable': name || '', isOutput: (isOutput || false).toString(), 'issecret': (secret || false).toString() }, varValue);
178
+ }
179
+ exports.setVariable = setVariable;
180
+ /**
181
+ * Registers a value with the logger, so the value will be masked from the logs. Multi-line secrets are not allowed.
182
+ *
183
+ * @param val value to register
184
+ */
185
+ function setSecret(val) {
186
+ if (val) {
187
+ if (val.match(/\r|\n/) && ("" + process.env['SYSTEM_UNSAFEALLOWMULTILINESECRET']).toUpperCase() !== 'TRUE') {
188
+ throw new Error(exports.loc('LIB_MultilineSecret'));
189
+ }
190
+ exports.command('task.setsecret', {}, val);
191
+ }
192
+ }
193
+ exports.setSecret = setSecret;
194
+ /**
195
+ * Gets the value of an input.
196
+ * If required is true and the value is not set, it will throw.
197
+ *
198
+ * @param name name of the input to get
199
+ * @param required whether input is required. optional, defaults to false
200
+ * @returns string
201
+ */
202
+ function getInput(name, required) {
203
+ var inval = im._vault.retrieveSecret('INPUT_' + im._getVariableKey(name));
204
+ if (required && !inval) {
205
+ throw new Error(exports.loc('LIB_InputRequired', name));
206
+ }
207
+ exports.debug(name + '=' + inval);
208
+ return inval;
209
+ }
210
+ exports.getInput = getInput;
211
+ /**
212
+ * Gets the value of an input.
213
+ * If the value is not set, it will throw.
214
+ *
215
+ * @param name name of the input to get
216
+ * @returns string
217
+ */
218
+ function getInputRequired(name) {
219
+ return getInput(name, true);
220
+ }
221
+ exports.getInputRequired = getInputRequired;
222
+ /**
223
+ * Gets the value of an input and converts to a bool. Convenience.
224
+ * If required is true and the value is not set, it will throw.
225
+ * If required is false and the value is not set, returns false.
226
+ *
227
+ * @param name name of the bool input to get
228
+ * @param required whether input is required. optional, defaults to false
229
+ * @returns boolean
230
+ */
231
+ function getBoolInput(name, required) {
232
+ return (getInput(name, required) || '').toUpperCase() == "TRUE";
233
+ }
234
+ exports.getBoolInput = getBoolInput;
235
+ /**
236
+ * Gets the value of an input and splits the value using a delimiter (space, comma, etc).
237
+ * Empty values are removed. This function is useful for splitting an input containing a simple
238
+ * list of items - such as build targets.
239
+ * IMPORTANT: Do not use this function for splitting additional args! Instead use argString(), which
240
+ * follows normal argument splitting rules and handles values encapsulated by quotes.
241
+ * If required is true and the value is not set, it will throw.
242
+ *
243
+ * @param name name of the input to get
244
+ * @param delim delimiter to split on
245
+ * @param required whether input is required. optional, defaults to false
246
+ * @returns string[]
247
+ */
248
+ function getDelimitedInput(name, delim, required) {
249
+ var inputVal = getInput(name, required);
250
+ if (!inputVal) {
251
+ return [];
252
+ }
253
+ var result = [];
254
+ inputVal.split(delim).forEach(function (x) {
255
+ if (x) {
256
+ result.push(x);
257
+ }
258
+ });
259
+ return result;
260
+ }
261
+ exports.getDelimitedInput = getDelimitedInput;
262
+ /**
263
+ * Checks whether a path inputs value was supplied by the user
264
+ * File paths are relative with a picker, so an empty path is the root of the repo.
265
+ * Useful if you need to condition work (like append an arg) if a value was supplied
266
+ *
267
+ * @param name name of the path input to check
268
+ * @returns boolean
269
+ */
270
+ function filePathSupplied(name) {
271
+ // normalize paths
272
+ var pathValue = this.resolve(this.getPathInput(name) || '');
273
+ var repoRoot = this.resolve(exports.getVariable('build.sourcesDirectory') || exports.getVariable('system.defaultWorkingDirectory') || '');
274
+ var supplied = pathValue !== repoRoot;
275
+ exports.debug(name + 'path supplied :' + supplied);
276
+ return supplied;
277
+ }
278
+ exports.filePathSupplied = filePathSupplied;
279
+ /**
280
+ * Gets the value of a path input
281
+ * It will be quoted for you if it isn't already and contains spaces
282
+ * If required is true and the value is not set, it will throw.
283
+ * If check is true and the path does not exist, it will throw.
284
+ *
285
+ * @param name name of the input to get
286
+ * @param required whether input is required. optional, defaults to false
287
+ * @param check whether path is checked. optional, defaults to false
288
+ * @returns string
289
+ */
290
+ function getPathInput(name, required, check) {
291
+ var inval = getInput(name, required);
292
+ if (inval) {
293
+ if (check) {
294
+ exports.checkPath(inval, name);
295
+ }
296
+ }
297
+ return inval;
298
+ }
299
+ exports.getPathInput = getPathInput;
300
+ /**
301
+ * Gets the value of a path input
302
+ * It will be quoted for you if it isn't already and contains spaces
303
+ * If the value is not set, it will throw.
304
+ * If check is true and the path does not exist, it will throw.
305
+ *
306
+ * @param name name of the input to get
307
+ * @param check whether path is checked. optional, defaults to false
308
+ * @returns string
309
+ */
310
+ function getPathInputRequired(name, check) {
311
+ return getPathInput(name, true, check);
312
+ }
313
+ exports.getPathInputRequired = getPathInputRequired;
314
+ //-----------------------------------------------------
315
+ // Endpoint Helpers
316
+ //-----------------------------------------------------
317
+ /**
318
+ * Gets the url for a service endpoint
319
+ * If the url was not set and is not optional, it will throw.
320
+ *
321
+ * @param id name of the service endpoint
322
+ * @param optional whether the url is optional
323
+ * @returns string
324
+ */
325
+ function getEndpointUrl(id, optional) {
326
+ var urlval = process.env['ENDPOINT_URL_' + id];
327
+ if (!optional && !urlval) {
328
+ throw new Error(exports.loc('LIB_EndpointNotExist', id));
329
+ }
330
+ exports.debug(id + '=' + urlval);
331
+ return urlval;
332
+ }
333
+ exports.getEndpointUrl = getEndpointUrl;
334
+ /**
335
+ * Gets the url for a service endpoint
336
+ * If the url was not set, it will throw.
337
+ *
338
+ * @param id name of the service endpoint
339
+ * @returns string
340
+ */
341
+ function getEndpointUrlRequired(id) {
342
+ return getEndpointUrl(id, false);
343
+ }
344
+ exports.getEndpointUrlRequired = getEndpointUrlRequired;
345
+ /*
346
+ * Gets the endpoint data parameter value with specified key for a service endpoint
347
+ * If the endpoint data parameter was not set and is not optional, it will throw.
348
+ *
349
+ * @param id name of the service endpoint
350
+ * @param key of the parameter
351
+ * @param optional whether the endpoint data is optional
352
+ * @returns {string} value of the endpoint data parameter
353
+ */
354
+ function getEndpointDataParameter(id, key, optional) {
355
+ var dataParamVal = process.env['ENDPOINT_DATA_' + id + '_' + key.toUpperCase()];
356
+ if (!optional && !dataParamVal) {
357
+ throw new Error(exports.loc('LIB_EndpointDataNotExist', id, key));
358
+ }
359
+ exports.debug(id + ' data ' + key + ' = ' + dataParamVal);
360
+ return dataParamVal;
361
+ }
362
+ exports.getEndpointDataParameter = getEndpointDataParameter;
363
+ /*
364
+ * Gets the endpoint data parameter value with specified key for a service endpoint
365
+ * If the endpoint data parameter was not set, it will throw.
366
+ *
367
+ * @param id name of the service endpoint
368
+ * @param key of the parameter
369
+ * @returns {string} value of the endpoint data parameter
370
+ */
371
+ function getEndpointDataParameterRequired(id, key) {
372
+ return getEndpointDataParameter(id, key, false);
373
+ }
374
+ exports.getEndpointDataParameterRequired = getEndpointDataParameterRequired;
375
+ /**
376
+ * Gets the endpoint authorization scheme for a service endpoint
377
+ * If the endpoint authorization scheme is not set and is not optional, it will throw.
378
+ *
379
+ * @param id name of the service endpoint
380
+ * @param optional whether the endpoint authorization scheme is optional
381
+ * @returns {string} value of the endpoint authorization scheme
382
+ */
383
+ function getEndpointAuthorizationScheme(id, optional) {
384
+ var authScheme = im._vault.retrieveSecret('ENDPOINT_AUTH_SCHEME_' + id);
385
+ if (!optional && !authScheme) {
386
+ throw new Error(exports.loc('LIB_EndpointAuthNotExist', id));
387
+ }
388
+ exports.debug(id + ' auth scheme = ' + authScheme);
389
+ return authScheme;
390
+ }
391
+ exports.getEndpointAuthorizationScheme = getEndpointAuthorizationScheme;
392
+ /**
393
+ * Gets the endpoint authorization scheme for a service endpoint
394
+ * If the endpoint authorization scheme is not set, it will throw.
395
+ *
396
+ * @param id name of the service endpoint
397
+ * @returns {string} value of the endpoint authorization scheme
398
+ */
399
+ function getEndpointAuthorizationSchemeRequired(id) {
400
+ return getEndpointAuthorizationScheme(id, false);
401
+ }
402
+ exports.getEndpointAuthorizationSchemeRequired = getEndpointAuthorizationSchemeRequired;
403
+ /**
404
+ * Gets the endpoint authorization parameter value for a service endpoint with specified key
405
+ * If the endpoint authorization parameter is not set and is not optional, it will throw.
406
+ *
407
+ * @param id name of the service endpoint
408
+ * @param key key to find the endpoint authorization parameter
409
+ * @param optional optional whether the endpoint authorization scheme is optional
410
+ * @returns {string} value of the endpoint authorization parameter value
411
+ */
412
+ function getEndpointAuthorizationParameter(id, key, optional) {
413
+ var authParam = im._vault.retrieveSecret('ENDPOINT_AUTH_PARAMETER_' + id + '_' + key.toUpperCase());
414
+ if (!optional && !authParam) {
415
+ throw new Error(exports.loc('LIB_EndpointAuthNotExist', id));
416
+ }
417
+ exports.debug(id + ' auth param ' + key + ' = ' + authParam);
418
+ return authParam;
419
+ }
420
+ exports.getEndpointAuthorizationParameter = getEndpointAuthorizationParameter;
421
+ /**
422
+ * Gets the endpoint authorization parameter value for a service endpoint with specified key
423
+ * If the endpoint authorization parameter is not set, it will throw.
424
+ *
425
+ * @param id name of the service endpoint
426
+ * @param key key to find the endpoint authorization parameter
427
+ * @returns {string} value of the endpoint authorization parameter value
428
+ */
429
+ function getEndpointAuthorizationParameterRequired(id, key) {
430
+ return getEndpointAuthorizationParameter(id, key, false);
431
+ }
432
+ exports.getEndpointAuthorizationParameterRequired = getEndpointAuthorizationParameterRequired;
433
+ /**
434
+ * Gets the authorization details for a service endpoint
435
+ * If the authorization was not set and is not optional, it will set the task result to Failed.
436
+ *
437
+ * @param id name of the service endpoint
438
+ * @param optional whether the url is optional
439
+ * @returns string
440
+ */
441
+ function getEndpointAuthorization(id, optional) {
442
+ var aval = im._vault.retrieveSecret('ENDPOINT_AUTH_' + id);
443
+ if (!optional && !aval) {
444
+ setResult(TaskResult.Failed, exports.loc('LIB_EndpointAuthNotExist', id));
445
+ }
446
+ exports.debug(id + ' exists ' + (!!aval));
447
+ var auth;
448
+ try {
449
+ if (aval) {
450
+ auth = JSON.parse(aval);
451
+ }
452
+ }
453
+ catch (err) {
454
+ throw new Error(exports.loc('LIB_InvalidEndpointAuth', aval));
455
+ }
456
+ return auth;
457
+ }
458
+ exports.getEndpointAuthorization = getEndpointAuthorization;
459
+ //-----------------------------------------------------
460
+ // SecureFile Helpers
461
+ //-----------------------------------------------------
462
+ /**
463
+ * Gets the name for a secure file
464
+ *
465
+ * @param id secure file id
466
+ * @returns string
467
+ */
468
+ function getSecureFileName(id) {
469
+ var name = process.env['SECUREFILE_NAME_' + id];
470
+ exports.debug('secure file name for id ' + id + ' = ' + name);
471
+ return name;
472
+ }
473
+ exports.getSecureFileName = getSecureFileName;
474
+ /**
475
+ * Gets the secure file ticket that can be used to download the secure file contents
476
+ *
477
+ * @param id name of the secure file
478
+ * @returns {string} secure file ticket
479
+ */
480
+ function getSecureFileTicket(id) {
481
+ var ticket = im._vault.retrieveSecret('SECUREFILE_TICKET_' + id);
482
+ exports.debug('secure file ticket for id ' + id + ' = ' + ticket);
483
+ return ticket;
484
+ }
485
+ exports.getSecureFileTicket = getSecureFileTicket;
486
+ //-----------------------------------------------------
487
+ // Task Variable Helpers
488
+ //-----------------------------------------------------
489
+ /**
490
+ * Gets a variable value that is set by previous step from the same wrapper task.
491
+ * Requires a 2.115.0 agent or higher.
492
+ *
493
+ * @param name name of the variable to get
494
+ * @returns string
495
+ */
496
+ function getTaskVariable(name) {
497
+ assertAgent('2.115.0');
498
+ var inval = im._vault.retrieveSecret('VSTS_TASKVARIABLE_' + im._getVariableKey(name));
499
+ if (inval) {
500
+ inval = inval.trim();
501
+ }
502
+ exports.debug('task variable: ' + name + '=' + inval);
503
+ return inval;
504
+ }
505
+ exports.getTaskVariable = getTaskVariable;
506
+ /**
507
+ * Sets a task variable which will only be available to subsequent steps belong to the same wrapper task.
508
+ * Requires a 2.115.0 agent or higher.
509
+ *
510
+ * @param name name of the variable to set
511
+ * @param val value to set
512
+ * @param secret whether variable is secret. optional, defaults to false
513
+ * @returns void
514
+ */
515
+ function setTaskVariable(name, val, secret) {
516
+ if (secret === void 0) { secret = false; }
517
+ assertAgent('2.115.0');
518
+ var key = im._getVariableKey(name);
519
+ // store the value
520
+ var varValue = val || '';
521
+ exports.debug('set task variable: ' + name + '=' + (secret && varValue ? '********' : varValue));
522
+ im._vault.storeSecret('VSTS_TASKVARIABLE_' + key, varValue);
523
+ delete process.env[key];
524
+ // write the command
525
+ exports.command('task.settaskvariable', { 'variable': name || '', 'issecret': (secret || false).toString() }, varValue);
526
+ }
527
+ exports.setTaskVariable = setTaskVariable;
528
+ //-----------------------------------------------------
529
+ // Cmd Helpers
530
+ //-----------------------------------------------------
531
+ exports.command = im._command;
532
+ exports.warning = im._warning;
533
+ exports.error = im._error;
534
+ exports.debug = im._debug;
535
+ //-----------------------------------------------------
536
+ // Disk Functions
537
+ //-----------------------------------------------------
538
+ function _checkShell(cmd, continueOnError) {
539
+ var se = shell.error();
540
+ if (se) {
541
+ exports.debug(cmd + ' failed');
542
+ var errMsg = exports.loc('LIB_OperationFailed', cmd, se);
543
+ exports.debug(errMsg);
544
+ if (!continueOnError) {
545
+ throw new Error(errMsg);
546
+ }
547
+ }
548
+ }
549
+ /**
550
+ * Get's stat on a path.
551
+ * Useful for checking whether a file or directory. Also getting created, modified and accessed time.
552
+ * see [fs.stat](https://nodejs.org/api/fs.html#fs_class_fs_stats)
553
+ *
554
+ * @param path path to check
555
+ * @returns fsStat
556
+ */
557
+ function stats(path) {
558
+ return fs.statSync(path);
559
+ }
560
+ exports.stats = stats;
561
+ exports.exist = im._exist;
562
+ function writeFile(file, data, options) {
563
+ if (typeof (options) === 'string') {
564
+ fs.writeFileSync(file, data, { encoding: options });
565
+ }
566
+ else {
567
+ fs.writeFileSync(file, data, options);
568
+ }
569
+ }
570
+ exports.writeFile = writeFile;
571
+ /**
572
+ * @deprecated Use `getPlatform`
573
+ * Useful for determining the host operating system.
574
+ * see [os.type](https://nodejs.org/api/os.html#os_os_type)
575
+ *
576
+ * @return the name of the operating system
577
+ */
578
+ function osType() {
579
+ return os.type();
580
+ }
581
+ exports.osType = osType;
582
+ /**
583
+ * Determine the operating system the build agent is running on.
584
+ * @returns {Platform}
585
+ * @throws {Error} Platform is not supported by our agent
586
+ */
587
+ function getPlatform() {
588
+ switch (process.platform) {
589
+ case 'win32': return Platform.Windows;
590
+ case 'darwin': return Platform.MacOS;
591
+ case 'linux': return Platform.Linux;
592
+ default: throw Error(exports.loc('LIB_PlatformNotSupported', process.platform));
593
+ }
594
+ }
595
+ exports.getPlatform = getPlatform;
596
+ /**
597
+ * Returns the process's current working directory.
598
+ * see [process.cwd](https://nodejs.org/api/process.html#process_process_cwd)
599
+ *
600
+ * @return the path to the current working directory of the process
601
+ */
602
+ function cwd() {
603
+ return process.cwd();
604
+ }
605
+ exports.cwd = cwd;
606
+ exports.checkPath = im._checkPath;
607
+ /**
608
+ * Change working directory.
609
+ *
610
+ * @param path new working directory path
611
+ * @returns void
612
+ */
613
+ function cd(path) {
614
+ if (path) {
615
+ shell.cd(path);
616
+ _checkShell('cd');
617
+ }
618
+ }
619
+ exports.cd = cd;
620
+ /**
621
+ * Change working directory and push it on the stack
622
+ *
623
+ * @param path new working directory path
624
+ * @returns void
625
+ */
626
+ function pushd(path) {
627
+ shell.pushd(path);
628
+ _checkShell('pushd');
629
+ }
630
+ exports.pushd = pushd;
631
+ /**
632
+ * Change working directory back to previously pushed directory
633
+ *
634
+ * @returns void
635
+ */
636
+ function popd() {
637
+ shell.popd();
638
+ _checkShell('popd');
639
+ }
640
+ exports.popd = popd;
641
+ /**
642
+ * Make a directory. Creates the full path with folders in between
643
+ * Will throw if it fails
644
+ *
645
+ * @param p path to create
646
+ * @returns void
647
+ */
648
+ function mkdirP(p) {
649
+ if (!p) {
650
+ throw new Error(exports.loc('LIB_ParameterIsRequired', 'p'));
651
+ }
652
+ // build a stack of directories to create
653
+ var stack = [];
654
+ var testDir = p;
655
+ while (true) {
656
+ // validate the loop is not out of control
657
+ if (stack.length >= (process.env['TASKLIB_TEST_MKDIRP_FAILSAFE'] || 1000)) {
658
+ // let the framework throw
659
+ exports.debug('loop is out of control');
660
+ fs.mkdirSync(p);
661
+ return;
662
+ }
663
+ exports.debug("testing directory '" + testDir + "'");
664
+ var stats_1 = void 0;
665
+ try {
666
+ stats_1 = fs.statSync(testDir);
667
+ }
668
+ catch (err) {
669
+ if (err.code == 'ENOENT') {
670
+ // validate the directory is not the drive root
671
+ var parentDir = path.dirname(testDir);
672
+ if (testDir == parentDir) {
673
+ throw new Error(exports.loc('LIB_MkdirFailedInvalidDriveRoot', p, testDir)); // Unable to create directory '{p}'. Root directory does not exist: '{testDir}'
674
+ }
675
+ // push the dir and test the parent
676
+ stack.push(testDir);
677
+ testDir = parentDir;
678
+ continue;
679
+ }
680
+ else if (err.code == 'UNKNOWN') {
681
+ throw new Error(exports.loc('LIB_MkdirFailedInvalidShare', p, testDir)); // Unable to create directory '{p}'. Unable to verify the directory exists: '{testDir}'. If directory is a file share, please verify the share name is correct, the share is online, and the current process has permission to access the share.
682
+ }
683
+ else {
684
+ throw err;
685
+ }
686
+ }
687
+ if (!stats_1.isDirectory()) {
688
+ throw new Error(exports.loc('LIB_MkdirFailedFileExists', p, testDir)); // Unable to create directory '{p}'. Conflicting file exists: '{testDir}'
689
+ }
690
+ // testDir exists
691
+ break;
692
+ }
693
+ // create each directory
694
+ while (stack.length) {
695
+ var dir = stack.pop(); // non-null because `stack.length` was truthy
696
+ exports.debug("mkdir '" + dir + "'");
697
+ try {
698
+ fs.mkdirSync(dir);
699
+ }
700
+ catch (err) {
701
+ throw new Error(exports.loc('LIB_MkdirFailed', p, err.message)); // Unable to create directory '{p}'. {err.message}
702
+ }
703
+ }
704
+ }
705
+ exports.mkdirP = mkdirP;
706
+ /**
707
+ * Resolves a sequence of paths or path segments into an absolute path.
708
+ * Calls node.js path.resolve()
709
+ * Allows L0 testing with consistent path formats on Mac/Linux and Windows in the mock implementation
710
+ * @param pathSegments
711
+ * @returns {string}
712
+ */
713
+ function resolve() {
714
+ var pathSegments = [];
715
+ for (var _i = 0; _i < arguments.length; _i++) {
716
+ pathSegments[_i] = arguments[_i];
717
+ }
718
+ var absolutePath = path.resolve.apply(this, pathSegments);
719
+ exports.debug('Absolute path for pathSegments: ' + pathSegments + ' = ' + absolutePath);
720
+ return absolutePath;
721
+ }
722
+ exports.resolve = resolve;
723
+ exports.which = im._which;
724
+ /**
725
+ * Returns array of files in the given path, or in current directory if no path provided. See shelljs.ls
726
+ * @param {string} options Available options: -R (recursive), -A (all files, include files beginning with ., except for . and ..)
727
+ * @param {string[]} paths Paths to search.
728
+ * @return {string[]} An array of files in the given path(s).
729
+ */
730
+ function ls(options, paths) {
731
+ if (options) {
732
+ return shell.ls(options, paths);
733
+ }
734
+ else {
735
+ return shell.ls(paths);
736
+ }
737
+ }
738
+ exports.ls = ls;
739
+ /**
740
+ * Copies a file or folder.
741
+ *
742
+ * @param source source path
743
+ * @param dest destination path
744
+ * @param options string -r, -f or -rf for recursive and force
745
+ * @param continueOnError optional. whether to continue on error
746
+ * @param retryCount optional. Retry count to copy the file. It might help to resolve intermittent issues e.g. with UNC target paths on a remote host.
747
+ */
748
+ function cp(source, dest, options, continueOnError, retryCount) {
749
+ if (retryCount === void 0) { retryCount = 0; }
750
+ while (retryCount >= 0) {
751
+ try {
752
+ if (options) {
753
+ shell.cp(options, source, dest);
754
+ }
755
+ else {
756
+ shell.cp(source, dest);
757
+ }
758
+ _checkShell('cp', false);
759
+ break;
760
+ }
761
+ catch (e) {
762
+ if (retryCount <= 0) {
763
+ if (continueOnError) {
764
+ exports.warning(e);
765
+ break;
766
+ }
767
+ else {
768
+ throw e;
769
+ }
770
+ }
771
+ else {
772
+ console.log(exports.loc('LIB_CopyFileFailed', retryCount));
773
+ retryCount--;
774
+ }
775
+ }
776
+ }
777
+ }
778
+ exports.cp = cp;
779
+ /**
780
+ * Moves a path.
781
+ *
782
+ * @param source source path
783
+ * @param dest destination path
784
+ * @param options string -f or -n for force and no clobber
785
+ * @param continueOnError optional. whether to continue on error
786
+ */
787
+ function mv(source, dest, options, continueOnError) {
788
+ if (options) {
789
+ shell.mv(options, source, dest);
790
+ }
791
+ else {
792
+ shell.mv(source, dest);
793
+ }
794
+ _checkShell('mv', continueOnError);
795
+ }
796
+ exports.mv = mv;
797
+ /**
798
+ * Tries to execute a function a specified number of times.
799
+ *
800
+ * @param func a function to be executed.
801
+ * @param args executed function arguments array.
802
+ * @param retryOptions optional. Defaults to { continueOnError: false, retryCount: 0 }.
803
+ * @returns the same as the usual function.
804
+ */
805
+ function retry(func, args, retryOptions) {
806
+ if (retryOptions === void 0) { retryOptions = { continueOnError: false, retryCount: 0 }; }
807
+ while (retryOptions.retryCount >= 0) {
808
+ try {
809
+ return func.apply(void 0, args);
810
+ }
811
+ catch (e) {
812
+ if (retryOptions.retryCount <= 0) {
813
+ if (retryOptions.continueOnError) {
814
+ exports.warning(e);
815
+ break;
816
+ }
817
+ else {
818
+ throw e;
819
+ }
820
+ }
821
+ else {
822
+ exports.debug("Attempt to execute function \"" + (func === null || func === void 0 ? void 0 : func.name) + "\" failed, retries left: " + retryOptions.retryCount);
823
+ retryOptions.retryCount--;
824
+ }
825
+ }
826
+ }
827
+ }
828
+ exports.retry = retry;
829
+ /**
830
+ * Gets info about item stats.
831
+ *
832
+ * @param path a path to the item to be processed.
833
+ * @param followSymbolicLink indicates whether to traverse descendants of symbolic link directories.
834
+ * @param allowBrokenSymbolicLinks when true, broken symbolic link will not cause an error.
835
+ * @returns fs.Stats
836
+ */
837
+ function _getStats(path, followSymbolicLink, allowBrokenSymbolicLinks) {
838
+ // stat returns info about the target of a symlink (or symlink chain),
839
+ // lstat returns info about a symlink itself
840
+ var stats;
841
+ if (followSymbolicLink) {
842
+ try {
843
+ // use stat (following symlinks)
844
+ stats = fs.statSync(path);
845
+ }
846
+ catch (err) {
847
+ if (err.code == 'ENOENT' && allowBrokenSymbolicLinks) {
848
+ // fallback to lstat (broken symlinks allowed)
849
+ stats = fs.lstatSync(path);
850
+ exports.debug(" " + path + " (broken symlink)");
851
+ }
852
+ else {
853
+ throw err;
854
+ }
855
+ }
856
+ }
857
+ else {
858
+ // use lstat (not following symlinks)
859
+ stats = fs.lstatSync(path);
860
+ }
861
+ return stats;
862
+ }
863
+ /**
864
+ * Recursively finds all paths a given path. Returns an array of paths.
865
+ *
866
+ * @param findPath path to search
867
+ * @param options optional. defaults to { followSymbolicLinks: true }. following soft links is generally appropriate unless deleting files.
868
+ * @returns string[]
869
+ */
870
+ function find(findPath, options) {
871
+ if (!findPath) {
872
+ exports.debug('no path specified');
873
+ return [];
874
+ }
875
+ // normalize the path, otherwise the first result is inconsistently formatted from the rest of the results
876
+ // because path.join() performs normalization.
877
+ findPath = path.normalize(findPath);
878
+ // debug trace the parameters
879
+ exports.debug("findPath: '" + findPath + "'");
880
+ options = options || _getDefaultFindOptions();
881
+ _debugFindOptions(options);
882
+ // return empty if not exists
883
+ try {
884
+ fs.lstatSync(findPath);
885
+ }
886
+ catch (err) {
887
+ if (err.code == 'ENOENT') {
888
+ exports.debug('0 results');
889
+ return [];
890
+ }
891
+ throw err;
892
+ }
893
+ try {
894
+ var result = [];
895
+ // push the first item
896
+ var stack = [new _FindItem(findPath, 1)];
897
+ var traversalChain = []; // used to detect cycles
898
+ var _loop_1 = function () {
899
+ // pop the next item and push to the result array
900
+ var item = stack.pop(); // non-null because `stack.length` was truthy
901
+ var stats_2 = void 0;
902
+ try {
903
+ // `item.path` equals `findPath` for the first item to be processed, when the `result` array is empty
904
+ var isPathToSearch = !result.length;
905
+ // following specified symlinks only if current path equals specified path
906
+ var followSpecifiedSymbolicLink = options.followSpecifiedSymbolicLink && isPathToSearch;
907
+ // following all symlinks or following symlink for the specified path
908
+ var followSymbolicLink = options.followSymbolicLinks || followSpecifiedSymbolicLink;
909
+ // stat the item. The stat info is used further below to determine whether to traverse deeper
910
+ stats_2 = _getStats(item.path, followSymbolicLink, options.allowBrokenSymbolicLinks);
911
+ }
912
+ catch (err) {
913
+ if (err.code == 'ENOENT' && options.skipMissingFiles) {
914
+ exports.warning("No such file or directory: \"" + item.path + "\" - skipping.");
915
+ return "continue";
916
+ }
917
+ throw err;
918
+ }
919
+ result.push(item.path);
920
+ // note, isDirectory() returns false for the lstat of a symlink
921
+ if (stats_2.isDirectory()) {
922
+ exports.debug(" " + item.path + " (directory)");
923
+ if (options.followSymbolicLinks) {
924
+ // get the realpath
925
+ var realPath_1;
926
+ if (im._isUncPath(item.path)) {
927
+ // Sometimes there are spontaneous issues when working with unc-paths, so retries have been added for them.
928
+ realPath_1 = retry(fs.realpathSync, [item.path], { continueOnError: false, retryCount: 5 });
929
+ }
930
+ else {
931
+ realPath_1 = fs.realpathSync(item.path);
932
+ }
933
+ // fixup the traversal chain to match the item level
934
+ while (traversalChain.length >= item.level) {
935
+ traversalChain.pop();
936
+ }
937
+ // test for a cycle
938
+ if (traversalChain.some(function (x) { return x == realPath_1; })) {
939
+ exports.debug(' cycle detected');
940
+ return "continue";
941
+ }
942
+ // update the traversal chain
943
+ traversalChain.push(realPath_1);
944
+ }
945
+ // push the child items in reverse onto the stack
946
+ var childLevel_1 = item.level + 1;
947
+ var childItems = fs.readdirSync(item.path)
948
+ .map(function (childName) { return new _FindItem(path.join(item.path, childName), childLevel_1); });
949
+ for (var i = childItems.length - 1; i >= 0; i--) {
950
+ stack.push(childItems[i]);
951
+ }
952
+ }
953
+ else {
954
+ exports.debug(" " + item.path + " (file)");
955
+ }
956
+ };
957
+ while (stack.length) {
958
+ _loop_1();
959
+ }
960
+ exports.debug(result.length + " results");
961
+ return result;
962
+ }
963
+ catch (err) {
964
+ throw new Error(exports.loc('LIB_OperationFailed', 'find', err.message));
965
+ }
966
+ }
967
+ exports.find = find;
968
+ var _FindItem = /** @class */ (function () {
969
+ function _FindItem(path, level) {
970
+ this.path = path;
971
+ this.level = level;
972
+ }
973
+ return _FindItem;
974
+ }());
975
+ function _debugFindOptions(options) {
976
+ exports.debug("findOptions.allowBrokenSymbolicLinks: '" + options.allowBrokenSymbolicLinks + "'");
977
+ exports.debug("findOptions.followSpecifiedSymbolicLink: '" + options.followSpecifiedSymbolicLink + "'");
978
+ exports.debug("findOptions.followSymbolicLinks: '" + options.followSymbolicLinks + "'");
979
+ exports.debug("findOptions.skipMissingFiles: '" + options.skipMissingFiles + "'");
980
+ }
981
+ function _getDefaultFindOptions() {
982
+ return {
983
+ allowBrokenSymbolicLinks: false,
984
+ followSpecifiedSymbolicLink: true,
985
+ followSymbolicLinks: true,
986
+ skipMissingFiles: false
987
+ };
988
+ }
989
+ /**
990
+ * Prefer tl.find() and tl.match() instead. This function is for backward compatibility
991
+ * when porting tasks to Node from the PowerShell or PowerShell3 execution handler.
992
+ *
993
+ * @param rootDirectory path to root unrooted patterns with
994
+ * @param pattern include and exclude patterns
995
+ * @param includeFiles whether to include files in the result. defaults to true when includeFiles and includeDirectories are both false
996
+ * @param includeDirectories whether to include directories in the result
997
+ * @returns string[]
998
+ */
999
+ function legacyFindFiles(rootDirectory, pattern, includeFiles, includeDirectories) {
1000
+ if (!pattern) {
1001
+ throw new Error('pattern parameter cannot be empty');
1002
+ }
1003
+ exports.debug("legacyFindFiles rootDirectory: '" + rootDirectory + "'");
1004
+ exports.debug("pattern: '" + pattern + "'");
1005
+ exports.debug("includeFiles: '" + includeFiles + "'");
1006
+ exports.debug("includeDirectories: '" + includeDirectories + "'");
1007
+ if (!includeFiles && !includeDirectories) {
1008
+ includeFiles = true;
1009
+ }
1010
+ // organize the patterns into include patterns and exclude patterns
1011
+ var includePatterns = [];
1012
+ var excludePatterns = [];
1013
+ pattern = pattern.replace(/;;/g, '\0');
1014
+ for (var _i = 0, _a = pattern.split(';'); _i < _a.length; _i++) {
1015
+ var pat = _a[_i];
1016
+ if (!pat) {
1017
+ continue;
1018
+ }
1019
+ pat = pat.replace(/\0/g, ';');
1020
+ // determine whether include pattern and remove any include/exclude prefix.
1021
+ // include patterns start with +: or anything other than -:
1022
+ // exclude patterns start with -:
1023
+ var isIncludePattern = void 0;
1024
+ if (im._startsWith(pat, '+:')) {
1025
+ pat = pat.substring(2);
1026
+ isIncludePattern = true;
1027
+ }
1028
+ else if (im._startsWith(pat, '-:')) {
1029
+ pat = pat.substring(2);
1030
+ isIncludePattern = false;
1031
+ }
1032
+ else {
1033
+ isIncludePattern = true;
1034
+ }
1035
+ // validate pattern does not end with a slash
1036
+ if (im._endsWith(pat, '/') || (process.platform == 'win32' && im._endsWith(pat, '\\'))) {
1037
+ throw new Error(exports.loc('LIB_InvalidPattern', pat));
1038
+ }
1039
+ // root the pattern
1040
+ if (rootDirectory && !path.isAbsolute(pat)) {
1041
+ pat = path.join(rootDirectory, pat);
1042
+ // remove trailing slash sometimes added by path.join() on Windows, e.g.
1043
+ // path.join('\\\\hello', 'world') => '\\\\hello\\world\\'
1044
+ // path.join('//hello', 'world') => '\\\\hello\\world\\'
1045
+ if (im._endsWith(pat, '\\')) {
1046
+ pat = pat.substring(0, pat.length - 1);
1047
+ }
1048
+ }
1049
+ if (isIncludePattern) {
1050
+ includePatterns.push(pat);
1051
+ }
1052
+ else {
1053
+ excludePatterns.push(im._legacyFindFiles_convertPatternToRegExp(pat));
1054
+ }
1055
+ }
1056
+ // find and apply patterns
1057
+ var count = 0;
1058
+ var result = _legacyFindFiles_getMatchingItems(includePatterns, excludePatterns, !!includeFiles, !!includeDirectories);
1059
+ exports.debug('all matches:');
1060
+ for (var _b = 0, result_1 = result; _b < result_1.length; _b++) {
1061
+ var resultItem = result_1[_b];
1062
+ exports.debug(' ' + resultItem);
1063
+ }
1064
+ exports.debug('total matched: ' + result.length);
1065
+ return result;
1066
+ }
1067
+ exports.legacyFindFiles = legacyFindFiles;
1068
+ function _legacyFindFiles_getMatchingItems(includePatterns, excludePatterns, includeFiles, includeDirectories) {
1069
+ exports.debug('getMatchingItems()');
1070
+ for (var _i = 0, includePatterns_1 = includePatterns; _i < includePatterns_1.length; _i++) {
1071
+ var pattern = includePatterns_1[_i];
1072
+ exports.debug("includePattern: '" + pattern + "'");
1073
+ }
1074
+ for (var _a = 0, excludePatterns_1 = excludePatterns; _a < excludePatterns_1.length; _a++) {
1075
+ var pattern = excludePatterns_1[_a];
1076
+ exports.debug("excludePattern: " + pattern);
1077
+ }
1078
+ exports.debug('includeFiles: ' + includeFiles);
1079
+ exports.debug('includeDirectories: ' + includeDirectories);
1080
+ var allFiles = {};
1081
+ var _loop_2 = function (pattern) {
1082
+ // determine the directory to search
1083
+ //
1084
+ // note, getDirectoryName removes redundant path separators
1085
+ var findPath = void 0;
1086
+ var starIndex = pattern.indexOf('*');
1087
+ var questionIndex = pattern.indexOf('?');
1088
+ if (starIndex < 0 && questionIndex < 0) {
1089
+ // if no wildcards are found, use the directory name portion of the path.
1090
+ // if there is no directory name (file name only in pattern or drive root),
1091
+ // this will return empty string.
1092
+ findPath = im._getDirectoryName(pattern);
1093
+ }
1094
+ else {
1095
+ // extract the directory prior to the first wildcard
1096
+ var index = Math.min(starIndex >= 0 ? starIndex : questionIndex, questionIndex >= 0 ? questionIndex : starIndex);
1097
+ findPath = im._getDirectoryName(pattern.substring(0, index));
1098
+ }
1099
+ // note, due to this short-circuit and the above usage of getDirectoryName, this
1100
+ // function has the same limitations regarding drive roots as the powershell
1101
+ // implementation.
1102
+ //
1103
+ // also note, since getDirectoryName eliminates slash redundancies, some additional
1104
+ // work may be required if removal of this limitation is attempted.
1105
+ if (!findPath) {
1106
+ return "continue";
1107
+ }
1108
+ var patternRegex = im._legacyFindFiles_convertPatternToRegExp(pattern);
1109
+ // find files/directories
1110
+ var items = find(findPath, { followSymbolicLinks: true })
1111
+ .filter(function (item) {
1112
+ if (includeFiles && includeDirectories) {
1113
+ return true;
1114
+ }
1115
+ var isDir = fs.statSync(item).isDirectory();
1116
+ return (includeFiles && !isDir) || (includeDirectories && isDir);
1117
+ })
1118
+ .forEach(function (item) {
1119
+ var normalizedPath = process.platform == 'win32' ? item.replace(/\\/g, '/') : item; // normalize separators
1120
+ // **/times/** will not match C:/fun/times because there isn't a trailing slash
1121
+ // so try both if including directories
1122
+ var alternatePath = normalizedPath + "/"; // potential bug: it looks like this will result in a false
1123
+ // positive if the item is a regular file and not a directory
1124
+ var isMatch = false;
1125
+ if (patternRegex.test(normalizedPath) || (includeDirectories && patternRegex.test(alternatePath))) {
1126
+ isMatch = true;
1127
+ // test whether the path should be excluded
1128
+ for (var _i = 0, excludePatterns_2 = excludePatterns; _i < excludePatterns_2.length; _i++) {
1129
+ var regex = excludePatterns_2[_i];
1130
+ if (regex.test(normalizedPath) || (includeDirectories && regex.test(alternatePath))) {
1131
+ isMatch = false;
1132
+ break;
1133
+ }
1134
+ }
1135
+ }
1136
+ if (isMatch) {
1137
+ allFiles[item] = item;
1138
+ }
1139
+ });
1140
+ };
1141
+ for (var _b = 0, includePatterns_2 = includePatterns; _b < includePatterns_2.length; _b++) {
1142
+ var pattern = includePatterns_2[_b];
1143
+ _loop_2(pattern);
1144
+ }
1145
+ return Object.keys(allFiles).sort();
1146
+ }
1147
+ /**
1148
+ * Remove a path recursively with force
1149
+ *
1150
+ * @param inputPath path to remove
1151
+ * @throws when the file or directory exists but could not be deleted.
1152
+ */
1153
+ function rmRF(inputPath) {
1154
+ exports.debug('rm -rf ' + inputPath);
1155
+ if (getPlatform() == Platform.Windows) {
1156
+ // Node doesn't provide a delete operation, only an unlink function. This means that if the file is being used by another
1157
+ // program (e.g. antivirus), it won't be deleted. To address this, we shell out the work to rd/del.
1158
+ try {
1159
+ if (fs.statSync(inputPath).isDirectory()) {
1160
+ exports.debug('removing directory ' + inputPath);
1161
+ childProcess.execSync("rd /s /q \"" + inputPath + "\"");
1162
+ }
1163
+ else {
1164
+ exports.debug('removing file ' + inputPath);
1165
+ childProcess.execSync("del /f /a \"" + inputPath + "\"");
1166
+ }
1167
+ }
1168
+ catch (err) {
1169
+ // if you try to delete a file that doesn't exist, desired result is achieved
1170
+ // other errors are valid
1171
+ if (err.code != 'ENOENT') {
1172
+ throw new Error(exports.loc('LIB_OperationFailed', 'rmRF', err.message));
1173
+ }
1174
+ }
1175
+ // Shelling out fails to remove a symlink folder with missing source, this unlink catches that
1176
+ try {
1177
+ fs.unlinkSync(inputPath);
1178
+ }
1179
+ catch (err) {
1180
+ // if you try to delete a file that doesn't exist, desired result is achieved
1181
+ // other errors are valid
1182
+ if (err.code != 'ENOENT') {
1183
+ throw new Error(exports.loc('LIB_OperationFailed', 'rmRF', err.message));
1184
+ }
1185
+ }
1186
+ }
1187
+ else {
1188
+ // get the lstats in order to workaround a bug in shelljs@0.3.0 where symlinks
1189
+ // with missing targets are not handled correctly by "rm('-rf', path)"
1190
+ var lstats = void 0;
1191
+ try {
1192
+ lstats = fs.lstatSync(inputPath);
1193
+ }
1194
+ catch (err) {
1195
+ // if you try to delete a file that doesn't exist, desired result is achieved
1196
+ // other errors are valid
1197
+ if (err.code == 'ENOENT') {
1198
+ return;
1199
+ }
1200
+ throw new Error(exports.loc('LIB_OperationFailed', 'rmRF', err.message));
1201
+ }
1202
+ if (lstats.isDirectory()) {
1203
+ exports.debug('removing directory');
1204
+ shell.rm('-rf', inputPath);
1205
+ var errMsg = shell.error();
1206
+ if (errMsg) {
1207
+ throw new Error(exports.loc('LIB_OperationFailed', 'rmRF', errMsg));
1208
+ }
1209
+ return;
1210
+ }
1211
+ exports.debug('removing file');
1212
+ try {
1213
+ fs.unlinkSync(inputPath);
1214
+ }
1215
+ catch (err) {
1216
+ throw new Error(exports.loc('LIB_OperationFailed', 'rmRF', err.message));
1217
+ }
1218
+ }
1219
+ }
1220
+ exports.rmRF = rmRF;
1221
+ /**
1222
+ * Exec a tool. Convenience wrapper over ToolRunner to exec with args in one call.
1223
+ * Output will be streamed to the live console.
1224
+ * Returns promise with return code
1225
+ *
1226
+ * @param tool path to tool to exec
1227
+ * @param args an arg string or array of args
1228
+ * @param options optional exec options. See IExecOptions
1229
+ * @returns number
1230
+ */
1231
+ function exec(tool, args, options) {
1232
+ var tr = this.tool(tool);
1233
+ tr.on('debug', function (data) {
1234
+ exports.debug(data);
1235
+ });
1236
+ if (args) {
1237
+ if (args instanceof Array) {
1238
+ tr.arg(args);
1239
+ }
1240
+ else if (typeof (args) === 'string') {
1241
+ tr.line(args);
1242
+ }
1243
+ }
1244
+ return tr.exec(options);
1245
+ }
1246
+ exports.exec = exec;
1247
+ /**
1248
+ * Exec a tool synchronously. Convenience wrapper over ToolRunner to execSync with args in one call.
1249
+ * Output will be *not* be streamed to the live console. It will be returned after execution is complete.
1250
+ * Appropriate for short running tools
1251
+ * Returns IExecResult with output and return code
1252
+ *
1253
+ * @param tool path to tool to exec
1254
+ * @param args an arg string or array of args
1255
+ * @param options optional exec options. See IExecSyncOptions
1256
+ * @returns IExecSyncResult
1257
+ */
1258
+ function execSync(tool, args, options) {
1259
+ var tr = this.tool(tool);
1260
+ tr.on('debug', function (data) {
1261
+ exports.debug(data);
1262
+ });
1263
+ if (args) {
1264
+ if (args instanceof Array) {
1265
+ tr.arg(args);
1266
+ }
1267
+ else if (typeof (args) === 'string') {
1268
+ tr.line(args);
1269
+ }
1270
+ }
1271
+ return tr.execSync(options);
1272
+ }
1273
+ exports.execSync = execSync;
1274
+ /**
1275
+ * Convenience factory to create a ToolRunner.
1276
+ *
1277
+ * @param tool path to tool to exec
1278
+ * @returns ToolRunner
1279
+ */
1280
+ function tool(tool) {
1281
+ var tr = new trm.ToolRunner(tool);
1282
+ tr.on('debug', function (message) {
1283
+ exports.debug(message);
1284
+ });
1285
+ return tr;
1286
+ }
1287
+ exports.tool = tool;
1288
+ /**
1289
+ * Applies glob patterns to a list of paths. Supports interleaved exclude patterns.
1290
+ *
1291
+ * @param list array of paths
1292
+ * @param patterns patterns to apply. supports interleaved exclude patterns.
1293
+ * @param patternRoot optional. default root to apply to unrooted patterns. not applied to basename-only patterns when matchBase:true.
1294
+ * @param options optional. defaults to { dot: true, nobrace: true, nocase: process.platform == 'win32' }.
1295
+ */
1296
+ function match(list, patterns, patternRoot, options) {
1297
+ // trace parameters
1298
+ exports.debug("patternRoot: '" + patternRoot + "'");
1299
+ options = options || _getDefaultMatchOptions(); // default match options
1300
+ _debugMatchOptions(options);
1301
+ // convert pattern to an array
1302
+ if (typeof patterns == 'string') {
1303
+ patterns = [patterns];
1304
+ }
1305
+ // hashtable to keep track of matches
1306
+ var map = {};
1307
+ var originalOptions = options;
1308
+ for (var _i = 0, patterns_1 = patterns; _i < patterns_1.length; _i++) {
1309
+ var pattern = patterns_1[_i];
1310
+ exports.debug("pattern: '" + pattern + "'");
1311
+ // trim and skip empty
1312
+ pattern = (pattern || '').trim();
1313
+ if (!pattern) {
1314
+ exports.debug('skipping empty pattern');
1315
+ continue;
1316
+ }
1317
+ // clone match options
1318
+ var options_1 = im._cloneMatchOptions(originalOptions);
1319
+ // skip comments
1320
+ if (!options_1.nocomment && im._startsWith(pattern, '#')) {
1321
+ exports.debug('skipping comment');
1322
+ continue;
1323
+ }
1324
+ // set nocomment - brace expansion could result in a leading '#'
1325
+ options_1.nocomment = true;
1326
+ // determine whether pattern is include or exclude
1327
+ var negateCount = 0;
1328
+ if (!options_1.nonegate) {
1329
+ while (pattern.charAt(negateCount) == '!') {
1330
+ negateCount++;
1331
+ }
1332
+ pattern = pattern.substring(negateCount); // trim leading '!'
1333
+ if (negateCount) {
1334
+ exports.debug("trimmed leading '!'. pattern: '" + pattern + "'");
1335
+ }
1336
+ }
1337
+ var isIncludePattern = negateCount == 0 ||
1338
+ (negateCount % 2 == 0 && !options_1.flipNegate) ||
1339
+ (negateCount % 2 == 1 && options_1.flipNegate);
1340
+ // set nonegate - brace expansion could result in a leading '!'
1341
+ options_1.nonegate = true;
1342
+ options_1.flipNegate = false;
1343
+ // expand braces - required to accurately root patterns
1344
+ var expanded = void 0;
1345
+ var preExpanded = pattern;
1346
+ if (options_1.nobrace) {
1347
+ expanded = [pattern];
1348
+ }
1349
+ else {
1350
+ // convert slashes on Windows before calling braceExpand(). unfortunately this means braces cannot
1351
+ // be escaped on Windows, this limitation is consistent with current limitations of minimatch (3.0.3).
1352
+ exports.debug('expanding braces');
1353
+ var convertedPattern = process.platform == 'win32' ? pattern.replace(/\\/g, '/') : pattern;
1354
+ expanded = minimatch.braceExpand(convertedPattern);
1355
+ }
1356
+ // set nobrace
1357
+ options_1.nobrace = true;
1358
+ for (var _a = 0, expanded_1 = expanded; _a < expanded_1.length; _a++) {
1359
+ var pattern_1 = expanded_1[_a];
1360
+ if (expanded.length != 1 || pattern_1 != preExpanded) {
1361
+ exports.debug("pattern: '" + pattern_1 + "'");
1362
+ }
1363
+ // trim and skip empty
1364
+ pattern_1 = (pattern_1 || '').trim();
1365
+ if (!pattern_1) {
1366
+ exports.debug('skipping empty pattern');
1367
+ continue;
1368
+ }
1369
+ // root the pattern when all of the following conditions are true:
1370
+ if (patternRoot && // patternRoot supplied
1371
+ !im._isRooted(pattern_1) && // AND pattern not rooted
1372
+ // AND matchBase:false or not basename only
1373
+ (!options_1.matchBase || (process.platform == 'win32' ? pattern_1.replace(/\\/g, '/') : pattern_1).indexOf('/') >= 0)) {
1374
+ pattern_1 = im._ensureRooted(patternRoot, pattern_1);
1375
+ exports.debug("rooted pattern: '" + pattern_1 + "'");
1376
+ }
1377
+ if (isIncludePattern) {
1378
+ // apply the pattern
1379
+ exports.debug('applying include pattern against original list');
1380
+ var matchResults = minimatch.match(list, pattern_1, options_1);
1381
+ exports.debug(matchResults.length + ' matches');
1382
+ // union the results
1383
+ for (var _b = 0, matchResults_1 = matchResults; _b < matchResults_1.length; _b++) {
1384
+ var matchResult = matchResults_1[_b];
1385
+ map[matchResult] = true;
1386
+ }
1387
+ }
1388
+ else {
1389
+ // apply the pattern
1390
+ exports.debug('applying exclude pattern against original list');
1391
+ var matchResults = minimatch.match(list, pattern_1, options_1);
1392
+ exports.debug(matchResults.length + ' matches');
1393
+ // substract the results
1394
+ for (var _c = 0, matchResults_2 = matchResults; _c < matchResults_2.length; _c++) {
1395
+ var matchResult = matchResults_2[_c];
1396
+ delete map[matchResult];
1397
+ }
1398
+ }
1399
+ }
1400
+ }
1401
+ // return a filtered version of the original list (preserves order and prevents duplication)
1402
+ var result = list.filter(function (item) { return map.hasOwnProperty(item); });
1403
+ exports.debug(result.length + ' final results');
1404
+ return result;
1405
+ }
1406
+ exports.match = match;
1407
+ /**
1408
+ * Filter to apply glob patterns
1409
+ *
1410
+ * @param pattern pattern to apply
1411
+ * @param options optional. defaults to { dot: true, nobrace: true, nocase: process.platform == 'win32' }.
1412
+ */
1413
+ function filter(pattern, options) {
1414
+ options = options || _getDefaultMatchOptions();
1415
+ return minimatch.filter(pattern, options);
1416
+ }
1417
+ exports.filter = filter;
1418
+ function _debugMatchOptions(options) {
1419
+ exports.debug("matchOptions.debug: '" + options.debug + "'");
1420
+ exports.debug("matchOptions.nobrace: '" + options.nobrace + "'");
1421
+ exports.debug("matchOptions.noglobstar: '" + options.noglobstar + "'");
1422
+ exports.debug("matchOptions.dot: '" + options.dot + "'");
1423
+ exports.debug("matchOptions.noext: '" + options.noext + "'");
1424
+ exports.debug("matchOptions.nocase: '" + options.nocase + "'");
1425
+ exports.debug("matchOptions.nonull: '" + options.nonull + "'");
1426
+ exports.debug("matchOptions.matchBase: '" + options.matchBase + "'");
1427
+ exports.debug("matchOptions.nocomment: '" + options.nocomment + "'");
1428
+ exports.debug("matchOptions.nonegate: '" + options.nonegate + "'");
1429
+ exports.debug("matchOptions.flipNegate: '" + options.flipNegate + "'");
1430
+ }
1431
+ function _getDefaultMatchOptions() {
1432
+ return {
1433
+ debug: false,
1434
+ nobrace: true,
1435
+ noglobstar: false,
1436
+ dot: true,
1437
+ noext: false,
1438
+ nocase: process.platform == 'win32',
1439
+ nonull: false,
1440
+ matchBase: false,
1441
+ nocomment: false,
1442
+ nonegate: false,
1443
+ flipNegate: false
1444
+ };
1445
+ }
1446
+ /**
1447
+ * Determines the find root from a list of patterns. Performs the find and then applies the glob patterns.
1448
+ * Supports interleaved exclude patterns. Unrooted patterns are rooted using defaultRoot, unless
1449
+ * matchOptions.matchBase is specified and the pattern is a basename only. For matchBase cases, the
1450
+ * defaultRoot is used as the find root.
1451
+ *
1452
+ * @param defaultRoot default path to root unrooted patterns. falls back to System.DefaultWorkingDirectory or process.cwd().
1453
+ * @param patterns pattern or array of patterns to apply
1454
+ * @param findOptions defaults to { followSymbolicLinks: true }. following soft links is generally appropriate unless deleting files.
1455
+ * @param matchOptions defaults to { dot: true, nobrace: true, nocase: process.platform == 'win32' }
1456
+ */
1457
+ function findMatch(defaultRoot, patterns, findOptions, matchOptions) {
1458
+ // apply defaults for parameters and trace
1459
+ defaultRoot = defaultRoot || this.getVariable('system.defaultWorkingDirectory') || process.cwd();
1460
+ exports.debug("defaultRoot: '" + defaultRoot + "'");
1461
+ patterns = patterns || [];
1462
+ patterns = typeof patterns == 'string' ? [patterns] : patterns;
1463
+ findOptions = findOptions || _getDefaultFindOptions();
1464
+ _debugFindOptions(findOptions);
1465
+ matchOptions = matchOptions || _getDefaultMatchOptions();
1466
+ _debugMatchOptions(matchOptions);
1467
+ // normalize slashes for root dir
1468
+ defaultRoot = im._normalizeSeparators(defaultRoot);
1469
+ var results = {};
1470
+ var originalMatchOptions = matchOptions;
1471
+ for (var _i = 0, _a = (patterns || []); _i < _a.length; _i++) {
1472
+ var pattern = _a[_i];
1473
+ exports.debug("pattern: '" + pattern + "'");
1474
+ // trim and skip empty
1475
+ pattern = (pattern || '').trim();
1476
+ if (!pattern) {
1477
+ exports.debug('skipping empty pattern');
1478
+ continue;
1479
+ }
1480
+ // clone match options
1481
+ var matchOptions_1 = im._cloneMatchOptions(originalMatchOptions);
1482
+ // skip comments
1483
+ if (!matchOptions_1.nocomment && im._startsWith(pattern, '#')) {
1484
+ exports.debug('skipping comment');
1485
+ continue;
1486
+ }
1487
+ // set nocomment - brace expansion could result in a leading '#'
1488
+ matchOptions_1.nocomment = true;
1489
+ // determine whether pattern is include or exclude
1490
+ var negateCount = 0;
1491
+ if (!matchOptions_1.nonegate) {
1492
+ while (pattern.charAt(negateCount) == '!') {
1493
+ negateCount++;
1494
+ }
1495
+ pattern = pattern.substring(negateCount); // trim leading '!'
1496
+ if (negateCount) {
1497
+ exports.debug("trimmed leading '!'. pattern: '" + pattern + "'");
1498
+ }
1499
+ }
1500
+ var isIncludePattern = negateCount == 0 ||
1501
+ (negateCount % 2 == 0 && !matchOptions_1.flipNegate) ||
1502
+ (negateCount % 2 == 1 && matchOptions_1.flipNegate);
1503
+ // set nonegate - brace expansion could result in a leading '!'
1504
+ matchOptions_1.nonegate = true;
1505
+ matchOptions_1.flipNegate = false;
1506
+ // expand braces - required to accurately interpret findPath
1507
+ var expanded = void 0;
1508
+ var preExpanded = pattern;
1509
+ if (matchOptions_1.nobrace) {
1510
+ expanded = [pattern];
1511
+ }
1512
+ else {
1513
+ // convert slashes on Windows before calling braceExpand(). unfortunately this means braces cannot
1514
+ // be escaped on Windows, this limitation is consistent with current limitations of minimatch (3.0.3).
1515
+ exports.debug('expanding braces');
1516
+ var convertedPattern = process.platform == 'win32' ? pattern.replace(/\\/g, '/') : pattern;
1517
+ expanded = minimatch.braceExpand(convertedPattern);
1518
+ }
1519
+ // set nobrace
1520
+ matchOptions_1.nobrace = true;
1521
+ for (var _b = 0, expanded_2 = expanded; _b < expanded_2.length; _b++) {
1522
+ var pattern_2 = expanded_2[_b];
1523
+ if (expanded.length != 1 || pattern_2 != preExpanded) {
1524
+ exports.debug("pattern: '" + pattern_2 + "'");
1525
+ }
1526
+ // trim and skip empty
1527
+ pattern_2 = (pattern_2 || '').trim();
1528
+ if (!pattern_2) {
1529
+ exports.debug('skipping empty pattern');
1530
+ continue;
1531
+ }
1532
+ if (isIncludePattern) {
1533
+ // determine the findPath
1534
+ var findInfo = im._getFindInfoFromPattern(defaultRoot, pattern_2, matchOptions_1);
1535
+ var findPath = findInfo.findPath;
1536
+ exports.debug("findPath: '" + findPath + "'");
1537
+ if (!findPath) {
1538
+ exports.debug('skipping empty path');
1539
+ continue;
1540
+ }
1541
+ // perform the find
1542
+ exports.debug("statOnly: '" + findInfo.statOnly + "'");
1543
+ var findResults = [];
1544
+ if (findInfo.statOnly) {
1545
+ // simply stat the path - all path segments were used to build the path
1546
+ try {
1547
+ fs.statSync(findPath);
1548
+ findResults.push(findPath);
1549
+ }
1550
+ catch (err) {
1551
+ if (err.code != 'ENOENT') {
1552
+ throw err;
1553
+ }
1554
+ exports.debug('ENOENT');
1555
+ }
1556
+ }
1557
+ else {
1558
+ findResults = find(findPath, findOptions);
1559
+ }
1560
+ exports.debug("found " + findResults.length + " paths");
1561
+ // apply the pattern
1562
+ exports.debug('applying include pattern');
1563
+ if (findInfo.adjustedPattern != pattern_2) {
1564
+ exports.debug("adjustedPattern: '" + findInfo.adjustedPattern + "'");
1565
+ pattern_2 = findInfo.adjustedPattern;
1566
+ }
1567
+ var matchResults = minimatch.match(findResults, pattern_2, matchOptions_1);
1568
+ exports.debug(matchResults.length + ' matches');
1569
+ // union the results
1570
+ for (var _c = 0, matchResults_3 = matchResults; _c < matchResults_3.length; _c++) {
1571
+ var matchResult = matchResults_3[_c];
1572
+ var key = process.platform == 'win32' ? matchResult.toUpperCase() : matchResult;
1573
+ results[key] = matchResult;
1574
+ }
1575
+ }
1576
+ else {
1577
+ // check if basename only and matchBase=true
1578
+ if (matchOptions_1.matchBase &&
1579
+ !im._isRooted(pattern_2) &&
1580
+ (process.platform == 'win32' ? pattern_2.replace(/\\/g, '/') : pattern_2).indexOf('/') < 0) {
1581
+ // do not root the pattern
1582
+ exports.debug('matchBase and basename only');
1583
+ }
1584
+ else {
1585
+ // root the exclude pattern
1586
+ pattern_2 = im._ensurePatternRooted(defaultRoot, pattern_2);
1587
+ exports.debug("after ensurePatternRooted, pattern: '" + pattern_2 + "'");
1588
+ }
1589
+ // apply the pattern
1590
+ exports.debug('applying exclude pattern');
1591
+ var matchResults = minimatch.match(Object.keys(results).map(function (key) { return results[key]; }), pattern_2, matchOptions_1);
1592
+ exports.debug(matchResults.length + ' matches');
1593
+ // substract the results
1594
+ for (var _d = 0, matchResults_4 = matchResults; _d < matchResults_4.length; _d++) {
1595
+ var matchResult = matchResults_4[_d];
1596
+ var key = process.platform == 'win32' ? matchResult.toUpperCase() : matchResult;
1597
+ delete results[key];
1598
+ }
1599
+ }
1600
+ }
1601
+ }
1602
+ var finalResult = Object.keys(results)
1603
+ .map(function (key) { return results[key]; })
1604
+ .sort();
1605
+ exports.debug(finalResult.length + ' final results');
1606
+ return finalResult;
1607
+ }
1608
+ exports.findMatch = findMatch;
1609
+ /**
1610
+ * Build Proxy URL in the following format: protocol://username:password@hostname:port
1611
+ * @param proxyUrl Url address of the proxy server (eg: http://example.com)
1612
+ * @param proxyUsername Proxy username (optional)
1613
+ * @param proxyPassword Proxy password (optional)
1614
+ * @returns string
1615
+ */
1616
+ function getProxyFormattedUrl(proxyUrl, proxyUsername, proxyPassword) {
1617
+ var parsedUrl = new URL(proxyUrl);
1618
+ var proxyAddress = parsedUrl.protocol + "//" + parsedUrl.host;
1619
+ if (proxyUsername) {
1620
+ proxyAddress = parsedUrl.protocol + "//" + proxyUsername + ":" + proxyPassword + "@" + parsedUrl.host;
1621
+ }
1622
+ return proxyAddress;
1623
+ }
1624
+ /**
1625
+ * Gets http proxy configuration used by Build/Release agent
1626
+ *
1627
+ * @return ProxyConfiguration
1628
+ */
1629
+ function getHttpProxyConfiguration(requestUrl) {
1630
+ var proxyUrl = exports.getVariable('Agent.ProxyUrl');
1631
+ if (proxyUrl && proxyUrl.length > 0) {
1632
+ var proxyUsername = exports.getVariable('Agent.ProxyUsername');
1633
+ var proxyPassword = exports.getVariable('Agent.ProxyPassword');
1634
+ var proxyBypassHosts = JSON.parse(exports.getVariable('Agent.ProxyBypassList') || '[]');
1635
+ var bypass_1 = false;
1636
+ if (requestUrl) {
1637
+ proxyBypassHosts.forEach(function (bypassHost) {
1638
+ if (new RegExp(bypassHost, 'i').test(requestUrl)) {
1639
+ bypass_1 = true;
1640
+ }
1641
+ });
1642
+ }
1643
+ if (bypass_1) {
1644
+ return null;
1645
+ }
1646
+ else {
1647
+ var proxyAddress = getProxyFormattedUrl(proxyUrl, proxyUsername, proxyPassword);
1648
+ return {
1649
+ proxyUrl: proxyUrl,
1650
+ proxyUsername: proxyUsername,
1651
+ proxyPassword: proxyPassword,
1652
+ proxyBypassHosts: proxyBypassHosts,
1653
+ proxyFormattedUrl: proxyAddress
1654
+ };
1655
+ }
1656
+ }
1657
+ else {
1658
+ return null;
1659
+ }
1660
+ }
1661
+ exports.getHttpProxyConfiguration = getHttpProxyConfiguration;
1662
+ /**
1663
+ * Gets http certificate configuration used by Build/Release agent
1664
+ *
1665
+ * @return CertConfiguration
1666
+ */
1667
+ function getHttpCertConfiguration() {
1668
+ var ca = exports.getVariable('Agent.CAInfo');
1669
+ var clientCert = exports.getVariable('Agent.ClientCert');
1670
+ if (ca || clientCert) {
1671
+ var certConfig = {};
1672
+ certConfig.caFile = ca;
1673
+ certConfig.certFile = clientCert;
1674
+ if (clientCert) {
1675
+ var clientCertKey = exports.getVariable('Agent.ClientCertKey');
1676
+ var clientCertArchive = exports.getVariable('Agent.ClientCertArchive');
1677
+ var clientCertPassword = exports.getVariable('Agent.ClientCertPassword');
1678
+ certConfig.keyFile = clientCertKey;
1679
+ certConfig.certArchiveFile = clientCertArchive;
1680
+ certConfig.passphrase = clientCertPassword;
1681
+ }
1682
+ return certConfig;
1683
+ }
1684
+ else {
1685
+ return null;
1686
+ }
1687
+ }
1688
+ exports.getHttpCertConfiguration = getHttpCertConfiguration;
1689
+ //-----------------------------------------------------
1690
+ // Test Publisher
1691
+ //-----------------------------------------------------
1692
+ var TestPublisher = /** @class */ (function () {
1693
+ function TestPublisher(testRunner) {
1694
+ this.testRunner = testRunner;
1695
+ }
1696
+ TestPublisher.prototype.publish = function (resultFiles, mergeResults, platform, config, runTitle, publishRunAttachments, testRunSystem) {
1697
+ // Could have used an initializer, but wanted to avoid reordering parameters when converting to strict null checks
1698
+ // (A parameter cannot both be optional and have an initializer)
1699
+ testRunSystem = testRunSystem || "VSTSTask";
1700
+ var properties = {};
1701
+ properties['type'] = this.testRunner;
1702
+ if (mergeResults) {
1703
+ properties['mergeResults'] = mergeResults;
1704
+ }
1705
+ if (platform) {
1706
+ properties['platform'] = platform;
1707
+ }
1708
+ if (config) {
1709
+ properties['config'] = config;
1710
+ }
1711
+ if (runTitle) {
1712
+ properties['runTitle'] = runTitle;
1713
+ }
1714
+ if (publishRunAttachments) {
1715
+ properties['publishRunAttachments'] = publishRunAttachments;
1716
+ }
1717
+ if (resultFiles) {
1718
+ properties['resultFiles'] = Array.isArray(resultFiles) ? resultFiles.join() : resultFiles;
1719
+ }
1720
+ properties['testRunSystem'] = testRunSystem;
1721
+ exports.command('results.publish', properties, '');
1722
+ };
1723
+ return TestPublisher;
1724
+ }());
1725
+ exports.TestPublisher = TestPublisher;
1726
+ //-----------------------------------------------------
1727
+ // Code coverage Publisher
1728
+ //-----------------------------------------------------
1729
+ var CodeCoveragePublisher = /** @class */ (function () {
1730
+ function CodeCoveragePublisher() {
1731
+ }
1732
+ CodeCoveragePublisher.prototype.publish = function (codeCoverageTool, summaryFileLocation, reportDirectory, additionalCodeCoverageFiles) {
1733
+ var properties = {};
1734
+ if (codeCoverageTool) {
1735
+ properties['codecoveragetool'] = codeCoverageTool;
1736
+ }
1737
+ if (summaryFileLocation) {
1738
+ properties['summaryfile'] = summaryFileLocation;
1739
+ }
1740
+ if (reportDirectory) {
1741
+ properties['reportdirectory'] = reportDirectory;
1742
+ }
1743
+ if (additionalCodeCoverageFiles) {
1744
+ properties['additionalcodecoveragefiles'] = Array.isArray(additionalCodeCoverageFiles) ? additionalCodeCoverageFiles.join() : additionalCodeCoverageFiles;
1745
+ }
1746
+ exports.command('codecoverage.publish', properties, "");
1747
+ };
1748
+ return CodeCoveragePublisher;
1749
+ }());
1750
+ exports.CodeCoveragePublisher = CodeCoveragePublisher;
1751
+ //-----------------------------------------------------
1752
+ // Code coverage Publisher
1753
+ //-----------------------------------------------------
1754
+ var CodeCoverageEnabler = /** @class */ (function () {
1755
+ function CodeCoverageEnabler(buildTool, ccTool) {
1756
+ this.buildTool = buildTool;
1757
+ this.ccTool = ccTool;
1758
+ }
1759
+ CodeCoverageEnabler.prototype.enableCodeCoverage = function (buildProps) {
1760
+ buildProps['buildtool'] = this.buildTool;
1761
+ buildProps['codecoveragetool'] = this.ccTool;
1762
+ exports.command('codecoverage.enable', buildProps, "");
1763
+ };
1764
+ return CodeCoverageEnabler;
1765
+ }());
1766
+ exports.CodeCoverageEnabler = CodeCoverageEnabler;
1767
+ //-----------------------------------------------------
1768
+ // Task Logging Commands
1769
+ //-----------------------------------------------------
1770
+ /**
1771
+ * Upload user interested file as additional log information
1772
+ * to the current timeline record.
1773
+ *
1774
+ * The file shall be available for download along with task logs.
1775
+ *
1776
+ * @param path Path to the file that should be uploaded.
1777
+ * @returns void
1778
+ */
1779
+ function uploadFile(path) {
1780
+ exports.command("task.uploadfile", null, path);
1781
+ }
1782
+ exports.uploadFile = uploadFile;
1783
+ /**
1784
+ * Instruction for the agent to update the PATH environment variable.
1785
+ * The specified directory is prepended to the PATH.
1786
+ * The updated environment variable will be reflected in subsequent tasks.
1787
+ *
1788
+ * @param path Local directory path.
1789
+ * @returns void
1790
+ */
1791
+ function prependPath(path) {
1792
+ assertAgent("2.115.0");
1793
+ exports.command("task.prependpath", null, path);
1794
+ }
1795
+ exports.prependPath = prependPath;
1796
+ /**
1797
+ * Upload and attach summary markdown to current timeline record.
1798
+ * This summary shall be added to the build/release summary and
1799
+ * not available for download with logs.
1800
+ *
1801
+ * @param path Local directory path.
1802
+ * @returns void
1803
+ */
1804
+ function uploadSummary(path) {
1805
+ exports.command("task.uploadsummary", null, path);
1806
+ }
1807
+ exports.uploadSummary = uploadSummary;
1808
+ /**
1809
+ * Upload and attach attachment to current timeline record.
1810
+ * These files are not available for download with logs.
1811
+ * These can only be referred to by extensions using the type or name values.
1812
+ *
1813
+ * @param type Attachment type.
1814
+ * @param name Attachment name.
1815
+ * @param path Attachment path.
1816
+ * @returns void
1817
+ */
1818
+ function addAttachment(type, name, path) {
1819
+ exports.command("task.addattachment", { "type": type, "name": name }, path);
1820
+ }
1821
+ exports.addAttachment = addAttachment;
1822
+ /**
1823
+ * Set an endpoint field with given value.
1824
+ * Value updated will be retained in the endpoint for
1825
+ * the subsequent tasks that execute within the same job.
1826
+ *
1827
+ * @param id Endpoint id.
1828
+ * @param field FieldType enum of AuthParameter, DataParameter or Url.
1829
+ * @param key Key.
1830
+ * @param value Value for key or url.
1831
+ * @returns void
1832
+ */
1833
+ function setEndpoint(id, field, key, value) {
1834
+ exports.command("task.setendpoint", { "id": id, "field": FieldType[field].toLowerCase(), "key": key }, value);
1835
+ }
1836
+ exports.setEndpoint = setEndpoint;
1837
+ /**
1838
+ * Set progress and current operation for current task.
1839
+ *
1840
+ * @param percent Percentage of completion.
1841
+ * @param currentOperation Current pperation.
1842
+ * @returns void
1843
+ */
1844
+ function setProgress(percent, currentOperation) {
1845
+ exports.command("task.setprogress", { "value": "" + percent }, currentOperation);
1846
+ }
1847
+ exports.setProgress = setProgress;
1848
+ /**
1849
+ * Indicates whether to write the logging command directly to the host or to the output pipeline.
1850
+ *
1851
+ * @param id Timeline record Guid.
1852
+ * @param parentId Parent timeline record Guid.
1853
+ * @param recordType Record type.
1854
+ * @param recordName Record name.
1855
+ * @param order Order of timeline record.
1856
+ * @param startTime Start time.
1857
+ * @param finishTime End time.
1858
+ * @param progress Percentage of completion.
1859
+ * @param state TaskState enum of Unknown, Initialized, InProgress or Completed.
1860
+ * @param result TaskResult enum of Succeeded, SucceededWithIssues, Failed, Cancelled or Skipped.
1861
+ * @param message current operation
1862
+ * @returns void
1863
+ */
1864
+ function logDetail(id, message, parentId, recordType, recordName, order, startTime, finishTime, progress, state, result) {
1865
+ var properties = {
1866
+ "id": id,
1867
+ "parentid": parentId,
1868
+ "type": recordType,
1869
+ "name": recordName,
1870
+ "order": order ? order.toString() : undefined,
1871
+ "starttime": startTime,
1872
+ "finishtime": finishTime,
1873
+ "progress": progress ? progress.toString() : undefined,
1874
+ "state": state ? TaskState[state] : undefined,
1875
+ "result": result ? TaskResult[result] : undefined
1876
+ };
1877
+ exports.command("task.logdetail", properties, message);
1878
+ }
1879
+ exports.logDetail = logDetail;
1880
+ /**
1881
+ * Log error or warning issue to timeline record of current task.
1882
+ *
1883
+ * @param type IssueType enum of Error or Warning.
1884
+ * @param sourcePath Source file location.
1885
+ * @param lineNumber Line number.
1886
+ * @param columnNumber Column number.
1887
+ * @param code Error or warning code.
1888
+ * @param message Error or warning message.
1889
+ * @returns void
1890
+ */
1891
+ function logIssue(type, message, sourcePath, lineNumber, columnNumber, errorCode) {
1892
+ var properties = {
1893
+ "type": IssueType[type].toLowerCase(),
1894
+ "code": errorCode,
1895
+ "sourcepath": sourcePath,
1896
+ "linenumber": lineNumber ? lineNumber.toString() : undefined,
1897
+ "columnnumber": columnNumber ? columnNumber.toString() : undefined,
1898
+ };
1899
+ exports.command("task.logissue", properties, message);
1900
+ }
1901
+ exports.logIssue = logIssue;
1902
+ //-----------------------------------------------------
1903
+ // Artifact Logging Commands
1904
+ //-----------------------------------------------------
1905
+ /**
1906
+ * Upload user interested file as additional log information
1907
+ * to the current timeline record.
1908
+ *
1909
+ * The file shall be available for download along with task logs.
1910
+ *
1911
+ * @param containerFolder Folder that the file will upload to, folder will be created if needed.
1912
+ * @param path Path to the file that should be uploaded.
1913
+ * @param name Artifact name.
1914
+ * @returns void
1915
+ */
1916
+ function uploadArtifact(containerFolder, path, name) {
1917
+ exports.command("artifact.upload", { "containerfolder": containerFolder, "artifactname": name }, path);
1918
+ }
1919
+ exports.uploadArtifact = uploadArtifact;
1920
+ /**
1921
+ * Create an artifact link, artifact location is required to be
1922
+ * a file container path, VC path or UNC share path.
1923
+ *
1924
+ * The file shall be available for download along with task logs.
1925
+ *
1926
+ * @param name Artifact name.
1927
+ * @param path Path to the file that should be associated.
1928
+ * @param artifactType ArtifactType enum of Container, FilePath, VersionControl, GitRef or TfvcLabel.
1929
+ * @returns void
1930
+ */
1931
+ function associateArtifact(name, path, artifactType) {
1932
+ exports.command("artifact.associate", { "type": ArtifactType[artifactType].toLowerCase(), "artifactname": name }, path);
1933
+ }
1934
+ exports.associateArtifact = associateArtifact;
1935
+ //-----------------------------------------------------
1936
+ // Build Logging Commands
1937
+ //-----------------------------------------------------
1938
+ /**
1939
+ * Upload user interested log to build’s container “logs\tool” folder.
1940
+ *
1941
+ * @param path Path to the file that should be uploaded.
1942
+ * @returns void
1943
+ */
1944
+ function uploadBuildLog(path) {
1945
+ exports.command("build.uploadlog", null, path);
1946
+ }
1947
+ exports.uploadBuildLog = uploadBuildLog;
1948
+ /**
1949
+ * Update build number for current build.
1950
+ *
1951
+ * @param value Value to be assigned as the build number.
1952
+ * @returns void
1953
+ */
1954
+ function updateBuildNumber(value) {
1955
+ exports.command("build.updatebuildnumber", null, value);
1956
+ }
1957
+ exports.updateBuildNumber = updateBuildNumber;
1958
+ /**
1959
+ * Add a tag for current build.
1960
+ *
1961
+ * @param value Tag value.
1962
+ * @returns void
1963
+ */
1964
+ function addBuildTag(value) {
1965
+ exports.command("build.addbuildtag", null, value);
1966
+ }
1967
+ exports.addBuildTag = addBuildTag;
1968
+ //-----------------------------------------------------
1969
+ // Release Logging Commands
1970
+ //-----------------------------------------------------
1971
+ /**
1972
+ * Update release name for current release.
1973
+ *
1974
+ * @param value Value to be assigned as the release name.
1975
+ * @returns void
1976
+ */
1977
+ function updateReleaseName(name) {
1978
+ assertAgent("2.132.0");
1979
+ exports.command("release.updatereleasename", null, name);
1980
+ }
1981
+ exports.updateReleaseName = updateReleaseName;
1982
+ //-----------------------------------------------------
1983
+ // Tools
1984
+ //-----------------------------------------------------
1985
+ exports.TaskCommand = tcm.TaskCommand;
1986
+ exports.commandFromString = tcm.commandFromString;
1987
+ exports.ToolRunner = trm.ToolRunner;
1988
+ //-----------------------------------------------------
1989
+ // Validation Checks
1990
+ //-----------------------------------------------------
1991
+ // async await needs generators in node 4.x+
1992
+ if (semver.lt(process.versions.node, '4.2.0')) {
1993
+ exports.warning('Tasks require a new agent. Upgrade your agent or node to 4.2.0 or later');
1994
+ }
1995
+ //-------------------------------------------------------------------
1996
+ // Populate the vault with sensitive data. Inputs and Endpoints
1997
+ //-------------------------------------------------------------------
1998
+ // avoid loading twice (overwrites .taskkey)
1999
+ if (!global['_vsts_task_lib_loaded']) {
2000
+ im._loadData();
2001
+ im._exposeProxySettings();
2002
+ im._exposeCertSettings();
2003
+ }