@codingame/monaco-vscode-task-service-override 1.85.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.
Files changed (25) hide show
  1. package/external/tslib/tslib.es6.js +11 -0
  2. package/index.d.ts +1 -0
  3. package/index.js +1 -0
  4. package/override/vs/platform/dialogs/common/dialogs.js +8 -0
  5. package/package.json +24 -0
  6. package/task.d.ts +5 -0
  7. package/task.js +12 -0
  8. package/vscode/src/vs/base/common/parsers.js +44 -0
  9. package/vscode/src/vs/workbench/contrib/tasks/browser/abstractTaskService.js +3851 -0
  10. package/vscode/src/vs/workbench/contrib/tasks/browser/runAutomaticTasks.js +167 -0
  11. package/vscode/src/vs/workbench/contrib/tasks/browser/task.contribution.js +694 -0
  12. package/vscode/src/vs/workbench/contrib/tasks/browser/taskQuickPick.js +452 -0
  13. package/vscode/src/vs/workbench/contrib/tasks/browser/taskService.js +36 -0
  14. package/vscode/src/vs/workbench/contrib/tasks/browser/taskTerminalStatus.js +191 -0
  15. package/vscode/src/vs/workbench/contrib/tasks/browser/tasksQuickAccess.js +121 -0
  16. package/vscode/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.js +1713 -0
  17. package/vscode/src/vs/workbench/contrib/tasks/common/jsonSchemaCommon.js +440 -0
  18. package/vscode/src/vs/workbench/contrib/tasks/common/jsonSchema_v1.js +125 -0
  19. package/vscode/src/vs/workbench/contrib/tasks/common/jsonSchema_v2.js +901 -0
  20. package/vscode/src/vs/workbench/contrib/tasks/common/problemCollectors.js +464 -0
  21. package/vscode/src/vs/workbench/contrib/tasks/common/problemMatcher.js +1796 -0
  22. package/vscode/src/vs/workbench/contrib/tasks/common/taskConfiguration.js +1581 -0
  23. package/vscode/src/vs/workbench/contrib/tasks/common/taskSystem.js +15 -0
  24. package/vscode/src/vs/workbench/contrib/tasks/common/taskTemplates.js +145 -0
  25. package/vscode/src/vs/workbench/contrib/terminal/browser/terminalEscapeSequences.js +13 -0
@@ -0,0 +1,1713 @@
1
+ import { asArray } from 'monaco-editor/esm/vs/base/common/arrays.js';
2
+ import * as Async from 'monaco-editor/esm/vs/base/common/async.js';
3
+ import { Emitter } from 'monaco-editor/esm/vs/base/common/event.js';
4
+ import { isUNC } from 'monaco-editor/esm/vs/base/common/extpath.js';
5
+ import { Disposable, DisposableStore } from 'monaco-editor/esm/vs/base/common/lifecycle.js';
6
+ import { LinkedMap } from 'monaco-editor/esm/vs/base/common/map.js';
7
+ import * as Objects from 'monaco-editor/esm/vs/base/common/objects.js';
8
+ import * as path from 'monaco-editor/esm/vs/base/common/path.js';
9
+ import * as platform from 'monaco-editor/esm/vs/base/common/platform.js';
10
+ import * as resources from 'monaco-editor/esm/vs/base/common/resources.js';
11
+ import Severity from 'monaco-editor/esm/vs/base/common/severity.js';
12
+ import * as Types from 'monaco-editor/esm/vs/base/common/types.js';
13
+ import * as nls from 'monaco-editor/esm/vs/nls.js';
14
+ import { MarkerSeverity } from 'monaco-editor/esm/vs/platform/markers/common/markers.js';
15
+ import { Markers } from 'vscode/vscode/vs/workbench/contrib/markers/common/markers';
16
+ import { ProblemMatcherRegistry } from '../common/problemMatcher.js';
17
+ import { Codicon } from 'monaco-editor/esm/vs/base/common/codicons.js';
18
+ import { Schemas } from 'monaco-editor/esm/vs/base/common/network.js';
19
+ import { ThemeIcon } from 'monaco-editor/esm/vs/base/common/themables.js';
20
+ import { URI } from 'monaco-editor/esm/vs/base/common/uri.js';
21
+ import { formatMessageForTerminal } from 'vscode/vscode/vs/platform/terminal/common/terminalStrings';
22
+ import { TaskTerminalStatus } from './taskTerminalStatus.js';
23
+ import { WatchingProblemCollector, StartStopProblemCollector } from '../common/problemCollectors.js';
24
+ import { GroupKind } from '../common/taskConfiguration.js';
25
+ import { Triggers, TaskError } from '../common/taskSystem.js';
26
+ import { InMemoryTask, CustomTask, ContributedTask, TaskEvent, CommandString, RuntimeType, TaskSourceKind, RevealProblemKind, RevealKind, PanelKind, ShellQuoting } from 'vscode/vscode/vs/workbench/contrib/tasks/common/tasks';
27
+ import { VSCodeSequence } from '../../terminal/browser/terminalEscapeSequences.js';
28
+ import { TerminalProcessExtHostProxy } from 'vscode/vscode/vs/workbench/contrib/terminal/browser/terminalProcessExtHostProxy';
29
+ import { TERMINAL_VIEW_ID } from 'vscode/vscode/vs/workbench/contrib/terminal/common/terminal';
30
+
31
+ const ReconnectionType = 'Task';
32
+ class VariableResolver {
33
+ static { this._regex = /\$\{(.*?)\}/g; }
34
+ constructor(workspaceFolder, taskSystemInfo, values, _service) {
35
+ this.workspaceFolder = workspaceFolder;
36
+ this.taskSystemInfo = taskSystemInfo;
37
+ this.values = values;
38
+ this._service = _service;
39
+ }
40
+ async resolve(value) {
41
+ const replacers = [];
42
+ value.replace(VariableResolver._regex, (match, ...args) => {
43
+ replacers.push(this._replacer(match, args));
44
+ return match;
45
+ });
46
+ const resolvedReplacers = await Promise.all(replacers);
47
+ return value.replace(VariableResolver._regex, () => resolvedReplacers.shift());
48
+ }
49
+ async _replacer(match, args) {
50
+ const result = this.values.get(match.substring(2, match.length - 1));
51
+ if ((result !== undefined) && (result !== null)) {
52
+ return result;
53
+ }
54
+ if (this._service) {
55
+ return this._service.resolveAsync(this.workspaceFolder, match);
56
+ }
57
+ return match;
58
+ }
59
+ }
60
+ class VerifiedTask {
61
+ constructor(task, resolver, trigger) {
62
+ this.task = task;
63
+ this.resolver = resolver;
64
+ this.trigger = trigger;
65
+ }
66
+ verify() {
67
+ let verified = false;
68
+ if (this.trigger && this.resolvedVariables && this.workspaceFolder && (this.shellLaunchConfig !== undefined)) {
69
+ verified = true;
70
+ }
71
+ return verified;
72
+ }
73
+ getVerifiedTask() {
74
+ if (this.verify()) {
75
+ return { task: this.task, resolver: this.resolver, trigger: this.trigger, resolvedVariables: this.resolvedVariables, systemInfo: this.systemInfo, workspaceFolder: this.workspaceFolder, shellLaunchConfig: this.shellLaunchConfig };
76
+ }
77
+ else {
78
+ throw new Error('VerifiedTask was not checked. verify must be checked before getVerifiedTask.');
79
+ }
80
+ }
81
+ }
82
+ class TerminalTaskSystem extends Disposable {
83
+ static { this.TelemetryEventName = 'taskService'; }
84
+ static { this.ProcessVarName = '__process__'; }
85
+ static { this._shellQuotes = {
86
+ 'cmd': {
87
+ strong: '"'
88
+ },
89
+ 'powershell': {
90
+ escape: {
91
+ escapeChar: '`',
92
+ charsToEscape: ' "\'()'
93
+ },
94
+ strong: '\'',
95
+ weak: '"'
96
+ },
97
+ 'bash': {
98
+ escape: {
99
+ escapeChar: '\\',
100
+ charsToEscape: ' "\''
101
+ },
102
+ strong: '\'',
103
+ weak: '"'
104
+ },
105
+ 'zsh': {
106
+ escape: {
107
+ escapeChar: '\\',
108
+ charsToEscape: ' "\''
109
+ },
110
+ strong: '\'',
111
+ weak: '"'
112
+ }
113
+ }; }
114
+ static { this._osShellQuotes = {
115
+ 'Linux': TerminalTaskSystem._shellQuotes['bash'],
116
+ 'Mac': TerminalTaskSystem._shellQuotes['bash'],
117
+ 'Windows': TerminalTaskSystem._shellQuotes['powershell']
118
+ }; }
119
+ taskShellIntegrationStartSequence(cwd) {
120
+ return (VSCodeSequence("A" ) +
121
+ VSCodeSequence("P" , `${"Task" }=True`) +
122
+ (cwd
123
+ ? VSCodeSequence("P" , `${"Cwd" }=${typeof cwd === 'string' ? cwd : cwd.fsPath}`)
124
+ : '') +
125
+ VSCodeSequence("B" ));
126
+ }
127
+ get taskShellIntegrationOutputSequence() {
128
+ return VSCodeSequence("C" );
129
+ }
130
+ constructor(_terminalService, _terminalGroupService, _outputService, _paneCompositeService, _viewsService, _markerService, _modelService, _configurationResolverService, _contextService, _environmentService, _outputChannelId, _fileService, _terminalProfileResolverService, _pathService, _viewDescriptorService, _logService, _notificationService, instantiationService, taskSystemInfoResolver) {
131
+ super();
132
+ this._terminalService = _terminalService;
133
+ this._terminalGroupService = _terminalGroupService;
134
+ this._outputService = _outputService;
135
+ this._paneCompositeService = _paneCompositeService;
136
+ this._viewsService = _viewsService;
137
+ this._markerService = _markerService;
138
+ this._modelService = _modelService;
139
+ this._configurationResolverService = _configurationResolverService;
140
+ this._contextService = _contextService;
141
+ this._environmentService = _environmentService;
142
+ this._outputChannelId = _outputChannelId;
143
+ this._fileService = _fileService;
144
+ this._terminalProfileResolverService = _terminalProfileResolverService;
145
+ this._pathService = _pathService;
146
+ this._viewDescriptorService = _viewDescriptorService;
147
+ this._logService = _logService;
148
+ this._notificationService = _notificationService;
149
+ this._isRerun = false;
150
+ this._terminalCreationQueue = Promise.resolve();
151
+ this._hasReconnected = false;
152
+ this._activeTasks = Object.create(null);
153
+ this._busyTasks = Object.create(null);
154
+ this._terminals = Object.create(null);
155
+ this._idleTaskTerminals = ( new LinkedMap());
156
+ this._sameTaskTerminals = Object.create(null);
157
+ this._onDidStateChange = ( new Emitter());
158
+ this._taskSystemInfoResolver = taskSystemInfoResolver;
159
+ this._register(this._terminalStatusManager = instantiationService.createInstance(TaskTerminalStatus));
160
+ }
161
+ get onDidStateChange() {
162
+ return this._onDidStateChange.event;
163
+ }
164
+ _log(value) {
165
+ this._appendOutput(value + '\n');
166
+ }
167
+ _showOutput() {
168
+ this._outputService.showChannel(this._outputChannelId, true);
169
+ }
170
+ reconnect(task, resolver) {
171
+ this._reconnectToTerminals();
172
+ return this.run(task, resolver, Triggers.reconnect);
173
+ }
174
+ run(task, resolver, trigger = Triggers.command) {
175
+ task = task.clone();
176
+ const instances = InMemoryTask.is(task) || this._isTaskEmpty(task) ? [] : this._getInstances(task);
177
+ const validInstance = instances.length < ((task.runOptions && task.runOptions.instanceLimit) ?? 1);
178
+ const instance = instances[0]?.count?.count ?? 0;
179
+ this._currentTask = ( new VerifiedTask(task, resolver, trigger));
180
+ if (instance > 0) {
181
+ task.instance = instance;
182
+ }
183
+ if (!validInstance) {
184
+ const terminalData = instances[instances.length - 1];
185
+ this._lastTask = this._currentTask;
186
+ return { kind: 2 , task: terminalData.task, active: { same: true, background: task.configurationProperties.isBackground }, promise: terminalData.promise };
187
+ }
188
+ try {
189
+ const executeResult = { kind: 1 , task, started: {}, promise: this._executeTask(task, resolver, trigger, ( new Set()), ( new Map()), undefined) };
190
+ executeResult.promise.then(summary => {
191
+ this._lastTask = this._currentTask;
192
+ });
193
+ return executeResult;
194
+ }
195
+ catch (error) {
196
+ if (error instanceof TaskError) {
197
+ throw error;
198
+ }
199
+ else if (error instanceof Error) {
200
+ this._log(error.message);
201
+ throw new TaskError(Severity.Error, error.message, 7 );
202
+ }
203
+ else {
204
+ this._log(( error.toString()));
205
+ throw new TaskError(Severity.Error, nls.localizeWithPath('vs/workbench/contrib/tasks/browser/terminalTaskSystem', 'TerminalTaskSystem.unknownError', 'A unknown error has occurred while executing a task. See task output log for details.'), 7 );
206
+ }
207
+ }
208
+ }
209
+ rerun() {
210
+ if (this._lastTask && this._lastTask.verify()) {
211
+ if ((this._lastTask.task.runOptions.reevaluateOnRerun !== undefined) && !this._lastTask.task.runOptions.reevaluateOnRerun) {
212
+ this._isRerun = true;
213
+ }
214
+ const result = this.run(this._lastTask.task, this._lastTask.resolver);
215
+ result.promise.then(summary => {
216
+ this._isRerun = false;
217
+ });
218
+ return result;
219
+ }
220
+ else {
221
+ return undefined;
222
+ }
223
+ }
224
+ _showTaskLoadErrors(task) {
225
+ if (task.taskLoadMessages && task.taskLoadMessages.length > 0) {
226
+ task.taskLoadMessages.forEach(loadMessage => {
227
+ this._log(loadMessage + '\n');
228
+ });
229
+ const openOutput = 'Show Output';
230
+ this._notificationService.prompt(Severity.Warning, ( nls.localizeWithPath(
231
+ 'vs/workbench/contrib/tasks/browser/terminalTaskSystem',
232
+ 'TerminalTaskSystem.taskLoadReporting',
233
+ "There are issues with task \"{0}\". See the output for more details.",
234
+ task._label
235
+ )), [{
236
+ label: openOutput,
237
+ run: () => this._showOutput()
238
+ }]);
239
+ }
240
+ }
241
+ isTaskVisible(task) {
242
+ const terminalData = this._activeTasks[task.getMapKey()];
243
+ if (!terminalData?.terminal) {
244
+ return false;
245
+ }
246
+ const activeTerminalInstance = this._terminalService.activeInstance;
247
+ const isPanelShowingTerminal = !!this._viewsService.getActiveViewWithId(TERMINAL_VIEW_ID);
248
+ return isPanelShowingTerminal && (activeTerminalInstance?.instanceId === terminalData.terminal.instanceId);
249
+ }
250
+ revealTask(task) {
251
+ const terminalData = this._activeTasks[task.getMapKey()];
252
+ if (!terminalData?.terminal) {
253
+ return false;
254
+ }
255
+ const isTerminalInPanel = this._viewDescriptorService.getViewLocationById(TERMINAL_VIEW_ID) === 1 ;
256
+ if (isTerminalInPanel && this.isTaskVisible(task)) {
257
+ if (this._previousPanelId) {
258
+ if (this._previousTerminalInstance) {
259
+ this._terminalService.setActiveInstance(this._previousTerminalInstance);
260
+ }
261
+ this._paneCompositeService.openPaneComposite(this._previousPanelId, 1 );
262
+ }
263
+ else {
264
+ this._paneCompositeService.hideActivePaneComposite(1 );
265
+ }
266
+ this._previousPanelId = undefined;
267
+ this._previousTerminalInstance = undefined;
268
+ }
269
+ else {
270
+ if (isTerminalInPanel) {
271
+ this._previousPanelId = this._paneCompositeService.getActivePaneComposite(1 )?.getId();
272
+ if (this._previousPanelId === TERMINAL_VIEW_ID) {
273
+ this._previousTerminalInstance = this._terminalService.activeInstance ?? undefined;
274
+ }
275
+ }
276
+ this._terminalService.setActiveInstance(terminalData.terminal);
277
+ if (CustomTask.is(task) || ContributedTask.is(task)) {
278
+ this._terminalGroupService.showPanel(task.command.presentation.focus);
279
+ }
280
+ }
281
+ return true;
282
+ }
283
+ isActive() {
284
+ return Promise.resolve(this.isActiveSync());
285
+ }
286
+ isActiveSync() {
287
+ return ( ( Object.values(this._activeTasks)).some(value => !!value.terminal));
288
+ }
289
+ canAutoTerminate() {
290
+ return ( Object.values(this._activeTasks)).every(value => !value.task.configurationProperties.promptOnClose);
291
+ }
292
+ getActiveTasks() {
293
+ return ( Object.values(this._activeTasks)).flatMap(value => value.terminal ? value.task : []);
294
+ }
295
+ getLastInstance(task) {
296
+ const recentKey = task.getKey();
297
+ return ( Object.values(this._activeTasks)).reverse().find((value) => recentKey && recentKey === value.task.getKey())?.task;
298
+ }
299
+ getBusyTasks() {
300
+ return ( ( Object.keys(this._busyTasks)).map(key => this._busyTasks[key]));
301
+ }
302
+ customExecutionComplete(task, result) {
303
+ const activeTerminal = this._activeTasks[task.getMapKey()];
304
+ if (!activeTerminal?.terminal) {
305
+ return Promise.reject(( new Error('Expected to have a terminal for a custom execution task')));
306
+ }
307
+ return ( new Promise((resolve) => {
308
+ resolve();
309
+ }));
310
+ }
311
+ _getInstances(task) {
312
+ const recentKey = task.getKey();
313
+ return ( Object.values(this._activeTasks)).filter((value) => recentKey && recentKey === value.task.getKey());
314
+ }
315
+ _removeFromActiveTasks(task) {
316
+ const key = typeof task === 'string' ? task : task.getMapKey();
317
+ const taskToRemove = this._activeTasks[key];
318
+ if (!taskToRemove) {
319
+ return;
320
+ }
321
+ delete this._activeTasks[key];
322
+ }
323
+ _fireTaskEvent(event) {
324
+ if (event.kind !== "changed" ) {
325
+ const activeTask = this._activeTasks[event.__task.getMapKey()];
326
+ if (activeTask) {
327
+ activeTask.state = event.kind;
328
+ }
329
+ }
330
+ this._onDidStateChange.fire(event);
331
+ }
332
+ terminate(task) {
333
+ const activeTerminal = this._activeTasks[task.getMapKey()];
334
+ const terminal = activeTerminal.terminal;
335
+ if (!terminal) {
336
+ return Promise.resolve({ success: false, task: undefined });
337
+ }
338
+ return ( new Promise((resolve, reject) => {
339
+ terminal.onDisposed(terminal => {
340
+ this._fireTaskEvent(TaskEvent.terminated(task, terminal.instanceId, terminal.exitReason));
341
+ });
342
+ const onExit = terminal.onExit(() => {
343
+ const task = activeTerminal.task;
344
+ try {
345
+ onExit.dispose();
346
+ this._fireTaskEvent(TaskEvent.terminated(task, terminal.instanceId, terminal.exitReason));
347
+ }
348
+ catch (error) {
349
+ }
350
+ resolve({ success: true, task: task });
351
+ });
352
+ terminal.dispose();
353
+ }));
354
+ }
355
+ terminateAll() {
356
+ const promises = [];
357
+ for (const [key, terminalData] of Object.entries(this._activeTasks)) {
358
+ const terminal = terminalData.terminal;
359
+ if (terminal) {
360
+ promises.push(( new Promise((resolve, reject) => {
361
+ const onExit = terminal.onExit(() => {
362
+ const task = terminalData.task;
363
+ try {
364
+ onExit.dispose();
365
+ this._fireTaskEvent(TaskEvent.terminated(task, terminal.instanceId, terminal.exitReason));
366
+ }
367
+ catch (error) {
368
+ }
369
+ if (this._activeTasks[key] === terminalData) {
370
+ delete this._activeTasks[key];
371
+ }
372
+ resolve({ success: true, task: terminalData.task });
373
+ });
374
+ })));
375
+ terminal.dispose();
376
+ }
377
+ }
378
+ return Promise.all(promises);
379
+ }
380
+ _showDependencyCycleMessage(task) {
381
+ this._log(( nls.localizeWithPath(
382
+ 'vs/workbench/contrib/tasks/browser/terminalTaskSystem',
383
+ 'dependencyCycle',
384
+ 'There is a dependency cycle. See task "{0}".',
385
+ task._label
386
+ )));
387
+ this._showOutput();
388
+ }
389
+ _executeTask(task, resolver, trigger, liveDependencies, encounteredTasks, alreadyResolved) {
390
+ this._showTaskLoadErrors(task);
391
+ const mapKey = task.getMapKey();
392
+ const promise = Promise.resolve().then(async () => {
393
+ alreadyResolved = alreadyResolved ?? ( new Map());
394
+ const promises = [];
395
+ if (task.configurationProperties.dependsOn) {
396
+ const nextLiveDependencies = ( new Set(liveDependencies)).add(task.getCommonTaskId());
397
+ for (const dependency of task.configurationProperties.dependsOn) {
398
+ const dependencyTask = await resolver.resolve(dependency.uri, dependency.task);
399
+ if (dependencyTask) {
400
+ this._adoptConfigurationForDependencyTask(dependencyTask, task);
401
+ let taskResult;
402
+ const commonKey = dependencyTask.getCommonTaskId();
403
+ if (( nextLiveDependencies.has(commonKey))) {
404
+ this._showDependencyCycleMessage(dependencyTask);
405
+ taskResult = Promise.resolve({});
406
+ }
407
+ else {
408
+ taskResult = encounteredTasks.get(commonKey);
409
+ if (!taskResult) {
410
+ const activeTask = this._activeTasks[dependencyTask.getMapKey()] ?? this._getInstances(dependencyTask).pop();
411
+ taskResult = activeTask && this._getDependencyPromise(activeTask);
412
+ }
413
+ }
414
+ if (!taskResult) {
415
+ this._fireTaskEvent(TaskEvent.general("dependsOnStarted" , task));
416
+ taskResult = this._executeDependencyTask(dependencyTask, resolver, trigger, nextLiveDependencies, encounteredTasks, alreadyResolved);
417
+ }
418
+ encounteredTasks.set(commonKey, taskResult);
419
+ promises.push(taskResult);
420
+ if (task.configurationProperties.dependsOrder === "sequence" ) {
421
+ const promiseResult = await taskResult;
422
+ if (promiseResult.exitCode !== 0) {
423
+ break;
424
+ }
425
+ }
426
+ }
427
+ else {
428
+ this._log(( nls.localizeWithPath(
429
+ 'vs/workbench/contrib/tasks/browser/terminalTaskSystem',
430
+ 'dependencyFailed',
431
+ 'Couldn\'t resolve dependent task \'{0}\' in workspace folder \'{1}\'',
432
+ Types.isString(dependency.task) ? dependency.task : JSON.stringify(dependency.task, undefined, 0),
433
+ ( dependency.uri.toString())
434
+ )));
435
+ this._showOutput();
436
+ }
437
+ }
438
+ }
439
+ return Promise.all(promises).then((summaries) => {
440
+ for (const summary of summaries) {
441
+ if (summary.exitCode !== 0) {
442
+ return { exitCode: summary.exitCode };
443
+ }
444
+ }
445
+ if ((ContributedTask.is(task) || CustomTask.is(task)) && (task.command)) {
446
+ if (this._isRerun) {
447
+ return this._reexecuteCommand(task, trigger, alreadyResolved);
448
+ }
449
+ else {
450
+ return this._executeCommand(task, trigger, alreadyResolved);
451
+ }
452
+ }
453
+ return { exitCode: 0 };
454
+ });
455
+ }).finally(() => {
456
+ if (this._activeTasks[mapKey] === activeTask) {
457
+ delete this._activeTasks[mapKey];
458
+ }
459
+ });
460
+ const lastInstance = this._getInstances(task).pop();
461
+ const count = lastInstance?.count ?? { count: 0 };
462
+ count.count++;
463
+ const activeTask = { task, promise, count };
464
+ this._activeTasks[mapKey] = activeTask;
465
+ return promise;
466
+ }
467
+ _createInactiveDependencyPromise(task) {
468
+ return ( new Promise(resolve => {
469
+ const taskInactiveDisposable = this.onDidStateChange(taskEvent => {
470
+ if (((taskEvent.kind === "inactive") ) && (taskEvent.__task === task)) {
471
+ taskInactiveDisposable.dispose();
472
+ resolve({ exitCode: 0 });
473
+ }
474
+ });
475
+ }));
476
+ }
477
+ _adoptConfigurationForDependencyTask(dependencyTask, task) {
478
+ if (dependencyTask.configurationProperties.icon) {
479
+ dependencyTask.configurationProperties.icon.id ||= task.configurationProperties.icon?.id;
480
+ dependencyTask.configurationProperties.icon.color ||= task.configurationProperties.icon?.color;
481
+ }
482
+ else {
483
+ dependencyTask.configurationProperties.icon = task.configurationProperties.icon;
484
+ }
485
+ }
486
+ async _getDependencyPromise(task) {
487
+ if (!task.task.configurationProperties.isBackground) {
488
+ return task.promise;
489
+ }
490
+ if (!task.task.configurationProperties.problemMatchers || task.task.configurationProperties.problemMatchers.length === 0) {
491
+ return task.promise;
492
+ }
493
+ if (task.state === "inactive" ) {
494
+ return { exitCode: 0 };
495
+ }
496
+ return this._createInactiveDependencyPromise(task.task);
497
+ }
498
+ async _executeDependencyTask(task, resolver, trigger, liveDependencies, encounteredTasks, alreadyResolved) {
499
+ if (!task.configurationProperties.isBackground) {
500
+ return this._executeTask(task, resolver, trigger, liveDependencies, encounteredTasks, alreadyResolved);
501
+ }
502
+ const inactivePromise = this._createInactiveDependencyPromise(task);
503
+ return Promise.race([inactivePromise, this._executeTask(task, resolver, trigger, liveDependencies, encounteredTasks, alreadyResolved)]);
504
+ }
505
+ async _resolveAndFindExecutable(systemInfo, workspaceFolder, task, cwd, envPath) {
506
+ const command = await this._configurationResolverService.resolveAsync(workspaceFolder, CommandString.value(task.command.name));
507
+ cwd = cwd ? await this._configurationResolverService.resolveAsync(workspaceFolder, cwd) : undefined;
508
+ const paths = envPath ? await Promise.all(( envPath.split(path.delimiter).map(p => this._configurationResolverService.resolveAsync(workspaceFolder, p)))) : undefined;
509
+ let foundExecutable = await systemInfo?.findExecutable(command, cwd, paths);
510
+ if (!foundExecutable) {
511
+ foundExecutable = path.join(cwd ?? '', command);
512
+ }
513
+ return foundExecutable;
514
+ }
515
+ _findUnresolvedVariables(variables, alreadyResolved) {
516
+ if (alreadyResolved.size === 0) {
517
+ return variables;
518
+ }
519
+ const unresolved = ( new Set());
520
+ for (const variable of variables) {
521
+ if (!( alreadyResolved.has(variable.substring(2, variable.length - 1)))) {
522
+ unresolved.add(variable);
523
+ }
524
+ }
525
+ return unresolved;
526
+ }
527
+ _mergeMaps(mergeInto, mergeFrom) {
528
+ for (const entry of mergeFrom) {
529
+ if (!( mergeInto.has(entry[0]))) {
530
+ mergeInto.set(entry[0], entry[1]);
531
+ }
532
+ }
533
+ }
534
+ async _acquireInput(taskSystemInfo, workspaceFolder, task, variables, alreadyResolved) {
535
+ const resolved = await this._resolveVariablesFromSet(taskSystemInfo, workspaceFolder, task, variables, alreadyResolved);
536
+ this._fireTaskEvent(TaskEvent.general("acquiredInput" , task));
537
+ return resolved;
538
+ }
539
+ _resolveVariablesFromSet(taskSystemInfo, workspaceFolder, task, variables, alreadyResolved) {
540
+ const isProcess = task.command && task.command.runtime === RuntimeType.Process;
541
+ const options = task.command && task.command.options ? task.command.options : undefined;
542
+ const cwd = options ? options.cwd : undefined;
543
+ let envPath = undefined;
544
+ if (options && options.env) {
545
+ for (const key of ( Object.keys(options.env))) {
546
+ if (key.toLowerCase() === 'path') {
547
+ if (Types.isString(options.env[key])) {
548
+ envPath = options.env[key];
549
+ }
550
+ break;
551
+ }
552
+ }
553
+ }
554
+ const unresolved = this._findUnresolvedVariables(variables, alreadyResolved);
555
+ let resolvedVariables;
556
+ if (taskSystemInfo && workspaceFolder) {
557
+ const resolveSet = {
558
+ variables: unresolved
559
+ };
560
+ if (taskSystemInfo.platform === 3 && isProcess) {
561
+ resolveSet.process = { name: CommandString.value(task.command.name) };
562
+ if (cwd) {
563
+ resolveSet.process.cwd = cwd;
564
+ }
565
+ if (envPath) {
566
+ resolveSet.process.path = envPath;
567
+ }
568
+ }
569
+ resolvedVariables = taskSystemInfo.resolveVariables(workspaceFolder, resolveSet, TaskSourceKind.toConfigurationTarget(task._source.kind)).then(async (resolved) => {
570
+ if (!resolved) {
571
+ return undefined;
572
+ }
573
+ this._mergeMaps(alreadyResolved, resolved.variables);
574
+ resolved.variables = ( new Map(alreadyResolved));
575
+ if (isProcess) {
576
+ let process = CommandString.value(task.command.name);
577
+ if (taskSystemInfo.platform === 3 ) {
578
+ process = await this._resolveAndFindExecutable(taskSystemInfo, workspaceFolder, task, cwd, envPath);
579
+ }
580
+ resolved.variables.set(TerminalTaskSystem.ProcessVarName, process);
581
+ }
582
+ return resolved;
583
+ });
584
+ return resolvedVariables;
585
+ }
586
+ else {
587
+ const variablesArray = ( new Array());
588
+ unresolved.forEach(variable => variablesArray.push(variable));
589
+ return ( new Promise((resolve, reject) => {
590
+ this._configurationResolverService.resolveWithInteraction(workspaceFolder, variablesArray, 'tasks', undefined, TaskSourceKind.toConfigurationTarget(task._source.kind)).then(async (resolvedVariablesMap) => {
591
+ if (resolvedVariablesMap) {
592
+ this._mergeMaps(alreadyResolved, resolvedVariablesMap);
593
+ resolvedVariablesMap = ( new Map(alreadyResolved));
594
+ if (isProcess) {
595
+ let processVarValue;
596
+ if (platform.isWindows) {
597
+ processVarValue = await this._resolveAndFindExecutable(taskSystemInfo, workspaceFolder, task, cwd, envPath);
598
+ }
599
+ else {
600
+ processVarValue = await this._configurationResolverService.resolveAsync(workspaceFolder, CommandString.value(task.command.name));
601
+ }
602
+ resolvedVariablesMap.set(TerminalTaskSystem.ProcessVarName, processVarValue);
603
+ }
604
+ const resolvedVariablesResult = {
605
+ variables: resolvedVariablesMap,
606
+ };
607
+ resolve(resolvedVariablesResult);
608
+ }
609
+ else {
610
+ resolve(undefined);
611
+ }
612
+ }, reason => {
613
+ reject(reason);
614
+ });
615
+ }));
616
+ }
617
+ }
618
+ _executeCommand(task, trigger, alreadyResolved) {
619
+ const taskWorkspaceFolder = task.getWorkspaceFolder();
620
+ let workspaceFolder;
621
+ if (taskWorkspaceFolder) {
622
+ workspaceFolder = this._currentTask.workspaceFolder = taskWorkspaceFolder;
623
+ }
624
+ else {
625
+ const folders = this._contextService.getWorkspace().folders;
626
+ workspaceFolder = folders.length > 0 ? folders[0] : undefined;
627
+ }
628
+ const systemInfo = this._currentTask.systemInfo = this._taskSystemInfoResolver(workspaceFolder);
629
+ const variables = ( new Set());
630
+ this._collectTaskVariables(variables, task);
631
+ const resolvedVariables = this._acquireInput(systemInfo, workspaceFolder, task, variables, alreadyResolved);
632
+ return resolvedVariables.then((resolvedVariables) => {
633
+ if (resolvedVariables && !this._isTaskEmpty(task)) {
634
+ this._currentTask.resolvedVariables = resolvedVariables;
635
+ return this._executeInTerminal(task, trigger, ( new VariableResolver(
636
+ workspaceFolder,
637
+ systemInfo,
638
+ resolvedVariables.variables,
639
+ this._configurationResolverService
640
+ )), workspaceFolder);
641
+ }
642
+ else {
643
+ this._fireTaskEvent(TaskEvent.general("end" , task));
644
+ return Promise.resolve({ exitCode: 0 });
645
+ }
646
+ }, reason => {
647
+ return Promise.reject(reason);
648
+ });
649
+ }
650
+ _isTaskEmpty(task) {
651
+ const isCustomExecution = (task.command.runtime === RuntimeType.CustomExecution);
652
+ return !((task.command !== undefined) && task.command.runtime && (isCustomExecution || (task.command.name !== undefined)));
653
+ }
654
+ _reexecuteCommand(task, trigger, alreadyResolved) {
655
+ const lastTask = this._lastTask;
656
+ if (!lastTask) {
657
+ return Promise.reject(( new Error('No task previously run')));
658
+ }
659
+ const workspaceFolder = this._currentTask.workspaceFolder = lastTask.workspaceFolder;
660
+ const variables = ( new Set());
661
+ this._collectTaskVariables(variables, task);
662
+ let hasAllVariables = true;
663
+ variables.forEach(value => {
664
+ if (value.substring(2, value.length - 1) in lastTask.getVerifiedTask().resolvedVariables) {
665
+ hasAllVariables = false;
666
+ }
667
+ });
668
+ if (!hasAllVariables) {
669
+ return this._acquireInput(lastTask.getVerifiedTask().systemInfo, lastTask.getVerifiedTask().workspaceFolder, task, variables, alreadyResolved).then((resolvedVariables) => {
670
+ if (!resolvedVariables) {
671
+ this._fireTaskEvent(TaskEvent.general("end" , task));
672
+ return { exitCode: 0 };
673
+ }
674
+ this._currentTask.resolvedVariables = resolvedVariables;
675
+ return this._executeInTerminal(task, trigger, ( new VariableResolver(
676
+ lastTask.getVerifiedTask().workspaceFolder,
677
+ lastTask.getVerifiedTask().systemInfo,
678
+ resolvedVariables.variables,
679
+ this._configurationResolverService
680
+ )), workspaceFolder);
681
+ }, reason => {
682
+ return Promise.reject(reason);
683
+ });
684
+ }
685
+ else {
686
+ this._currentTask.resolvedVariables = lastTask.getVerifiedTask().resolvedVariables;
687
+ return this._executeInTerminal(task, trigger, ( new VariableResolver(
688
+ lastTask.getVerifiedTask().workspaceFolder,
689
+ lastTask.getVerifiedTask().systemInfo,
690
+ lastTask.getVerifiedTask().resolvedVariables.variables,
691
+ this._configurationResolverService
692
+ )), workspaceFolder);
693
+ }
694
+ }
695
+ async _executeInTerminal(task, trigger, resolver, workspaceFolder) {
696
+ let terminal = undefined;
697
+ let error = undefined;
698
+ let promise = undefined;
699
+ if (task.configurationProperties.isBackground) {
700
+ const problemMatchers = await this._resolveMatchers(resolver, task.configurationProperties.problemMatchers);
701
+ const watchingProblemMatcher = ( new WatchingProblemCollector(
702
+ problemMatchers,
703
+ this._markerService,
704
+ this._modelService,
705
+ this._fileService
706
+ ));
707
+ if ((problemMatchers.length > 0) && !watchingProblemMatcher.isWatching()) {
708
+ this._appendOutput(( nls.localizeWithPath(
709
+ 'vs/workbench/contrib/tasks/browser/terminalTaskSystem',
710
+ 'TerminalTaskSystem.nonWatchingMatcher',
711
+ 'Task {0} is a background task but uses a problem matcher without a background pattern',
712
+ task._label
713
+ )));
714
+ this._showOutput();
715
+ }
716
+ const toDispose = ( new DisposableStore());
717
+ let eventCounter = 0;
718
+ const mapKey = task.getMapKey();
719
+ toDispose.add(watchingProblemMatcher.onDidStateChange((event) => {
720
+ if (event.kind === "backgroundProcessingBegins" ) {
721
+ eventCounter++;
722
+ this._busyTasks[mapKey] = task;
723
+ this._fireTaskEvent(TaskEvent.general("active" , task, terminal?.instanceId));
724
+ }
725
+ else if (event.kind === "backgroundProcessingEnds" ) {
726
+ eventCounter--;
727
+ if (this._busyTasks[mapKey]) {
728
+ delete this._busyTasks[mapKey];
729
+ }
730
+ this._fireTaskEvent(TaskEvent.general("inactive" , task, terminal?.instanceId));
731
+ if (eventCounter === 0) {
732
+ if ((watchingProblemMatcher.numberOfMatches > 0) && watchingProblemMatcher.maxMarkerSeverity &&
733
+ (watchingProblemMatcher.maxMarkerSeverity >= MarkerSeverity.Error)) {
734
+ const reveal = task.command.presentation.reveal;
735
+ const revealProblems = task.command.presentation.revealProblems;
736
+ if (revealProblems === RevealProblemKind.OnProblem) {
737
+ this._viewsService.openView(Markers.MARKERS_VIEW_ID, true);
738
+ }
739
+ else if (reveal === RevealKind.Silent) {
740
+ this._terminalService.setActiveInstance(terminal);
741
+ this._terminalGroupService.showPanel(false);
742
+ }
743
+ }
744
+ }
745
+ }
746
+ }));
747
+ watchingProblemMatcher.aboutToStart();
748
+ let delayer = undefined;
749
+ [terminal, error] = await this._createTerminal(task, resolver, workspaceFolder);
750
+ if (error) {
751
+ return Promise.reject(( new Error(error.message)));
752
+ }
753
+ if (!terminal) {
754
+ return Promise.reject(( new Error(`Failed to create terminal for task ${task._label}`)));
755
+ }
756
+ this._terminalStatusManager.addTerminal(task, terminal, watchingProblemMatcher);
757
+ let processStartedSignaled = false;
758
+ terminal.processReady.then(() => {
759
+ if (!processStartedSignaled) {
760
+ this._fireTaskEvent(TaskEvent.processStarted(task, terminal.instanceId, terminal.processId));
761
+ processStartedSignaled = true;
762
+ }
763
+ }, (_error) => {
764
+ this._logService.error('Task terminal process never got ready');
765
+ });
766
+ this._fireTaskEvent(TaskEvent.start(task, terminal.instanceId, resolver.values));
767
+ let onData;
768
+ if (problemMatchers.length) {
769
+ onData = terminal.onLineData((line) => {
770
+ watchingProblemMatcher.processLine(line);
771
+ if (!delayer) {
772
+ delayer = new Async.Delayer(3000);
773
+ }
774
+ delayer.trigger(() => {
775
+ watchingProblemMatcher.forceDelivery();
776
+ delayer = undefined;
777
+ });
778
+ });
779
+ }
780
+ promise = ( new Promise((resolve, reject) => {
781
+ const onExit = terminal.onExit((terminalLaunchResult) => {
782
+ const exitCode = typeof terminalLaunchResult === 'number' ? terminalLaunchResult : terminalLaunchResult?.code;
783
+ onData?.dispose();
784
+ onExit.dispose();
785
+ const key = task.getMapKey();
786
+ if (this._busyTasks[mapKey]) {
787
+ delete this._busyTasks[mapKey];
788
+ }
789
+ this._removeFromActiveTasks(task);
790
+ this._fireTaskEvent(TaskEvent.changed());
791
+ if (terminalLaunchResult !== undefined) {
792
+ switch (task.command.presentation.panel) {
793
+ case PanelKind.Dedicated:
794
+ this._sameTaskTerminals[key] = ( terminal.instanceId.toString());
795
+ break;
796
+ case PanelKind.Shared:
797
+ this._idleTaskTerminals.set(key, ( terminal.instanceId.toString()), 1 );
798
+ break;
799
+ }
800
+ }
801
+ const reveal = task.command.presentation.reveal;
802
+ if ((reveal === RevealKind.Silent) && ((exitCode !== 0) || (watchingProblemMatcher.numberOfMatches > 0) && watchingProblemMatcher.maxMarkerSeverity &&
803
+ (watchingProblemMatcher.maxMarkerSeverity >= MarkerSeverity.Error))) {
804
+ try {
805
+ this._terminalService.setActiveInstance(terminal);
806
+ this._terminalGroupService.showPanel(false);
807
+ }
808
+ catch (e) {
809
+ }
810
+ }
811
+ watchingProblemMatcher.done();
812
+ watchingProblemMatcher.dispose();
813
+ if (!processStartedSignaled) {
814
+ this._fireTaskEvent(TaskEvent.processStarted(task, terminal.instanceId, terminal.processId));
815
+ processStartedSignaled = true;
816
+ }
817
+ this._fireTaskEvent(TaskEvent.processEnded(task, terminal.instanceId, exitCode));
818
+ for (let i = 0; i < eventCounter; i++) {
819
+ this._fireTaskEvent(TaskEvent.general("inactive" , task, terminal.instanceId));
820
+ }
821
+ eventCounter = 0;
822
+ this._fireTaskEvent(TaskEvent.general("end" , task));
823
+ toDispose.dispose();
824
+ resolve({ exitCode: exitCode ?? undefined });
825
+ });
826
+ }));
827
+ if (trigger === Triggers.reconnect && !!terminal.xterm) {
828
+ const bufferLines = [];
829
+ const bufferReverseIterator = terminal.xterm.getBufferReverseIterator();
830
+ const startRegex = ( new RegExp(( watchingProblemMatcher.beginPatterns.map(pattern => pattern.source)).join('|')));
831
+ for (const nextLine of bufferReverseIterator) {
832
+ bufferLines.push(nextLine);
833
+ if (startRegex.test(nextLine)) {
834
+ break;
835
+ }
836
+ }
837
+ let delayer = undefined;
838
+ for (let i = bufferLines.length - 1; i >= 0; i--) {
839
+ watchingProblemMatcher.processLine(bufferLines[i]);
840
+ if (!delayer) {
841
+ delayer = new Async.Delayer(3000);
842
+ }
843
+ delayer.trigger(() => {
844
+ watchingProblemMatcher.forceDelivery();
845
+ delayer = undefined;
846
+ });
847
+ }
848
+ }
849
+ }
850
+ else {
851
+ [terminal, error] = await this._createTerminal(task, resolver, workspaceFolder);
852
+ if (error) {
853
+ return Promise.reject(( new Error(error.message)));
854
+ }
855
+ if (!terminal) {
856
+ return Promise.reject(( new Error(`Failed to create terminal for task ${task._label}`)));
857
+ }
858
+ let processStartedSignaled = false;
859
+ terminal.processReady.then(() => {
860
+ if (!processStartedSignaled) {
861
+ this._fireTaskEvent(TaskEvent.processStarted(task, terminal.instanceId, terminal.processId));
862
+ processStartedSignaled = true;
863
+ }
864
+ }, (_error) => {
865
+ });
866
+ this._fireTaskEvent(TaskEvent.start(task, terminal.instanceId, resolver.values));
867
+ const mapKey = task.getMapKey();
868
+ this._busyTasks[mapKey] = task;
869
+ this._fireTaskEvent(TaskEvent.general("active" , task, terminal.instanceId));
870
+ const problemMatchers = await this._resolveMatchers(resolver, task.configurationProperties.problemMatchers);
871
+ const startStopProblemMatcher = ( new StartStopProblemCollector(
872
+ problemMatchers,
873
+ this._markerService,
874
+ this._modelService,
875
+ 0 ,
876
+ this._fileService
877
+ ));
878
+ this._terminalStatusManager.addTerminal(task, terminal, startStopProblemMatcher);
879
+ const onData = terminal.onLineData((line) => {
880
+ startStopProblemMatcher.processLine(line);
881
+ });
882
+ promise = ( new Promise((resolve, reject) => {
883
+ const onExit = terminal.onExit((terminalLaunchResult) => {
884
+ const exitCode = typeof terminalLaunchResult === 'number' ? terminalLaunchResult : terminalLaunchResult?.code;
885
+ onExit.dispose();
886
+ const key = task.getMapKey();
887
+ this._removeFromActiveTasks(task);
888
+ this._fireTaskEvent(TaskEvent.changed());
889
+ if (terminalLaunchResult !== undefined) {
890
+ switch (task.command.presentation.panel) {
891
+ case PanelKind.Dedicated:
892
+ this._sameTaskTerminals[key] = ( terminal.instanceId.toString());
893
+ break;
894
+ case PanelKind.Shared:
895
+ this._idleTaskTerminals.set(key, ( terminal.instanceId.toString()), 1 );
896
+ break;
897
+ }
898
+ }
899
+ const reveal = task.command.presentation.reveal;
900
+ const revealProblems = task.command.presentation.revealProblems;
901
+ const revealProblemPanel = terminal && (revealProblems === RevealProblemKind.OnProblem) && (startStopProblemMatcher.numberOfMatches > 0);
902
+ if (revealProblemPanel) {
903
+ this._viewsService.openView(Markers.MARKERS_VIEW_ID);
904
+ }
905
+ else if (terminal && (reveal === RevealKind.Silent) && ((exitCode !== 0) || (startStopProblemMatcher.numberOfMatches > 0) && startStopProblemMatcher.maxMarkerSeverity &&
906
+ (startStopProblemMatcher.maxMarkerSeverity >= MarkerSeverity.Error))) {
907
+ try {
908
+ this._terminalService.setActiveInstance(terminal);
909
+ this._terminalGroupService.showPanel(false);
910
+ }
911
+ catch (e) {
912
+ }
913
+ }
914
+ setTimeout(() => {
915
+ onData.dispose();
916
+ startStopProblemMatcher.done();
917
+ startStopProblemMatcher.dispose();
918
+ }, 100);
919
+ if (!processStartedSignaled && terminal) {
920
+ this._fireTaskEvent(TaskEvent.processStarted(task, terminal.instanceId, terminal.processId));
921
+ processStartedSignaled = true;
922
+ }
923
+ this._fireTaskEvent(TaskEvent.processEnded(task, terminal?.instanceId, exitCode ?? undefined));
924
+ if (this._busyTasks[mapKey]) {
925
+ delete this._busyTasks[mapKey];
926
+ }
927
+ this._fireTaskEvent(TaskEvent.general("inactive" , task, terminal?.instanceId));
928
+ this._fireTaskEvent(TaskEvent.general("end" , task, terminal?.instanceId));
929
+ resolve({ exitCode: exitCode ?? undefined });
930
+ });
931
+ }));
932
+ }
933
+ const showProblemPanel = task.command.presentation && (task.command.presentation.revealProblems === RevealProblemKind.Always);
934
+ if (showProblemPanel) {
935
+ this._viewsService.openView(Markers.MARKERS_VIEW_ID);
936
+ }
937
+ else if (task.command.presentation && (task.command.presentation.focus || task.command.presentation.reveal === RevealKind.Always)) {
938
+ this._terminalService.setActiveInstance(terminal);
939
+ await this._terminalService.revealActiveTerminal();
940
+ if (task.command.presentation.focus) {
941
+ this._terminalService.focusActiveInstance();
942
+ }
943
+ }
944
+ this._activeTasks[task.getMapKey()].terminal = terminal;
945
+ this._fireTaskEvent(TaskEvent.changed());
946
+ return promise;
947
+ }
948
+ _createTerminalName(task) {
949
+ const needsFolderQualification = this._contextService.getWorkbenchState() === 3 ;
950
+ return needsFolderQualification ? task.getQualifiedLabel() : (task.configurationProperties.name || '');
951
+ }
952
+ async _createShellLaunchConfig(task, workspaceFolder, variableResolver, platform, options, command, args, waitOnExit) {
953
+ let shellLaunchConfig;
954
+ const isShellCommand = task.command.runtime === RuntimeType.Shell;
955
+ const needsFolderQualification = this._contextService.getWorkbenchState() === 3 ;
956
+ const terminalName = this._createTerminalName(task);
957
+ const type = ReconnectionType;
958
+ const originalCommand = task.command.name;
959
+ let cwd;
960
+ if (options.cwd) {
961
+ cwd = options.cwd;
962
+ if (!path.isAbsolute(cwd)) {
963
+ if (workspaceFolder && (workspaceFolder.uri.scheme === Schemas.file)) {
964
+ cwd = path.join(workspaceFolder.uri.fsPath, cwd);
965
+ }
966
+ }
967
+ cwd = isUNC(cwd) ? cwd : resources.toLocalResource(( URI.from({ scheme: Schemas.file, path: cwd })), this._environmentService.remoteAuthority, this._pathService.defaultUriScheme);
968
+ }
969
+ if (isShellCommand) {
970
+ let os;
971
+ switch (platform) {
972
+ case 3 :
973
+ os = 1 ;
974
+ break;
975
+ case 1 :
976
+ os = 2 ;
977
+ break;
978
+ case 2 :
979
+ default:
980
+ os = 3 ;
981
+ break;
982
+ }
983
+ const defaultProfile = await this._terminalProfileResolverService.getDefaultProfile({
984
+ allowAutomationShell: true,
985
+ os,
986
+ remoteAuthority: this._environmentService.remoteAuthority
987
+ });
988
+ let icon;
989
+ if (task.configurationProperties.icon?.id) {
990
+ icon = ThemeIcon.fromId(task.configurationProperties.icon.id);
991
+ }
992
+ else {
993
+ const taskGroupKind = task.configurationProperties.group ? GroupKind.to(task.configurationProperties.group) : undefined;
994
+ const kindId = typeof taskGroupKind === 'string' ? taskGroupKind : taskGroupKind?.kind;
995
+ icon = kindId === 'test' ? ThemeIcon.fromId(Codicon.beaker.id) : defaultProfile.icon;
996
+ }
997
+ shellLaunchConfig = {
998
+ name: terminalName,
999
+ type,
1000
+ executable: defaultProfile.path,
1001
+ args: defaultProfile.args,
1002
+ env: { ...defaultProfile.env },
1003
+ icon,
1004
+ color: task.configurationProperties.icon?.color || undefined,
1005
+ waitOnExit
1006
+ };
1007
+ let shellSpecified = false;
1008
+ const shellOptions = task.command.options && task.command.options.shell;
1009
+ if (shellOptions) {
1010
+ if (shellOptions.executable) {
1011
+ if (shellOptions.executable !== shellLaunchConfig.executable) {
1012
+ shellLaunchConfig.args = undefined;
1013
+ }
1014
+ shellLaunchConfig.executable = await this._resolveVariable(variableResolver, shellOptions.executable);
1015
+ shellSpecified = true;
1016
+ }
1017
+ if (shellOptions.args) {
1018
+ shellLaunchConfig.args = await this._resolveVariables(variableResolver, shellOptions.args.slice());
1019
+ }
1020
+ }
1021
+ if (shellLaunchConfig.args === undefined) {
1022
+ shellLaunchConfig.args = [];
1023
+ }
1024
+ const shellArgs = Array.isArray(shellLaunchConfig.args) ? shellLaunchConfig.args.slice(0) : [shellLaunchConfig.args];
1025
+ const toAdd = [];
1026
+ const basename = path.posix.basename((await this._pathService.fileURI(shellLaunchConfig.executable)).path).toLowerCase();
1027
+ const commandLine = this._buildShellCommandLine(platform, basename, shellOptions, command, originalCommand, args);
1028
+ let windowsShellArgs = false;
1029
+ if (platform === 3 ) {
1030
+ windowsShellArgs = true;
1031
+ const userHome = await this._pathService.userHome();
1032
+ if (basename === 'cmd.exe' && ((options.cwd && isUNC(options.cwd)) || (!options.cwd && isUNC(userHome.fsPath)))) {
1033
+ return undefined;
1034
+ }
1035
+ if ((basename === 'powershell.exe') || (basename === 'pwsh.exe')) {
1036
+ if (!shellSpecified) {
1037
+ toAdd.push('-Command');
1038
+ }
1039
+ }
1040
+ else if ((basename === 'bash.exe') || (basename === 'zsh.exe')) {
1041
+ windowsShellArgs = false;
1042
+ if (!shellSpecified) {
1043
+ toAdd.push('-c');
1044
+ }
1045
+ }
1046
+ else if (basename === 'wsl.exe') {
1047
+ if (!shellSpecified) {
1048
+ toAdd.push('-e');
1049
+ }
1050
+ }
1051
+ else {
1052
+ if (!shellSpecified) {
1053
+ toAdd.push('/d', '/c');
1054
+ }
1055
+ }
1056
+ }
1057
+ else {
1058
+ if (!shellSpecified) {
1059
+ toAdd.push('-c');
1060
+ }
1061
+ }
1062
+ const combinedShellArgs = this._addAllArgument(toAdd, shellArgs);
1063
+ combinedShellArgs.push(commandLine);
1064
+ shellLaunchConfig.args = windowsShellArgs ? combinedShellArgs.join(' ') : combinedShellArgs;
1065
+ if (task.command.presentation && task.command.presentation.echo) {
1066
+ if (needsFolderQualification && workspaceFolder) {
1067
+ const folder = cwd ? path.posix.basename(( cwd.toString())) : workspaceFolder.name;
1068
+ shellLaunchConfig.initialText = this.taskShellIntegrationStartSequence(cwd) + formatMessageForTerminal(( nls.localizeWithPath('vs/workbench/contrib/tasks/browser/terminalTaskSystem', {
1069
+ key: 'task.executingInFolder',
1070
+ comment: ['The workspace folder the task is running in', 'The task command line or label']
1071
+ }, 'Executing task in folder {0}: {1}', folder, commandLine)), { excludeLeadingNewLine: true }) + this.taskShellIntegrationOutputSequence;
1072
+ }
1073
+ else {
1074
+ shellLaunchConfig.initialText = this.taskShellIntegrationStartSequence(cwd) + formatMessageForTerminal(( nls.localizeWithPath('vs/workbench/contrib/tasks/browser/terminalTaskSystem', {
1075
+ key: 'task.executing.shellIntegration',
1076
+ comment: ['The task command line or label']
1077
+ }, 'Executing task: {0}', commandLine)), { excludeLeadingNewLine: true }) + this.taskShellIntegrationOutputSequence;
1078
+ }
1079
+ }
1080
+ else {
1081
+ shellLaunchConfig.initialText = {
1082
+ text: this.taskShellIntegrationStartSequence(cwd) + this.taskShellIntegrationOutputSequence,
1083
+ trailingNewLine: false
1084
+ };
1085
+ }
1086
+ }
1087
+ else {
1088
+ const commandExecutable = (task.command.runtime !== RuntimeType.CustomExecution) ? CommandString.value(command) : undefined;
1089
+ const executable = !isShellCommand
1090
+ ? await this._resolveVariable(variableResolver, await this._resolveVariable(variableResolver, '${' + TerminalTaskSystem.ProcessVarName + '}'))
1091
+ : commandExecutable;
1092
+ shellLaunchConfig = {
1093
+ name: terminalName,
1094
+ type,
1095
+ icon: task.configurationProperties.icon?.id ? ThemeIcon.fromId(task.configurationProperties.icon.id) : undefined,
1096
+ color: task.configurationProperties.icon?.color || undefined,
1097
+ executable: executable,
1098
+ args: ( args.map(a => Types.isString(a) ? a : a.value)),
1099
+ waitOnExit
1100
+ };
1101
+ if (task.command.presentation && task.command.presentation.echo) {
1102
+ const getArgsToEcho = (args) => {
1103
+ if (!args || args.length === 0) {
1104
+ return '';
1105
+ }
1106
+ if (Types.isString(args)) {
1107
+ return args;
1108
+ }
1109
+ return args.join(' ');
1110
+ };
1111
+ if (needsFolderQualification && workspaceFolder) {
1112
+ shellLaunchConfig.initialText = this.taskShellIntegrationStartSequence(cwd) + formatMessageForTerminal(( nls.localizeWithPath('vs/workbench/contrib/tasks/browser/terminalTaskSystem', {
1113
+ key: 'task.executingInFolder',
1114
+ comment: ['The workspace folder the task is running in', 'The task command line or label']
1115
+ }, 'Executing task in folder {0}: {1}', workspaceFolder.name, `${shellLaunchConfig.executable} ${getArgsToEcho(shellLaunchConfig.args)}`)), { excludeLeadingNewLine: true }) + this.taskShellIntegrationOutputSequence;
1116
+ }
1117
+ else {
1118
+ shellLaunchConfig.initialText = this.taskShellIntegrationStartSequence(cwd) + formatMessageForTerminal(( nls.localizeWithPath('vs/workbench/contrib/tasks/browser/terminalTaskSystem', {
1119
+ key: 'task.executing.shell-integration',
1120
+ comment: ['The task command line or label']
1121
+ }, 'Executing task: {0}', `${shellLaunchConfig.executable} ${getArgsToEcho(shellLaunchConfig.args)}`)), { excludeLeadingNewLine: true }) + this.taskShellIntegrationOutputSequence;
1122
+ }
1123
+ }
1124
+ else {
1125
+ shellLaunchConfig.initialText = {
1126
+ text: this.taskShellIntegrationStartSequence(cwd) + this.taskShellIntegrationOutputSequence,
1127
+ trailingNewLine: false
1128
+ };
1129
+ }
1130
+ }
1131
+ if (cwd) {
1132
+ shellLaunchConfig.cwd = cwd;
1133
+ }
1134
+ if (options.env) {
1135
+ if (shellLaunchConfig.env) {
1136
+ shellLaunchConfig.env = { ...shellLaunchConfig.env, ...options.env };
1137
+ }
1138
+ else {
1139
+ shellLaunchConfig.env = options.env;
1140
+ }
1141
+ }
1142
+ shellLaunchConfig.isFeatureTerminal = true;
1143
+ shellLaunchConfig.useShellEnvironment = true;
1144
+ return shellLaunchConfig;
1145
+ }
1146
+ _addAllArgument(shellCommandArgs, configuredShellArgs) {
1147
+ const combinedShellArgs = Objects.deepClone(configuredShellArgs);
1148
+ shellCommandArgs.forEach(element => {
1149
+ const shouldAddShellCommandArg = configuredShellArgs.every((arg, index) => {
1150
+ if ((arg.toLowerCase() === element) && (configuredShellArgs.length > index + 1)) {
1151
+ return !configuredShellArgs.slice(index + 1).every(testArg => testArg.startsWith('-'));
1152
+ }
1153
+ else {
1154
+ return arg.toLowerCase() !== element;
1155
+ }
1156
+ });
1157
+ if (shouldAddShellCommandArg) {
1158
+ combinedShellArgs.push(element);
1159
+ }
1160
+ });
1161
+ return combinedShellArgs;
1162
+ }
1163
+ async _reconnectToTerminal(task) {
1164
+ if (!this._reconnectedTerminals) {
1165
+ return;
1166
+ }
1167
+ for (let i = 0; i < this._reconnectedTerminals.length; i++) {
1168
+ const terminal = this._reconnectedTerminals[i];
1169
+ if (getReconnectionData(terminal)?.lastTask === task.getCommonTaskId()) {
1170
+ this._reconnectedTerminals.splice(i, 1);
1171
+ return terminal;
1172
+ }
1173
+ }
1174
+ return undefined;
1175
+ }
1176
+ async _doCreateTerminal(task, group, launchConfigs) {
1177
+ const reconnectedTerminal = await this._reconnectToTerminal(task);
1178
+ const onDisposed = (terminal) => this._fireTaskEvent(TaskEvent.terminated(task, terminal.instanceId, terminal.exitReason));
1179
+ if (reconnectedTerminal) {
1180
+ if ('command' in task && task.command.presentation) {
1181
+ reconnectedTerminal.waitOnExit = getWaitOnExitValue(task.command.presentation, task.configurationProperties);
1182
+ }
1183
+ reconnectedTerminal.onDisposed(onDisposed);
1184
+ this._logService.trace('reconnected to task and terminal', task._id);
1185
+ return reconnectedTerminal;
1186
+ }
1187
+ if (group) {
1188
+ for (const terminal of ( Object.values(this._terminals))) {
1189
+ if (terminal.group === group) {
1190
+ this._logService.trace(`Found terminal to split for group ${group}`);
1191
+ const originalInstance = terminal.terminal;
1192
+ const result = await this._terminalService.createTerminal({ location: { parentTerminal: originalInstance }, config: launchConfigs });
1193
+ result.onDisposed(onDisposed);
1194
+ if (result) {
1195
+ return result;
1196
+ }
1197
+ }
1198
+ }
1199
+ this._logService.trace(`No terminal found to split for group ${group}`);
1200
+ }
1201
+ const createdTerminal = await this._terminalService.createTerminal({ config: launchConfigs });
1202
+ createdTerminal.onDisposed(onDisposed);
1203
+ return createdTerminal;
1204
+ }
1205
+ _reconnectToTerminals() {
1206
+ if (this._hasReconnected) {
1207
+ this._logService.trace(`Already reconnected, to ${this._reconnectedTerminals?.length} terminals so returning`);
1208
+ return;
1209
+ }
1210
+ this._reconnectedTerminals = this._terminalService.getReconnectedTerminals(ReconnectionType)?.filter(t => !t.isDisposed && getReconnectionData(t)) || [];
1211
+ this._logService.trace(`Attempting reconnection of ${this._reconnectedTerminals?.length} terminals`);
1212
+ if (!this._reconnectedTerminals?.length) {
1213
+ this._logService.trace(`No terminals to reconnect to so returning`);
1214
+ }
1215
+ else {
1216
+ for (const terminal of this._reconnectedTerminals) {
1217
+ const data = getReconnectionData(terminal);
1218
+ if (data) {
1219
+ const terminalData = { lastTask: data.lastTask, group: data.group, terminal };
1220
+ this._terminals[terminal.instanceId] = terminalData;
1221
+ this._logService.trace('Reconnecting to task terminal', terminalData.lastTask, terminal.instanceId);
1222
+ }
1223
+ }
1224
+ }
1225
+ this._hasReconnected = true;
1226
+ }
1227
+ _deleteTaskAndTerminal(terminal, terminalData) {
1228
+ delete this._terminals[terminal.instanceId];
1229
+ delete this._sameTaskTerminals[terminalData.lastTask];
1230
+ this._idleTaskTerminals.delete(terminalData.lastTask);
1231
+ const mapKey = terminalData.lastTask;
1232
+ this._removeFromActiveTasks(mapKey);
1233
+ if (this._busyTasks[mapKey]) {
1234
+ delete this._busyTasks[mapKey];
1235
+ }
1236
+ }
1237
+ async _createTerminal(task, resolver, workspaceFolder) {
1238
+ const platform$1 = resolver.taskSystemInfo ? resolver.taskSystemInfo.platform : platform.platform;
1239
+ const options = await this._resolveOptions(resolver, task.command.options);
1240
+ const presentationOptions = task.command.presentation;
1241
+ if (!presentationOptions) {
1242
+ throw new Error('Task presentation options should not be undefined here.');
1243
+ }
1244
+ const waitOnExit = getWaitOnExitValue(presentationOptions, task.configurationProperties);
1245
+ let command;
1246
+ let args;
1247
+ let launchConfigs;
1248
+ if (task.command.runtime === RuntimeType.CustomExecution) {
1249
+ this._currentTask.shellLaunchConfig = launchConfigs = {
1250
+ customPtyImplementation: (id, cols, rows) => ( new TerminalProcessExtHostProxy(id, cols, rows, this._terminalService)),
1251
+ waitOnExit,
1252
+ name: this._createTerminalName(task),
1253
+ initialText: task.command.presentation && task.command.presentation.echo ? formatMessageForTerminal(( nls.localizeWithPath('vs/workbench/contrib/tasks/browser/terminalTaskSystem', {
1254
+ key: 'task.executing',
1255
+ comment: ['The task command line or label']
1256
+ }, 'Executing task: {0}', task._label)), { excludeLeadingNewLine: true }) : undefined,
1257
+ isFeatureTerminal: true,
1258
+ icon: task.configurationProperties.icon?.id ? ThemeIcon.fromId(task.configurationProperties.icon.id) : undefined,
1259
+ color: task.configurationProperties.icon?.color || undefined
1260
+ };
1261
+ }
1262
+ else {
1263
+ const resolvedResult = await this._resolveCommandAndArgs(resolver, task.command);
1264
+ command = resolvedResult.command;
1265
+ args = resolvedResult.args;
1266
+ this._currentTask.shellLaunchConfig = launchConfigs = await this._createShellLaunchConfig(task, workspaceFolder, resolver, platform$1, options, command, args, waitOnExit);
1267
+ if (launchConfigs === undefined) {
1268
+ return [undefined, ( new TaskError(Severity.Error, ( nls.localizeWithPath(
1269
+ 'vs/workbench/contrib/tasks/browser/terminalTaskSystem',
1270
+ 'TerminalTaskSystem',
1271
+ 'Can\'t execute a shell command on an UNC drive using cmd.exe.'
1272
+ )), 7 ))];
1273
+ }
1274
+ }
1275
+ const prefersSameTerminal = presentationOptions.panel === PanelKind.Dedicated;
1276
+ const allowsSharedTerminal = presentationOptions.panel === PanelKind.Shared;
1277
+ const group = presentationOptions.group;
1278
+ const taskKey = task.getMapKey();
1279
+ let terminalToReuse;
1280
+ if (prefersSameTerminal) {
1281
+ const terminalId = this._sameTaskTerminals[taskKey];
1282
+ if (terminalId) {
1283
+ terminalToReuse = this._terminals[terminalId];
1284
+ delete this._sameTaskTerminals[taskKey];
1285
+ }
1286
+ }
1287
+ else if (allowsSharedTerminal) {
1288
+ let terminalId = this._idleTaskTerminals.remove(taskKey);
1289
+ if (!terminalId) {
1290
+ for (const taskId of ( this._idleTaskTerminals.keys())) {
1291
+ const idleTerminalId = this._idleTaskTerminals.get(taskId);
1292
+ if (idleTerminalId && this._terminals[idleTerminalId] && this._terminals[idleTerminalId].group === group) {
1293
+ terminalId = this._idleTaskTerminals.remove(taskId);
1294
+ break;
1295
+ }
1296
+ }
1297
+ }
1298
+ if (terminalId) {
1299
+ terminalToReuse = this._terminals[terminalId];
1300
+ }
1301
+ }
1302
+ if (terminalToReuse) {
1303
+ if (!launchConfigs) {
1304
+ throw new Error('Task shell launch configuration should not be undefined here.');
1305
+ }
1306
+ terminalToReuse.terminal.scrollToBottom();
1307
+ if (task.configurationProperties.isBackground) {
1308
+ launchConfigs.reconnectionProperties = { ownerId: ReconnectionType, data: { lastTask: task.getCommonTaskId(), group, label: task._label, id: task._id } };
1309
+ }
1310
+ await terminalToReuse.terminal.reuseTerminal(launchConfigs);
1311
+ if (task.command.presentation && task.command.presentation.clear) {
1312
+ terminalToReuse.terminal.clearBuffer();
1313
+ }
1314
+ this._terminals[( terminalToReuse.terminal.instanceId.toString())].lastTask = taskKey;
1315
+ return [terminalToReuse.terminal, undefined];
1316
+ }
1317
+ this._terminalCreationQueue = this._terminalCreationQueue.then(() => this._doCreateTerminal(task, group, launchConfigs));
1318
+ const terminal = (await this._terminalCreationQueue);
1319
+ if (task.configurationProperties.isBackground) {
1320
+ terminal.shellLaunchConfig.reconnectionProperties = { ownerId: ReconnectionType, data: { lastTask: task.getCommonTaskId(), group, label: task._label, id: task._id } };
1321
+ }
1322
+ const terminalKey = ( terminal.instanceId.toString());
1323
+ const terminalData = { terminal: terminal, lastTask: taskKey, group };
1324
+ terminal.onDisposed(() => this._deleteTaskAndTerminal(terminal, terminalData));
1325
+ this._terminals[terminalKey] = terminalData;
1326
+ return [terminal, undefined];
1327
+ }
1328
+ _buildShellCommandLine(platform, shellExecutable, shellOptions, command, originalCommand, args) {
1329
+ const basename = path.parse(shellExecutable).name.toLowerCase();
1330
+ const shellQuoteOptions = this._getQuotingOptions(basename, shellOptions, platform);
1331
+ function needsQuotes(value) {
1332
+ if (value.length >= 2) {
1333
+ const first = value[0] === shellQuoteOptions.strong ? shellQuoteOptions.strong : value[0] === shellQuoteOptions.weak ? shellQuoteOptions.weak : undefined;
1334
+ if (first === value[value.length - 1]) {
1335
+ return false;
1336
+ }
1337
+ }
1338
+ let quote;
1339
+ for (let i = 0; i < value.length; i++) {
1340
+ const ch = value[i];
1341
+ if (ch === quote) {
1342
+ quote = undefined;
1343
+ }
1344
+ else if (quote !== undefined) {
1345
+ continue;
1346
+ }
1347
+ else if (ch === shellQuoteOptions.escape) {
1348
+ i++;
1349
+ }
1350
+ else if (ch === shellQuoteOptions.strong || ch === shellQuoteOptions.weak) {
1351
+ quote = ch;
1352
+ }
1353
+ else if (ch === ' ') {
1354
+ return true;
1355
+ }
1356
+ }
1357
+ return false;
1358
+ }
1359
+ function quote(value, kind) {
1360
+ if (kind === ShellQuoting.Strong && shellQuoteOptions.strong) {
1361
+ return [shellQuoteOptions.strong + value + shellQuoteOptions.strong, true];
1362
+ }
1363
+ else if (kind === ShellQuoting.Weak && shellQuoteOptions.weak) {
1364
+ return [shellQuoteOptions.weak + value + shellQuoteOptions.weak, true];
1365
+ }
1366
+ else if (kind === ShellQuoting.Escape && shellQuoteOptions.escape) {
1367
+ if (Types.isString(shellQuoteOptions.escape)) {
1368
+ return [value.replace(/ /g, shellQuoteOptions.escape + ' '), true];
1369
+ }
1370
+ else {
1371
+ const buffer = [];
1372
+ for (const ch of shellQuoteOptions.escape.charsToEscape) {
1373
+ buffer.push(`\\${ch}`);
1374
+ }
1375
+ const regexp = ( new RegExp('[' + buffer.join(',') + ']', 'g'));
1376
+ const escapeChar = shellQuoteOptions.escape.escapeChar;
1377
+ return [value.replace(regexp, (match) => escapeChar + match), true];
1378
+ }
1379
+ }
1380
+ return [value, false];
1381
+ }
1382
+ function quoteIfNecessary(value) {
1383
+ if (Types.isString(value)) {
1384
+ if (needsQuotes(value)) {
1385
+ return quote(value, ShellQuoting.Strong);
1386
+ }
1387
+ else {
1388
+ return [value, false];
1389
+ }
1390
+ }
1391
+ else {
1392
+ return quote(value.value, value.quoting);
1393
+ }
1394
+ }
1395
+ if ((!args || args.length === 0) && Types.isString(command) && (command === originalCommand || needsQuotes(originalCommand))) {
1396
+ return command;
1397
+ }
1398
+ const result = [];
1399
+ let commandQuoted = false;
1400
+ let argQuoted = false;
1401
+ let value;
1402
+ let quoted;
1403
+ [value, quoted] = quoteIfNecessary(command);
1404
+ result.push(value);
1405
+ commandQuoted = quoted;
1406
+ for (const arg of args) {
1407
+ [value, quoted] = quoteIfNecessary(arg);
1408
+ result.push(value);
1409
+ argQuoted = argQuoted || quoted;
1410
+ }
1411
+ let commandLine = result.join(' ');
1412
+ if (platform === 3 ) {
1413
+ if (basename === 'cmd' && commandQuoted && argQuoted) {
1414
+ commandLine = '"' + commandLine + '"';
1415
+ }
1416
+ else if ((basename === 'powershell' || basename === 'pwsh') && commandQuoted) {
1417
+ commandLine = '& ' + commandLine;
1418
+ }
1419
+ }
1420
+ return commandLine;
1421
+ }
1422
+ _getQuotingOptions(shellBasename, shellOptions, platform$1) {
1423
+ if (shellOptions && shellOptions.quoting) {
1424
+ return shellOptions.quoting;
1425
+ }
1426
+ return TerminalTaskSystem._shellQuotes[shellBasename] || TerminalTaskSystem._osShellQuotes[platform.PlatformToString(platform$1)];
1427
+ }
1428
+ _collectTaskVariables(variables, task) {
1429
+ if (task.command && task.command.name) {
1430
+ this._collectCommandVariables(variables, task.command, task);
1431
+ }
1432
+ this._collectMatcherVariables(variables, task.configurationProperties.problemMatchers);
1433
+ if (task.command.runtime === RuntimeType.CustomExecution && (CustomTask.is(task) || ContributedTask.is(task))) {
1434
+ let definition;
1435
+ if (CustomTask.is(task)) {
1436
+ definition = task._source.config.element;
1437
+ }
1438
+ else {
1439
+ definition = Objects.deepClone(task.defines);
1440
+ delete definition._key;
1441
+ delete definition.type;
1442
+ }
1443
+ this._collectDefinitionVariables(variables, definition);
1444
+ }
1445
+ }
1446
+ _collectDefinitionVariables(variables, definition) {
1447
+ if (Types.isString(definition)) {
1448
+ this._collectVariables(variables, definition);
1449
+ }
1450
+ else if (Array.isArray(definition)) {
1451
+ definition.forEach((element) => this._collectDefinitionVariables(variables, element));
1452
+ }
1453
+ else if (Types.isObject(definition)) {
1454
+ for (const key in definition) {
1455
+ this._collectDefinitionVariables(variables, definition[key]);
1456
+ }
1457
+ }
1458
+ }
1459
+ _collectCommandVariables(variables, command, task) {
1460
+ if (command.runtime === RuntimeType.CustomExecution) {
1461
+ return;
1462
+ }
1463
+ if (command.name === undefined) {
1464
+ throw new Error('Command name should never be undefined here.');
1465
+ }
1466
+ this._collectVariables(variables, command.name);
1467
+ command.args?.forEach(arg => this._collectVariables(variables, arg));
1468
+ const scope = task._source.scope;
1469
+ if (scope !== 1 ) {
1470
+ variables.add('${workspaceFolder}');
1471
+ }
1472
+ if (command.options) {
1473
+ const options = command.options;
1474
+ if (options.cwd) {
1475
+ this._collectVariables(variables, options.cwd);
1476
+ }
1477
+ const optionsEnv = options.env;
1478
+ if (optionsEnv) {
1479
+ ( Object.keys(optionsEnv)).forEach((key) => {
1480
+ const value = optionsEnv[key];
1481
+ if (Types.isString(value)) {
1482
+ this._collectVariables(variables, value);
1483
+ }
1484
+ });
1485
+ }
1486
+ if (options.shell) {
1487
+ if (options.shell.executable) {
1488
+ this._collectVariables(variables, options.shell.executable);
1489
+ }
1490
+ options.shell.args?.forEach(arg => this._collectVariables(variables, arg));
1491
+ }
1492
+ }
1493
+ }
1494
+ _collectMatcherVariables(variables, values) {
1495
+ if (values === undefined || values === null || values.length === 0) {
1496
+ return;
1497
+ }
1498
+ values.forEach((value) => {
1499
+ let matcher;
1500
+ if (Types.isString(value)) {
1501
+ if (value[0] === '$') {
1502
+ matcher = ProblemMatcherRegistry.get(value.substring(1));
1503
+ }
1504
+ else {
1505
+ matcher = ProblemMatcherRegistry.get(value);
1506
+ }
1507
+ }
1508
+ else {
1509
+ matcher = value;
1510
+ }
1511
+ if (matcher && matcher.filePrefix) {
1512
+ if (Types.isString(matcher.filePrefix)) {
1513
+ this._collectVariables(variables, matcher.filePrefix);
1514
+ }
1515
+ else {
1516
+ for (const fp of [...asArray(matcher.filePrefix.include || []), ...asArray(matcher.filePrefix.exclude || [])]) {
1517
+ this._collectVariables(variables, fp);
1518
+ }
1519
+ }
1520
+ }
1521
+ });
1522
+ }
1523
+ _collectVariables(variables, value) {
1524
+ const string = Types.isString(value) ? value : value.value;
1525
+ const r = /\$\{(.*?)\}/g;
1526
+ let matches;
1527
+ do {
1528
+ matches = r.exec(string);
1529
+ if (matches) {
1530
+ variables.add(matches[0]);
1531
+ }
1532
+ } while (matches);
1533
+ }
1534
+ async _resolveCommandAndArgs(resolver, commandConfig) {
1535
+ let args = commandConfig.args ? commandConfig.args.slice() : [];
1536
+ args = await this._resolveVariables(resolver, args);
1537
+ const command = await this._resolveVariable(resolver, commandConfig.name);
1538
+ return { command, args };
1539
+ }
1540
+ async _resolveVariables(resolver, value) {
1541
+ return Promise.all(( value.map(s => this._resolveVariable(resolver, s))));
1542
+ }
1543
+ async _resolveMatchers(resolver, values) {
1544
+ if (values === undefined || values === null || values.length === 0) {
1545
+ return [];
1546
+ }
1547
+ const result = [];
1548
+ for (const value of values) {
1549
+ let matcher;
1550
+ if (Types.isString(value)) {
1551
+ if (value[0] === '$') {
1552
+ matcher = ProblemMatcherRegistry.get(value.substring(1));
1553
+ }
1554
+ else {
1555
+ matcher = ProblemMatcherRegistry.get(value);
1556
+ }
1557
+ }
1558
+ else {
1559
+ matcher = value;
1560
+ }
1561
+ if (!matcher) {
1562
+ this._appendOutput(( nls.localizeWithPath(
1563
+ 'vs/workbench/contrib/tasks/browser/terminalTaskSystem',
1564
+ 'unknownProblemMatcher',
1565
+ 'Problem matcher {0} can\'t be resolved. The matcher will be ignored'
1566
+ )));
1567
+ continue;
1568
+ }
1569
+ const taskSystemInfo = resolver.taskSystemInfo;
1570
+ const hasFilePrefix = matcher.filePrefix !== undefined;
1571
+ const hasUriProvider = taskSystemInfo !== undefined && taskSystemInfo.uriProvider !== undefined;
1572
+ if (!hasFilePrefix && !hasUriProvider) {
1573
+ result.push(matcher);
1574
+ }
1575
+ else {
1576
+ const copy = Objects.deepClone(matcher);
1577
+ if (hasUriProvider && (taskSystemInfo !== undefined)) {
1578
+ copy.uriProvider = taskSystemInfo.uriProvider;
1579
+ }
1580
+ if (hasFilePrefix) {
1581
+ const filePrefix = copy.filePrefix;
1582
+ if (Types.isString(filePrefix)) {
1583
+ copy.filePrefix = await this._resolveVariable(resolver, filePrefix);
1584
+ }
1585
+ else if (filePrefix !== undefined) {
1586
+ if (filePrefix.include) {
1587
+ filePrefix.include = Array.isArray(filePrefix.include)
1588
+ ? await Promise.all(( filePrefix.include.map(x => this._resolveVariable(resolver, x))))
1589
+ : await this._resolveVariable(resolver, filePrefix.include);
1590
+ }
1591
+ if (filePrefix.exclude) {
1592
+ filePrefix.exclude = Array.isArray(filePrefix.exclude)
1593
+ ? await Promise.all(( filePrefix.exclude.map(x => this._resolveVariable(resolver, x))))
1594
+ : await this._resolveVariable(resolver, filePrefix.exclude);
1595
+ }
1596
+ }
1597
+ }
1598
+ result.push(copy);
1599
+ }
1600
+ }
1601
+ return result;
1602
+ }
1603
+ async _resolveVariable(resolver, value) {
1604
+ if (Types.isString(value)) {
1605
+ return resolver.resolve(value);
1606
+ }
1607
+ else if (value !== undefined) {
1608
+ return {
1609
+ value: await resolver.resolve(value.value),
1610
+ quoting: value.quoting
1611
+ };
1612
+ }
1613
+ else {
1614
+ throw new Error('Should never try to resolve undefined.');
1615
+ }
1616
+ }
1617
+ async _resolveOptions(resolver, options) {
1618
+ if (options === undefined || options === null) {
1619
+ let cwd;
1620
+ try {
1621
+ cwd = await this._resolveVariable(resolver, '${workspaceFolder}');
1622
+ }
1623
+ catch (e) {
1624
+ }
1625
+ return { cwd };
1626
+ }
1627
+ const result = Types.isString(options.cwd)
1628
+ ? { cwd: await this._resolveVariable(resolver, options.cwd) }
1629
+ : { cwd: await this._resolveVariable(resolver, '${workspaceFolder}') };
1630
+ if (options.env) {
1631
+ result.env = Object.create(null);
1632
+ for (const key of ( Object.keys(options.env))) {
1633
+ const value = options.env[key];
1634
+ if (Types.isString(value)) {
1635
+ result.env[key] = await this._resolveVariable(resolver, value);
1636
+ }
1637
+ else {
1638
+ result.env[key] = ( value.toString());
1639
+ }
1640
+ }
1641
+ }
1642
+ return result;
1643
+ }
1644
+ static { this.WellKnownCommands = {
1645
+ 'ant': true,
1646
+ 'cmake': true,
1647
+ 'eslint': true,
1648
+ 'gradle': true,
1649
+ 'grunt': true,
1650
+ 'gulp': true,
1651
+ 'jake': true,
1652
+ 'jenkins': true,
1653
+ 'jshint': true,
1654
+ 'make': true,
1655
+ 'maven': true,
1656
+ 'msbuild': true,
1657
+ 'msc': true,
1658
+ 'nmake': true,
1659
+ 'npm': true,
1660
+ 'rake': true,
1661
+ 'tsc': true,
1662
+ 'xbuild': true
1663
+ }; }
1664
+ getSanitizedCommand(cmd) {
1665
+ let result = cmd.toLowerCase();
1666
+ const index = result.lastIndexOf(path.sep);
1667
+ if (index !== -1) {
1668
+ result = result.substring(index + 1);
1669
+ }
1670
+ if (TerminalTaskSystem.WellKnownCommands[result]) {
1671
+ return result;
1672
+ }
1673
+ return 'other';
1674
+ }
1675
+ _appendOutput(output) {
1676
+ const outputChannel = this._outputService.getChannel(this._outputChannelId);
1677
+ outputChannel?.append(output);
1678
+ }
1679
+ }
1680
+ function getWaitOnExitValue(presentationOptions, configurationProperties) {
1681
+ if ((presentationOptions.close === undefined) || (presentationOptions.close === false)) {
1682
+ if ((presentationOptions.reveal !== RevealKind.Never) || !configurationProperties.isBackground || (presentationOptions.close === false)) {
1683
+ if (presentationOptions.panel === PanelKind.New) {
1684
+ return taskShellIntegrationWaitOnExitSequence(( nls.localizeWithPath(
1685
+ 'vs/workbench/contrib/tasks/browser/terminalTaskSystem',
1686
+ 'closeTerminal',
1687
+ 'Press any key to close the terminal.'
1688
+ )));
1689
+ }
1690
+ else if (presentationOptions.showReuseMessage) {
1691
+ return taskShellIntegrationWaitOnExitSequence(( nls.localizeWithPath(
1692
+ 'vs/workbench/contrib/tasks/browser/terminalTaskSystem',
1693
+ 'reuseTerminal',
1694
+ 'Terminal will be reused by tasks, press any key to close it.'
1695
+ )));
1696
+ }
1697
+ else {
1698
+ return true;
1699
+ }
1700
+ }
1701
+ }
1702
+ return !presentationOptions.close;
1703
+ }
1704
+ function taskShellIntegrationWaitOnExitSequence(message) {
1705
+ return (exitCode) => {
1706
+ return `${VSCodeSequence("D" , ( exitCode.toString()))}${message}`;
1707
+ };
1708
+ }
1709
+ function getReconnectionData(terminal) {
1710
+ return terminal.shellLaunchConfig.attachPersistentProcess?.reconnectionProperties?.data;
1711
+ }
1712
+
1713
+ export { TerminalTaskSystem };