@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.
- package/external/tslib/tslib.es6.js +11 -0
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/override/vs/platform/dialogs/common/dialogs.js +8 -0
- package/package.json +24 -0
- package/task.d.ts +5 -0
- package/task.js +12 -0
- package/vscode/src/vs/base/common/parsers.js +44 -0
- package/vscode/src/vs/workbench/contrib/tasks/browser/abstractTaskService.js +3851 -0
- package/vscode/src/vs/workbench/contrib/tasks/browser/runAutomaticTasks.js +167 -0
- package/vscode/src/vs/workbench/contrib/tasks/browser/task.contribution.js +694 -0
- package/vscode/src/vs/workbench/contrib/tasks/browser/taskQuickPick.js +452 -0
- package/vscode/src/vs/workbench/contrib/tasks/browser/taskService.js +36 -0
- package/vscode/src/vs/workbench/contrib/tasks/browser/taskTerminalStatus.js +191 -0
- package/vscode/src/vs/workbench/contrib/tasks/browser/tasksQuickAccess.js +121 -0
- package/vscode/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.js +1713 -0
- package/vscode/src/vs/workbench/contrib/tasks/common/jsonSchemaCommon.js +440 -0
- package/vscode/src/vs/workbench/contrib/tasks/common/jsonSchema_v1.js +125 -0
- package/vscode/src/vs/workbench/contrib/tasks/common/jsonSchema_v2.js +901 -0
- package/vscode/src/vs/workbench/contrib/tasks/common/problemCollectors.js +464 -0
- package/vscode/src/vs/workbench/contrib/tasks/common/problemMatcher.js +1796 -0
- package/vscode/src/vs/workbench/contrib/tasks/common/taskConfiguration.js +1581 -0
- package/vscode/src/vs/workbench/contrib/tasks/common/taskSystem.js +15 -0
- package/vscode/src/vs/workbench/contrib/tasks/common/taskTemplates.js +145 -0
- package/vscode/src/vs/workbench/contrib/terminal/browser/terminalEscapeSequences.js +13 -0
|
@@ -0,0 +1,3851 @@
|
|
|
1
|
+
import { __decorate, __param } from '../../../../../../../external/tslib/tslib.es6.js';
|
|
2
|
+
import { Action } from 'monaco-editor/esm/vs/base/common/actions.js';
|
|
3
|
+
import { Emitter, Event } from 'monaco-editor/esm/vs/base/common/event.js';
|
|
4
|
+
import * as glob from 'monaco-editor/esm/vs/base/common/glob.js';
|
|
5
|
+
import * as json from 'monaco-editor/esm/vs/base/common/json.js';
|
|
6
|
+
import { Disposable, dispose } from 'monaco-editor/esm/vs/base/common/lifecycle.js';
|
|
7
|
+
import { LRUCache } from 'monaco-editor/esm/vs/base/common/map.js';
|
|
8
|
+
import * as Objects from 'monaco-editor/esm/vs/base/common/objects.js';
|
|
9
|
+
import { ValidationStatus } from '../../../../base/common/parsers.js';
|
|
10
|
+
import * as platform from 'monaco-editor/esm/vs/base/common/platform.js';
|
|
11
|
+
import * as resources from 'monaco-editor/esm/vs/base/common/resources.js';
|
|
12
|
+
import Severity from 'monaco-editor/esm/vs/base/common/severity.js';
|
|
13
|
+
import * as Types from 'monaco-editor/esm/vs/base/common/types.js';
|
|
14
|
+
import { URI } from 'monaco-editor/esm/vs/base/common/uri.js';
|
|
15
|
+
import * as UUID from 'monaco-editor/esm/vs/base/common/uuid.js';
|
|
16
|
+
import * as nls from 'monaco-editor/esm/vs/nls.js';
|
|
17
|
+
import { CommandsRegistry, ICommandService } from 'monaco-editor/esm/vs/platform/commands/common/commands.js';
|
|
18
|
+
import { IConfigurationService } from 'monaco-editor/esm/vs/platform/configuration/common/configuration.js';
|
|
19
|
+
import { IFileService } from 'monaco-editor/esm/vs/platform/files/common/files.js';
|
|
20
|
+
import { IMarkerService } from 'monaco-editor/esm/vs/platform/markers/common/markers.js';
|
|
21
|
+
import { IProgressService } from 'monaco-editor/esm/vs/platform/progress/common/progress.js';
|
|
22
|
+
import { IStorageService } from 'monaco-editor/esm/vs/platform/storage/common/storage.js';
|
|
23
|
+
import { ITelemetryService } from 'monaco-editor/esm/vs/platform/telemetry/common/telemetry.js';
|
|
24
|
+
import { ProblemMatcherRegistry } from '../common/problemMatcher.js';
|
|
25
|
+
import { IExtensionService } from 'vscode/vscode/vs/workbench/services/extensions/common/extensions';
|
|
26
|
+
import '../../../../../../../override/vs/platform/dialogs/common/dialogs.js';
|
|
27
|
+
import { INotificationService } from 'monaco-editor/esm/vs/platform/notification/common/notification.js';
|
|
28
|
+
import { IOpenerService } from 'monaco-editor/esm/vs/platform/opener/common/opener.js';
|
|
29
|
+
import { IModelService } from 'monaco-editor/esm/vs/editor/common/services/model.js';
|
|
30
|
+
import { WorkspaceFolder, IWorkspaceContextService } from 'monaco-editor/esm/vs/platform/workspace/common/workspace.js';
|
|
31
|
+
import { Markers } from 'vscode/vscode/vs/workbench/contrib/markers/common/markers';
|
|
32
|
+
import { IConfigurationResolverService } from 'vscode/vscode/vs/workbench/services/configurationResolver/common/configurationResolver';
|
|
33
|
+
import { IEditorService } from 'vscode/vscode/vs/workbench/services/editor/common/editorService';
|
|
34
|
+
import { IOutputService } from 'vscode/vscode/vs/workbench/services/output/common/output';
|
|
35
|
+
import { ITextFileService } from 'vscode/vscode/vs/workbench/services/textfile/common/textfiles';
|
|
36
|
+
import { ITerminalService, ITerminalGroupService } from 'vscode/vscode/vs/workbench/contrib/terminal/browser/terminal';
|
|
37
|
+
import { ITerminalProfileResolverService } from 'vscode/vscode/vs/workbench/contrib/terminal/common/terminal';
|
|
38
|
+
import { TASK_RUNNING_STATE, TaskGroup, ConfiguringTask, TaskSourceKind, TaskDefinition, USER_TASKS_GROUP_KEY, ContributedTask, CustomTask, TaskSorter, InMemoryTask, KeyedTaskIdentifier, ExecutionEngine, RuntimeType } from 'vscode/vscode/vs/workbench/contrib/tasks/common/tasks';
|
|
39
|
+
import { TaskCommandsRegistered, ServerlessWebContext, CustomExecutionSupportedContext, ShellExecutionSupportedContext, ProcessExecutionSupportedContext, TaskExecutionSupportedContext } from 'vscode/vscode/vs/workbench/contrib/tasks/common/taskService';
|
|
40
|
+
import { TaskError } from '../common/taskSystem.js';
|
|
41
|
+
import { getTemplates } from '../common/taskTemplates.js';
|
|
42
|
+
import { createCustomTask, TaskConfigSource, GroupKind, parse, ExecutionEngine as ExecutionEngine$1, JsonSchemaVersion } from '../common/taskConfiguration.js';
|
|
43
|
+
import { TerminalTaskSystem } from './terminalTaskSystem.js';
|
|
44
|
+
import { IQuickInputService } from 'monaco-editor/esm/vs/platform/quickinput/common/quickInput.js';
|
|
45
|
+
import { IContextKeyService } from 'monaco-editor/esm/vs/platform/contextkey/common/contextkey.js';
|
|
46
|
+
import { TaskDefinitionRegistry } from 'vscode/vscode/vs/workbench/contrib/tasks/common/taskDefinitionRegistry';
|
|
47
|
+
import { raceTimeout } from 'monaco-editor/esm/vs/base/common/async.js';
|
|
48
|
+
import { CancellationTokenSource } from 'monaco-editor/esm/vs/base/common/cancellation.js';
|
|
49
|
+
import { toFormattedString } from 'vscode/vscode/vs/base/common/jsonFormatter';
|
|
50
|
+
import { Schemas } from 'monaco-editor/esm/vs/base/common/network.js';
|
|
51
|
+
import { ThemeIcon } from 'monaco-editor/esm/vs/base/common/themables.js';
|
|
52
|
+
import { ITextModelService } from 'monaco-editor/esm/vs/editor/common/services/resolverService.js';
|
|
53
|
+
import { IInstantiationService } from 'monaco-editor/esm/vs/platform/instantiation/common/instantiation.js';
|
|
54
|
+
import { ILogService } from 'monaco-editor/esm/vs/platform/log/common/log.js';
|
|
55
|
+
import { TerminalExitReason } from 'vscode/vscode/vs/platform/terminal/common/terminal';
|
|
56
|
+
import { IThemeService } from 'monaco-editor/esm/vs/platform/theme/common/themeService.js';
|
|
57
|
+
import { IWorkspaceTrustRequestService, IWorkspaceTrustManagementService } from 'monaco-editor/esm/vs/platform/workspace/common/workspaceTrust.js';
|
|
58
|
+
import { VirtualWorkspaceContext } from 'vscode/vscode/vs/workbench/common/contextkeys';
|
|
59
|
+
import { EditorResourceAccessor } from 'vscode/vscode/vs/workbench/common/editor';
|
|
60
|
+
import { IViewsService, IViewDescriptorService } from 'vscode/vscode/vs/workbench/common/views';
|
|
61
|
+
import { isWorkspaceFolder, QUICKOPEN_DETAIL_CONFIG, TaskQuickPick, QUICKOPEN_SKIP_CONFIG, configureTaskIcon } from './taskQuickPick.js';
|
|
62
|
+
import { IWorkbenchEnvironmentService } from 'vscode/vscode/vs/workbench/services/environment/common/environmentService';
|
|
63
|
+
import { ILifecycleService } from 'vscode/vscode/vs/workbench/services/lifecycle/common/lifecycle';
|
|
64
|
+
import { IPaneCompositePartService } from 'vscode/vscode/vs/workbench/services/panecomposite/browser/panecomposite';
|
|
65
|
+
import { IPathService } from 'vscode/vscode/vs/workbench/services/path/common/pathService';
|
|
66
|
+
import { IPreferencesService } from 'vscode/vscode/vs/workbench/services/preferences/common/preferences';
|
|
67
|
+
import { IRemoteAgentService } from 'vscode/vscode/vs/workbench/services/remote/common/remoteAgentService';
|
|
68
|
+
import { IDialogService } from 'vscode/vscode/vs/platform/dialogs/common/dialogs';
|
|
69
|
+
|
|
70
|
+
var AbstractTaskService_1;
|
|
71
|
+
const QUICKOPEN_HISTORY_LIMIT_CONFIG = 'task.quickOpen.history';
|
|
72
|
+
const PROBLEM_MATCHER_NEVER_CONFIG = 'task.problemMatchers.neverPrompt';
|
|
73
|
+
const USE_SLOW_PICKER = 'task.quickOpen.showAll';
|
|
74
|
+
var ConfigureTaskAction;
|
|
75
|
+
( (function(ConfigureTaskAction) {
|
|
76
|
+
ConfigureTaskAction.ID = 'workbench.action.tasks.configureTaskRunner';
|
|
77
|
+
ConfigureTaskAction.TEXT = ( nls.localizeWithPath(
|
|
78
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
79
|
+
'ConfigureTaskRunnerAction.label',
|
|
80
|
+
"Configure Task"
|
|
81
|
+
));
|
|
82
|
+
})(ConfigureTaskAction || (ConfigureTaskAction = {})));
|
|
83
|
+
class ProblemReporter {
|
|
84
|
+
constructor(_outputChannel) {
|
|
85
|
+
this._outputChannel = _outputChannel;
|
|
86
|
+
this._validationStatus = ( new ValidationStatus());
|
|
87
|
+
}
|
|
88
|
+
info(message) {
|
|
89
|
+
this._validationStatus.state = 1 ;
|
|
90
|
+
this._outputChannel.append(message + '\n');
|
|
91
|
+
}
|
|
92
|
+
warn(message) {
|
|
93
|
+
this._validationStatus.state = 2 ;
|
|
94
|
+
this._outputChannel.append(message + '\n');
|
|
95
|
+
}
|
|
96
|
+
error(message) {
|
|
97
|
+
this._validationStatus.state = 3 ;
|
|
98
|
+
this._outputChannel.append(message + '\n');
|
|
99
|
+
}
|
|
100
|
+
fatal(message) {
|
|
101
|
+
this._validationStatus.state = 4 ;
|
|
102
|
+
this._outputChannel.append(message + '\n');
|
|
103
|
+
}
|
|
104
|
+
get status() {
|
|
105
|
+
return this._validationStatus;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
class TaskMap {
|
|
109
|
+
constructor() {
|
|
110
|
+
this._store = ( new Map());
|
|
111
|
+
}
|
|
112
|
+
forEach(callback) {
|
|
113
|
+
this._store.forEach(callback);
|
|
114
|
+
}
|
|
115
|
+
static getKey(workspaceFolder) {
|
|
116
|
+
let key;
|
|
117
|
+
if (Types.isString(workspaceFolder)) {
|
|
118
|
+
key = workspaceFolder;
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
const uri = isWorkspaceFolder(workspaceFolder) ? workspaceFolder.uri : workspaceFolder.configuration;
|
|
122
|
+
key = uri ? ( uri.toString()) : '';
|
|
123
|
+
}
|
|
124
|
+
return key;
|
|
125
|
+
}
|
|
126
|
+
get(workspaceFolder) {
|
|
127
|
+
const key = TaskMap.getKey(workspaceFolder);
|
|
128
|
+
let result = this._store.get(key);
|
|
129
|
+
if (!result) {
|
|
130
|
+
result = [];
|
|
131
|
+
this._store.set(key, result);
|
|
132
|
+
}
|
|
133
|
+
return result;
|
|
134
|
+
}
|
|
135
|
+
add(workspaceFolder, ...task) {
|
|
136
|
+
const key = TaskMap.getKey(workspaceFolder);
|
|
137
|
+
let values = this._store.get(key);
|
|
138
|
+
if (!values) {
|
|
139
|
+
values = [];
|
|
140
|
+
this._store.set(key, values);
|
|
141
|
+
}
|
|
142
|
+
values.push(...task);
|
|
143
|
+
}
|
|
144
|
+
all() {
|
|
145
|
+
const result = [];
|
|
146
|
+
this._store.forEach((values) => result.push(...values));
|
|
147
|
+
return result;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
let AbstractTaskService = class AbstractTaskService extends Disposable {
|
|
151
|
+
static { AbstractTaskService_1 = this; }
|
|
152
|
+
static { this.RecentlyUsedTasks_Key = 'workbench.tasks.recentlyUsedTasks'; }
|
|
153
|
+
static { this.RecentlyUsedTasks_KeyV2 = 'workbench.tasks.recentlyUsedTasks2'; }
|
|
154
|
+
static { this.PersistentTasks_Key = 'workbench.tasks.persistentTasks'; }
|
|
155
|
+
static { this.IgnoreTask010DonotShowAgain_key = 'workbench.tasks.ignoreTask010Shown'; }
|
|
156
|
+
static { this.OutputChannelId = 'tasks'; }
|
|
157
|
+
static { this.OutputChannelLabel = ( nls.localizeWithPath('vs/workbench/contrib/tasks/browser/abstractTaskService', 'tasks', "Tasks")); }
|
|
158
|
+
static { this._nextHandle = 0; }
|
|
159
|
+
get isReconnected() { return this._tasksReconnected; }
|
|
160
|
+
constructor(_configurationService, _markerService, _outputService, _paneCompositeService, _viewsService, _commandService, _editorService, _fileService, _contextService, _telemetryService, _textFileService, _modelService, _extensionService, _quickInputService, _configurationResolverService, _terminalService, _terminalGroupService, _storageService, _progressService, _openerService, _dialogService, _notificationService, _contextKeyService, _environmentService, _terminalProfileResolverService, _pathService, _textModelResolverService, _preferencesService, _viewDescriptorService, _workspaceTrustRequestService, _workspaceTrustManagementService, _logService, _themeService, _lifecycleService, remoteAgentService, _instantiationService) {
|
|
161
|
+
super();
|
|
162
|
+
this._configurationService = _configurationService;
|
|
163
|
+
this._markerService = _markerService;
|
|
164
|
+
this._outputService = _outputService;
|
|
165
|
+
this._paneCompositeService = _paneCompositeService;
|
|
166
|
+
this._viewsService = _viewsService;
|
|
167
|
+
this._commandService = _commandService;
|
|
168
|
+
this._editorService = _editorService;
|
|
169
|
+
this._fileService = _fileService;
|
|
170
|
+
this._contextService = _contextService;
|
|
171
|
+
this._telemetryService = _telemetryService;
|
|
172
|
+
this._textFileService = _textFileService;
|
|
173
|
+
this._modelService = _modelService;
|
|
174
|
+
this._extensionService = _extensionService;
|
|
175
|
+
this._quickInputService = _quickInputService;
|
|
176
|
+
this._configurationResolverService = _configurationResolverService;
|
|
177
|
+
this._terminalService = _terminalService;
|
|
178
|
+
this._terminalGroupService = _terminalGroupService;
|
|
179
|
+
this._storageService = _storageService;
|
|
180
|
+
this._progressService = _progressService;
|
|
181
|
+
this._openerService = _openerService;
|
|
182
|
+
this._dialogService = _dialogService;
|
|
183
|
+
this._notificationService = _notificationService;
|
|
184
|
+
this._contextKeyService = _contextKeyService;
|
|
185
|
+
this._environmentService = _environmentService;
|
|
186
|
+
this._terminalProfileResolverService = _terminalProfileResolverService;
|
|
187
|
+
this._pathService = _pathService;
|
|
188
|
+
this._textModelResolverService = _textModelResolverService;
|
|
189
|
+
this._preferencesService = _preferencesService;
|
|
190
|
+
this._viewDescriptorService = _viewDescriptorService;
|
|
191
|
+
this._workspaceTrustRequestService = _workspaceTrustRequestService;
|
|
192
|
+
this._workspaceTrustManagementService = _workspaceTrustManagementService;
|
|
193
|
+
this._logService = _logService;
|
|
194
|
+
this._themeService = _themeService;
|
|
195
|
+
this._lifecycleService = _lifecycleService;
|
|
196
|
+
this._instantiationService = _instantiationService;
|
|
197
|
+
this._tasksReconnected = false;
|
|
198
|
+
this._taskSystemListeners = [];
|
|
199
|
+
this._onDidRegisterSupportedExecutions = ( new Emitter());
|
|
200
|
+
this._onDidRegisterAllSupportedExecutions = ( new Emitter());
|
|
201
|
+
this._onDidChangeTaskSystemInfo = ( new Emitter());
|
|
202
|
+
this._willRestart = false;
|
|
203
|
+
this.onDidChangeTaskSystemInfo = this._onDidChangeTaskSystemInfo.event;
|
|
204
|
+
this._onDidReconnectToTasks = ( new Emitter());
|
|
205
|
+
this.onDidReconnectToTasks = this._onDidReconnectToTasks.event;
|
|
206
|
+
this._whenTaskSystemReady = Event.toPromise(this.onDidChangeTaskSystemInfo);
|
|
207
|
+
this._workspaceTasksPromise = undefined;
|
|
208
|
+
this._taskSystem = undefined;
|
|
209
|
+
this._taskSystemListeners = undefined;
|
|
210
|
+
this._outputChannel = this._outputService.getChannel(AbstractTaskService_1.OutputChannelId);
|
|
211
|
+
this._providers = ( new Map());
|
|
212
|
+
this._providerTypes = ( new Map());
|
|
213
|
+
this._taskSystemInfos = ( new Map());
|
|
214
|
+
this._register(this._contextService.onDidChangeWorkspaceFolders(() => {
|
|
215
|
+
const folderSetup = this._computeWorkspaceFolderSetup();
|
|
216
|
+
if (this.executionEngine !== folderSetup[2]) {
|
|
217
|
+
this._disposeTaskSystemListeners();
|
|
218
|
+
this._taskSystem = undefined;
|
|
219
|
+
}
|
|
220
|
+
this._updateSetup(folderSetup);
|
|
221
|
+
return this._updateWorkspaceTasks(2 );
|
|
222
|
+
}));
|
|
223
|
+
this._register(this._configurationService.onDidChangeConfiguration((e) => {
|
|
224
|
+
if (!e.affectsConfiguration('tasks') || (!this._taskSystem && !this._workspaceTasksPromise)) {
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
if (!this._taskSystem || this._taskSystem instanceof TerminalTaskSystem) {
|
|
228
|
+
this._outputChannel.clear();
|
|
229
|
+
}
|
|
230
|
+
if (e.affectsConfiguration("task.reconnection" )) {
|
|
231
|
+
if (!this._configurationService.getValue("task.reconnection" )) {
|
|
232
|
+
this._persistentTasks?.clear();
|
|
233
|
+
this._storageService.remove(AbstractTaskService_1.PersistentTasks_Key, 1 );
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
this._setTaskLRUCacheLimit();
|
|
237
|
+
return this._updateWorkspaceTasks(3 );
|
|
238
|
+
}));
|
|
239
|
+
this._taskRunningState = TASK_RUNNING_STATE.bindTo(_contextKeyService);
|
|
240
|
+
this._onDidStateChange = this._register(( new Emitter()));
|
|
241
|
+
this._registerCommands().then(() => TaskCommandsRegistered.bindTo(this._contextKeyService).set(true));
|
|
242
|
+
ServerlessWebContext.bindTo(this._contextKeyService).set(platform.isWeb && !remoteAgentService.getConnection()?.remoteAuthority);
|
|
243
|
+
this._configurationResolverService.contributeVariable('defaultBuildTask', async () => {
|
|
244
|
+
let tasks = await this._getTasksForGroup(TaskGroup.Build);
|
|
245
|
+
if (tasks.length > 0) {
|
|
246
|
+
const defaults = this._getDefaultTasks(tasks);
|
|
247
|
+
if (defaults.length === 1) {
|
|
248
|
+
return defaults[0]._label;
|
|
249
|
+
}
|
|
250
|
+
else if (defaults.length) {
|
|
251
|
+
tasks = defaults;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
let entry;
|
|
255
|
+
if (tasks && tasks.length > 0) {
|
|
256
|
+
entry = await this._showQuickPick(tasks, ( nls.localizeWithPath(
|
|
257
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
258
|
+
'TaskService.pickBuildTaskForLabel',
|
|
259
|
+
'Select the build task (there is no default build task defined)'
|
|
260
|
+
)));
|
|
261
|
+
}
|
|
262
|
+
const task = entry ? entry.task : undefined;
|
|
263
|
+
if (!task) {
|
|
264
|
+
return undefined;
|
|
265
|
+
}
|
|
266
|
+
return task._label;
|
|
267
|
+
});
|
|
268
|
+
this._lifecycleService.onBeforeShutdown(e => {
|
|
269
|
+
this._willRestart = e.reason !== 3 ;
|
|
270
|
+
});
|
|
271
|
+
this._register(this.onDidStateChange(e => {
|
|
272
|
+
this._log(( nls.localizeWithPath(
|
|
273
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
274
|
+
'taskEvent',
|
|
275
|
+
'Task Event kind: {0}',
|
|
276
|
+
e.kind
|
|
277
|
+
)), true);
|
|
278
|
+
if (e.kind === "changed" ) ;
|
|
279
|
+
else if ((this._willRestart || (e.kind === "terminated" && e.exitReason === TerminalExitReason.User)) && e.taskId) {
|
|
280
|
+
const key = e.__task.getKey();
|
|
281
|
+
if (key) {
|
|
282
|
+
this.removePersistentTask(key);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
else if (e.kind === "start" && e.__task && e.__task.getWorkspaceFolder()) {
|
|
286
|
+
this._setPersistentTask(e.__task);
|
|
287
|
+
}
|
|
288
|
+
}));
|
|
289
|
+
this._waitForAllSupportedExecutions = ( new Promise(resolve => {
|
|
290
|
+
Event.once(this._onDidRegisterAllSupportedExecutions.event)(() => resolve());
|
|
291
|
+
}));
|
|
292
|
+
if (this._terminalService.getReconnectedTerminals('Task')?.length) {
|
|
293
|
+
this._attemptTaskReconnection();
|
|
294
|
+
}
|
|
295
|
+
else {
|
|
296
|
+
this._terminalService.whenConnected.then(() => {
|
|
297
|
+
if (this._terminalService.getReconnectedTerminals('Task')?.length) {
|
|
298
|
+
this._attemptTaskReconnection();
|
|
299
|
+
}
|
|
300
|
+
else {
|
|
301
|
+
this._tasksReconnected = true;
|
|
302
|
+
this._onDidReconnectToTasks.fire();
|
|
303
|
+
}
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
this._upgrade();
|
|
307
|
+
}
|
|
308
|
+
registerSupportedExecutions(custom, shell, process) {
|
|
309
|
+
if (custom !== undefined) {
|
|
310
|
+
const customContext = CustomExecutionSupportedContext.bindTo(this._contextKeyService);
|
|
311
|
+
customContext.set(custom);
|
|
312
|
+
}
|
|
313
|
+
const isVirtual = !!VirtualWorkspaceContext.getValue(this._contextKeyService);
|
|
314
|
+
if (shell !== undefined) {
|
|
315
|
+
const shellContext = ShellExecutionSupportedContext.bindTo(this._contextKeyService);
|
|
316
|
+
shellContext.set(shell && !isVirtual);
|
|
317
|
+
}
|
|
318
|
+
if (process !== undefined) {
|
|
319
|
+
const processContext = ProcessExecutionSupportedContext.bindTo(this._contextKeyService);
|
|
320
|
+
processContext.set(process && !isVirtual);
|
|
321
|
+
}
|
|
322
|
+
this._workspaceTasksPromise = undefined;
|
|
323
|
+
this._onDidRegisterSupportedExecutions.fire();
|
|
324
|
+
if (custom && shell && process) {
|
|
325
|
+
this._onDidRegisterAllSupportedExecutions.fire();
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
_attemptTaskReconnection() {
|
|
329
|
+
if (this._lifecycleService.startupKind !== 3 ) {
|
|
330
|
+
this._log(( nls.localizeWithPath(
|
|
331
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
332
|
+
'TaskService.skippingReconnection',
|
|
333
|
+
'Startup kind not window reload, setting connected and removing persistent tasks'
|
|
334
|
+
)), true);
|
|
335
|
+
this._tasksReconnected = true;
|
|
336
|
+
this._storageService.remove(AbstractTaskService_1.PersistentTasks_Key, 1 );
|
|
337
|
+
}
|
|
338
|
+
if (!this._configurationService.getValue("task.reconnection" ) || this._tasksReconnected) {
|
|
339
|
+
this._log(( nls.localizeWithPath(
|
|
340
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
341
|
+
'TaskService.notConnecting',
|
|
342
|
+
'Setting tasks connected configured value {0}, tasks were already reconnected {1}',
|
|
343
|
+
this._configurationService.getValue("task.reconnection" ),
|
|
344
|
+
this._tasksReconnected
|
|
345
|
+
)), true);
|
|
346
|
+
this._tasksReconnected = true;
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
this._log(( nls.localizeWithPath(
|
|
350
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
351
|
+
'TaskService.reconnecting',
|
|
352
|
+
'Reconnecting to running tasks...'
|
|
353
|
+
)), true);
|
|
354
|
+
this.getWorkspaceTasks(4 ).then(async () => {
|
|
355
|
+
this._tasksReconnected = await this._reconnectTasks();
|
|
356
|
+
this._log(( nls.localizeWithPath(
|
|
357
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
358
|
+
'TaskService.reconnected',
|
|
359
|
+
'Reconnected to running tasks.'
|
|
360
|
+
)), true);
|
|
361
|
+
this._onDidReconnectToTasks.fire();
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
async _reconnectTasks() {
|
|
365
|
+
const tasks = await this.getSavedTasks('persistent');
|
|
366
|
+
if (!tasks.length) {
|
|
367
|
+
this._log(( nls.localizeWithPath(
|
|
368
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
369
|
+
'TaskService.noTasks',
|
|
370
|
+
'No persistent tasks to reconnect.'
|
|
371
|
+
)), true);
|
|
372
|
+
return true;
|
|
373
|
+
}
|
|
374
|
+
const taskLabels = ( tasks.map(task => task._label)).join(', ');
|
|
375
|
+
this._log(( nls.localizeWithPath(
|
|
376
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
377
|
+
'TaskService.reconnectingTasks',
|
|
378
|
+
'Reconnecting to {0} tasks...',
|
|
379
|
+
taskLabels
|
|
380
|
+
)), true);
|
|
381
|
+
for (const task of tasks) {
|
|
382
|
+
if (ConfiguringTask.is(task)) {
|
|
383
|
+
const resolved = await this.tryResolveTask(task);
|
|
384
|
+
if (resolved) {
|
|
385
|
+
this.run(resolved, undefined, 4 );
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
else {
|
|
389
|
+
this.run(task, undefined, 4 );
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
return true;
|
|
393
|
+
}
|
|
394
|
+
get onDidStateChange() {
|
|
395
|
+
return this._onDidStateChange.event;
|
|
396
|
+
}
|
|
397
|
+
get supportsMultipleTaskExecutions() {
|
|
398
|
+
return this.inTerminal();
|
|
399
|
+
}
|
|
400
|
+
async _registerCommands() {
|
|
401
|
+
CommandsRegistry.registerCommand({
|
|
402
|
+
id: 'workbench.action.tasks.runTask',
|
|
403
|
+
handler: async (accessor, arg) => {
|
|
404
|
+
if (await this._trust()) {
|
|
405
|
+
await this._runTaskCommand(arg);
|
|
406
|
+
}
|
|
407
|
+
},
|
|
408
|
+
metadata: {
|
|
409
|
+
description: 'Run Task',
|
|
410
|
+
args: [{
|
|
411
|
+
name: 'args',
|
|
412
|
+
isOptional: true,
|
|
413
|
+
description: ( nls.localizeWithPath(
|
|
414
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
415
|
+
'runTask.arg',
|
|
416
|
+
"Filters the tasks shown in the quickpick"
|
|
417
|
+
)),
|
|
418
|
+
schema: {
|
|
419
|
+
anyOf: [
|
|
420
|
+
{
|
|
421
|
+
type: 'string',
|
|
422
|
+
description: ( nls.localizeWithPath(
|
|
423
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
424
|
+
'runTask.label',
|
|
425
|
+
"The task's label or a term to filter by"
|
|
426
|
+
))
|
|
427
|
+
},
|
|
428
|
+
{
|
|
429
|
+
type: 'object',
|
|
430
|
+
properties: {
|
|
431
|
+
type: {
|
|
432
|
+
type: 'string',
|
|
433
|
+
description: ( nls.localizeWithPath(
|
|
434
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
435
|
+
'runTask.type',
|
|
436
|
+
"The contributed task type"
|
|
437
|
+
))
|
|
438
|
+
},
|
|
439
|
+
task: {
|
|
440
|
+
type: 'string',
|
|
441
|
+
description: ( nls.localizeWithPath(
|
|
442
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
443
|
+
'runTask.task',
|
|
444
|
+
"The task's label or a term to filter by"
|
|
445
|
+
))
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
]
|
|
450
|
+
}
|
|
451
|
+
}]
|
|
452
|
+
}
|
|
453
|
+
});
|
|
454
|
+
CommandsRegistry.registerCommand('workbench.action.tasks.reRunTask', async (accessor, arg) => {
|
|
455
|
+
if (await this._trust()) {
|
|
456
|
+
this._reRunTaskCommand();
|
|
457
|
+
}
|
|
458
|
+
});
|
|
459
|
+
CommandsRegistry.registerCommand('workbench.action.tasks.restartTask', async (accessor, arg) => {
|
|
460
|
+
if (await this._trust()) {
|
|
461
|
+
this._runRestartTaskCommand(arg);
|
|
462
|
+
}
|
|
463
|
+
});
|
|
464
|
+
CommandsRegistry.registerCommand('workbench.action.tasks.terminate', async (accessor, arg) => {
|
|
465
|
+
if (await this._trust()) {
|
|
466
|
+
this._runTerminateCommand(arg);
|
|
467
|
+
}
|
|
468
|
+
});
|
|
469
|
+
CommandsRegistry.registerCommand('workbench.action.tasks.showLog', () => {
|
|
470
|
+
this._showOutput(undefined, true);
|
|
471
|
+
});
|
|
472
|
+
CommandsRegistry.registerCommand('workbench.action.tasks.build', async () => {
|
|
473
|
+
if (await this._trust()) {
|
|
474
|
+
this._runBuildCommand();
|
|
475
|
+
}
|
|
476
|
+
});
|
|
477
|
+
CommandsRegistry.registerCommand('workbench.action.tasks.test', async () => {
|
|
478
|
+
if (await this._trust()) {
|
|
479
|
+
this._runTestCommand();
|
|
480
|
+
}
|
|
481
|
+
});
|
|
482
|
+
CommandsRegistry.registerCommand('workbench.action.tasks.configureTaskRunner', async () => {
|
|
483
|
+
if (await this._trust()) {
|
|
484
|
+
this._runConfigureTasks();
|
|
485
|
+
}
|
|
486
|
+
});
|
|
487
|
+
CommandsRegistry.registerCommand('workbench.action.tasks.configureDefaultBuildTask', async () => {
|
|
488
|
+
if (await this._trust()) {
|
|
489
|
+
this._runConfigureDefaultBuildTask();
|
|
490
|
+
}
|
|
491
|
+
});
|
|
492
|
+
CommandsRegistry.registerCommand('workbench.action.tasks.configureDefaultTestTask', async () => {
|
|
493
|
+
if (await this._trust()) {
|
|
494
|
+
this._runConfigureDefaultTestTask();
|
|
495
|
+
}
|
|
496
|
+
});
|
|
497
|
+
CommandsRegistry.registerCommand('workbench.action.tasks.showTasks', async () => {
|
|
498
|
+
if (await this._trust()) {
|
|
499
|
+
return this.runShowTasks();
|
|
500
|
+
}
|
|
501
|
+
});
|
|
502
|
+
CommandsRegistry.registerCommand('workbench.action.tasks.toggleProblems', () => this._commandService.executeCommand(Markers.TOGGLE_MARKERS_VIEW_ACTION_ID));
|
|
503
|
+
CommandsRegistry.registerCommand('workbench.action.tasks.openUserTasks', async () => {
|
|
504
|
+
const resource = this._getResourceForKind(TaskSourceKind.User);
|
|
505
|
+
if (resource) {
|
|
506
|
+
this._openTaskFile(resource, TaskSourceKind.User);
|
|
507
|
+
}
|
|
508
|
+
});
|
|
509
|
+
CommandsRegistry.registerCommand('workbench.action.tasks.openWorkspaceFileTasks', async () => {
|
|
510
|
+
const resource = this._getResourceForKind(TaskSourceKind.WorkspaceFile);
|
|
511
|
+
if (resource) {
|
|
512
|
+
this._openTaskFile(resource, TaskSourceKind.WorkspaceFile);
|
|
513
|
+
}
|
|
514
|
+
});
|
|
515
|
+
}
|
|
516
|
+
get workspaceFolders() {
|
|
517
|
+
if (!this._workspaceFolders) {
|
|
518
|
+
this._updateSetup();
|
|
519
|
+
}
|
|
520
|
+
return this._workspaceFolders;
|
|
521
|
+
}
|
|
522
|
+
get ignoredWorkspaceFolders() {
|
|
523
|
+
if (!this._ignoredWorkspaceFolders) {
|
|
524
|
+
this._updateSetup();
|
|
525
|
+
}
|
|
526
|
+
return this._ignoredWorkspaceFolders;
|
|
527
|
+
}
|
|
528
|
+
get executionEngine() {
|
|
529
|
+
if (this._executionEngine === undefined) {
|
|
530
|
+
this._updateSetup();
|
|
531
|
+
}
|
|
532
|
+
return this._executionEngine;
|
|
533
|
+
}
|
|
534
|
+
get schemaVersion() {
|
|
535
|
+
if (this._schemaVersion === undefined) {
|
|
536
|
+
this._updateSetup();
|
|
537
|
+
}
|
|
538
|
+
return this._schemaVersion;
|
|
539
|
+
}
|
|
540
|
+
get showIgnoreMessage() {
|
|
541
|
+
if (this._showIgnoreMessage === undefined) {
|
|
542
|
+
this._showIgnoreMessage = !this._storageService.getBoolean(AbstractTaskService_1.IgnoreTask010DonotShowAgain_key, 1 , false);
|
|
543
|
+
}
|
|
544
|
+
return this._showIgnoreMessage;
|
|
545
|
+
}
|
|
546
|
+
_getActivationEvents(type) {
|
|
547
|
+
const result = [];
|
|
548
|
+
result.push('onCommand:workbench.action.tasks.runTask');
|
|
549
|
+
if (type) {
|
|
550
|
+
result.push(`onTaskType:${type}`);
|
|
551
|
+
}
|
|
552
|
+
else {
|
|
553
|
+
for (const definition of TaskDefinitionRegistry.all()) {
|
|
554
|
+
result.push(`onTaskType:${definition.taskType}`);
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
return result;
|
|
558
|
+
}
|
|
559
|
+
async _activateTaskProviders(type) {
|
|
560
|
+
await this._extensionService.whenInstalledExtensionsRegistered();
|
|
561
|
+
await raceTimeout(Promise.all(( this._getActivationEvents(type).map(activationEvent => this._extensionService.activateByEvent(activationEvent)))), 5000, () => console.warn('Timed out activating extensions for task providers'));
|
|
562
|
+
}
|
|
563
|
+
_updateSetup(setup) {
|
|
564
|
+
if (!setup) {
|
|
565
|
+
setup = this._computeWorkspaceFolderSetup();
|
|
566
|
+
}
|
|
567
|
+
this._workspaceFolders = setup[0];
|
|
568
|
+
if (this._ignoredWorkspaceFolders) {
|
|
569
|
+
if (this._ignoredWorkspaceFolders.length !== setup[1].length) {
|
|
570
|
+
this._showIgnoreMessage = undefined;
|
|
571
|
+
}
|
|
572
|
+
else {
|
|
573
|
+
const set = ( new Set());
|
|
574
|
+
this._ignoredWorkspaceFolders.forEach(folder => set.add(( folder.uri.toString())));
|
|
575
|
+
for (const folder of setup[1]) {
|
|
576
|
+
if (!( set.has(( folder.uri.toString())))) {
|
|
577
|
+
this._showIgnoreMessage = undefined;
|
|
578
|
+
break;
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
this._ignoredWorkspaceFolders = setup[1];
|
|
584
|
+
this._executionEngine = setup[2];
|
|
585
|
+
this._schemaVersion = setup[3];
|
|
586
|
+
this._workspace = setup[4];
|
|
587
|
+
}
|
|
588
|
+
_showOutput(runSource = 1 , userRequested) {
|
|
589
|
+
if (!VirtualWorkspaceContext.getValue(this._contextKeyService) && (((runSource === 1) ) || ((runSource === 3) ))) {
|
|
590
|
+
if (userRequested) {
|
|
591
|
+
this._outputService.showChannel(this._outputChannel.id, true);
|
|
592
|
+
}
|
|
593
|
+
else {
|
|
594
|
+
this._notificationService.prompt(Severity.Warning, ( nls.localizeWithPath(
|
|
595
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
596
|
+
'taskServiceOutputPrompt',
|
|
597
|
+
'There are task errors. See the output for details.'
|
|
598
|
+
)), [{
|
|
599
|
+
label: ( nls.localizeWithPath(
|
|
600
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
601
|
+
'showOutput',
|
|
602
|
+
"Show output"
|
|
603
|
+
)),
|
|
604
|
+
run: () => {
|
|
605
|
+
this._outputService.showChannel(this._outputChannel.id, true);
|
|
606
|
+
}
|
|
607
|
+
}]);
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
_disposeTaskSystemListeners() {
|
|
612
|
+
if (this._taskSystemListeners) {
|
|
613
|
+
dispose(this._taskSystemListeners);
|
|
614
|
+
this._taskSystemListeners = undefined;
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
registerTaskProvider(provider, type) {
|
|
618
|
+
if (!provider) {
|
|
619
|
+
return {
|
|
620
|
+
dispose: () => { }
|
|
621
|
+
};
|
|
622
|
+
}
|
|
623
|
+
const handle = AbstractTaskService_1._nextHandle++;
|
|
624
|
+
this._providers.set(handle, provider);
|
|
625
|
+
this._providerTypes.set(handle, type);
|
|
626
|
+
return {
|
|
627
|
+
dispose: () => {
|
|
628
|
+
this._providers.delete(handle);
|
|
629
|
+
this._providerTypes.delete(handle);
|
|
630
|
+
}
|
|
631
|
+
};
|
|
632
|
+
}
|
|
633
|
+
get hasTaskSystemInfo() {
|
|
634
|
+
const infosCount = Array.from(( this._taskSystemInfos.values())).flat().length;
|
|
635
|
+
if (this._environmentService.remoteAuthority) {
|
|
636
|
+
return infosCount > 1;
|
|
637
|
+
}
|
|
638
|
+
return infosCount > 0;
|
|
639
|
+
}
|
|
640
|
+
registerTaskSystem(key, info) {
|
|
641
|
+
if (info.platform === 0 ) {
|
|
642
|
+
key = this.workspaceFolders.length ? this.workspaceFolders[0].uri.scheme : key;
|
|
643
|
+
}
|
|
644
|
+
if (!( this._taskSystemInfos.has(key))) {
|
|
645
|
+
this._taskSystemInfos.set(key, [info]);
|
|
646
|
+
}
|
|
647
|
+
else {
|
|
648
|
+
const infos = this._taskSystemInfos.get(key);
|
|
649
|
+
if (info.platform === 0 ) {
|
|
650
|
+
infos.push(info);
|
|
651
|
+
}
|
|
652
|
+
else {
|
|
653
|
+
infos.unshift(info);
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
if (this.hasTaskSystemInfo) {
|
|
657
|
+
this._onDidChangeTaskSystemInfo.fire();
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
_getTaskSystemInfo(key) {
|
|
661
|
+
const infos = this._taskSystemInfos.get(key);
|
|
662
|
+
return (infos && infos.length) ? infos[0] : undefined;
|
|
663
|
+
}
|
|
664
|
+
extensionCallbackTaskComplete(task, result) {
|
|
665
|
+
if (!this._taskSystem) {
|
|
666
|
+
return Promise.resolve();
|
|
667
|
+
}
|
|
668
|
+
return this._taskSystem.customExecutionComplete(task, result);
|
|
669
|
+
}
|
|
670
|
+
async _findWorkspaceTasks(predicate) {
|
|
671
|
+
const result = [];
|
|
672
|
+
const tasks = await this.getWorkspaceTasks();
|
|
673
|
+
for (const [, workspaceTasks] of tasks) {
|
|
674
|
+
if (workspaceTasks.configurations) {
|
|
675
|
+
for (const taskName in workspaceTasks.configurations.byIdentifier) {
|
|
676
|
+
const task = workspaceTasks.configurations.byIdentifier[taskName];
|
|
677
|
+
if (predicate(task, workspaceTasks.workspaceFolder)) {
|
|
678
|
+
result.push(task);
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
if (workspaceTasks.set) {
|
|
683
|
+
for (const task of workspaceTasks.set.tasks) {
|
|
684
|
+
if (predicate(task, workspaceTasks.workspaceFolder)) {
|
|
685
|
+
result.push(task);
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
return result;
|
|
691
|
+
}
|
|
692
|
+
async _findWorkspaceTasksInGroup(group, isDefault) {
|
|
693
|
+
return this._findWorkspaceTasks((task) => {
|
|
694
|
+
const taskGroup = task.configurationProperties.group;
|
|
695
|
+
if (taskGroup && typeof taskGroup !== 'string') {
|
|
696
|
+
return (taskGroup._id === group._id && (!isDefault || !!taskGroup.isDefault));
|
|
697
|
+
}
|
|
698
|
+
return false;
|
|
699
|
+
});
|
|
700
|
+
}
|
|
701
|
+
async getTask(folder, identifier, compareId = false, type = undefined) {
|
|
702
|
+
if (!(await this._trust())) {
|
|
703
|
+
return;
|
|
704
|
+
}
|
|
705
|
+
const name = Types.isString(folder) ? folder : isWorkspaceFolder(folder) ? folder.name : folder.configuration ? resources.basename(folder.configuration) : undefined;
|
|
706
|
+
if (( this.ignoredWorkspaceFolders.some(ignored => ignored.name === name))) {
|
|
707
|
+
return Promise.reject(( new Error(( nls.localizeWithPath(
|
|
708
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
709
|
+
'TaskServer.folderIgnored',
|
|
710
|
+
'The folder {0} is ignored since it uses task version 0.1.0',
|
|
711
|
+
name
|
|
712
|
+
)))));
|
|
713
|
+
}
|
|
714
|
+
const key = !Types.isString(identifier)
|
|
715
|
+
? TaskDefinition.createTaskIdentifier(identifier, console)
|
|
716
|
+
: identifier;
|
|
717
|
+
if (key === undefined) {
|
|
718
|
+
return Promise.resolve(undefined);
|
|
719
|
+
}
|
|
720
|
+
const requestedFolder = TaskMap.getKey(folder);
|
|
721
|
+
const matchedTasks = await this._findWorkspaceTasks((task, workspaceFolder) => {
|
|
722
|
+
const taskFolder = TaskMap.getKey(workspaceFolder);
|
|
723
|
+
if (taskFolder !== requestedFolder && taskFolder !== USER_TASKS_GROUP_KEY) {
|
|
724
|
+
return false;
|
|
725
|
+
}
|
|
726
|
+
return task.matches(key, compareId);
|
|
727
|
+
});
|
|
728
|
+
matchedTasks.sort(task => task._source.kind === TaskSourceKind.Extension ? 1 : -1);
|
|
729
|
+
if (matchedTasks.length > 0) {
|
|
730
|
+
const task = matchedTasks[0];
|
|
731
|
+
if (ConfiguringTask.is(task)) {
|
|
732
|
+
return this.tryResolveTask(task);
|
|
733
|
+
}
|
|
734
|
+
else {
|
|
735
|
+
return task;
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
const map = await this._getGroupedTasks({ type });
|
|
739
|
+
let values = map.get(folder);
|
|
740
|
+
values = values.concat(map.get(USER_TASKS_GROUP_KEY));
|
|
741
|
+
if (!values) {
|
|
742
|
+
return undefined;
|
|
743
|
+
}
|
|
744
|
+
values = values.filter(task => task.matches(key, compareId)).sort(task => task._source.kind === TaskSourceKind.Extension ? 1 : -1);
|
|
745
|
+
return values.length > 0 ? values[0] : undefined;
|
|
746
|
+
}
|
|
747
|
+
async tryResolveTask(configuringTask) {
|
|
748
|
+
if (!(await this._trust())) {
|
|
749
|
+
return;
|
|
750
|
+
}
|
|
751
|
+
await this._activateTaskProviders(configuringTask.type);
|
|
752
|
+
let matchingProvider;
|
|
753
|
+
let matchingProviderUnavailable = false;
|
|
754
|
+
for (const [handle, provider] of this._providers) {
|
|
755
|
+
const providerType = this._providerTypes.get(handle);
|
|
756
|
+
if (configuringTask.type === providerType) {
|
|
757
|
+
if (providerType && !this._isTaskProviderEnabled(providerType)) {
|
|
758
|
+
matchingProviderUnavailable = true;
|
|
759
|
+
continue;
|
|
760
|
+
}
|
|
761
|
+
matchingProvider = provider;
|
|
762
|
+
break;
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
if (!matchingProvider) {
|
|
766
|
+
if (matchingProviderUnavailable) {
|
|
767
|
+
this._log(( nls.localizeWithPath(
|
|
768
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
769
|
+
'TaskService.providerUnavailable',
|
|
770
|
+
'Warning: {0} tasks are unavailable in the current environment.',
|
|
771
|
+
configuringTask.configures.type
|
|
772
|
+
)));
|
|
773
|
+
}
|
|
774
|
+
return;
|
|
775
|
+
}
|
|
776
|
+
try {
|
|
777
|
+
const resolvedTask = await matchingProvider.resolveTask(configuringTask);
|
|
778
|
+
if (resolvedTask && (resolvedTask._id === configuringTask._id)) {
|
|
779
|
+
return createCustomTask(resolvedTask, configuringTask);
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
catch (error) {
|
|
783
|
+
}
|
|
784
|
+
const tasks = await this.tasks({ type: configuringTask.type });
|
|
785
|
+
for (const task of tasks) {
|
|
786
|
+
if (task._id === configuringTask._id) {
|
|
787
|
+
return createCustomTask(task, configuringTask);
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
return;
|
|
791
|
+
}
|
|
792
|
+
async tasks(filter) {
|
|
793
|
+
if (!(await this._trust())) {
|
|
794
|
+
return [];
|
|
795
|
+
}
|
|
796
|
+
if (!this._versionAndEngineCompatible(filter)) {
|
|
797
|
+
return Promise.resolve([]);
|
|
798
|
+
}
|
|
799
|
+
return this._getGroupedTasks(filter).then((map) => {
|
|
800
|
+
if (!filter || !filter.type) {
|
|
801
|
+
return map.all();
|
|
802
|
+
}
|
|
803
|
+
const result = [];
|
|
804
|
+
map.forEach((tasks) => {
|
|
805
|
+
for (const task of tasks) {
|
|
806
|
+
if (ContributedTask.is(task) && ((task.defines.type === filter.type) || (task._source.label === filter.type))) {
|
|
807
|
+
result.push(task);
|
|
808
|
+
}
|
|
809
|
+
else if (CustomTask.is(task)) {
|
|
810
|
+
if (task.type === filter.type) {
|
|
811
|
+
result.push(task);
|
|
812
|
+
}
|
|
813
|
+
else {
|
|
814
|
+
const customizes = task.customizes();
|
|
815
|
+
if (customizes && customizes.type === filter.type) {
|
|
816
|
+
result.push(task);
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
});
|
|
822
|
+
return result;
|
|
823
|
+
});
|
|
824
|
+
}
|
|
825
|
+
taskTypes() {
|
|
826
|
+
const types = [];
|
|
827
|
+
if (this._isProvideTasksEnabled()) {
|
|
828
|
+
for (const definition of TaskDefinitionRegistry.all()) {
|
|
829
|
+
if (this._isTaskProviderEnabled(definition.taskType)) {
|
|
830
|
+
types.push(definition.taskType);
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
return types;
|
|
835
|
+
}
|
|
836
|
+
createSorter() {
|
|
837
|
+
return ( new TaskSorter(
|
|
838
|
+
this._contextService.getWorkspace() ? this._contextService.getWorkspace().folders : []
|
|
839
|
+
));
|
|
840
|
+
}
|
|
841
|
+
_isActive() {
|
|
842
|
+
if (!this._taskSystem) {
|
|
843
|
+
return Promise.resolve(false);
|
|
844
|
+
}
|
|
845
|
+
return this._taskSystem.isActive();
|
|
846
|
+
}
|
|
847
|
+
async getActiveTasks() {
|
|
848
|
+
if (!this._taskSystem) {
|
|
849
|
+
return [];
|
|
850
|
+
}
|
|
851
|
+
return this._taskSystem.getActiveTasks();
|
|
852
|
+
}
|
|
853
|
+
async getBusyTasks() {
|
|
854
|
+
if (!this._taskSystem) {
|
|
855
|
+
return [];
|
|
856
|
+
}
|
|
857
|
+
return this._taskSystem.getBusyTasks();
|
|
858
|
+
}
|
|
859
|
+
getRecentlyUsedTasksV1() {
|
|
860
|
+
if (this._recentlyUsedTasksV1) {
|
|
861
|
+
return this._recentlyUsedTasksV1;
|
|
862
|
+
}
|
|
863
|
+
const quickOpenHistoryLimit = this._configurationService.getValue(QUICKOPEN_HISTORY_LIMIT_CONFIG);
|
|
864
|
+
this._recentlyUsedTasksV1 = ( new LRUCache(quickOpenHistoryLimit));
|
|
865
|
+
const storageValue = this._storageService.get(AbstractTaskService_1.RecentlyUsedTasks_Key, 1 );
|
|
866
|
+
if (storageValue) {
|
|
867
|
+
try {
|
|
868
|
+
const values = JSON.parse(storageValue);
|
|
869
|
+
if (Array.isArray(values)) {
|
|
870
|
+
for (const value of values) {
|
|
871
|
+
this._recentlyUsedTasksV1.set(value, value);
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
catch (error) {
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
return this._recentlyUsedTasksV1;
|
|
879
|
+
}
|
|
880
|
+
_getTasksFromStorage(type) {
|
|
881
|
+
return type === 'persistent' ? this._getPersistentTasks() : this._getRecentTasks();
|
|
882
|
+
}
|
|
883
|
+
_getRecentTasks() {
|
|
884
|
+
if (this._recentlyUsedTasks) {
|
|
885
|
+
return this._recentlyUsedTasks;
|
|
886
|
+
}
|
|
887
|
+
const quickOpenHistoryLimit = this._configurationService.getValue(QUICKOPEN_HISTORY_LIMIT_CONFIG);
|
|
888
|
+
this._recentlyUsedTasks = ( new LRUCache(quickOpenHistoryLimit));
|
|
889
|
+
const storageValue = this._storageService.get(AbstractTaskService_1.RecentlyUsedTasks_KeyV2, 1 );
|
|
890
|
+
if (storageValue) {
|
|
891
|
+
try {
|
|
892
|
+
const values = JSON.parse(storageValue);
|
|
893
|
+
if (Array.isArray(values)) {
|
|
894
|
+
for (const value of values) {
|
|
895
|
+
this._recentlyUsedTasks.set(value[0], value[1]);
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
catch (error) {
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
return this._recentlyUsedTasks;
|
|
903
|
+
}
|
|
904
|
+
_getPersistentTasks() {
|
|
905
|
+
if (this._persistentTasks) {
|
|
906
|
+
this._log(( nls.localizeWithPath(
|
|
907
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
908
|
+
'taskService.gettingCachedTasks',
|
|
909
|
+
'Returning cached tasks {0}',
|
|
910
|
+
this._persistentTasks.size
|
|
911
|
+
)), true);
|
|
912
|
+
return this._persistentTasks;
|
|
913
|
+
}
|
|
914
|
+
this._persistentTasks = ( new LRUCache(10));
|
|
915
|
+
const storageValue = this._storageService.get(AbstractTaskService_1.PersistentTasks_Key, 1 );
|
|
916
|
+
if (storageValue) {
|
|
917
|
+
try {
|
|
918
|
+
const values = JSON.parse(storageValue);
|
|
919
|
+
if (Array.isArray(values)) {
|
|
920
|
+
for (const value of values) {
|
|
921
|
+
this._persistentTasks.set(value[0], value[1]);
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
catch (error) {
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
return this._persistentTasks;
|
|
929
|
+
}
|
|
930
|
+
_getFolderFromTaskKey(key) {
|
|
931
|
+
const keyValue = JSON.parse(key);
|
|
932
|
+
return {
|
|
933
|
+
folder: keyValue.folder, isWorkspaceFile: keyValue.id?.endsWith(TaskSourceKind.WorkspaceFile)
|
|
934
|
+
};
|
|
935
|
+
}
|
|
936
|
+
async getSavedTasks(type) {
|
|
937
|
+
const folderMap = Object.create(null);
|
|
938
|
+
this.workspaceFolders.forEach(folder => {
|
|
939
|
+
folderMap[( folder.uri.toString())] = folder;
|
|
940
|
+
});
|
|
941
|
+
const folderToTasksMap = ( new Map());
|
|
942
|
+
const workspaceToTaskMap = ( new Map());
|
|
943
|
+
const storedTasks = this._getTasksFromStorage(type);
|
|
944
|
+
const tasks = [];
|
|
945
|
+
this._log(( nls.localizeWithPath(
|
|
946
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
947
|
+
'taskService.getSavedTasks',
|
|
948
|
+
'Fetching tasks from task storage.'
|
|
949
|
+
)), true);
|
|
950
|
+
function addTaskToMap(map, folder, task) {
|
|
951
|
+
if (folder && !( map.has(folder))) {
|
|
952
|
+
map.set(folder, []);
|
|
953
|
+
}
|
|
954
|
+
if (folder && (folderMap[folder] || (folder === USER_TASKS_GROUP_KEY)) && task) {
|
|
955
|
+
map.get(folder).push(task);
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
for (const entry of storedTasks.entries()) {
|
|
959
|
+
try {
|
|
960
|
+
const key = entry[0];
|
|
961
|
+
const task = JSON.parse(entry[1]);
|
|
962
|
+
const folderInfo = this._getFolderFromTaskKey(key);
|
|
963
|
+
this._log(( nls.localizeWithPath(
|
|
964
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
965
|
+
'taskService.getSavedTasks.reading',
|
|
966
|
+
'Reading tasks from task storage, {0}, {1}, {2}',
|
|
967
|
+
key,
|
|
968
|
+
task,
|
|
969
|
+
folderInfo.folder
|
|
970
|
+
)), true);
|
|
971
|
+
addTaskToMap(folderInfo.isWorkspaceFile ? workspaceToTaskMap : folderToTasksMap, folderInfo.folder, task);
|
|
972
|
+
}
|
|
973
|
+
catch (error) {
|
|
974
|
+
this._log(( nls.localizeWithPath(
|
|
975
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
976
|
+
'taskService.getSavedTasks.error',
|
|
977
|
+
'Fetching a task from task storage failed: {0}.',
|
|
978
|
+
error
|
|
979
|
+
)), true);
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
const readTasksMap = ( new Map());
|
|
983
|
+
async function readTasks(that, map, isWorkspaceFile) {
|
|
984
|
+
for (const key of ( map.keys())) {
|
|
985
|
+
const custom = [];
|
|
986
|
+
const customized = Object.create(null);
|
|
987
|
+
const taskConfigSource = (folderMap[key]
|
|
988
|
+
? (isWorkspaceFile
|
|
989
|
+
? TaskConfigSource.WorkspaceFile : TaskConfigSource.TasksJson)
|
|
990
|
+
: TaskConfigSource.User);
|
|
991
|
+
await that._computeTasksForSingleConfig(folderMap[key] ?? (await that._getAFolder()), {
|
|
992
|
+
version: '2.0.0',
|
|
993
|
+
tasks: map.get(key)
|
|
994
|
+
}, 0 , custom, customized, taskConfigSource, true);
|
|
995
|
+
custom.forEach(task => {
|
|
996
|
+
const taskKey = task.getKey();
|
|
997
|
+
if (taskKey) {
|
|
998
|
+
readTasksMap.set(taskKey, task);
|
|
999
|
+
}
|
|
1000
|
+
});
|
|
1001
|
+
for (const configuration in customized) {
|
|
1002
|
+
const taskKey = customized[configuration].getKey();
|
|
1003
|
+
if (taskKey) {
|
|
1004
|
+
readTasksMap.set(taskKey, customized[configuration]);
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
await readTasks(this, folderToTasksMap, false);
|
|
1010
|
+
await readTasks(this, workspaceToTaskMap, true);
|
|
1011
|
+
for (const key of ( storedTasks.keys())) {
|
|
1012
|
+
if (( readTasksMap.has(key))) {
|
|
1013
|
+
tasks.push(readTasksMap.get(key));
|
|
1014
|
+
this._log(( nls.localizeWithPath(
|
|
1015
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
1016
|
+
'taskService.getSavedTasks.resolved',
|
|
1017
|
+
'Resolved task {0}',
|
|
1018
|
+
key
|
|
1019
|
+
)), true);
|
|
1020
|
+
}
|
|
1021
|
+
else {
|
|
1022
|
+
this._log(( nls.localizeWithPath(
|
|
1023
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
1024
|
+
'taskService.getSavedTasks.unresolved',
|
|
1025
|
+
'Unable to resolve task {0} ',
|
|
1026
|
+
key
|
|
1027
|
+
)), true);
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
return tasks;
|
|
1031
|
+
}
|
|
1032
|
+
removeRecentlyUsedTask(taskRecentlyUsedKey) {
|
|
1033
|
+
if (( this._getTasksFromStorage('historical').has(taskRecentlyUsedKey))) {
|
|
1034
|
+
this._getTasksFromStorage('historical').delete(taskRecentlyUsedKey);
|
|
1035
|
+
this._saveRecentlyUsedTasks();
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
removePersistentTask(key) {
|
|
1039
|
+
this._log(( nls.localizeWithPath(
|
|
1040
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
1041
|
+
'taskService.removePersistentTask',
|
|
1042
|
+
'Removing persistent task {0}',
|
|
1043
|
+
key
|
|
1044
|
+
)), true);
|
|
1045
|
+
if (( this._getTasksFromStorage('persistent').has(key))) {
|
|
1046
|
+
this._getTasksFromStorage('persistent').delete(key);
|
|
1047
|
+
this._savePersistentTasks();
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
_setTaskLRUCacheLimit() {
|
|
1051
|
+
const quickOpenHistoryLimit = this._configurationService.getValue(QUICKOPEN_HISTORY_LIMIT_CONFIG);
|
|
1052
|
+
if (this._recentlyUsedTasks) {
|
|
1053
|
+
this._recentlyUsedTasks.limit = quickOpenHistoryLimit;
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
async _setRecentlyUsedTask(task) {
|
|
1057
|
+
let key = task.getKey();
|
|
1058
|
+
if (!InMemoryTask.is(task) && key) {
|
|
1059
|
+
const customizations = this._createCustomizableTask(task);
|
|
1060
|
+
if (ContributedTask.is(task) && customizations) {
|
|
1061
|
+
const custom = [];
|
|
1062
|
+
const customized = Object.create(null);
|
|
1063
|
+
await this._computeTasksForSingleConfig(task._source.workspaceFolder ?? this.workspaceFolders[0], {
|
|
1064
|
+
version: '2.0.0',
|
|
1065
|
+
tasks: [customizations]
|
|
1066
|
+
}, 0 , custom, customized, TaskConfigSource.TasksJson, true);
|
|
1067
|
+
for (const configuration in customized) {
|
|
1068
|
+
key = customized[configuration].getKey();
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
this._getTasksFromStorage('historical').set(key, JSON.stringify(customizations));
|
|
1072
|
+
this._saveRecentlyUsedTasks();
|
|
1073
|
+
}
|
|
1074
|
+
}
|
|
1075
|
+
_saveRecentlyUsedTasks() {
|
|
1076
|
+
if (!this._recentlyUsedTasks) {
|
|
1077
|
+
return;
|
|
1078
|
+
}
|
|
1079
|
+
const quickOpenHistoryLimit = this._configurationService.getValue(QUICKOPEN_HISTORY_LIMIT_CONFIG);
|
|
1080
|
+
if (quickOpenHistoryLimit === 0) {
|
|
1081
|
+
return;
|
|
1082
|
+
}
|
|
1083
|
+
let keys = [...( this._recentlyUsedTasks.keys())];
|
|
1084
|
+
if (keys.length > quickOpenHistoryLimit) {
|
|
1085
|
+
keys = keys.slice(0, quickOpenHistoryLimit);
|
|
1086
|
+
}
|
|
1087
|
+
const keyValues = [];
|
|
1088
|
+
for (const key of keys) {
|
|
1089
|
+
keyValues.push([key, this._recentlyUsedTasks.get(key, 0 )]);
|
|
1090
|
+
}
|
|
1091
|
+
this._storageService.store(AbstractTaskService_1.RecentlyUsedTasks_KeyV2, JSON.stringify(keyValues), 1 , 1 );
|
|
1092
|
+
}
|
|
1093
|
+
async _setPersistentTask(task) {
|
|
1094
|
+
if (!this._configurationService.getValue("task.reconnection" )) {
|
|
1095
|
+
return;
|
|
1096
|
+
}
|
|
1097
|
+
let key = task.getKey();
|
|
1098
|
+
if (!InMemoryTask.is(task) && key) {
|
|
1099
|
+
const customizations = this._createCustomizableTask(task);
|
|
1100
|
+
if (ContributedTask.is(task) && customizations) {
|
|
1101
|
+
const custom = [];
|
|
1102
|
+
const customized = Object.create(null);
|
|
1103
|
+
await this._computeTasksForSingleConfig(task._source.workspaceFolder ?? this.workspaceFolders[0], {
|
|
1104
|
+
version: '2.0.0',
|
|
1105
|
+
tasks: [customizations]
|
|
1106
|
+
}, 0 , custom, customized, TaskConfigSource.TasksJson, true);
|
|
1107
|
+
for (const configuration in customized) {
|
|
1108
|
+
key = customized[configuration].getKey();
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
if (!task.configurationProperties.isBackground) {
|
|
1112
|
+
return;
|
|
1113
|
+
}
|
|
1114
|
+
this._log(( nls.localizeWithPath(
|
|
1115
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
1116
|
+
'taskService.setPersistentTask',
|
|
1117
|
+
'Setting persistent task {0}',
|
|
1118
|
+
key
|
|
1119
|
+
)), true);
|
|
1120
|
+
this._getTasksFromStorage('persistent').set(key, JSON.stringify(customizations));
|
|
1121
|
+
this._savePersistentTasks();
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
_savePersistentTasks() {
|
|
1125
|
+
this._persistentTasks = this._getTasksFromStorage('persistent');
|
|
1126
|
+
const keys = [...( this._persistentTasks.keys())];
|
|
1127
|
+
const keyValues = [];
|
|
1128
|
+
for (const key of keys) {
|
|
1129
|
+
keyValues.push([key, this._persistentTasks.get(key, 0 )]);
|
|
1130
|
+
}
|
|
1131
|
+
this._log(( nls.localizeWithPath(
|
|
1132
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
1133
|
+
'savePersistentTask',
|
|
1134
|
+
'Saving persistent tasks: {0}',
|
|
1135
|
+
keys.join(', ')
|
|
1136
|
+
)), true);
|
|
1137
|
+
this._storageService.store(AbstractTaskService_1.PersistentTasks_Key, JSON.stringify(keyValues), 1 , 1 );
|
|
1138
|
+
}
|
|
1139
|
+
_openDocumentation() {
|
|
1140
|
+
this._openerService.open(( URI.parse(
|
|
1141
|
+
'https://code.visualstudio.com/docs/editor/tasks#_defining-a-problem-matcher'
|
|
1142
|
+
)));
|
|
1143
|
+
}
|
|
1144
|
+
async _findSingleWorkspaceTaskOfGroup(group) {
|
|
1145
|
+
const tasksOfGroup = await this._findWorkspaceTasksInGroup(group, true);
|
|
1146
|
+
if ((tasksOfGroup.length === 1) && (typeof tasksOfGroup[0].configurationProperties.group !== 'string') && tasksOfGroup[0].configurationProperties.group?.isDefault) {
|
|
1147
|
+
let resolvedTask;
|
|
1148
|
+
if (ConfiguringTask.is(tasksOfGroup[0])) {
|
|
1149
|
+
resolvedTask = await this.tryResolveTask(tasksOfGroup[0]);
|
|
1150
|
+
}
|
|
1151
|
+
else {
|
|
1152
|
+
resolvedTask = tasksOfGroup[0];
|
|
1153
|
+
}
|
|
1154
|
+
if (resolvedTask) {
|
|
1155
|
+
return this.run(resolvedTask, undefined, 1 );
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
1158
|
+
return undefined;
|
|
1159
|
+
}
|
|
1160
|
+
async _build() {
|
|
1161
|
+
const tryBuildShortcut = await this._findSingleWorkspaceTaskOfGroup(TaskGroup.Build);
|
|
1162
|
+
if (tryBuildShortcut) {
|
|
1163
|
+
return tryBuildShortcut;
|
|
1164
|
+
}
|
|
1165
|
+
return this._getGroupedTasksAndExecute();
|
|
1166
|
+
}
|
|
1167
|
+
async _runTest() {
|
|
1168
|
+
const tryTestShortcut = await this._findSingleWorkspaceTaskOfGroup(TaskGroup.Test);
|
|
1169
|
+
if (tryTestShortcut) {
|
|
1170
|
+
return tryTestShortcut;
|
|
1171
|
+
}
|
|
1172
|
+
return this._getGroupedTasksAndExecute(true);
|
|
1173
|
+
}
|
|
1174
|
+
async _getGroupedTasksAndExecute(test) {
|
|
1175
|
+
const tasks = await this._getGroupedTasks();
|
|
1176
|
+
const runnable = this._createRunnableTask(tasks, test ? TaskGroup.Test : TaskGroup.Build);
|
|
1177
|
+
if (!runnable || !runnable.task) {
|
|
1178
|
+
if (test) {
|
|
1179
|
+
if (this.schemaVersion === 1 ) {
|
|
1180
|
+
throw new TaskError(Severity.Info, nls.localizeWithPath('vs/workbench/contrib/tasks/browser/abstractTaskService', 'TaskService.noTestTask1', 'No test task defined. Mark a task with \'isTestCommand\' in the tasks.json file.'), 3 );
|
|
1181
|
+
}
|
|
1182
|
+
else {
|
|
1183
|
+
throw new TaskError(Severity.Info, nls.localizeWithPath('vs/workbench/contrib/tasks/browser/abstractTaskService', 'TaskService.noTestTask2', 'No test task defined. Mark a task with as a \'test\' group in the tasks.json file.'), 3 );
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
else {
|
|
1187
|
+
if (this.schemaVersion === 1 ) {
|
|
1188
|
+
throw new TaskError(Severity.Info, nls.localizeWithPath('vs/workbench/contrib/tasks/browser/abstractTaskService', 'TaskService.noBuildTask1', 'No build task defined. Mark a task with \'isBuildCommand\' in the tasks.json file.'), 2 );
|
|
1189
|
+
}
|
|
1190
|
+
else {
|
|
1191
|
+
throw new TaskError(Severity.Info, nls.localizeWithPath('vs/workbench/contrib/tasks/browser/abstractTaskService', 'TaskService.noBuildTask2', 'No build task defined. Mark a task with as a \'build\' group in the tasks.json file.'), 2 );
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
1194
|
+
}
|
|
1195
|
+
let executeTaskResult;
|
|
1196
|
+
try {
|
|
1197
|
+
executeTaskResult = await this._executeTask(runnable.task, runnable.resolver, 1 );
|
|
1198
|
+
}
|
|
1199
|
+
catch (error) {
|
|
1200
|
+
this._handleError(error);
|
|
1201
|
+
return Promise.reject(error);
|
|
1202
|
+
}
|
|
1203
|
+
return executeTaskResult;
|
|
1204
|
+
}
|
|
1205
|
+
async run(task, options, runSource = 0 ) {
|
|
1206
|
+
if (!(await this._trust())) {
|
|
1207
|
+
return;
|
|
1208
|
+
}
|
|
1209
|
+
if (!task) {
|
|
1210
|
+
throw new TaskError(Severity.Info, nls.localizeWithPath('vs/workbench/contrib/tasks/browser/abstractTaskService', 'TaskServer.noTask', 'Task to execute is undefined'), 5 );
|
|
1211
|
+
}
|
|
1212
|
+
const resolver = this._createResolver();
|
|
1213
|
+
let executeTaskResult;
|
|
1214
|
+
try {
|
|
1215
|
+
if (options && options.attachProblemMatcher && this._shouldAttachProblemMatcher(task) && !InMemoryTask.is(task)) {
|
|
1216
|
+
const taskToExecute = await this._attachProblemMatcher(task);
|
|
1217
|
+
if (taskToExecute) {
|
|
1218
|
+
executeTaskResult = await this._executeTask(taskToExecute, resolver, runSource);
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1221
|
+
else {
|
|
1222
|
+
executeTaskResult = await this._executeTask(task, resolver, runSource);
|
|
1223
|
+
}
|
|
1224
|
+
return executeTaskResult;
|
|
1225
|
+
}
|
|
1226
|
+
catch (error) {
|
|
1227
|
+
this._handleError(error);
|
|
1228
|
+
return Promise.reject(error);
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
_isProvideTasksEnabled() {
|
|
1232
|
+
const settingValue = this._configurationService.getValue("task.autoDetect" );
|
|
1233
|
+
return settingValue === 'on';
|
|
1234
|
+
}
|
|
1235
|
+
_isProblemMatcherPromptEnabled(type) {
|
|
1236
|
+
const settingValue = this._configurationService.getValue(PROBLEM_MATCHER_NEVER_CONFIG);
|
|
1237
|
+
if (Types.isBoolean(settingValue)) {
|
|
1238
|
+
return !settingValue;
|
|
1239
|
+
}
|
|
1240
|
+
if (type === undefined) {
|
|
1241
|
+
return true;
|
|
1242
|
+
}
|
|
1243
|
+
const settingValueMap = settingValue;
|
|
1244
|
+
return !settingValueMap[type];
|
|
1245
|
+
}
|
|
1246
|
+
_getTypeForTask(task) {
|
|
1247
|
+
let type;
|
|
1248
|
+
if (CustomTask.is(task)) {
|
|
1249
|
+
const configProperties = task._source.config.element;
|
|
1250
|
+
type = configProperties.type;
|
|
1251
|
+
}
|
|
1252
|
+
else {
|
|
1253
|
+
type = task.getDefinition().type;
|
|
1254
|
+
}
|
|
1255
|
+
return type;
|
|
1256
|
+
}
|
|
1257
|
+
_shouldAttachProblemMatcher(task) {
|
|
1258
|
+
const enabled = this._isProblemMatcherPromptEnabled(this._getTypeForTask(task));
|
|
1259
|
+
if (enabled === false) {
|
|
1260
|
+
return false;
|
|
1261
|
+
}
|
|
1262
|
+
if (!this._canCustomize(task)) {
|
|
1263
|
+
return false;
|
|
1264
|
+
}
|
|
1265
|
+
if (task.configurationProperties.group !== undefined && task.configurationProperties.group !== TaskGroup.Build) {
|
|
1266
|
+
return false;
|
|
1267
|
+
}
|
|
1268
|
+
if (task.configurationProperties.problemMatchers !== undefined && task.configurationProperties.problemMatchers.length > 0) {
|
|
1269
|
+
return false;
|
|
1270
|
+
}
|
|
1271
|
+
if (ContributedTask.is(task)) {
|
|
1272
|
+
return !task.hasDefinedMatchers && !!task.configurationProperties.problemMatchers && (task.configurationProperties.problemMatchers.length === 0);
|
|
1273
|
+
}
|
|
1274
|
+
if (CustomTask.is(task)) {
|
|
1275
|
+
const configProperties = task._source.config.element;
|
|
1276
|
+
return configProperties.problemMatcher === undefined && !task.hasDefinedMatchers;
|
|
1277
|
+
}
|
|
1278
|
+
return false;
|
|
1279
|
+
}
|
|
1280
|
+
async _updateNeverProblemMatcherSetting(type) {
|
|
1281
|
+
const current = this._configurationService.getValue(PROBLEM_MATCHER_NEVER_CONFIG);
|
|
1282
|
+
if (current === true) {
|
|
1283
|
+
return;
|
|
1284
|
+
}
|
|
1285
|
+
let newValue;
|
|
1286
|
+
if (current !== false) {
|
|
1287
|
+
newValue = current;
|
|
1288
|
+
}
|
|
1289
|
+
else {
|
|
1290
|
+
newValue = Object.create(null);
|
|
1291
|
+
}
|
|
1292
|
+
newValue[type] = true;
|
|
1293
|
+
return this._configurationService.updateValue(PROBLEM_MATCHER_NEVER_CONFIG, newValue);
|
|
1294
|
+
}
|
|
1295
|
+
async _attachProblemMatcher(task) {
|
|
1296
|
+
let entries = [];
|
|
1297
|
+
for (const key of ( ProblemMatcherRegistry.keys())) {
|
|
1298
|
+
const matcher = ProblemMatcherRegistry.get(key);
|
|
1299
|
+
if (matcher.deprecated) {
|
|
1300
|
+
continue;
|
|
1301
|
+
}
|
|
1302
|
+
if (matcher.name === matcher.label) {
|
|
1303
|
+
entries.push({ label: matcher.name, matcher: matcher });
|
|
1304
|
+
}
|
|
1305
|
+
else {
|
|
1306
|
+
entries.push({
|
|
1307
|
+
label: matcher.label,
|
|
1308
|
+
description: `$${matcher.name}`,
|
|
1309
|
+
matcher: matcher
|
|
1310
|
+
});
|
|
1311
|
+
}
|
|
1312
|
+
}
|
|
1313
|
+
if (entries.length === 0) {
|
|
1314
|
+
return;
|
|
1315
|
+
}
|
|
1316
|
+
entries = entries.sort((a, b) => {
|
|
1317
|
+
if (a.label && b.label) {
|
|
1318
|
+
return a.label.localeCompare(b.label);
|
|
1319
|
+
}
|
|
1320
|
+
else {
|
|
1321
|
+
return 0;
|
|
1322
|
+
}
|
|
1323
|
+
});
|
|
1324
|
+
entries.unshift({ type: 'separator', label: ( nls.localizeWithPath(
|
|
1325
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
1326
|
+
'TaskService.associate',
|
|
1327
|
+
'associate'
|
|
1328
|
+
)) });
|
|
1329
|
+
let taskType;
|
|
1330
|
+
if (CustomTask.is(task)) {
|
|
1331
|
+
const configProperties = task._source.config.element;
|
|
1332
|
+
taskType = configProperties.type;
|
|
1333
|
+
}
|
|
1334
|
+
else {
|
|
1335
|
+
taskType = task.getDefinition().type;
|
|
1336
|
+
}
|
|
1337
|
+
entries.unshift({ label: ( nls.localizeWithPath(
|
|
1338
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
1339
|
+
'TaskService.attachProblemMatcher.continueWithout',
|
|
1340
|
+
'Continue without scanning the task output'
|
|
1341
|
+
)), matcher: undefined }, { label: ( nls.localizeWithPath(
|
|
1342
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
1343
|
+
'TaskService.attachProblemMatcher.never',
|
|
1344
|
+
'Never scan the task output for this task'
|
|
1345
|
+
)), matcher: undefined, never: true }, { label: ( nls.localizeWithPath(
|
|
1346
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
1347
|
+
'TaskService.attachProblemMatcher.neverType',
|
|
1348
|
+
'Never scan the task output for {0} tasks',
|
|
1349
|
+
taskType
|
|
1350
|
+
)), matcher: undefined, setting: taskType }, { label: ( nls.localizeWithPath(
|
|
1351
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
1352
|
+
'TaskService.attachProblemMatcher.learnMoreAbout',
|
|
1353
|
+
'Learn more about scanning the task output'
|
|
1354
|
+
)), matcher: undefined, learnMore: true });
|
|
1355
|
+
const problemMatcher = await this._quickInputService.pick(entries, { placeHolder: ( nls.localizeWithPath(
|
|
1356
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
1357
|
+
'selectProblemMatcher',
|
|
1358
|
+
'Select for which kind of errors and warnings to scan the task output'
|
|
1359
|
+
)) });
|
|
1360
|
+
if (!problemMatcher) {
|
|
1361
|
+
return task;
|
|
1362
|
+
}
|
|
1363
|
+
if (problemMatcher.learnMore) {
|
|
1364
|
+
this._openDocumentation();
|
|
1365
|
+
return undefined;
|
|
1366
|
+
}
|
|
1367
|
+
if (problemMatcher.never) {
|
|
1368
|
+
this.customize(task, { problemMatcher: [] }, true);
|
|
1369
|
+
return task;
|
|
1370
|
+
}
|
|
1371
|
+
if (problemMatcher.matcher) {
|
|
1372
|
+
const newTask = task.clone();
|
|
1373
|
+
const matcherReference = `$${problemMatcher.matcher.name}`;
|
|
1374
|
+
const properties = { problemMatcher: [matcherReference] };
|
|
1375
|
+
newTask.configurationProperties.problemMatchers = [matcherReference];
|
|
1376
|
+
const matcher = ProblemMatcherRegistry.get(problemMatcher.matcher.name);
|
|
1377
|
+
if (matcher && matcher.watching !== undefined) {
|
|
1378
|
+
properties.isBackground = true;
|
|
1379
|
+
newTask.configurationProperties.isBackground = true;
|
|
1380
|
+
}
|
|
1381
|
+
this.customize(task, properties, true);
|
|
1382
|
+
return newTask;
|
|
1383
|
+
}
|
|
1384
|
+
if (problemMatcher.setting) {
|
|
1385
|
+
await this._updateNeverProblemMatcherSetting(problemMatcher.setting);
|
|
1386
|
+
}
|
|
1387
|
+
return task;
|
|
1388
|
+
}
|
|
1389
|
+
async _getTasksForGroup(group) {
|
|
1390
|
+
const groups = await this._getGroupedTasks();
|
|
1391
|
+
const result = [];
|
|
1392
|
+
groups.forEach(tasks => {
|
|
1393
|
+
for (const task of tasks) {
|
|
1394
|
+
const configTaskGroup = TaskGroup.from(task.configurationProperties.group);
|
|
1395
|
+
if (configTaskGroup?._id === group._id) {
|
|
1396
|
+
result.push(task);
|
|
1397
|
+
}
|
|
1398
|
+
}
|
|
1399
|
+
});
|
|
1400
|
+
return result;
|
|
1401
|
+
}
|
|
1402
|
+
needsFolderQualification() {
|
|
1403
|
+
return this._contextService.getWorkbenchState() === 3 ;
|
|
1404
|
+
}
|
|
1405
|
+
_canCustomize(task) {
|
|
1406
|
+
if (this.schemaVersion !== 2 ) {
|
|
1407
|
+
return false;
|
|
1408
|
+
}
|
|
1409
|
+
if (CustomTask.is(task)) {
|
|
1410
|
+
return true;
|
|
1411
|
+
}
|
|
1412
|
+
if (ContributedTask.is(task)) {
|
|
1413
|
+
return !!task.getWorkspaceFolder();
|
|
1414
|
+
}
|
|
1415
|
+
return false;
|
|
1416
|
+
}
|
|
1417
|
+
async _formatTaskForJson(resource, task) {
|
|
1418
|
+
let reference;
|
|
1419
|
+
let stringValue = '';
|
|
1420
|
+
try {
|
|
1421
|
+
reference = await this._textModelResolverService.createModelReference(resource);
|
|
1422
|
+
const model = reference.object.textEditorModel;
|
|
1423
|
+
const { tabSize, insertSpaces } = model.getOptions();
|
|
1424
|
+
const eol = model.getEOL();
|
|
1425
|
+
let stringified = toFormattedString(task, { eol, tabSize, insertSpaces });
|
|
1426
|
+
const regex = ( new RegExp(eol + (insertSpaces ? ' '.repeat(tabSize) : '\\t'), 'g'));
|
|
1427
|
+
stringified = stringified.replace(regex, eol + (insertSpaces ? ' '.repeat(tabSize * 3) : '\t\t\t'));
|
|
1428
|
+
const twoTabs = insertSpaces ? ' '.repeat(tabSize * 2) : '\t\t';
|
|
1429
|
+
stringValue = twoTabs + stringified.slice(0, stringified.length - 1) + twoTabs + stringified.slice(stringified.length - 1);
|
|
1430
|
+
}
|
|
1431
|
+
finally {
|
|
1432
|
+
reference?.dispose();
|
|
1433
|
+
}
|
|
1434
|
+
return stringValue;
|
|
1435
|
+
}
|
|
1436
|
+
async _openEditorAtTask(resource, task, configIndex = -1) {
|
|
1437
|
+
if (resource === undefined) {
|
|
1438
|
+
return Promise.resolve(false);
|
|
1439
|
+
}
|
|
1440
|
+
const fileContent = await this._fileService.readFile(resource);
|
|
1441
|
+
const content = fileContent.value;
|
|
1442
|
+
if (!content || !task) {
|
|
1443
|
+
return false;
|
|
1444
|
+
}
|
|
1445
|
+
const contentValue = ( content.toString());
|
|
1446
|
+
let stringValue;
|
|
1447
|
+
if (configIndex !== -1) {
|
|
1448
|
+
const json = this._configurationService.getValue('tasks', { resource });
|
|
1449
|
+
if (json.tasks && (json.tasks.length > configIndex)) {
|
|
1450
|
+
stringValue = await this._formatTaskForJson(resource, json.tasks[configIndex]);
|
|
1451
|
+
}
|
|
1452
|
+
}
|
|
1453
|
+
if (!stringValue) {
|
|
1454
|
+
if (typeof task === 'string') {
|
|
1455
|
+
stringValue = task;
|
|
1456
|
+
}
|
|
1457
|
+
else {
|
|
1458
|
+
stringValue = await this._formatTaskForJson(resource, task);
|
|
1459
|
+
}
|
|
1460
|
+
}
|
|
1461
|
+
const index = contentValue.indexOf(stringValue);
|
|
1462
|
+
let startLineNumber = 1;
|
|
1463
|
+
for (let i = 0; i < index; i++) {
|
|
1464
|
+
if (contentValue.charAt(i) === '\n') {
|
|
1465
|
+
startLineNumber++;
|
|
1466
|
+
}
|
|
1467
|
+
}
|
|
1468
|
+
let endLineNumber = startLineNumber;
|
|
1469
|
+
for (let i = 0; i < stringValue.length; i++) {
|
|
1470
|
+
if (stringValue.charAt(i) === '\n') {
|
|
1471
|
+
endLineNumber++;
|
|
1472
|
+
}
|
|
1473
|
+
}
|
|
1474
|
+
const selection = startLineNumber > 1 ? { startLineNumber, startColumn: startLineNumber === endLineNumber ? 4 : 3, endLineNumber, endColumn: startLineNumber === endLineNumber ? undefined : 4 } : undefined;
|
|
1475
|
+
await this._editorService.openEditor({
|
|
1476
|
+
resource,
|
|
1477
|
+
options: {
|
|
1478
|
+
pinned: false,
|
|
1479
|
+
forceReload: true,
|
|
1480
|
+
selection,
|
|
1481
|
+
selectionRevealType: 1
|
|
1482
|
+
}
|
|
1483
|
+
});
|
|
1484
|
+
return !!selection;
|
|
1485
|
+
}
|
|
1486
|
+
_createCustomizableTask(task) {
|
|
1487
|
+
let toCustomize;
|
|
1488
|
+
const taskConfig = CustomTask.is(task) || ConfiguringTask.is(task) ? task._source.config : undefined;
|
|
1489
|
+
if (taskConfig && taskConfig.element) {
|
|
1490
|
+
toCustomize = { ...(taskConfig.element) };
|
|
1491
|
+
}
|
|
1492
|
+
else if (ContributedTask.is(task)) {
|
|
1493
|
+
toCustomize = {};
|
|
1494
|
+
const identifier = Object.assign(Object.create(null), task.defines);
|
|
1495
|
+
delete identifier['_key'];
|
|
1496
|
+
( Object.keys(identifier)).forEach(key => toCustomize[key] = identifier[key]);
|
|
1497
|
+
if (task.configurationProperties.problemMatchers && task.configurationProperties.problemMatchers.length > 0 && Types.isStringArray(task.configurationProperties.problemMatchers)) {
|
|
1498
|
+
toCustomize.problemMatcher = task.configurationProperties.problemMatchers;
|
|
1499
|
+
}
|
|
1500
|
+
if (task.configurationProperties.group) {
|
|
1501
|
+
toCustomize.group = GroupKind.to(task.configurationProperties.group);
|
|
1502
|
+
}
|
|
1503
|
+
}
|
|
1504
|
+
if (!toCustomize) {
|
|
1505
|
+
return undefined;
|
|
1506
|
+
}
|
|
1507
|
+
if (toCustomize.problemMatcher === undefined && task.configurationProperties.problemMatchers === undefined || (task.configurationProperties.problemMatchers && task.configurationProperties.problemMatchers.length === 0)) {
|
|
1508
|
+
toCustomize.problemMatcher = [];
|
|
1509
|
+
}
|
|
1510
|
+
if (task._source.label !== 'Workspace') {
|
|
1511
|
+
toCustomize.label = task.configurationProperties.identifier;
|
|
1512
|
+
}
|
|
1513
|
+
else {
|
|
1514
|
+
toCustomize.label = task._label;
|
|
1515
|
+
}
|
|
1516
|
+
toCustomize.detail = task.configurationProperties.detail;
|
|
1517
|
+
return toCustomize;
|
|
1518
|
+
}
|
|
1519
|
+
async customize(task, properties, openConfig) {
|
|
1520
|
+
if (!(await this._trust())) {
|
|
1521
|
+
return;
|
|
1522
|
+
}
|
|
1523
|
+
const workspaceFolder = task.getWorkspaceFolder();
|
|
1524
|
+
if (!workspaceFolder) {
|
|
1525
|
+
return Promise.resolve(undefined);
|
|
1526
|
+
}
|
|
1527
|
+
const configuration = this._getConfiguration(workspaceFolder, task._source.kind);
|
|
1528
|
+
if (configuration.hasParseErrors) {
|
|
1529
|
+
this._notificationService.warn(( nls.localizeWithPath(
|
|
1530
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
1531
|
+
'customizeParseErrors',
|
|
1532
|
+
'The current task configuration has errors. Please fix the errors first before customizing a task.'
|
|
1533
|
+
)));
|
|
1534
|
+
return Promise.resolve(undefined);
|
|
1535
|
+
}
|
|
1536
|
+
const fileConfig = configuration.config;
|
|
1537
|
+
const toCustomize = this._createCustomizableTask(task);
|
|
1538
|
+
if (!toCustomize) {
|
|
1539
|
+
return Promise.resolve(undefined);
|
|
1540
|
+
}
|
|
1541
|
+
const index = CustomTask.is(task) ? task._source.config.index : undefined;
|
|
1542
|
+
if (properties) {
|
|
1543
|
+
for (const property of Object.getOwnPropertyNames(properties)) {
|
|
1544
|
+
const value = properties[property];
|
|
1545
|
+
if (value !== undefined && value !== null) {
|
|
1546
|
+
toCustomize[property] = value;
|
|
1547
|
+
}
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1550
|
+
if (!fileConfig) {
|
|
1551
|
+
const value = {
|
|
1552
|
+
version: '2.0.0',
|
|
1553
|
+
tasks: [toCustomize]
|
|
1554
|
+
};
|
|
1555
|
+
let content = [
|
|
1556
|
+
'{',
|
|
1557
|
+
( nls.localizeWithPath(
|
|
1558
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
1559
|
+
'tasksJsonComment',
|
|
1560
|
+
'\t// See https://go.microsoft.com/fwlink/?LinkId=733558 \n\t// for the documentation about the tasks.json format'
|
|
1561
|
+
)),
|
|
1562
|
+
].join('\n') + JSON.stringify(value, null, '\t').substr(1);
|
|
1563
|
+
const editorConfig = this._configurationService.getValue();
|
|
1564
|
+
if (editorConfig.editor.insertSpaces) {
|
|
1565
|
+
content = content.replace(/(\n)(\t+)/g, (_, s1, s2) => s1 + ' '.repeat(s2.length * editorConfig.editor.tabSize));
|
|
1566
|
+
}
|
|
1567
|
+
await this._textFileService.create([{ resource: workspaceFolder.toResource('.vscode/tasks.json'), value: content }]);
|
|
1568
|
+
}
|
|
1569
|
+
else {
|
|
1570
|
+
if ((index === -1) && properties) {
|
|
1571
|
+
if (properties.problemMatcher !== undefined) {
|
|
1572
|
+
fileConfig.problemMatcher = properties.problemMatcher;
|
|
1573
|
+
await this._writeConfiguration(workspaceFolder, 'tasks.problemMatchers', fileConfig.problemMatcher, task._source.kind);
|
|
1574
|
+
}
|
|
1575
|
+
else if (properties.group !== undefined) {
|
|
1576
|
+
fileConfig.group = properties.group;
|
|
1577
|
+
await this._writeConfiguration(workspaceFolder, 'tasks.group', fileConfig.group, task._source.kind);
|
|
1578
|
+
}
|
|
1579
|
+
}
|
|
1580
|
+
else {
|
|
1581
|
+
if (!Array.isArray(fileConfig.tasks)) {
|
|
1582
|
+
fileConfig.tasks = [];
|
|
1583
|
+
}
|
|
1584
|
+
if (index === undefined) {
|
|
1585
|
+
fileConfig.tasks.push(toCustomize);
|
|
1586
|
+
}
|
|
1587
|
+
else {
|
|
1588
|
+
fileConfig.tasks[index] = toCustomize;
|
|
1589
|
+
}
|
|
1590
|
+
await this._writeConfiguration(workspaceFolder, 'tasks.tasks', fileConfig.tasks, task._source.kind);
|
|
1591
|
+
}
|
|
1592
|
+
}
|
|
1593
|
+
if (openConfig) {
|
|
1594
|
+
this._openEditorAtTask(this._getResourceForTask(task), toCustomize);
|
|
1595
|
+
}
|
|
1596
|
+
}
|
|
1597
|
+
_writeConfiguration(workspaceFolder, key, value, source) {
|
|
1598
|
+
let target = undefined;
|
|
1599
|
+
switch (source) {
|
|
1600
|
+
case TaskSourceKind.User:
|
|
1601
|
+
target = 2 ;
|
|
1602
|
+
break;
|
|
1603
|
+
case TaskSourceKind.WorkspaceFile:
|
|
1604
|
+
target = 5 ;
|
|
1605
|
+
break;
|
|
1606
|
+
default: if (this._contextService.getWorkbenchState() === 2 ) {
|
|
1607
|
+
target = 5 ;
|
|
1608
|
+
}
|
|
1609
|
+
else if (this._contextService.getWorkbenchState() === 3 ) {
|
|
1610
|
+
target = 6 ;
|
|
1611
|
+
}
|
|
1612
|
+
}
|
|
1613
|
+
if (target) {
|
|
1614
|
+
return this._configurationService.updateValue(key, value, { resource: workspaceFolder.uri }, target);
|
|
1615
|
+
}
|
|
1616
|
+
else {
|
|
1617
|
+
return undefined;
|
|
1618
|
+
}
|
|
1619
|
+
}
|
|
1620
|
+
_getResourceForKind(kind) {
|
|
1621
|
+
this._updateSetup();
|
|
1622
|
+
switch (kind) {
|
|
1623
|
+
case TaskSourceKind.User: {
|
|
1624
|
+
return resources.joinPath(resources.dirname(this._preferencesService.userSettingsResource), 'tasks.json');
|
|
1625
|
+
}
|
|
1626
|
+
case TaskSourceKind.WorkspaceFile: {
|
|
1627
|
+
if (this._workspace && this._workspace.configuration) {
|
|
1628
|
+
return this._workspace.configuration;
|
|
1629
|
+
}
|
|
1630
|
+
}
|
|
1631
|
+
default: {
|
|
1632
|
+
return undefined;
|
|
1633
|
+
}
|
|
1634
|
+
}
|
|
1635
|
+
}
|
|
1636
|
+
_getResourceForTask(task) {
|
|
1637
|
+
if (CustomTask.is(task)) {
|
|
1638
|
+
let uri = this._getResourceForKind(task._source.kind);
|
|
1639
|
+
if (!uri) {
|
|
1640
|
+
const taskFolder = task.getWorkspaceFolder();
|
|
1641
|
+
if (taskFolder) {
|
|
1642
|
+
uri = taskFolder.toResource(task._source.config.file);
|
|
1643
|
+
}
|
|
1644
|
+
else {
|
|
1645
|
+
uri = this.workspaceFolders[0].uri;
|
|
1646
|
+
}
|
|
1647
|
+
}
|
|
1648
|
+
return uri;
|
|
1649
|
+
}
|
|
1650
|
+
else {
|
|
1651
|
+
return task.getWorkspaceFolder().toResource('.vscode/tasks.json');
|
|
1652
|
+
}
|
|
1653
|
+
}
|
|
1654
|
+
async openConfig(task) {
|
|
1655
|
+
let resource;
|
|
1656
|
+
if (task) {
|
|
1657
|
+
resource = this._getResourceForTask(task);
|
|
1658
|
+
}
|
|
1659
|
+
else {
|
|
1660
|
+
resource = (this._workspaceFolders && (this._workspaceFolders.length > 0)) ? this._workspaceFolders[0].toResource('.vscode/tasks.json') : undefined;
|
|
1661
|
+
}
|
|
1662
|
+
return this._openEditorAtTask(resource, task ? task._label : undefined, task ? task._source.config.index : -1);
|
|
1663
|
+
}
|
|
1664
|
+
_createRunnableTask(tasks, group) {
|
|
1665
|
+
const resolverData = ( new Map());
|
|
1666
|
+
const workspaceTasks = [];
|
|
1667
|
+
const extensionTasks = [];
|
|
1668
|
+
tasks.forEach((tasks, folder) => {
|
|
1669
|
+
let data = resolverData.get(folder);
|
|
1670
|
+
if (!data) {
|
|
1671
|
+
data = {
|
|
1672
|
+
id: ( new Map()),
|
|
1673
|
+
label: ( new Map()),
|
|
1674
|
+
identifier: ( new Map())
|
|
1675
|
+
};
|
|
1676
|
+
resolverData.set(folder, data);
|
|
1677
|
+
}
|
|
1678
|
+
for (const task of tasks) {
|
|
1679
|
+
data.id.set(task._id, task);
|
|
1680
|
+
data.label.set(task._label, task);
|
|
1681
|
+
if (task.configurationProperties.identifier) {
|
|
1682
|
+
data.identifier.set(task.configurationProperties.identifier, task);
|
|
1683
|
+
}
|
|
1684
|
+
if (group && task.configurationProperties.group === group) {
|
|
1685
|
+
if (task._source.kind === TaskSourceKind.Workspace) {
|
|
1686
|
+
workspaceTasks.push(task);
|
|
1687
|
+
}
|
|
1688
|
+
else {
|
|
1689
|
+
extensionTasks.push(task);
|
|
1690
|
+
}
|
|
1691
|
+
}
|
|
1692
|
+
}
|
|
1693
|
+
});
|
|
1694
|
+
const resolver = {
|
|
1695
|
+
resolve: async (uri, alias) => {
|
|
1696
|
+
const data = resolverData.get(typeof uri === 'string' ? uri : ( uri.toString()));
|
|
1697
|
+
if (!data) {
|
|
1698
|
+
return undefined;
|
|
1699
|
+
}
|
|
1700
|
+
return data.id.get(alias) || data.label.get(alias) || data.identifier.get(alias);
|
|
1701
|
+
}
|
|
1702
|
+
};
|
|
1703
|
+
if (workspaceTasks.length > 0) {
|
|
1704
|
+
if (workspaceTasks.length > 1) {
|
|
1705
|
+
this._log(( nls.localizeWithPath(
|
|
1706
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
1707
|
+
'moreThanOneBuildTask',
|
|
1708
|
+
'There are many build tasks defined in the tasks.json. Executing the first one.'
|
|
1709
|
+
)));
|
|
1710
|
+
}
|
|
1711
|
+
return { task: workspaceTasks[0], resolver };
|
|
1712
|
+
}
|
|
1713
|
+
if (extensionTasks.length === 0) {
|
|
1714
|
+
return undefined;
|
|
1715
|
+
}
|
|
1716
|
+
if (extensionTasks.length === 1) {
|
|
1717
|
+
return { task: extensionTasks[0], resolver };
|
|
1718
|
+
}
|
|
1719
|
+
else {
|
|
1720
|
+
const id = UUID.generateUuid();
|
|
1721
|
+
const task = ( new InMemoryTask(
|
|
1722
|
+
id,
|
|
1723
|
+
{ kind: TaskSourceKind.InMemory, label: 'inMemory' },
|
|
1724
|
+
id,
|
|
1725
|
+
'inMemory',
|
|
1726
|
+
{ reevaluateOnRerun: true },
|
|
1727
|
+
{
|
|
1728
|
+
identifier: id,
|
|
1729
|
+
dependsOn: ( extensionTasks.map(
|
|
1730
|
+
(extensionTask) => { return { uri: extensionTask.getWorkspaceFolder().uri, task: extensionTask._id }; }
|
|
1731
|
+
)),
|
|
1732
|
+
name: id
|
|
1733
|
+
}
|
|
1734
|
+
));
|
|
1735
|
+
return { task, resolver };
|
|
1736
|
+
}
|
|
1737
|
+
}
|
|
1738
|
+
_createResolver(grouped) {
|
|
1739
|
+
let resolverData;
|
|
1740
|
+
async function quickResolve(that, uri, identifier) {
|
|
1741
|
+
const foundTasks = await that._findWorkspaceTasks((task) => {
|
|
1742
|
+
const taskUri = ((ConfiguringTask.is(task) || CustomTask.is(task)) ? task._source.config.workspaceFolder?.uri : undefined);
|
|
1743
|
+
const originalUri = (typeof uri === 'string' ? uri : ( uri.toString()));
|
|
1744
|
+
if (taskUri?.toString() !== originalUri) {
|
|
1745
|
+
return false;
|
|
1746
|
+
}
|
|
1747
|
+
if (Types.isString(identifier)) {
|
|
1748
|
+
return ((task._label === identifier) || (task.configurationProperties.identifier === identifier));
|
|
1749
|
+
}
|
|
1750
|
+
else {
|
|
1751
|
+
const keyedIdentifier = task.getDefinition(true);
|
|
1752
|
+
const searchIdentifier = TaskDefinition.createTaskIdentifier(identifier, console);
|
|
1753
|
+
return (searchIdentifier && keyedIdentifier) ? (searchIdentifier._key === keyedIdentifier._key) : false;
|
|
1754
|
+
}
|
|
1755
|
+
});
|
|
1756
|
+
if (foundTasks.length === 0) {
|
|
1757
|
+
return undefined;
|
|
1758
|
+
}
|
|
1759
|
+
const task = foundTasks[0];
|
|
1760
|
+
if (ConfiguringTask.is(task)) {
|
|
1761
|
+
return that.tryResolveTask(task);
|
|
1762
|
+
}
|
|
1763
|
+
return task;
|
|
1764
|
+
}
|
|
1765
|
+
async function getResolverData(that) {
|
|
1766
|
+
if (resolverData === undefined) {
|
|
1767
|
+
resolverData = ( new Map());
|
|
1768
|
+
(grouped || (await that._getGroupedTasks())).forEach((tasks, folder) => {
|
|
1769
|
+
let data = resolverData.get(folder);
|
|
1770
|
+
if (!data) {
|
|
1771
|
+
data = { label: ( new Map()), identifier: ( new Map()), taskIdentifier: ( new Map()) };
|
|
1772
|
+
resolverData.set(folder, data);
|
|
1773
|
+
}
|
|
1774
|
+
for (const task of tasks) {
|
|
1775
|
+
data.label.set(task._label, task);
|
|
1776
|
+
if (task.configurationProperties.identifier) {
|
|
1777
|
+
data.identifier.set(task.configurationProperties.identifier, task);
|
|
1778
|
+
}
|
|
1779
|
+
const keyedIdentifier = task.getDefinition(true);
|
|
1780
|
+
if (keyedIdentifier !== undefined) {
|
|
1781
|
+
data.taskIdentifier.set(keyedIdentifier._key, task);
|
|
1782
|
+
}
|
|
1783
|
+
}
|
|
1784
|
+
});
|
|
1785
|
+
}
|
|
1786
|
+
return resolverData;
|
|
1787
|
+
}
|
|
1788
|
+
async function fullResolve(that, uri, identifier) {
|
|
1789
|
+
const allResolverData = await getResolverData(that);
|
|
1790
|
+
const data = allResolverData.get(typeof uri === 'string' ? uri : ( uri.toString()));
|
|
1791
|
+
if (!data) {
|
|
1792
|
+
return undefined;
|
|
1793
|
+
}
|
|
1794
|
+
if (Types.isString(identifier)) {
|
|
1795
|
+
return data.label.get(identifier) || data.identifier.get(identifier);
|
|
1796
|
+
}
|
|
1797
|
+
else {
|
|
1798
|
+
const key = TaskDefinition.createTaskIdentifier(identifier, console);
|
|
1799
|
+
return key !== undefined ? data.taskIdentifier.get(key._key) : undefined;
|
|
1800
|
+
}
|
|
1801
|
+
}
|
|
1802
|
+
return {
|
|
1803
|
+
resolve: async (uri, identifier) => {
|
|
1804
|
+
if (!identifier) {
|
|
1805
|
+
return undefined;
|
|
1806
|
+
}
|
|
1807
|
+
if ((resolverData === undefined) && (grouped === undefined)) {
|
|
1808
|
+
return (await quickResolve(this, uri, identifier)) ?? fullResolve(this, uri, identifier);
|
|
1809
|
+
}
|
|
1810
|
+
else {
|
|
1811
|
+
return fullResolve(this, uri, identifier);
|
|
1812
|
+
}
|
|
1813
|
+
}
|
|
1814
|
+
};
|
|
1815
|
+
}
|
|
1816
|
+
async _saveBeforeRun() {
|
|
1817
|
+
let SaveBeforeRunConfigOptions;
|
|
1818
|
+
( (function(SaveBeforeRunConfigOptions) {
|
|
1819
|
+
SaveBeforeRunConfigOptions["Always"] = "always";
|
|
1820
|
+
SaveBeforeRunConfigOptions["Never"] = "never";
|
|
1821
|
+
SaveBeforeRunConfigOptions["Prompt"] = "prompt";
|
|
1822
|
+
})(SaveBeforeRunConfigOptions || (SaveBeforeRunConfigOptions = {})));
|
|
1823
|
+
const saveBeforeRunTaskConfig = this._configurationService.getValue("task.saveBeforeRun" );
|
|
1824
|
+
if (saveBeforeRunTaskConfig === SaveBeforeRunConfigOptions.Never) {
|
|
1825
|
+
return false;
|
|
1826
|
+
}
|
|
1827
|
+
else if (saveBeforeRunTaskConfig === SaveBeforeRunConfigOptions.Prompt && ( this._editorService.editors.some(e => e.isDirty()))) {
|
|
1828
|
+
const { confirmed } = await this._dialogService.confirm({
|
|
1829
|
+
message: ( nls.localizeWithPath(
|
|
1830
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
1831
|
+
'TaskSystem.saveBeforeRun.prompt.title',
|
|
1832
|
+
"Save all editors?"
|
|
1833
|
+
)),
|
|
1834
|
+
detail: ( nls.localizeWithPath(
|
|
1835
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
1836
|
+
'detail',
|
|
1837
|
+
"Do you want to save all editors before running the task?"
|
|
1838
|
+
)),
|
|
1839
|
+
primaryButton: ( nls.localizeWithPath(
|
|
1840
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
1841
|
+
{ key: 'saveBeforeRun.save', comment: ['&& denotes a mnemonic'] },
|
|
1842
|
+
'&&Save'
|
|
1843
|
+
)),
|
|
1844
|
+
cancelButton: ( nls.localizeWithPath(
|
|
1845
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
1846
|
+
'saveBeforeRun.dontSave',
|
|
1847
|
+
'Don\'t save'
|
|
1848
|
+
)),
|
|
1849
|
+
});
|
|
1850
|
+
if (!confirmed) {
|
|
1851
|
+
return false;
|
|
1852
|
+
}
|
|
1853
|
+
}
|
|
1854
|
+
await this._editorService.saveAll({ reason: 2 });
|
|
1855
|
+
return true;
|
|
1856
|
+
}
|
|
1857
|
+
async _executeTask(task, resolver, runSource) {
|
|
1858
|
+
let taskToRun = task;
|
|
1859
|
+
if (await this._saveBeforeRun()) {
|
|
1860
|
+
await this._configurationService.reloadConfiguration();
|
|
1861
|
+
await this._updateWorkspaceTasks();
|
|
1862
|
+
const taskFolder = task.getWorkspaceFolder();
|
|
1863
|
+
const taskIdentifier = task.configurationProperties.identifier;
|
|
1864
|
+
const taskType = CustomTask.is(task) ? task.customizes()?.type : (ContributedTask.is(task) ? task.type : undefined);
|
|
1865
|
+
taskToRun = ((taskFolder && taskIdentifier && ((runSource === 1) ))
|
|
1866
|
+
? await this.getTask(taskFolder, taskIdentifier, false, taskType) : task) ?? task;
|
|
1867
|
+
}
|
|
1868
|
+
await ProblemMatcherRegistry.onReady();
|
|
1869
|
+
const executeResult = runSource === 4 ? this._getTaskSystem().reconnect(taskToRun, resolver) : this._getTaskSystem().run(taskToRun, resolver);
|
|
1870
|
+
if (executeResult) {
|
|
1871
|
+
return this._handleExecuteResult(executeResult, runSource);
|
|
1872
|
+
}
|
|
1873
|
+
return { exitCode: 0 };
|
|
1874
|
+
}
|
|
1875
|
+
async _handleExecuteResult(executeResult, runSource) {
|
|
1876
|
+
if (runSource === 1 ) {
|
|
1877
|
+
await this._setRecentlyUsedTask(executeResult.task);
|
|
1878
|
+
}
|
|
1879
|
+
if (executeResult.kind === 2 ) {
|
|
1880
|
+
const active = executeResult.active;
|
|
1881
|
+
if (active && active.same && runSource === 2 || runSource === 4 ) {
|
|
1882
|
+
this._logService.debug('Ignoring task that is already active', executeResult.task);
|
|
1883
|
+
return executeResult.promise;
|
|
1884
|
+
}
|
|
1885
|
+
if (active && active.same) {
|
|
1886
|
+
if (this._taskSystem?.isTaskVisible(executeResult.task)) {
|
|
1887
|
+
const message = ( nls.localizeWithPath(
|
|
1888
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
1889
|
+
'TaskSystem.activeSame.noBackground',
|
|
1890
|
+
'The task \'{0}\' is already active.',
|
|
1891
|
+
executeResult.task.getQualifiedLabel()
|
|
1892
|
+
));
|
|
1893
|
+
const lastInstance = this._getTaskSystem().getLastInstance(executeResult.task) ?? executeResult.task;
|
|
1894
|
+
this._notificationService.prompt(Severity.Warning, message, [{
|
|
1895
|
+
label: ( nls.localizeWithPath(
|
|
1896
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
1897
|
+
'terminateTask',
|
|
1898
|
+
"Terminate Task"
|
|
1899
|
+
)),
|
|
1900
|
+
run: () => this.terminate(lastInstance)
|
|
1901
|
+
},
|
|
1902
|
+
{
|
|
1903
|
+
label: ( nls.localizeWithPath(
|
|
1904
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
1905
|
+
'restartTask',
|
|
1906
|
+
"Restart Task"
|
|
1907
|
+
)),
|
|
1908
|
+
run: () => this._restart(lastInstance)
|
|
1909
|
+
}], { sticky: true });
|
|
1910
|
+
}
|
|
1911
|
+
else {
|
|
1912
|
+
this._taskSystem?.revealTask(executeResult.task);
|
|
1913
|
+
}
|
|
1914
|
+
}
|
|
1915
|
+
else {
|
|
1916
|
+
throw new TaskError(Severity.Warning, nls.localizeWithPath('vs/workbench/contrib/tasks/browser/abstractTaskService', 'TaskSystem.active', 'There is already a task running. Terminate it first before executing another task.'), 1 );
|
|
1917
|
+
}
|
|
1918
|
+
}
|
|
1919
|
+
this._setRecentlyUsedTask(executeResult.task);
|
|
1920
|
+
return executeResult.promise;
|
|
1921
|
+
}
|
|
1922
|
+
async _restart(task) {
|
|
1923
|
+
if (!this._taskSystem) {
|
|
1924
|
+
return;
|
|
1925
|
+
}
|
|
1926
|
+
const response = await this._taskSystem.terminate(task);
|
|
1927
|
+
if (response.success) {
|
|
1928
|
+
try {
|
|
1929
|
+
await this.run(task);
|
|
1930
|
+
}
|
|
1931
|
+
catch {
|
|
1932
|
+
}
|
|
1933
|
+
}
|
|
1934
|
+
else {
|
|
1935
|
+
this._notificationService.warn(( nls.localizeWithPath(
|
|
1936
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
1937
|
+
'TaskSystem.restartFailed',
|
|
1938
|
+
'Failed to terminate and restart task {0}',
|
|
1939
|
+
Types.isString(task) ? task : task.configurationProperties.name
|
|
1940
|
+
)));
|
|
1941
|
+
}
|
|
1942
|
+
}
|
|
1943
|
+
async terminate(task) {
|
|
1944
|
+
if (!(await this._trust())) {
|
|
1945
|
+
return { success: true, task: undefined };
|
|
1946
|
+
}
|
|
1947
|
+
if (!this._taskSystem) {
|
|
1948
|
+
return { success: true, task: undefined };
|
|
1949
|
+
}
|
|
1950
|
+
return this._taskSystem.terminate(task);
|
|
1951
|
+
}
|
|
1952
|
+
_terminateAll() {
|
|
1953
|
+
if (!this._taskSystem) {
|
|
1954
|
+
return Promise.resolve([]);
|
|
1955
|
+
}
|
|
1956
|
+
return this._taskSystem.terminateAll();
|
|
1957
|
+
}
|
|
1958
|
+
_createTerminalTaskSystem() {
|
|
1959
|
+
return ( new TerminalTaskSystem(
|
|
1960
|
+
this._terminalService,
|
|
1961
|
+
this._terminalGroupService,
|
|
1962
|
+
this._outputService,
|
|
1963
|
+
this._paneCompositeService,
|
|
1964
|
+
this._viewsService,
|
|
1965
|
+
this._markerService,
|
|
1966
|
+
this._modelService,
|
|
1967
|
+
this._configurationResolverService,
|
|
1968
|
+
this._contextService,
|
|
1969
|
+
this._environmentService,
|
|
1970
|
+
AbstractTaskService_1.OutputChannelId,
|
|
1971
|
+
this._fileService,
|
|
1972
|
+
this._terminalProfileResolverService,
|
|
1973
|
+
this._pathService,
|
|
1974
|
+
this._viewDescriptorService,
|
|
1975
|
+
this._logService,
|
|
1976
|
+
this._notificationService,
|
|
1977
|
+
this._instantiationService,
|
|
1978
|
+
(workspaceFolder) => {
|
|
1979
|
+
if (workspaceFolder) {
|
|
1980
|
+
return this._getTaskSystemInfo(workspaceFolder.uri.scheme);
|
|
1981
|
+
}
|
|
1982
|
+
else if (this._taskSystemInfos.size > 0) {
|
|
1983
|
+
const infos = Array.from(this._taskSystemInfos.entries());
|
|
1984
|
+
const notFile = infos.filter(info => info[0] !== Schemas.file);
|
|
1985
|
+
if (notFile.length > 0) {
|
|
1986
|
+
return notFile[0][1][0];
|
|
1987
|
+
}
|
|
1988
|
+
return infos[0][1][0];
|
|
1989
|
+
}
|
|
1990
|
+
else {
|
|
1991
|
+
return undefined;
|
|
1992
|
+
}
|
|
1993
|
+
}
|
|
1994
|
+
));
|
|
1995
|
+
}
|
|
1996
|
+
_isTaskProviderEnabled(type) {
|
|
1997
|
+
const definition = TaskDefinitionRegistry.get(type);
|
|
1998
|
+
return !definition || !definition.when || this._contextKeyService.contextMatchesRules(definition.when);
|
|
1999
|
+
}
|
|
2000
|
+
async _getGroupedTasks(filter) {
|
|
2001
|
+
await this._waitForAllSupportedExecutions;
|
|
2002
|
+
const type = filter?.type;
|
|
2003
|
+
const needsRecentTasksMigration = this._needsRecentTasksMigration();
|
|
2004
|
+
await this._activateTaskProviders(filter?.type);
|
|
2005
|
+
const validTypes = Object.create(null);
|
|
2006
|
+
TaskDefinitionRegistry.all().forEach(definition => validTypes[definition.taskType] = true);
|
|
2007
|
+
validTypes['shell'] = true;
|
|
2008
|
+
validTypes['process'] = true;
|
|
2009
|
+
const contributedTaskSets = await ( new Promise(resolve => {
|
|
2010
|
+
const result = [];
|
|
2011
|
+
let counter = 0;
|
|
2012
|
+
const done = (value) => {
|
|
2013
|
+
if (value) {
|
|
2014
|
+
result.push(value);
|
|
2015
|
+
}
|
|
2016
|
+
if (--counter === 0) {
|
|
2017
|
+
resolve(result);
|
|
2018
|
+
}
|
|
2019
|
+
};
|
|
2020
|
+
const error = (error) => {
|
|
2021
|
+
try {
|
|
2022
|
+
if (error && Types.isString(error.message)) {
|
|
2023
|
+
this._log(`Error: ${error.message}\n`);
|
|
2024
|
+
this._showOutput();
|
|
2025
|
+
}
|
|
2026
|
+
else {
|
|
2027
|
+
this._log('Unknown error received while collecting tasks from providers.');
|
|
2028
|
+
this._showOutput();
|
|
2029
|
+
}
|
|
2030
|
+
}
|
|
2031
|
+
finally {
|
|
2032
|
+
if (--counter === 0) {
|
|
2033
|
+
resolve(result);
|
|
2034
|
+
}
|
|
2035
|
+
}
|
|
2036
|
+
};
|
|
2037
|
+
if (this._isProvideTasksEnabled() && ((this.schemaVersion === 2) ) && (this._providers.size > 0)) {
|
|
2038
|
+
let foundAnyProviders = false;
|
|
2039
|
+
for (const [handle, provider] of this._providers) {
|
|
2040
|
+
const providerType = this._providerTypes.get(handle);
|
|
2041
|
+
if ((type === undefined) || (type === providerType)) {
|
|
2042
|
+
if (providerType && !this._isTaskProviderEnabled(providerType)) {
|
|
2043
|
+
continue;
|
|
2044
|
+
}
|
|
2045
|
+
foundAnyProviders = true;
|
|
2046
|
+
counter++;
|
|
2047
|
+
raceTimeout(provider.provideTasks(validTypes).then((taskSet) => {
|
|
2048
|
+
for (const task of taskSet.tasks) {
|
|
2049
|
+
if (task.type !== this._providerTypes.get(handle)) {
|
|
2050
|
+
this._log(( nls.localizeWithPath(
|
|
2051
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
2052
|
+
'unexpectedTaskType',
|
|
2053
|
+
"The task provider for \"{0}\" tasks unexpectedly provided a task of type \"{1}\".\n",
|
|
2054
|
+
this._providerTypes.get(handle),
|
|
2055
|
+
task.type
|
|
2056
|
+
)));
|
|
2057
|
+
if ((task.type !== 'shell') && (task.type !== 'process')) {
|
|
2058
|
+
this._showOutput();
|
|
2059
|
+
}
|
|
2060
|
+
break;
|
|
2061
|
+
}
|
|
2062
|
+
}
|
|
2063
|
+
return done(taskSet);
|
|
2064
|
+
}, error), 5000, () => {
|
|
2065
|
+
console.error('Timed out getting tasks from ', providerType);
|
|
2066
|
+
done(undefined);
|
|
2067
|
+
});
|
|
2068
|
+
}
|
|
2069
|
+
}
|
|
2070
|
+
if (!foundAnyProviders) {
|
|
2071
|
+
resolve(result);
|
|
2072
|
+
}
|
|
2073
|
+
}
|
|
2074
|
+
else {
|
|
2075
|
+
resolve(result);
|
|
2076
|
+
}
|
|
2077
|
+
}));
|
|
2078
|
+
const result = ( new TaskMap());
|
|
2079
|
+
const contributedTasks = ( new TaskMap());
|
|
2080
|
+
for (const set of contributedTaskSets) {
|
|
2081
|
+
for (const task of set.tasks) {
|
|
2082
|
+
const workspaceFolder = task.getWorkspaceFolder();
|
|
2083
|
+
if (workspaceFolder) {
|
|
2084
|
+
contributedTasks.add(workspaceFolder, task);
|
|
2085
|
+
}
|
|
2086
|
+
}
|
|
2087
|
+
}
|
|
2088
|
+
try {
|
|
2089
|
+
const customTasks = await this.getWorkspaceTasks();
|
|
2090
|
+
const customTasksKeyValuePairs = Array.from(customTasks);
|
|
2091
|
+
const customTasksPromises = ( customTasksKeyValuePairs.map(async ([key, folderTasks]) => {
|
|
2092
|
+
const contributed = contributedTasks.get(key);
|
|
2093
|
+
if (!folderTasks.set) {
|
|
2094
|
+
if (contributed) {
|
|
2095
|
+
result.add(key, ...contributed);
|
|
2096
|
+
}
|
|
2097
|
+
return;
|
|
2098
|
+
}
|
|
2099
|
+
if (this._contextService.getWorkbenchState() === 1 ) {
|
|
2100
|
+
result.add(key, ...folderTasks.set.tasks);
|
|
2101
|
+
}
|
|
2102
|
+
else {
|
|
2103
|
+
const configurations = folderTasks.configurations;
|
|
2104
|
+
const legacyTaskConfigurations = folderTasks.set ? this._getLegacyTaskConfigurations(folderTasks.set) : undefined;
|
|
2105
|
+
const customTasksToDelete = [];
|
|
2106
|
+
if (configurations || legacyTaskConfigurations) {
|
|
2107
|
+
const unUsedConfigurations = ( new Set());
|
|
2108
|
+
if (configurations) {
|
|
2109
|
+
( Object.keys(configurations.byIdentifier)).forEach(key => unUsedConfigurations.add(key));
|
|
2110
|
+
}
|
|
2111
|
+
for (const task of contributed) {
|
|
2112
|
+
if (!ContributedTask.is(task)) {
|
|
2113
|
+
continue;
|
|
2114
|
+
}
|
|
2115
|
+
if (configurations) {
|
|
2116
|
+
const configuringTask = configurations.byIdentifier[task.defines._key];
|
|
2117
|
+
if (configuringTask) {
|
|
2118
|
+
unUsedConfigurations.delete(task.defines._key);
|
|
2119
|
+
result.add(key, createCustomTask(task, configuringTask));
|
|
2120
|
+
}
|
|
2121
|
+
else {
|
|
2122
|
+
result.add(key, task);
|
|
2123
|
+
}
|
|
2124
|
+
}
|
|
2125
|
+
else if (legacyTaskConfigurations) {
|
|
2126
|
+
const configuringTask = legacyTaskConfigurations[task.defines._key];
|
|
2127
|
+
if (configuringTask) {
|
|
2128
|
+
result.add(key, createCustomTask(task, configuringTask));
|
|
2129
|
+
customTasksToDelete.push(configuringTask);
|
|
2130
|
+
}
|
|
2131
|
+
else {
|
|
2132
|
+
result.add(key, task);
|
|
2133
|
+
}
|
|
2134
|
+
}
|
|
2135
|
+
else {
|
|
2136
|
+
result.add(key, task);
|
|
2137
|
+
}
|
|
2138
|
+
}
|
|
2139
|
+
if (customTasksToDelete.length > 0) {
|
|
2140
|
+
const toDelete = customTasksToDelete.reduce((map, task) => {
|
|
2141
|
+
map[task._id] = true;
|
|
2142
|
+
return map;
|
|
2143
|
+
}, Object.create(null));
|
|
2144
|
+
for (const task of folderTasks.set.tasks) {
|
|
2145
|
+
if (toDelete[task._id]) {
|
|
2146
|
+
continue;
|
|
2147
|
+
}
|
|
2148
|
+
result.add(key, task);
|
|
2149
|
+
}
|
|
2150
|
+
}
|
|
2151
|
+
else {
|
|
2152
|
+
result.add(key, ...folderTasks.set.tasks);
|
|
2153
|
+
}
|
|
2154
|
+
const unUsedConfigurationsAsArray = Array.from(unUsedConfigurations);
|
|
2155
|
+
const unUsedConfigurationPromises = ( unUsedConfigurationsAsArray.map(async (value) => {
|
|
2156
|
+
const configuringTask = configurations.byIdentifier[value];
|
|
2157
|
+
if (type && (type !== configuringTask.configures.type)) {
|
|
2158
|
+
return;
|
|
2159
|
+
}
|
|
2160
|
+
let requiredTaskProviderUnavailable = false;
|
|
2161
|
+
for (const [handle, provider] of this._providers) {
|
|
2162
|
+
const providerType = this._providerTypes.get(handle);
|
|
2163
|
+
if (configuringTask.type === providerType) {
|
|
2164
|
+
if (providerType && !this._isTaskProviderEnabled(providerType)) {
|
|
2165
|
+
requiredTaskProviderUnavailable = true;
|
|
2166
|
+
continue;
|
|
2167
|
+
}
|
|
2168
|
+
try {
|
|
2169
|
+
const resolvedTask = await provider.resolveTask(configuringTask);
|
|
2170
|
+
if (resolvedTask && (resolvedTask._id === configuringTask._id)) {
|
|
2171
|
+
result.add(key, createCustomTask(resolvedTask, configuringTask));
|
|
2172
|
+
return;
|
|
2173
|
+
}
|
|
2174
|
+
}
|
|
2175
|
+
catch (error) {
|
|
2176
|
+
}
|
|
2177
|
+
}
|
|
2178
|
+
}
|
|
2179
|
+
if (requiredTaskProviderUnavailable) {
|
|
2180
|
+
this._log(( nls.localizeWithPath(
|
|
2181
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
2182
|
+
'TaskService.providerUnavailable',
|
|
2183
|
+
'Warning: {0} tasks are unavailable in the current environment.',
|
|
2184
|
+
configuringTask.configures.type
|
|
2185
|
+
)));
|
|
2186
|
+
}
|
|
2187
|
+
else {
|
|
2188
|
+
this._log(( nls.localizeWithPath(
|
|
2189
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
2190
|
+
'TaskService.noConfiguration',
|
|
2191
|
+
'Error: The {0} task detection didn\'t contribute a task for the following configuration:\n{1}\nThe task will be ignored.',
|
|
2192
|
+
configuringTask.configures.type,
|
|
2193
|
+
JSON.stringify(configuringTask._source.config.element, undefined, 4)
|
|
2194
|
+
)));
|
|
2195
|
+
this._showOutput();
|
|
2196
|
+
}
|
|
2197
|
+
}));
|
|
2198
|
+
await Promise.all(unUsedConfigurationPromises);
|
|
2199
|
+
}
|
|
2200
|
+
else {
|
|
2201
|
+
result.add(key, ...folderTasks.set.tasks);
|
|
2202
|
+
result.add(key, ...contributed);
|
|
2203
|
+
}
|
|
2204
|
+
}
|
|
2205
|
+
}));
|
|
2206
|
+
await Promise.all(customTasksPromises);
|
|
2207
|
+
if (needsRecentTasksMigration) {
|
|
2208
|
+
await this._migrateRecentTasks(result.all());
|
|
2209
|
+
}
|
|
2210
|
+
return result;
|
|
2211
|
+
}
|
|
2212
|
+
catch {
|
|
2213
|
+
const result = ( new TaskMap());
|
|
2214
|
+
for (const set of contributedTaskSets) {
|
|
2215
|
+
for (const task of set.tasks) {
|
|
2216
|
+
const folder = task.getWorkspaceFolder();
|
|
2217
|
+
if (folder) {
|
|
2218
|
+
result.add(folder, task);
|
|
2219
|
+
}
|
|
2220
|
+
}
|
|
2221
|
+
}
|
|
2222
|
+
return result;
|
|
2223
|
+
}
|
|
2224
|
+
}
|
|
2225
|
+
_getLegacyTaskConfigurations(workspaceTasks) {
|
|
2226
|
+
let result;
|
|
2227
|
+
function getResult() {
|
|
2228
|
+
if (result) {
|
|
2229
|
+
return result;
|
|
2230
|
+
}
|
|
2231
|
+
result = Object.create(null);
|
|
2232
|
+
return result;
|
|
2233
|
+
}
|
|
2234
|
+
for (const task of workspaceTasks.tasks) {
|
|
2235
|
+
if (CustomTask.is(task)) {
|
|
2236
|
+
const commandName = task.command && task.command.name;
|
|
2237
|
+
if (commandName === 'gulp' || commandName === 'grunt' || commandName === 'jake') {
|
|
2238
|
+
const identifier = KeyedTaskIdentifier.create({
|
|
2239
|
+
type: commandName,
|
|
2240
|
+
task: task.configurationProperties.name
|
|
2241
|
+
});
|
|
2242
|
+
getResult()[identifier._key] = task;
|
|
2243
|
+
}
|
|
2244
|
+
}
|
|
2245
|
+
}
|
|
2246
|
+
return result;
|
|
2247
|
+
}
|
|
2248
|
+
async getWorkspaceTasks(runSource = 1 ) {
|
|
2249
|
+
if (!(await this._trust())) {
|
|
2250
|
+
return ( new Map());
|
|
2251
|
+
}
|
|
2252
|
+
await raceTimeout(this._waitForAllSupportedExecutions, 2000, () => {
|
|
2253
|
+
this._logService.warn('Timed out waiting for all supported executions');
|
|
2254
|
+
});
|
|
2255
|
+
await this._whenTaskSystemReady;
|
|
2256
|
+
if (this._workspaceTasksPromise) {
|
|
2257
|
+
return this._workspaceTasksPromise;
|
|
2258
|
+
}
|
|
2259
|
+
return this._updateWorkspaceTasks(runSource);
|
|
2260
|
+
}
|
|
2261
|
+
_updateWorkspaceTasks(runSource = 1 ) {
|
|
2262
|
+
this._workspaceTasksPromise = this._computeWorkspaceTasks(runSource);
|
|
2263
|
+
return this._workspaceTasksPromise;
|
|
2264
|
+
}
|
|
2265
|
+
async _getAFolder() {
|
|
2266
|
+
let folder = this.workspaceFolders.length > 0 ? this.workspaceFolders[0] : undefined;
|
|
2267
|
+
if (!folder) {
|
|
2268
|
+
const userhome = await this._pathService.userHome();
|
|
2269
|
+
folder = ( new WorkspaceFolder({ uri: userhome, name: resources.basename(userhome), index: 0 }));
|
|
2270
|
+
}
|
|
2271
|
+
return folder;
|
|
2272
|
+
}
|
|
2273
|
+
async _computeWorkspaceTasks(runSource = 1 ) {
|
|
2274
|
+
const promises = [];
|
|
2275
|
+
for (const folder of this.workspaceFolders) {
|
|
2276
|
+
promises.push(this._computeWorkspaceFolderTasks(folder, runSource));
|
|
2277
|
+
}
|
|
2278
|
+
const values = await Promise.all(promises);
|
|
2279
|
+
const result = ( new Map());
|
|
2280
|
+
for (const value of values) {
|
|
2281
|
+
if (value) {
|
|
2282
|
+
result.set(( value.workspaceFolder.uri.toString()), value);
|
|
2283
|
+
}
|
|
2284
|
+
}
|
|
2285
|
+
const folder = await this._getAFolder();
|
|
2286
|
+
if (this._contextService.getWorkbenchState() !== 1 ) {
|
|
2287
|
+
const workspaceFileTasks = await this._computeWorkspaceFileTasks(folder, runSource);
|
|
2288
|
+
if (workspaceFileTasks && this._workspace && this._workspace.configuration) {
|
|
2289
|
+
result.set(( this._workspace.configuration.toString()), workspaceFileTasks);
|
|
2290
|
+
}
|
|
2291
|
+
}
|
|
2292
|
+
const userTasks = await this._computeUserTasks(folder, runSource);
|
|
2293
|
+
if (userTasks) {
|
|
2294
|
+
result.set(USER_TASKS_GROUP_KEY, userTasks);
|
|
2295
|
+
}
|
|
2296
|
+
return result;
|
|
2297
|
+
}
|
|
2298
|
+
get _jsonTasksSupported() {
|
|
2299
|
+
return ShellExecutionSupportedContext.getValue(this._contextKeyService) === true && ProcessExecutionSupportedContext.getValue(this._contextKeyService) === true;
|
|
2300
|
+
}
|
|
2301
|
+
async _computeWorkspaceFolderTasks(workspaceFolder, runSource = 1 ) {
|
|
2302
|
+
const workspaceFolderConfiguration = (this._executionEngine === ExecutionEngine.Process ? await this._computeLegacyConfiguration(workspaceFolder) : await this._computeConfiguration(workspaceFolder));
|
|
2303
|
+
if (!workspaceFolderConfiguration || !workspaceFolderConfiguration.config || workspaceFolderConfiguration.hasErrors) {
|
|
2304
|
+
return Promise.resolve({ workspaceFolder, set: undefined, configurations: undefined, hasErrors: workspaceFolderConfiguration ? workspaceFolderConfiguration.hasErrors : false });
|
|
2305
|
+
}
|
|
2306
|
+
await ProblemMatcherRegistry.onReady();
|
|
2307
|
+
const taskSystemInfo = this._getTaskSystemInfo(workspaceFolder.uri.scheme);
|
|
2308
|
+
const problemReporter = ( new ProblemReporter(this._outputChannel));
|
|
2309
|
+
const parseResult = parse(workspaceFolder, undefined, taskSystemInfo ? taskSystemInfo.platform : platform.platform, workspaceFolderConfiguration.config, problemReporter, TaskConfigSource.TasksJson, this._contextKeyService);
|
|
2310
|
+
let hasErrors = false;
|
|
2311
|
+
if (!parseResult.validationStatus.isOK() && ((parseResult.validationStatus.state !== 1) )) {
|
|
2312
|
+
hasErrors = true;
|
|
2313
|
+
this._showOutput(runSource);
|
|
2314
|
+
}
|
|
2315
|
+
if (problemReporter.status.isFatal()) {
|
|
2316
|
+
problemReporter.fatal(( nls.localizeWithPath(
|
|
2317
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
2318
|
+
'TaskSystem.configurationErrors',
|
|
2319
|
+
'Error: the provided task configuration has validation errors and can\'t not be used. Please correct the errors first.'
|
|
2320
|
+
)));
|
|
2321
|
+
return { workspaceFolder, set: undefined, configurations: undefined, hasErrors };
|
|
2322
|
+
}
|
|
2323
|
+
let customizedTasks;
|
|
2324
|
+
if (parseResult.configured && parseResult.configured.length > 0) {
|
|
2325
|
+
customizedTasks = {
|
|
2326
|
+
byIdentifier: Object.create(null)
|
|
2327
|
+
};
|
|
2328
|
+
for (const task of parseResult.configured) {
|
|
2329
|
+
customizedTasks.byIdentifier[task.configures._key] = task;
|
|
2330
|
+
}
|
|
2331
|
+
}
|
|
2332
|
+
if (!this._jsonTasksSupported && (parseResult.custom.length > 0)) {
|
|
2333
|
+
console.warn('Custom workspace tasks are not supported.');
|
|
2334
|
+
}
|
|
2335
|
+
return { workspaceFolder, set: { tasks: this._jsonTasksSupported ? parseResult.custom : [] }, configurations: customizedTasks, hasErrors };
|
|
2336
|
+
}
|
|
2337
|
+
_testParseExternalConfig(config, location) {
|
|
2338
|
+
if (!config) {
|
|
2339
|
+
return { config: undefined, hasParseErrors: false };
|
|
2340
|
+
}
|
|
2341
|
+
const parseErrors = config.$parseErrors;
|
|
2342
|
+
if (parseErrors) {
|
|
2343
|
+
let isAffected = false;
|
|
2344
|
+
for (const parseError of parseErrors) {
|
|
2345
|
+
if (/tasks\.json$/.test(parseError)) {
|
|
2346
|
+
isAffected = true;
|
|
2347
|
+
break;
|
|
2348
|
+
}
|
|
2349
|
+
}
|
|
2350
|
+
if (isAffected) {
|
|
2351
|
+
this._log(( nls.localizeWithPath(
|
|
2352
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
2353
|
+
{ key: 'TaskSystem.invalidTaskJsonOther', comment: ['Message notifies of an error in one of several places there is tasks related json, not necessarily in a file named tasks.json'] },
|
|
2354
|
+
'Error: The content of the tasks json in {0} has syntax errors. Please correct them before executing a task.',
|
|
2355
|
+
location
|
|
2356
|
+
)));
|
|
2357
|
+
this._showOutput();
|
|
2358
|
+
return { config, hasParseErrors: true };
|
|
2359
|
+
}
|
|
2360
|
+
}
|
|
2361
|
+
return { config, hasParseErrors: false };
|
|
2362
|
+
}
|
|
2363
|
+
_log(value, verbose) {
|
|
2364
|
+
if (!verbose || this._configurationService.getValue("task.verboseLogging" )) {
|
|
2365
|
+
this._outputChannel.append(value + '\n');
|
|
2366
|
+
}
|
|
2367
|
+
}
|
|
2368
|
+
async _computeWorkspaceFileTasks(workspaceFolder, runSource = 1 ) {
|
|
2369
|
+
if (this._executionEngine === ExecutionEngine.Process) {
|
|
2370
|
+
return this._emptyWorkspaceTaskResults(workspaceFolder);
|
|
2371
|
+
}
|
|
2372
|
+
const workspaceFileConfig = this._getConfiguration(workspaceFolder, TaskSourceKind.WorkspaceFile);
|
|
2373
|
+
const configuration = this._testParseExternalConfig(workspaceFileConfig.config, ( nls.localizeWithPath(
|
|
2374
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
2375
|
+
'TasksSystem.locationWorkspaceConfig',
|
|
2376
|
+
'workspace file'
|
|
2377
|
+
)));
|
|
2378
|
+
const customizedTasks = {
|
|
2379
|
+
byIdentifier: Object.create(null)
|
|
2380
|
+
};
|
|
2381
|
+
const custom = [];
|
|
2382
|
+
await this._computeTasksForSingleConfig(workspaceFolder, configuration.config, runSource, custom, customizedTasks.byIdentifier, TaskConfigSource.WorkspaceFile);
|
|
2383
|
+
const engine = configuration.config ? ExecutionEngine$1.from(configuration.config) : ExecutionEngine.Terminal;
|
|
2384
|
+
if (engine === ExecutionEngine.Process) {
|
|
2385
|
+
this._notificationService.warn(( nls.localizeWithPath(
|
|
2386
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
2387
|
+
'TaskSystem.versionWorkspaceFile',
|
|
2388
|
+
'Only tasks version 2.0.0 permitted in workspace configuration files.'
|
|
2389
|
+
)));
|
|
2390
|
+
return this._emptyWorkspaceTaskResults(workspaceFolder);
|
|
2391
|
+
}
|
|
2392
|
+
return { workspaceFolder, set: { tasks: custom }, configurations: customizedTasks, hasErrors: configuration.hasParseErrors };
|
|
2393
|
+
}
|
|
2394
|
+
async _computeUserTasks(workspaceFolder, runSource = 1 ) {
|
|
2395
|
+
if (this._executionEngine === ExecutionEngine.Process) {
|
|
2396
|
+
return this._emptyWorkspaceTaskResults(workspaceFolder);
|
|
2397
|
+
}
|
|
2398
|
+
const userTasksConfig = this._getConfiguration(workspaceFolder, TaskSourceKind.User);
|
|
2399
|
+
const configuration = this._testParseExternalConfig(userTasksConfig.config, ( nls.localizeWithPath(
|
|
2400
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
2401
|
+
'TasksSystem.locationUserConfig',
|
|
2402
|
+
'user settings'
|
|
2403
|
+
)));
|
|
2404
|
+
const customizedTasks = {
|
|
2405
|
+
byIdentifier: Object.create(null)
|
|
2406
|
+
};
|
|
2407
|
+
const custom = [];
|
|
2408
|
+
await this._computeTasksForSingleConfig(workspaceFolder, configuration.config, runSource, custom, customizedTasks.byIdentifier, TaskConfigSource.User);
|
|
2409
|
+
const engine = configuration.config ? ExecutionEngine$1.from(configuration.config) : ExecutionEngine.Terminal;
|
|
2410
|
+
if (engine === ExecutionEngine.Process) {
|
|
2411
|
+
this._notificationService.warn(( nls.localizeWithPath(
|
|
2412
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
2413
|
+
'TaskSystem.versionSettings',
|
|
2414
|
+
'Only tasks version 2.0.0 permitted in user settings.'
|
|
2415
|
+
)));
|
|
2416
|
+
return this._emptyWorkspaceTaskResults(workspaceFolder);
|
|
2417
|
+
}
|
|
2418
|
+
return { workspaceFolder, set: { tasks: custom }, configurations: customizedTasks, hasErrors: configuration.hasParseErrors };
|
|
2419
|
+
}
|
|
2420
|
+
_emptyWorkspaceTaskResults(workspaceFolder) {
|
|
2421
|
+
return { workspaceFolder, set: undefined, configurations: undefined, hasErrors: false };
|
|
2422
|
+
}
|
|
2423
|
+
async _computeTasksForSingleConfig(workspaceFolder, config, runSource, custom, customized, source, isRecentTask = false) {
|
|
2424
|
+
if (!config) {
|
|
2425
|
+
return false;
|
|
2426
|
+
}
|
|
2427
|
+
const taskSystemInfo = this._getTaskSystemInfo(workspaceFolder.uri.scheme);
|
|
2428
|
+
const problemReporter = ( new ProblemReporter(this._outputChannel));
|
|
2429
|
+
const parseResult = parse(workspaceFolder, this._workspace, taskSystemInfo ? taskSystemInfo.platform : platform.platform, config, problemReporter, source, this._contextKeyService, isRecentTask);
|
|
2430
|
+
let hasErrors = false;
|
|
2431
|
+
if (!parseResult.validationStatus.isOK() && ((parseResult.validationStatus.state !== 1) )) {
|
|
2432
|
+
this._showOutput(runSource);
|
|
2433
|
+
hasErrors = true;
|
|
2434
|
+
}
|
|
2435
|
+
if (problemReporter.status.isFatal()) {
|
|
2436
|
+
problemReporter.fatal(( nls.localizeWithPath(
|
|
2437
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
2438
|
+
'TaskSystem.configurationErrors',
|
|
2439
|
+
'Error: the provided task configuration has validation errors and can\'t not be used. Please correct the errors first.'
|
|
2440
|
+
)));
|
|
2441
|
+
return hasErrors;
|
|
2442
|
+
}
|
|
2443
|
+
if (parseResult.configured && parseResult.configured.length > 0) {
|
|
2444
|
+
for (const task of parseResult.configured) {
|
|
2445
|
+
customized[task.configures._key] = task;
|
|
2446
|
+
}
|
|
2447
|
+
}
|
|
2448
|
+
if (!this._jsonTasksSupported && (parseResult.custom.length > 0)) {
|
|
2449
|
+
console.warn('Custom workspace tasks are not supported.');
|
|
2450
|
+
}
|
|
2451
|
+
else {
|
|
2452
|
+
for (const task of parseResult.custom) {
|
|
2453
|
+
custom.push(task);
|
|
2454
|
+
}
|
|
2455
|
+
}
|
|
2456
|
+
return hasErrors;
|
|
2457
|
+
}
|
|
2458
|
+
_computeConfiguration(workspaceFolder) {
|
|
2459
|
+
const { config, hasParseErrors } = this._getConfiguration(workspaceFolder);
|
|
2460
|
+
return Promise.resolve({ workspaceFolder, config, hasErrors: hasParseErrors });
|
|
2461
|
+
}
|
|
2462
|
+
_computeWorkspaceFolderSetup() {
|
|
2463
|
+
const workspaceFolders = [];
|
|
2464
|
+
const ignoredWorkspaceFolders = [];
|
|
2465
|
+
let executionEngine = ExecutionEngine.Terminal;
|
|
2466
|
+
let schemaVersion = 2 ;
|
|
2467
|
+
let workspace;
|
|
2468
|
+
if (this._contextService.getWorkbenchState() === 2 ) {
|
|
2469
|
+
const workspaceFolder = this._contextService.getWorkspace().folders[0];
|
|
2470
|
+
workspaceFolders.push(workspaceFolder);
|
|
2471
|
+
executionEngine = this._computeExecutionEngine(workspaceFolder);
|
|
2472
|
+
const telemetryData = {
|
|
2473
|
+
executionEngineVersion: executionEngine
|
|
2474
|
+
};
|
|
2475
|
+
this._telemetryService.publicLog('taskService.engineVersion', telemetryData);
|
|
2476
|
+
schemaVersion = this._computeJsonSchemaVersion(workspaceFolder);
|
|
2477
|
+
}
|
|
2478
|
+
else if (this._contextService.getWorkbenchState() === 3 ) {
|
|
2479
|
+
workspace = this._contextService.getWorkspace();
|
|
2480
|
+
for (const workspaceFolder of this._contextService.getWorkspace().folders) {
|
|
2481
|
+
if (schemaVersion === this._computeJsonSchemaVersion(workspaceFolder)) {
|
|
2482
|
+
workspaceFolders.push(workspaceFolder);
|
|
2483
|
+
}
|
|
2484
|
+
else {
|
|
2485
|
+
ignoredWorkspaceFolders.push(workspaceFolder);
|
|
2486
|
+
this._log(( nls.localizeWithPath(
|
|
2487
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
2488
|
+
'taskService.ignoreingFolder',
|
|
2489
|
+
'Ignoring task configurations for workspace folder {0}. Multi folder workspace task support requires that all folders use task version 2.0.0',
|
|
2490
|
+
workspaceFolder.uri.fsPath
|
|
2491
|
+
)));
|
|
2492
|
+
}
|
|
2493
|
+
}
|
|
2494
|
+
}
|
|
2495
|
+
return [workspaceFolders, ignoredWorkspaceFolders, executionEngine, schemaVersion, workspace];
|
|
2496
|
+
}
|
|
2497
|
+
_computeExecutionEngine(workspaceFolder) {
|
|
2498
|
+
const { config } = this._getConfiguration(workspaceFolder);
|
|
2499
|
+
if (!config) {
|
|
2500
|
+
return ExecutionEngine._default;
|
|
2501
|
+
}
|
|
2502
|
+
return ExecutionEngine$1.from(config);
|
|
2503
|
+
}
|
|
2504
|
+
_computeJsonSchemaVersion(workspaceFolder) {
|
|
2505
|
+
const { config } = this._getConfiguration(workspaceFolder);
|
|
2506
|
+
if (!config) {
|
|
2507
|
+
return 2 ;
|
|
2508
|
+
}
|
|
2509
|
+
return JsonSchemaVersion.from(config);
|
|
2510
|
+
}
|
|
2511
|
+
_getConfiguration(workspaceFolder, source) {
|
|
2512
|
+
let result;
|
|
2513
|
+
if ((source !== TaskSourceKind.User) && ((this._contextService.getWorkbenchState() === 1) )) {
|
|
2514
|
+
result = undefined;
|
|
2515
|
+
}
|
|
2516
|
+
else {
|
|
2517
|
+
const wholeConfig = this._configurationService.inspect('tasks', { resource: workspaceFolder.uri });
|
|
2518
|
+
switch (source) {
|
|
2519
|
+
case TaskSourceKind.User: {
|
|
2520
|
+
if (wholeConfig.userValue !== wholeConfig.workspaceFolderValue) {
|
|
2521
|
+
result = Objects.deepClone(wholeConfig.userValue);
|
|
2522
|
+
}
|
|
2523
|
+
break;
|
|
2524
|
+
}
|
|
2525
|
+
case TaskSourceKind.Workspace:
|
|
2526
|
+
result = Objects.deepClone(wholeConfig.workspaceFolderValue);
|
|
2527
|
+
break;
|
|
2528
|
+
case TaskSourceKind.WorkspaceFile: {
|
|
2529
|
+
if (((this._contextService.getWorkbenchState() === 3) )
|
|
2530
|
+
&& (wholeConfig.workspaceFolderValue !== wholeConfig.workspaceValue)) {
|
|
2531
|
+
result = Objects.deepClone(wholeConfig.workspaceValue);
|
|
2532
|
+
}
|
|
2533
|
+
break;
|
|
2534
|
+
}
|
|
2535
|
+
default: result = Objects.deepClone(wholeConfig.workspaceFolderValue);
|
|
2536
|
+
}
|
|
2537
|
+
}
|
|
2538
|
+
if (!result) {
|
|
2539
|
+
return { config: undefined, hasParseErrors: false };
|
|
2540
|
+
}
|
|
2541
|
+
const parseErrors = result.$parseErrors;
|
|
2542
|
+
if (parseErrors) {
|
|
2543
|
+
let isAffected = false;
|
|
2544
|
+
for (const parseError of parseErrors) {
|
|
2545
|
+
if (/tasks\.json$/.test(parseError)) {
|
|
2546
|
+
isAffected = true;
|
|
2547
|
+
break;
|
|
2548
|
+
}
|
|
2549
|
+
}
|
|
2550
|
+
if (isAffected) {
|
|
2551
|
+
this._log(( nls.localizeWithPath(
|
|
2552
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
2553
|
+
'TaskSystem.invalidTaskJson',
|
|
2554
|
+
'Error: The content of the tasks.json file has syntax errors. Please correct them before executing a task.'
|
|
2555
|
+
)));
|
|
2556
|
+
this._showOutput();
|
|
2557
|
+
return { config: undefined, hasParseErrors: true };
|
|
2558
|
+
}
|
|
2559
|
+
}
|
|
2560
|
+
return { config: result, hasParseErrors: false };
|
|
2561
|
+
}
|
|
2562
|
+
inTerminal() {
|
|
2563
|
+
if (this._taskSystem) {
|
|
2564
|
+
return this._taskSystem instanceof TerminalTaskSystem;
|
|
2565
|
+
}
|
|
2566
|
+
return this._executionEngine === ExecutionEngine.Terminal;
|
|
2567
|
+
}
|
|
2568
|
+
configureAction() {
|
|
2569
|
+
const thisCapture = this;
|
|
2570
|
+
return new (class extends Action {
|
|
2571
|
+
constructor() {
|
|
2572
|
+
super(ConfigureTaskAction.ID, ConfigureTaskAction.TEXT, undefined, true, () => { thisCapture._runConfigureTasks(); return Promise.resolve(undefined); });
|
|
2573
|
+
}
|
|
2574
|
+
});
|
|
2575
|
+
}
|
|
2576
|
+
_handleError(err) {
|
|
2577
|
+
let showOutput = true;
|
|
2578
|
+
if (err instanceof TaskError) {
|
|
2579
|
+
const buildError = err;
|
|
2580
|
+
const needsConfig = buildError.code === 0 || buildError.code === 2 || buildError.code === 3 ;
|
|
2581
|
+
const needsTerminate = buildError.code === 1 ;
|
|
2582
|
+
if (needsConfig || needsTerminate) {
|
|
2583
|
+
this._notificationService.prompt(buildError.severity, buildError.message, [{
|
|
2584
|
+
label: needsConfig ? ConfigureTaskAction.TEXT : ( nls.localizeWithPath(
|
|
2585
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
2586
|
+
'TerminateAction.label',
|
|
2587
|
+
"Terminate Task"
|
|
2588
|
+
)),
|
|
2589
|
+
run: () => {
|
|
2590
|
+
if (needsConfig) {
|
|
2591
|
+
this._runConfigureTasks();
|
|
2592
|
+
}
|
|
2593
|
+
else {
|
|
2594
|
+
this._runTerminateCommand();
|
|
2595
|
+
}
|
|
2596
|
+
}
|
|
2597
|
+
}]);
|
|
2598
|
+
}
|
|
2599
|
+
else {
|
|
2600
|
+
this._notificationService.notify({ severity: buildError.severity, message: buildError.message });
|
|
2601
|
+
}
|
|
2602
|
+
}
|
|
2603
|
+
else if (err instanceof Error) {
|
|
2604
|
+
const error = err;
|
|
2605
|
+
this._notificationService.error(error.message);
|
|
2606
|
+
showOutput = false;
|
|
2607
|
+
}
|
|
2608
|
+
else if (Types.isString(err)) {
|
|
2609
|
+
this._notificationService.error(err);
|
|
2610
|
+
}
|
|
2611
|
+
else {
|
|
2612
|
+
this._notificationService.error(( nls.localizeWithPath(
|
|
2613
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
2614
|
+
'TaskSystem.unknownError',
|
|
2615
|
+
'An error has occurred while running a task. See task log for details.'
|
|
2616
|
+
)));
|
|
2617
|
+
}
|
|
2618
|
+
if (showOutput) {
|
|
2619
|
+
this._showOutput();
|
|
2620
|
+
}
|
|
2621
|
+
}
|
|
2622
|
+
_showDetail() {
|
|
2623
|
+
return this._configurationService.getValue(QUICKOPEN_DETAIL_CONFIG);
|
|
2624
|
+
}
|
|
2625
|
+
async _createTaskQuickPickEntries(tasks, group = false, sort = false, selectedEntry, includeRecents = true) {
|
|
2626
|
+
let encounteredTasks = {};
|
|
2627
|
+
if (tasks === undefined || tasks === null || tasks.length === 0) {
|
|
2628
|
+
return [];
|
|
2629
|
+
}
|
|
2630
|
+
const TaskQuickPickEntry = (task) => {
|
|
2631
|
+
const newEntry = { label: task._label, description: this.getTaskDescription(task), task, detail: this._showDetail() ? task.configurationProperties.detail : undefined };
|
|
2632
|
+
if (encounteredTasks[task._id]) {
|
|
2633
|
+
if (encounteredTasks[task._id].length === 1) {
|
|
2634
|
+
encounteredTasks[task._id][0].label += ' (1)';
|
|
2635
|
+
}
|
|
2636
|
+
newEntry.label = newEntry.label + ' (' + ( (encounteredTasks[task._id].length + 1).toString()) + ')';
|
|
2637
|
+
}
|
|
2638
|
+
else {
|
|
2639
|
+
encounteredTasks[task._id] = [];
|
|
2640
|
+
}
|
|
2641
|
+
encounteredTasks[task._id].push(newEntry);
|
|
2642
|
+
return newEntry;
|
|
2643
|
+
};
|
|
2644
|
+
function fillEntries(entries, tasks, groupLabel) {
|
|
2645
|
+
if (tasks.length) {
|
|
2646
|
+
entries.push({ type: 'separator', label: groupLabel });
|
|
2647
|
+
}
|
|
2648
|
+
for (const task of tasks) {
|
|
2649
|
+
const entry = TaskQuickPickEntry(task);
|
|
2650
|
+
entry.buttons = [{ iconClass: ThemeIcon.asClassName(configureTaskIcon), tooltip: ( nls.localizeWithPath(
|
|
2651
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
2652
|
+
'configureTask',
|
|
2653
|
+
"Configure Task"
|
|
2654
|
+
)) }];
|
|
2655
|
+
if (selectedEntry && (task === selectedEntry.task)) {
|
|
2656
|
+
entries.unshift(selectedEntry);
|
|
2657
|
+
}
|
|
2658
|
+
else {
|
|
2659
|
+
entries.push(entry);
|
|
2660
|
+
}
|
|
2661
|
+
}
|
|
2662
|
+
}
|
|
2663
|
+
let entries;
|
|
2664
|
+
if (group) {
|
|
2665
|
+
entries = [];
|
|
2666
|
+
if (tasks.length === 1) {
|
|
2667
|
+
entries.push(TaskQuickPickEntry(tasks[0]));
|
|
2668
|
+
}
|
|
2669
|
+
else {
|
|
2670
|
+
const recentlyUsedTasks = await this.getSavedTasks('historical');
|
|
2671
|
+
const recent = [];
|
|
2672
|
+
const recentSet = ( new Set());
|
|
2673
|
+
let configured = [];
|
|
2674
|
+
let detected = [];
|
|
2675
|
+
const taskMap = Object.create(null);
|
|
2676
|
+
tasks.forEach(task => {
|
|
2677
|
+
const key = task.getCommonTaskId();
|
|
2678
|
+
if (key) {
|
|
2679
|
+
taskMap[key] = task;
|
|
2680
|
+
}
|
|
2681
|
+
});
|
|
2682
|
+
recentlyUsedTasks.reverse().forEach(recentTask => {
|
|
2683
|
+
const key = recentTask.getCommonTaskId();
|
|
2684
|
+
if (key) {
|
|
2685
|
+
recentSet.add(key);
|
|
2686
|
+
const task = taskMap[key];
|
|
2687
|
+
if (task) {
|
|
2688
|
+
recent.push(task);
|
|
2689
|
+
}
|
|
2690
|
+
}
|
|
2691
|
+
});
|
|
2692
|
+
for (const task of tasks) {
|
|
2693
|
+
const key = task.getCommonTaskId();
|
|
2694
|
+
if (!key || !( recentSet.has(key))) {
|
|
2695
|
+
if ((task._source.kind === TaskSourceKind.Workspace) || (task._source.kind === TaskSourceKind.User)) {
|
|
2696
|
+
configured.push(task);
|
|
2697
|
+
}
|
|
2698
|
+
else {
|
|
2699
|
+
detected.push(task);
|
|
2700
|
+
}
|
|
2701
|
+
}
|
|
2702
|
+
}
|
|
2703
|
+
const sorter = this.createSorter();
|
|
2704
|
+
if (includeRecents) {
|
|
2705
|
+
fillEntries(entries, recent, ( nls.localizeWithPath(
|
|
2706
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
2707
|
+
'recentlyUsed',
|
|
2708
|
+
'recently used tasks'
|
|
2709
|
+
)));
|
|
2710
|
+
}
|
|
2711
|
+
configured = configured.sort((a, b) => sorter.compare(a, b));
|
|
2712
|
+
fillEntries(entries, configured, ( nls.localizeWithPath(
|
|
2713
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
2714
|
+
'configured',
|
|
2715
|
+
'configured tasks'
|
|
2716
|
+
)));
|
|
2717
|
+
detected = detected.sort((a, b) => sorter.compare(a, b));
|
|
2718
|
+
fillEntries(entries, detected, ( nls.localizeWithPath(
|
|
2719
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
2720
|
+
'detected',
|
|
2721
|
+
'detected tasks'
|
|
2722
|
+
)));
|
|
2723
|
+
}
|
|
2724
|
+
}
|
|
2725
|
+
else {
|
|
2726
|
+
if (sort) {
|
|
2727
|
+
const sorter = this.createSorter();
|
|
2728
|
+
tasks = tasks.sort((a, b) => sorter.compare(a, b));
|
|
2729
|
+
}
|
|
2730
|
+
entries = ( tasks.map(task => TaskQuickPickEntry(task)));
|
|
2731
|
+
}
|
|
2732
|
+
encounteredTasks = {};
|
|
2733
|
+
return entries;
|
|
2734
|
+
}
|
|
2735
|
+
async _showTwoLevelQuickPick(placeHolder, defaultEntry, type, name) {
|
|
2736
|
+
return this._instantiationService.createInstance(TaskQuickPick).show(placeHolder, defaultEntry, type, name);
|
|
2737
|
+
}
|
|
2738
|
+
async _showQuickPick(tasks, placeHolder, defaultEntry, group = false, sort = false, selectedEntry, additionalEntries, name) {
|
|
2739
|
+
const resolvedTasks = await tasks;
|
|
2740
|
+
const entries = await raceTimeout(this._createTaskQuickPickEntries(resolvedTasks, group, sort, selectedEntry), 200, () => undefined);
|
|
2741
|
+
if (!entries) {
|
|
2742
|
+
return undefined;
|
|
2743
|
+
}
|
|
2744
|
+
if (entries.length === 1 && this._configurationService.getValue(QUICKOPEN_SKIP_CONFIG)) {
|
|
2745
|
+
return entries[0];
|
|
2746
|
+
}
|
|
2747
|
+
else if ((entries.length === 0) && defaultEntry) {
|
|
2748
|
+
entries.push(defaultEntry);
|
|
2749
|
+
}
|
|
2750
|
+
else if (entries.length > 1 && additionalEntries && additionalEntries.length > 0) {
|
|
2751
|
+
entries.push({ type: 'separator', label: '' });
|
|
2752
|
+
entries.push(additionalEntries[0]);
|
|
2753
|
+
}
|
|
2754
|
+
const picker = this._quickInputService.createQuickPick();
|
|
2755
|
+
picker.placeholder = placeHolder;
|
|
2756
|
+
picker.matchOnDescription = true;
|
|
2757
|
+
if (name) {
|
|
2758
|
+
picker.value = name;
|
|
2759
|
+
}
|
|
2760
|
+
picker.onDidTriggerItemButton(context => {
|
|
2761
|
+
const task = context.item.task;
|
|
2762
|
+
this._quickInputService.cancel();
|
|
2763
|
+
if (ContributedTask.is(task)) {
|
|
2764
|
+
this.customize(task, undefined, true);
|
|
2765
|
+
}
|
|
2766
|
+
else if (CustomTask.is(task)) {
|
|
2767
|
+
this.openConfig(task);
|
|
2768
|
+
}
|
|
2769
|
+
});
|
|
2770
|
+
picker.items = entries;
|
|
2771
|
+
picker.show();
|
|
2772
|
+
return ( new Promise(resolve => {
|
|
2773
|
+
this._register(picker.onDidAccept(async () => {
|
|
2774
|
+
const selectedEntry = picker.selectedItems ? picker.selectedItems[0] : undefined;
|
|
2775
|
+
picker.dispose();
|
|
2776
|
+
if (!selectedEntry) {
|
|
2777
|
+
resolve(undefined);
|
|
2778
|
+
}
|
|
2779
|
+
resolve(selectedEntry);
|
|
2780
|
+
}));
|
|
2781
|
+
}));
|
|
2782
|
+
}
|
|
2783
|
+
_needsRecentTasksMigration() {
|
|
2784
|
+
return (this.getRecentlyUsedTasksV1().size > 0) && (this._getTasksFromStorage('historical').size === 0);
|
|
2785
|
+
}
|
|
2786
|
+
async _migrateRecentTasks(tasks) {
|
|
2787
|
+
if (!this._needsRecentTasksMigration()) {
|
|
2788
|
+
return;
|
|
2789
|
+
}
|
|
2790
|
+
const recentlyUsedTasks = this.getRecentlyUsedTasksV1();
|
|
2791
|
+
const taskMap = Object.create(null);
|
|
2792
|
+
tasks.forEach(task => {
|
|
2793
|
+
const key = task.getKey();
|
|
2794
|
+
if (key) {
|
|
2795
|
+
taskMap[key] = task;
|
|
2796
|
+
}
|
|
2797
|
+
});
|
|
2798
|
+
const reversed = [...( recentlyUsedTasks.keys())].reverse();
|
|
2799
|
+
for (const key in reversed) {
|
|
2800
|
+
const task = taskMap[key];
|
|
2801
|
+
if (task) {
|
|
2802
|
+
await this._setRecentlyUsedTask(task);
|
|
2803
|
+
}
|
|
2804
|
+
}
|
|
2805
|
+
this._storageService.remove(AbstractTaskService_1.RecentlyUsedTasks_Key, 1 );
|
|
2806
|
+
}
|
|
2807
|
+
_showIgnoredFoldersMessage() {
|
|
2808
|
+
if (this.ignoredWorkspaceFolders.length === 0 || !this.showIgnoreMessage) {
|
|
2809
|
+
return Promise.resolve(undefined);
|
|
2810
|
+
}
|
|
2811
|
+
this._notificationService.prompt(Severity.Info, ( nls.localizeWithPath(
|
|
2812
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
2813
|
+
'TaskService.ignoredFolder',
|
|
2814
|
+
'The following workspace folders are ignored since they use task version 0.1.0: {0}',
|
|
2815
|
+
( this.ignoredWorkspaceFolders.map(f => f.name)).join(', ')
|
|
2816
|
+
)), [{
|
|
2817
|
+
label: ( nls.localizeWithPath(
|
|
2818
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
2819
|
+
'TaskService.notAgain',
|
|
2820
|
+
"Don't Show Again"
|
|
2821
|
+
)),
|
|
2822
|
+
isSecondary: true,
|
|
2823
|
+
run: () => {
|
|
2824
|
+
this._storageService.store(AbstractTaskService_1.IgnoreTask010DonotShowAgain_key, true, 1 , 1 );
|
|
2825
|
+
this._showIgnoreMessage = false;
|
|
2826
|
+
}
|
|
2827
|
+
}]);
|
|
2828
|
+
return Promise.resolve(undefined);
|
|
2829
|
+
}
|
|
2830
|
+
async _trust() {
|
|
2831
|
+
if (ServerlessWebContext && !TaskExecutionSupportedContext) {
|
|
2832
|
+
return false;
|
|
2833
|
+
}
|
|
2834
|
+
await this._workspaceTrustManagementService.workspaceTrustInitialized;
|
|
2835
|
+
if (!this._workspaceTrustManagementService.isWorkspaceTrusted()) {
|
|
2836
|
+
return (await this._workspaceTrustRequestService.requestWorkspaceTrust({
|
|
2837
|
+
message: ( nls.localizeWithPath(
|
|
2838
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
2839
|
+
'TaskService.requestTrust',
|
|
2840
|
+
"Listing and running tasks requires that some of the files in this workspace be executed as code."
|
|
2841
|
+
))
|
|
2842
|
+
})) === true;
|
|
2843
|
+
}
|
|
2844
|
+
return true;
|
|
2845
|
+
}
|
|
2846
|
+
async _runTaskCommand(filter) {
|
|
2847
|
+
if (!this._tasksReconnected) {
|
|
2848
|
+
return;
|
|
2849
|
+
}
|
|
2850
|
+
if (!filter) {
|
|
2851
|
+
return this._doRunTaskCommand();
|
|
2852
|
+
}
|
|
2853
|
+
const type = typeof filter === 'string' ? undefined : filter.type;
|
|
2854
|
+
const taskName = typeof filter === 'string' ? filter : filter.task;
|
|
2855
|
+
const grouped = await this._getGroupedTasks({ type });
|
|
2856
|
+
const identifier = this._getTaskIdentifier(filter);
|
|
2857
|
+
const tasks = grouped.all();
|
|
2858
|
+
const resolver = this._createResolver(grouped);
|
|
2859
|
+
const folderURIs = ( this._contextService.getWorkspace().folders.map(folder => folder.uri));
|
|
2860
|
+
if (this._contextService.getWorkbenchState() === 3 ) {
|
|
2861
|
+
folderURIs.push(this._contextService.getWorkspace().configuration);
|
|
2862
|
+
}
|
|
2863
|
+
folderURIs.push(USER_TASKS_GROUP_KEY);
|
|
2864
|
+
if (identifier) {
|
|
2865
|
+
for (const uri of folderURIs) {
|
|
2866
|
+
const task = await resolver.resolve(uri, identifier);
|
|
2867
|
+
if (task) {
|
|
2868
|
+
this.run(task);
|
|
2869
|
+
return;
|
|
2870
|
+
}
|
|
2871
|
+
}
|
|
2872
|
+
}
|
|
2873
|
+
const exactMatchTask = !taskName ? undefined : tasks.find(t => t.configurationProperties.identifier === taskName || t.getDefinition(true)?.configurationProperties?.identifier === taskName);
|
|
2874
|
+
if (!exactMatchTask) {
|
|
2875
|
+
return this._doRunTaskCommand(tasks, type, taskName);
|
|
2876
|
+
}
|
|
2877
|
+
for (const uri of folderURIs) {
|
|
2878
|
+
const task = await resolver.resolve(uri, taskName);
|
|
2879
|
+
if (task) {
|
|
2880
|
+
await this.run(task, { attachProblemMatcher: true }, 1 );
|
|
2881
|
+
return;
|
|
2882
|
+
}
|
|
2883
|
+
}
|
|
2884
|
+
}
|
|
2885
|
+
_tasksAndGroupedTasks(filter) {
|
|
2886
|
+
if (!this._versionAndEngineCompatible(filter)) {
|
|
2887
|
+
return { tasks: Promise.resolve([]), grouped: Promise.resolve(( new TaskMap())) };
|
|
2888
|
+
}
|
|
2889
|
+
const grouped = this._getGroupedTasks(filter);
|
|
2890
|
+
const tasks = grouped.then((map) => {
|
|
2891
|
+
if (!filter || !filter.type) {
|
|
2892
|
+
return map.all();
|
|
2893
|
+
}
|
|
2894
|
+
const result = [];
|
|
2895
|
+
map.forEach((tasks) => {
|
|
2896
|
+
for (const task of tasks) {
|
|
2897
|
+
if (ContributedTask.is(task) && task.defines.type === filter.type) {
|
|
2898
|
+
result.push(task);
|
|
2899
|
+
}
|
|
2900
|
+
else if (CustomTask.is(task)) {
|
|
2901
|
+
if (task.type === filter.type) {
|
|
2902
|
+
result.push(task);
|
|
2903
|
+
}
|
|
2904
|
+
else {
|
|
2905
|
+
const customizes = task.customizes();
|
|
2906
|
+
if (customizes && customizes.type === filter.type) {
|
|
2907
|
+
result.push(task);
|
|
2908
|
+
}
|
|
2909
|
+
}
|
|
2910
|
+
}
|
|
2911
|
+
}
|
|
2912
|
+
});
|
|
2913
|
+
return result;
|
|
2914
|
+
});
|
|
2915
|
+
return { tasks, grouped };
|
|
2916
|
+
}
|
|
2917
|
+
_doRunTaskCommand(tasks, type, name) {
|
|
2918
|
+
const pickThen = (task) => {
|
|
2919
|
+
if (task === undefined) {
|
|
2920
|
+
return;
|
|
2921
|
+
}
|
|
2922
|
+
if (task === null) {
|
|
2923
|
+
this._runConfigureTasks();
|
|
2924
|
+
}
|
|
2925
|
+
else {
|
|
2926
|
+
this.run(task, { attachProblemMatcher: true }, 1 ).then(undefined, reason => {
|
|
2927
|
+
});
|
|
2928
|
+
}
|
|
2929
|
+
};
|
|
2930
|
+
const placeholder = ( nls.localizeWithPath(
|
|
2931
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
2932
|
+
'TaskService.pickRunTask',
|
|
2933
|
+
'Select the task to run'
|
|
2934
|
+
));
|
|
2935
|
+
this._showIgnoredFoldersMessage().then(() => {
|
|
2936
|
+
if (this._configurationService.getValue(USE_SLOW_PICKER)) {
|
|
2937
|
+
let taskResult = undefined;
|
|
2938
|
+
if (!tasks) {
|
|
2939
|
+
taskResult = this._tasksAndGroupedTasks();
|
|
2940
|
+
}
|
|
2941
|
+
this._showQuickPick(tasks ? tasks : taskResult.tasks, placeholder, {
|
|
2942
|
+
label: '$(plus) ' + ( nls.localizeWithPath(
|
|
2943
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
2944
|
+
'TaskService.noEntryToRun',
|
|
2945
|
+
'Configure a Task'
|
|
2946
|
+
)),
|
|
2947
|
+
task: null
|
|
2948
|
+
}, true, undefined, undefined, undefined, name).
|
|
2949
|
+
then((entry) => {
|
|
2950
|
+
return pickThen(entry ? entry.task : undefined);
|
|
2951
|
+
});
|
|
2952
|
+
}
|
|
2953
|
+
else {
|
|
2954
|
+
this._showTwoLevelQuickPick(placeholder, {
|
|
2955
|
+
label: '$(plus) ' + ( nls.localizeWithPath(
|
|
2956
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
2957
|
+
'TaskService.noEntryToRun',
|
|
2958
|
+
'Configure a Task'
|
|
2959
|
+
)),
|
|
2960
|
+
task: null
|
|
2961
|
+
}, type, name).
|
|
2962
|
+
then(pickThen);
|
|
2963
|
+
}
|
|
2964
|
+
});
|
|
2965
|
+
}
|
|
2966
|
+
_reRunTaskCommand() {
|
|
2967
|
+
ProblemMatcherRegistry.onReady().then(() => {
|
|
2968
|
+
return this._editorService.saveAll({ reason: 2 }).then(() => {
|
|
2969
|
+
const executeResult = this._getTaskSystem().rerun();
|
|
2970
|
+
if (executeResult) {
|
|
2971
|
+
return this._handleExecuteResult(executeResult);
|
|
2972
|
+
}
|
|
2973
|
+
else {
|
|
2974
|
+
if (!this._taskRunningState.get()) {
|
|
2975
|
+
this._doRunTaskCommand();
|
|
2976
|
+
}
|
|
2977
|
+
return Promise.resolve(undefined);
|
|
2978
|
+
}
|
|
2979
|
+
});
|
|
2980
|
+
});
|
|
2981
|
+
}
|
|
2982
|
+
_getDefaultTasks(tasks, taskGlobsInList = false) {
|
|
2983
|
+
const defaults = [];
|
|
2984
|
+
for (const task of tasks) {
|
|
2985
|
+
if (taskGlobsInList && typeof task.configurationProperties.group.isDefault === 'string') {
|
|
2986
|
+
defaults.push(task);
|
|
2987
|
+
}
|
|
2988
|
+
else if (!taskGlobsInList && task.configurationProperties.group.isDefault === true) {
|
|
2989
|
+
defaults.push(task);
|
|
2990
|
+
}
|
|
2991
|
+
}
|
|
2992
|
+
return defaults;
|
|
2993
|
+
}
|
|
2994
|
+
_runTaskGroupCommand(taskGroup, strings, configure, legacyCommand) {
|
|
2995
|
+
if (this.schemaVersion === 1 ) {
|
|
2996
|
+
legacyCommand();
|
|
2997
|
+
return;
|
|
2998
|
+
}
|
|
2999
|
+
const options = {
|
|
3000
|
+
location: 10 ,
|
|
3001
|
+
title: strings.fetching
|
|
3002
|
+
};
|
|
3003
|
+
const promise = (async () => {
|
|
3004
|
+
let groupTasks = [];
|
|
3005
|
+
async function runSingleTask(task, problemMatcherOptions, that) {
|
|
3006
|
+
that.run(task, problemMatcherOptions, 1 ).then(undefined, reason => {
|
|
3007
|
+
});
|
|
3008
|
+
}
|
|
3009
|
+
const chooseAndRunTask = (tasks) => {
|
|
3010
|
+
this._showIgnoredFoldersMessage().then(() => {
|
|
3011
|
+
this._showQuickPick(tasks, strings.select, {
|
|
3012
|
+
label: strings.notFoundConfigure,
|
|
3013
|
+
task: null
|
|
3014
|
+
}, true).then((entry) => {
|
|
3015
|
+
const task = entry ? entry.task : undefined;
|
|
3016
|
+
if (task === undefined) {
|
|
3017
|
+
return;
|
|
3018
|
+
}
|
|
3019
|
+
if (task === null) {
|
|
3020
|
+
configure.apply(this);
|
|
3021
|
+
return;
|
|
3022
|
+
}
|
|
3023
|
+
runSingleTask(task, { attachProblemMatcher: true }, this);
|
|
3024
|
+
});
|
|
3025
|
+
});
|
|
3026
|
+
};
|
|
3027
|
+
let globTasksDetected = false;
|
|
3028
|
+
const absoluteURI = EditorResourceAccessor.getOriginalUri(this._editorService.activeEditor);
|
|
3029
|
+
if (absoluteURI) {
|
|
3030
|
+
const workspaceFolder = this._contextService.getWorkspaceFolder(absoluteURI);
|
|
3031
|
+
if (workspaceFolder) {
|
|
3032
|
+
const configuredTasks = this._getConfiguration(workspaceFolder)?.config?.tasks;
|
|
3033
|
+
if (configuredTasks) {
|
|
3034
|
+
globTasksDetected = configuredTasks.filter(task => task.group && typeof task.group !== 'string' && typeof task.group.isDefault === 'string').length > 0;
|
|
3035
|
+
if (globTasksDetected) {
|
|
3036
|
+
const relativePath = workspaceFolder?.uri ? (resources.relativePath(workspaceFolder.uri, absoluteURI) ?? absoluteURI.path) : absoluteURI.path;
|
|
3037
|
+
groupTasks = await this._findWorkspaceTasks((task) => {
|
|
3038
|
+
const currentTaskGroup = task.configurationProperties.group;
|
|
3039
|
+
if (currentTaskGroup && typeof currentTaskGroup !== 'string' && typeof currentTaskGroup.isDefault === 'string') {
|
|
3040
|
+
return (currentTaskGroup._id === taskGroup._id && glob.match(currentTaskGroup.isDefault, relativePath));
|
|
3041
|
+
}
|
|
3042
|
+
return false;
|
|
3043
|
+
});
|
|
3044
|
+
}
|
|
3045
|
+
}
|
|
3046
|
+
}
|
|
3047
|
+
}
|
|
3048
|
+
if (!globTasksDetected && groupTasks.length === 0) {
|
|
3049
|
+
groupTasks = await this._findWorkspaceTasksInGroup(taskGroup, true);
|
|
3050
|
+
}
|
|
3051
|
+
const handleMultipleTasks = (areGlobTasks) => {
|
|
3052
|
+
return this._getTasksForGroup(taskGroup).then((tasks) => {
|
|
3053
|
+
if (tasks.length > 0) {
|
|
3054
|
+
const defaults = this._getDefaultTasks(tasks, areGlobTasks);
|
|
3055
|
+
if (defaults.length === 1) {
|
|
3056
|
+
runSingleTask(defaults[0], undefined, this);
|
|
3057
|
+
return;
|
|
3058
|
+
}
|
|
3059
|
+
else if (defaults.length > 0) {
|
|
3060
|
+
tasks = defaults;
|
|
3061
|
+
}
|
|
3062
|
+
}
|
|
3063
|
+
chooseAndRunTask(tasks);
|
|
3064
|
+
});
|
|
3065
|
+
};
|
|
3066
|
+
const resolveTaskAndRun = (taskGroupTask) => {
|
|
3067
|
+
if (ConfiguringTask.is(taskGroupTask)) {
|
|
3068
|
+
this.tryResolveTask(taskGroupTask).then(resolvedTask => {
|
|
3069
|
+
runSingleTask(resolvedTask, undefined, this);
|
|
3070
|
+
});
|
|
3071
|
+
}
|
|
3072
|
+
else {
|
|
3073
|
+
runSingleTask(taskGroupTask, undefined, this);
|
|
3074
|
+
}
|
|
3075
|
+
};
|
|
3076
|
+
if (groupTasks.length === 1) {
|
|
3077
|
+
return resolveTaskAndRun(groupTasks[0]);
|
|
3078
|
+
}
|
|
3079
|
+
if (globTasksDetected && groupTasks.length > 1) {
|
|
3080
|
+
return handleMultipleTasks(true);
|
|
3081
|
+
}
|
|
3082
|
+
if (!groupTasks.length) {
|
|
3083
|
+
groupTasks = await this._findWorkspaceTasksInGroup(taskGroup, false);
|
|
3084
|
+
}
|
|
3085
|
+
if (groupTasks.length === 1) {
|
|
3086
|
+
return resolveTaskAndRun(groupTasks[0]);
|
|
3087
|
+
}
|
|
3088
|
+
return handleMultipleTasks(false);
|
|
3089
|
+
})();
|
|
3090
|
+
this._progressService.withProgress(options, () => promise);
|
|
3091
|
+
}
|
|
3092
|
+
_runBuildCommand() {
|
|
3093
|
+
if (!this._tasksReconnected) {
|
|
3094
|
+
return;
|
|
3095
|
+
}
|
|
3096
|
+
return this._runTaskGroupCommand(TaskGroup.Build, {
|
|
3097
|
+
fetching: ( nls.localizeWithPath(
|
|
3098
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
3099
|
+
'TaskService.fetchingBuildTasks',
|
|
3100
|
+
'Fetching build tasks...'
|
|
3101
|
+
)),
|
|
3102
|
+
select: ( nls.localizeWithPath(
|
|
3103
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
3104
|
+
'TaskService.pickBuildTask',
|
|
3105
|
+
'Select the build task to run'
|
|
3106
|
+
)),
|
|
3107
|
+
notFoundConfigure: ( nls.localizeWithPath(
|
|
3108
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
3109
|
+
'TaskService.noBuildTask',
|
|
3110
|
+
'No build task to run found. Configure Build Task...'
|
|
3111
|
+
))
|
|
3112
|
+
}, this._runConfigureDefaultBuildTask, this._build);
|
|
3113
|
+
}
|
|
3114
|
+
_runTestCommand() {
|
|
3115
|
+
return this._runTaskGroupCommand(TaskGroup.Test, {
|
|
3116
|
+
fetching: ( nls.localizeWithPath(
|
|
3117
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
3118
|
+
'TaskService.fetchingTestTasks',
|
|
3119
|
+
'Fetching test tasks...'
|
|
3120
|
+
)),
|
|
3121
|
+
select: ( nls.localizeWithPath(
|
|
3122
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
3123
|
+
'TaskService.pickTestTask',
|
|
3124
|
+
'Select the test task to run'
|
|
3125
|
+
)),
|
|
3126
|
+
notFoundConfigure: ( nls.localizeWithPath(
|
|
3127
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
3128
|
+
'TaskService.noTestTaskTerminal',
|
|
3129
|
+
'No test task to run found. Configure Tasks...'
|
|
3130
|
+
))
|
|
3131
|
+
}, this._runConfigureDefaultTestTask, this._runTest);
|
|
3132
|
+
}
|
|
3133
|
+
_runTerminateCommand(arg) {
|
|
3134
|
+
if (arg === 'terminateAll') {
|
|
3135
|
+
this._terminateAll();
|
|
3136
|
+
return;
|
|
3137
|
+
}
|
|
3138
|
+
const runQuickPick = (promise) => {
|
|
3139
|
+
this._showQuickPick(promise || this.getActiveTasks(), ( nls.localizeWithPath(
|
|
3140
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
3141
|
+
'TaskService.taskToTerminate',
|
|
3142
|
+
'Select a task to terminate'
|
|
3143
|
+
)), {
|
|
3144
|
+
label: ( nls.localizeWithPath(
|
|
3145
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
3146
|
+
'TaskService.noTaskRunning',
|
|
3147
|
+
'No task is currently running'
|
|
3148
|
+
)),
|
|
3149
|
+
task: undefined
|
|
3150
|
+
}, false, true, undefined, [{
|
|
3151
|
+
label: ( nls.localizeWithPath(
|
|
3152
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
3153
|
+
'TaskService.terminateAllRunningTasks',
|
|
3154
|
+
'All Running Tasks'
|
|
3155
|
+
)),
|
|
3156
|
+
id: 'terminateAll',
|
|
3157
|
+
task: undefined
|
|
3158
|
+
}]).then(entry => {
|
|
3159
|
+
if (entry && entry.id === 'terminateAll') {
|
|
3160
|
+
this._terminateAll();
|
|
3161
|
+
}
|
|
3162
|
+
const task = entry ? entry.task : undefined;
|
|
3163
|
+
if (task === undefined || task === null) {
|
|
3164
|
+
return;
|
|
3165
|
+
}
|
|
3166
|
+
this.terminate(task);
|
|
3167
|
+
});
|
|
3168
|
+
};
|
|
3169
|
+
if (this.inTerminal()) {
|
|
3170
|
+
const identifier = this._getTaskIdentifier(arg);
|
|
3171
|
+
let promise;
|
|
3172
|
+
if (identifier !== undefined) {
|
|
3173
|
+
promise = this.getActiveTasks();
|
|
3174
|
+
promise.then((tasks) => {
|
|
3175
|
+
for (const task of tasks) {
|
|
3176
|
+
if (task.matches(identifier)) {
|
|
3177
|
+
this.terminate(task);
|
|
3178
|
+
return;
|
|
3179
|
+
}
|
|
3180
|
+
}
|
|
3181
|
+
runQuickPick(promise);
|
|
3182
|
+
});
|
|
3183
|
+
}
|
|
3184
|
+
else {
|
|
3185
|
+
runQuickPick();
|
|
3186
|
+
}
|
|
3187
|
+
}
|
|
3188
|
+
else {
|
|
3189
|
+
this._isActive().then((active) => {
|
|
3190
|
+
if (active) {
|
|
3191
|
+
this._terminateAll().then((responses) => {
|
|
3192
|
+
const response = responses[0];
|
|
3193
|
+
if (response.success) {
|
|
3194
|
+
return;
|
|
3195
|
+
}
|
|
3196
|
+
if (response.code && response.code === 3 ) {
|
|
3197
|
+
this._notificationService.error(( nls.localizeWithPath(
|
|
3198
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
3199
|
+
'TerminateAction.noProcess',
|
|
3200
|
+
'The launched process doesn\'t exist anymore. If the task spawned background tasks exiting VS Code might result in orphaned processes.'
|
|
3201
|
+
)));
|
|
3202
|
+
}
|
|
3203
|
+
else {
|
|
3204
|
+
this._notificationService.error(( nls.localizeWithPath(
|
|
3205
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
3206
|
+
'TerminateAction.failed',
|
|
3207
|
+
'Failed to terminate running task'
|
|
3208
|
+
)));
|
|
3209
|
+
}
|
|
3210
|
+
});
|
|
3211
|
+
}
|
|
3212
|
+
});
|
|
3213
|
+
}
|
|
3214
|
+
}
|
|
3215
|
+
async _runRestartTaskCommand(arg) {
|
|
3216
|
+
const activeTasks = await this.getActiveTasks();
|
|
3217
|
+
if (activeTasks.length === 1) {
|
|
3218
|
+
this._restart(activeTasks[0]);
|
|
3219
|
+
return;
|
|
3220
|
+
}
|
|
3221
|
+
if (this.inTerminal()) {
|
|
3222
|
+
const identifier = this._getTaskIdentifier(arg);
|
|
3223
|
+
if (identifier !== undefined) {
|
|
3224
|
+
for (const task of activeTasks) {
|
|
3225
|
+
if (task.matches(identifier)) {
|
|
3226
|
+
this._restart(task);
|
|
3227
|
+
return;
|
|
3228
|
+
}
|
|
3229
|
+
}
|
|
3230
|
+
}
|
|
3231
|
+
const entry = await this._showQuickPick(activeTasks, ( nls.localizeWithPath(
|
|
3232
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
3233
|
+
'TaskService.taskToRestart',
|
|
3234
|
+
'Select the task to restart'
|
|
3235
|
+
)), {
|
|
3236
|
+
label: ( nls.localizeWithPath(
|
|
3237
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
3238
|
+
'TaskService.noTaskToRestart',
|
|
3239
|
+
'No task to restart'
|
|
3240
|
+
)),
|
|
3241
|
+
task: null
|
|
3242
|
+
}, false, true);
|
|
3243
|
+
if (entry && entry.task) {
|
|
3244
|
+
this._restart(entry.task);
|
|
3245
|
+
}
|
|
3246
|
+
}
|
|
3247
|
+
else {
|
|
3248
|
+
if (activeTasks.length > 0) {
|
|
3249
|
+
this._restart(activeTasks[0]);
|
|
3250
|
+
}
|
|
3251
|
+
}
|
|
3252
|
+
}
|
|
3253
|
+
_getTaskIdentifier(filter) {
|
|
3254
|
+
let result = undefined;
|
|
3255
|
+
if (Types.isString(filter)) {
|
|
3256
|
+
result = filter;
|
|
3257
|
+
}
|
|
3258
|
+
else if (filter && Types.isString(filter.type)) {
|
|
3259
|
+
result = TaskDefinition.createTaskIdentifier(filter, console);
|
|
3260
|
+
}
|
|
3261
|
+
return result;
|
|
3262
|
+
}
|
|
3263
|
+
_configHasTasks(taskConfig) {
|
|
3264
|
+
return !!taskConfig && !!taskConfig.tasks && taskConfig.tasks.length > 0;
|
|
3265
|
+
}
|
|
3266
|
+
_openTaskFile(resource, taskSource) {
|
|
3267
|
+
let configFileCreated = false;
|
|
3268
|
+
this._fileService.stat(resource).then((stat) => stat, () => undefined).then(async (stat) => {
|
|
3269
|
+
const fileExists = !!stat;
|
|
3270
|
+
const configValue = this._configurationService.inspect('tasks');
|
|
3271
|
+
let tasksExistInFile;
|
|
3272
|
+
let target;
|
|
3273
|
+
switch (taskSource) {
|
|
3274
|
+
case TaskSourceKind.User:
|
|
3275
|
+
tasksExistInFile = this._configHasTasks(configValue.userValue);
|
|
3276
|
+
target = 2 ;
|
|
3277
|
+
break;
|
|
3278
|
+
case TaskSourceKind.WorkspaceFile:
|
|
3279
|
+
tasksExistInFile = this._configHasTasks(configValue.workspaceValue);
|
|
3280
|
+
target = 5 ;
|
|
3281
|
+
break;
|
|
3282
|
+
default:
|
|
3283
|
+
tasksExistInFile = this._configHasTasks(configValue.workspaceFolderValue);
|
|
3284
|
+
target = 6 ;
|
|
3285
|
+
}
|
|
3286
|
+
let content;
|
|
3287
|
+
if (!tasksExistInFile) {
|
|
3288
|
+
const pickTemplateResult = await this._quickInputService.pick(getTemplates(), { placeHolder: ( nls.localizeWithPath(
|
|
3289
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
3290
|
+
'TaskService.template',
|
|
3291
|
+
'Select a Task Template'
|
|
3292
|
+
)) });
|
|
3293
|
+
if (!pickTemplateResult) {
|
|
3294
|
+
return Promise.resolve(undefined);
|
|
3295
|
+
}
|
|
3296
|
+
content = pickTemplateResult.content;
|
|
3297
|
+
const editorConfig = this._configurationService.getValue();
|
|
3298
|
+
if (editorConfig.editor.insertSpaces) {
|
|
3299
|
+
content = content.replace(/(\n)(\t+)/g, (_, s1, s2) => s1 + ' '.repeat(s2.length * editorConfig.editor.tabSize));
|
|
3300
|
+
}
|
|
3301
|
+
configFileCreated = true;
|
|
3302
|
+
}
|
|
3303
|
+
if (!fileExists && content) {
|
|
3304
|
+
return this._textFileService.create([{ resource, value: content }]).then(result => {
|
|
3305
|
+
return result[0].resource;
|
|
3306
|
+
});
|
|
3307
|
+
}
|
|
3308
|
+
else if (fileExists && (tasksExistInFile || content)) {
|
|
3309
|
+
if (content) {
|
|
3310
|
+
this._configurationService.updateValue('tasks', json.parse(content), target);
|
|
3311
|
+
}
|
|
3312
|
+
return stat?.resource;
|
|
3313
|
+
}
|
|
3314
|
+
return undefined;
|
|
3315
|
+
}).then((resource) => {
|
|
3316
|
+
if (!resource) {
|
|
3317
|
+
return;
|
|
3318
|
+
}
|
|
3319
|
+
this._editorService.openEditor({
|
|
3320
|
+
resource,
|
|
3321
|
+
options: {
|
|
3322
|
+
pinned: configFileCreated
|
|
3323
|
+
}
|
|
3324
|
+
});
|
|
3325
|
+
});
|
|
3326
|
+
}
|
|
3327
|
+
_isTaskEntry(value) {
|
|
3328
|
+
const candidate = value;
|
|
3329
|
+
return candidate && !!candidate.task;
|
|
3330
|
+
}
|
|
3331
|
+
_isSettingEntry(value) {
|
|
3332
|
+
const candidate = value;
|
|
3333
|
+
return candidate && !!candidate.settingType;
|
|
3334
|
+
}
|
|
3335
|
+
_configureTask(task) {
|
|
3336
|
+
if (ContributedTask.is(task)) {
|
|
3337
|
+
this.customize(task, undefined, true);
|
|
3338
|
+
}
|
|
3339
|
+
else if (CustomTask.is(task)) {
|
|
3340
|
+
this.openConfig(task);
|
|
3341
|
+
}
|
|
3342
|
+
else if (ConfiguringTask.is(task)) ;
|
|
3343
|
+
}
|
|
3344
|
+
_handleSelection(selection) {
|
|
3345
|
+
if (!selection) {
|
|
3346
|
+
return;
|
|
3347
|
+
}
|
|
3348
|
+
if (this._isTaskEntry(selection)) {
|
|
3349
|
+
this._configureTask(selection.task);
|
|
3350
|
+
}
|
|
3351
|
+
else if (this._isSettingEntry(selection)) {
|
|
3352
|
+
const taskQuickPick = this._instantiationService.createInstance(TaskQuickPick);
|
|
3353
|
+
taskQuickPick.handleSettingOption(selection.settingType);
|
|
3354
|
+
}
|
|
3355
|
+
else if (selection.folder && ((this._contextService.getWorkbenchState() !== 1) )) {
|
|
3356
|
+
this._openTaskFile(selection.folder.toResource('.vscode/tasks.json'), TaskSourceKind.Workspace);
|
|
3357
|
+
}
|
|
3358
|
+
else {
|
|
3359
|
+
const resource = this._getResourceForKind(TaskSourceKind.User);
|
|
3360
|
+
if (resource) {
|
|
3361
|
+
this._openTaskFile(resource, TaskSourceKind.User);
|
|
3362
|
+
}
|
|
3363
|
+
}
|
|
3364
|
+
}
|
|
3365
|
+
getTaskDescription(task) {
|
|
3366
|
+
let description;
|
|
3367
|
+
if (task._source.kind === TaskSourceKind.User) {
|
|
3368
|
+
description = ( nls.localizeWithPath(
|
|
3369
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
3370
|
+
'taskQuickPick.userSettings',
|
|
3371
|
+
'User'
|
|
3372
|
+
));
|
|
3373
|
+
}
|
|
3374
|
+
else if (task._source.kind === TaskSourceKind.WorkspaceFile) {
|
|
3375
|
+
description = task.getWorkspaceFileName();
|
|
3376
|
+
}
|
|
3377
|
+
else if (this.needsFolderQualification()) {
|
|
3378
|
+
const workspaceFolder = task.getWorkspaceFolder();
|
|
3379
|
+
if (workspaceFolder) {
|
|
3380
|
+
description = workspaceFolder.name;
|
|
3381
|
+
}
|
|
3382
|
+
}
|
|
3383
|
+
return description;
|
|
3384
|
+
}
|
|
3385
|
+
async _runConfigureTasks() {
|
|
3386
|
+
if (!(await this._trust())) {
|
|
3387
|
+
return;
|
|
3388
|
+
}
|
|
3389
|
+
let taskPromise;
|
|
3390
|
+
if (this.schemaVersion === 2 ) {
|
|
3391
|
+
taskPromise = this._getGroupedTasks();
|
|
3392
|
+
}
|
|
3393
|
+
else {
|
|
3394
|
+
taskPromise = Promise.resolve(( new TaskMap()));
|
|
3395
|
+
}
|
|
3396
|
+
const stats = ( this._contextService.getWorkspace().folders.map((folder) => {
|
|
3397
|
+
return this._fileService.stat(folder.toResource('.vscode/tasks.json')).then(stat => stat, () => undefined);
|
|
3398
|
+
}));
|
|
3399
|
+
const createLabel = ( nls.localizeWithPath(
|
|
3400
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
3401
|
+
'TaskService.createJsonFile',
|
|
3402
|
+
'Create tasks.json file from template'
|
|
3403
|
+
));
|
|
3404
|
+
const openLabel = ( nls.localizeWithPath(
|
|
3405
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
3406
|
+
'TaskService.openJsonFile',
|
|
3407
|
+
'Open tasks.json file'
|
|
3408
|
+
));
|
|
3409
|
+
const tokenSource = ( new CancellationTokenSource());
|
|
3410
|
+
const cancellationToken = tokenSource.token;
|
|
3411
|
+
const entries = Promise.all(stats).then((stats) => {
|
|
3412
|
+
return taskPromise.then((taskMap) => {
|
|
3413
|
+
const entries = [];
|
|
3414
|
+
let configuredCount = 0;
|
|
3415
|
+
let tasks = taskMap.all();
|
|
3416
|
+
if (tasks.length > 0) {
|
|
3417
|
+
tasks = tasks.sort((a, b) => a._label.localeCompare(b._label));
|
|
3418
|
+
for (const task of tasks) {
|
|
3419
|
+
const entry = { label: TaskQuickPick.getTaskLabelWithIcon(task), task, description: this.getTaskDescription(task), detail: this._showDetail() ? task.configurationProperties.detail : undefined };
|
|
3420
|
+
TaskQuickPick.applyColorStyles(task, entry, this._themeService);
|
|
3421
|
+
entries.push(entry);
|
|
3422
|
+
if (!ContributedTask.is(task)) {
|
|
3423
|
+
configuredCount++;
|
|
3424
|
+
}
|
|
3425
|
+
}
|
|
3426
|
+
}
|
|
3427
|
+
const needsCreateOrOpen = (configuredCount === 0);
|
|
3428
|
+
if (needsCreateOrOpen || (taskMap.get(USER_TASKS_GROUP_KEY).length === configuredCount)) {
|
|
3429
|
+
const label = stats[0] !== undefined ? openLabel : createLabel;
|
|
3430
|
+
if (entries.length) {
|
|
3431
|
+
entries.push({ type: 'separator' });
|
|
3432
|
+
}
|
|
3433
|
+
entries.push({ label, folder: this._contextService.getWorkspace().folders[0] });
|
|
3434
|
+
}
|
|
3435
|
+
if ((entries.length === 1) && !needsCreateOrOpen) {
|
|
3436
|
+
tokenSource.cancel();
|
|
3437
|
+
}
|
|
3438
|
+
return entries;
|
|
3439
|
+
});
|
|
3440
|
+
});
|
|
3441
|
+
const timeout = await Promise.race([( new Promise((resolve) => {
|
|
3442
|
+
entries.then(() => resolve(false));
|
|
3443
|
+
})), ( new Promise((resolve) => {
|
|
3444
|
+
const timer = setTimeout(() => {
|
|
3445
|
+
clearTimeout(timer);
|
|
3446
|
+
resolve(true);
|
|
3447
|
+
}, 200);
|
|
3448
|
+
}))]);
|
|
3449
|
+
if (!timeout && ((await entries).length === 1) && this._configurationService.getValue(QUICKOPEN_SKIP_CONFIG)) {
|
|
3450
|
+
const entry = ((await entries)[0]);
|
|
3451
|
+
if (entry.task) {
|
|
3452
|
+
this._handleSelection(entry);
|
|
3453
|
+
return;
|
|
3454
|
+
}
|
|
3455
|
+
}
|
|
3456
|
+
const entriesWithSettings = entries.then(resolvedEntries => {
|
|
3457
|
+
resolvedEntries.push(...TaskQuickPick.allSettingEntries(this._configurationService));
|
|
3458
|
+
return resolvedEntries;
|
|
3459
|
+
});
|
|
3460
|
+
this._quickInputService.pick(entriesWithSettings, { placeHolder: ( nls.localizeWithPath(
|
|
3461
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
3462
|
+
'TaskService.pickTask',
|
|
3463
|
+
'Select a task to configure'
|
|
3464
|
+
)) }, cancellationToken).
|
|
3465
|
+
then(async (selection) => {
|
|
3466
|
+
if (cancellationToken.isCancellationRequested) {
|
|
3467
|
+
const task = (await entries)[0];
|
|
3468
|
+
if (task.task) {
|
|
3469
|
+
selection = task;
|
|
3470
|
+
}
|
|
3471
|
+
}
|
|
3472
|
+
this._handleSelection(selection);
|
|
3473
|
+
});
|
|
3474
|
+
}
|
|
3475
|
+
_runConfigureDefaultBuildTask() {
|
|
3476
|
+
if (this.schemaVersion === 2 ) {
|
|
3477
|
+
this.tasks().then((tasks => {
|
|
3478
|
+
if (tasks.length === 0) {
|
|
3479
|
+
this._runConfigureTasks();
|
|
3480
|
+
return;
|
|
3481
|
+
}
|
|
3482
|
+
const entries = [];
|
|
3483
|
+
let selectedTask;
|
|
3484
|
+
let selectedEntry;
|
|
3485
|
+
this._showIgnoredFoldersMessage().then(() => {
|
|
3486
|
+
for (const task of tasks) {
|
|
3487
|
+
const taskGroup = TaskGroup.from(task.configurationProperties.group);
|
|
3488
|
+
if (taskGroup && taskGroup.isDefault && taskGroup._id === TaskGroup.Build._id) {
|
|
3489
|
+
const label = ( nls.localizeWithPath(
|
|
3490
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
3491
|
+
'TaskService.defaultBuildTaskExists',
|
|
3492
|
+
'{0} is already marked as the default build task',
|
|
3493
|
+
TaskQuickPick.getTaskLabelWithIcon(task, task.getQualifiedLabel())
|
|
3494
|
+
));
|
|
3495
|
+
selectedTask = task;
|
|
3496
|
+
selectedEntry = { label, task, description: this.getTaskDescription(task), detail: this._showDetail() ? task.configurationProperties.detail : undefined };
|
|
3497
|
+
TaskQuickPick.applyColorStyles(task, selectedEntry, this._themeService);
|
|
3498
|
+
}
|
|
3499
|
+
else {
|
|
3500
|
+
const entry = { label: TaskQuickPick.getTaskLabelWithIcon(task), task, description: this.getTaskDescription(task), detail: this._showDetail() ? task.configurationProperties.detail : undefined };
|
|
3501
|
+
TaskQuickPick.applyColorStyles(task, entry, this._themeService);
|
|
3502
|
+
entries.push(entry);
|
|
3503
|
+
}
|
|
3504
|
+
}
|
|
3505
|
+
if (selectedEntry) {
|
|
3506
|
+
entries.unshift(selectedEntry);
|
|
3507
|
+
}
|
|
3508
|
+
const tokenSource = ( new CancellationTokenSource());
|
|
3509
|
+
const cancellationToken = tokenSource.token;
|
|
3510
|
+
this._quickInputService.pick(entries, { placeHolder: ( nls.localizeWithPath(
|
|
3511
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
3512
|
+
'TaskService.pickTask',
|
|
3513
|
+
'Select a task to configure'
|
|
3514
|
+
)) }, cancellationToken).
|
|
3515
|
+
then(async (entry) => {
|
|
3516
|
+
if (cancellationToken.isCancellationRequested) {
|
|
3517
|
+
const task = (await entries)[0];
|
|
3518
|
+
if (task.task) {
|
|
3519
|
+
entry = task;
|
|
3520
|
+
}
|
|
3521
|
+
}
|
|
3522
|
+
const task = entry && 'task' in entry ? entry.task : undefined;
|
|
3523
|
+
if ((task === undefined) || (task === null)) {
|
|
3524
|
+
return;
|
|
3525
|
+
}
|
|
3526
|
+
if (task === selectedTask && CustomTask.is(task)) {
|
|
3527
|
+
this.openConfig(task);
|
|
3528
|
+
}
|
|
3529
|
+
if (!InMemoryTask.is(task)) {
|
|
3530
|
+
this.customize(task, { group: { kind: 'build', isDefault: true } }, true).then(() => {
|
|
3531
|
+
if (selectedTask && (task !== selectedTask) && !InMemoryTask.is(selectedTask)) {
|
|
3532
|
+
this.customize(selectedTask, { group: 'build' }, false);
|
|
3533
|
+
}
|
|
3534
|
+
});
|
|
3535
|
+
}
|
|
3536
|
+
});
|
|
3537
|
+
this._quickInputService.pick(entries, {
|
|
3538
|
+
placeHolder: ( nls.localizeWithPath(
|
|
3539
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
3540
|
+
'TaskService.pickDefaultBuildTask',
|
|
3541
|
+
'Select the task to be used as the default build task'
|
|
3542
|
+
))
|
|
3543
|
+
}).
|
|
3544
|
+
then((entry) => {
|
|
3545
|
+
const task = entry && 'task' in entry ? entry.task : undefined;
|
|
3546
|
+
if ((task === undefined) || (task === null)) {
|
|
3547
|
+
return;
|
|
3548
|
+
}
|
|
3549
|
+
if (task === selectedTask && CustomTask.is(task)) {
|
|
3550
|
+
this.openConfig(task);
|
|
3551
|
+
}
|
|
3552
|
+
if (!InMemoryTask.is(task)) {
|
|
3553
|
+
this.customize(task, { group: { kind: 'build', isDefault: true } }, true).then(() => {
|
|
3554
|
+
if (selectedTask && (task !== selectedTask) && !InMemoryTask.is(selectedTask)) {
|
|
3555
|
+
this.customize(selectedTask, { group: 'build' }, false);
|
|
3556
|
+
}
|
|
3557
|
+
});
|
|
3558
|
+
}
|
|
3559
|
+
});
|
|
3560
|
+
});
|
|
3561
|
+
}));
|
|
3562
|
+
}
|
|
3563
|
+
else {
|
|
3564
|
+
this._runConfigureTasks();
|
|
3565
|
+
}
|
|
3566
|
+
}
|
|
3567
|
+
_runConfigureDefaultTestTask() {
|
|
3568
|
+
if (this.schemaVersion === 2 ) {
|
|
3569
|
+
this.tasks().then((tasks => {
|
|
3570
|
+
if (tasks.length === 0) {
|
|
3571
|
+
this._runConfigureTasks();
|
|
3572
|
+
return;
|
|
3573
|
+
}
|
|
3574
|
+
let selectedTask;
|
|
3575
|
+
let selectedEntry;
|
|
3576
|
+
for (const task of tasks) {
|
|
3577
|
+
const taskGroup = TaskGroup.from(task.configurationProperties.group);
|
|
3578
|
+
if (taskGroup && taskGroup.isDefault && taskGroup._id === TaskGroup.Test._id) {
|
|
3579
|
+
selectedTask = task;
|
|
3580
|
+
break;
|
|
3581
|
+
}
|
|
3582
|
+
}
|
|
3583
|
+
if (selectedTask) {
|
|
3584
|
+
selectedEntry = {
|
|
3585
|
+
label: ( nls.localizeWithPath(
|
|
3586
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
3587
|
+
'TaskService.defaultTestTaskExists',
|
|
3588
|
+
'{0} is already marked as the default test task.',
|
|
3589
|
+
selectedTask.getQualifiedLabel()
|
|
3590
|
+
)),
|
|
3591
|
+
task: selectedTask,
|
|
3592
|
+
detail: this._showDetail() ? selectedTask.configurationProperties.detail : undefined
|
|
3593
|
+
};
|
|
3594
|
+
}
|
|
3595
|
+
this._showIgnoredFoldersMessage().then(() => {
|
|
3596
|
+
this._showQuickPick(tasks, ( nls.localizeWithPath(
|
|
3597
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
3598
|
+
'TaskService.pickDefaultTestTask',
|
|
3599
|
+
'Select the task to be used as the default test task'
|
|
3600
|
+
)), undefined, true, false, selectedEntry).then((entry) => {
|
|
3601
|
+
const task = entry ? entry.task : undefined;
|
|
3602
|
+
if (!task) {
|
|
3603
|
+
return;
|
|
3604
|
+
}
|
|
3605
|
+
if (task === selectedTask && CustomTask.is(task)) {
|
|
3606
|
+
this.openConfig(task);
|
|
3607
|
+
}
|
|
3608
|
+
if (!InMemoryTask.is(task)) {
|
|
3609
|
+
this.customize(task, { group: { kind: 'test', isDefault: true } }, true).then(() => {
|
|
3610
|
+
if (selectedTask && (task !== selectedTask) && !InMemoryTask.is(selectedTask)) {
|
|
3611
|
+
this.customize(selectedTask, { group: 'test' }, false);
|
|
3612
|
+
}
|
|
3613
|
+
});
|
|
3614
|
+
}
|
|
3615
|
+
});
|
|
3616
|
+
});
|
|
3617
|
+
}));
|
|
3618
|
+
}
|
|
3619
|
+
else {
|
|
3620
|
+
this._runConfigureTasks();
|
|
3621
|
+
}
|
|
3622
|
+
}
|
|
3623
|
+
async runShowTasks() {
|
|
3624
|
+
const activeTasksPromise = this.getActiveTasks();
|
|
3625
|
+
const activeTasks = await activeTasksPromise;
|
|
3626
|
+
let group;
|
|
3627
|
+
if (activeTasks.length === 1) {
|
|
3628
|
+
this._taskSystem.revealTask(activeTasks[0]);
|
|
3629
|
+
}
|
|
3630
|
+
else if (activeTasks.length && activeTasks.every((task) => {
|
|
3631
|
+
if (InMemoryTask.is(task)) {
|
|
3632
|
+
return false;
|
|
3633
|
+
}
|
|
3634
|
+
if (!group) {
|
|
3635
|
+
group = task.command.presentation?.group;
|
|
3636
|
+
}
|
|
3637
|
+
return task.command.presentation?.group && (task.command.presentation.group === group);
|
|
3638
|
+
})) {
|
|
3639
|
+
this._taskSystem.revealTask(activeTasks[0]);
|
|
3640
|
+
}
|
|
3641
|
+
else {
|
|
3642
|
+
this._showQuickPick(activeTasksPromise, ( nls.localizeWithPath(
|
|
3643
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
3644
|
+
'TaskService.pickShowTask',
|
|
3645
|
+
'Select the task to show its output'
|
|
3646
|
+
)), {
|
|
3647
|
+
label: ( nls.localizeWithPath(
|
|
3648
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
3649
|
+
'TaskService.noTaskIsRunning',
|
|
3650
|
+
'No task is running'
|
|
3651
|
+
)),
|
|
3652
|
+
task: null
|
|
3653
|
+
}, false, true).then((entry) => {
|
|
3654
|
+
const task = entry ? entry.task : undefined;
|
|
3655
|
+
if (task === undefined || task === null) {
|
|
3656
|
+
return;
|
|
3657
|
+
}
|
|
3658
|
+
this._taskSystem.revealTask(task);
|
|
3659
|
+
});
|
|
3660
|
+
}
|
|
3661
|
+
}
|
|
3662
|
+
async _createTasksDotOld(folder) {
|
|
3663
|
+
const tasksFile = folder.toResource('.vscode/tasks.json');
|
|
3664
|
+
if (await this._fileService.exists(tasksFile)) {
|
|
3665
|
+
const oldFile = tasksFile.with({ path: `${tasksFile.path}.old` });
|
|
3666
|
+
await this._fileService.copy(tasksFile, oldFile, true);
|
|
3667
|
+
return [oldFile, tasksFile];
|
|
3668
|
+
}
|
|
3669
|
+
return undefined;
|
|
3670
|
+
}
|
|
3671
|
+
_upgradeTask(task, suppressTaskName, globalConfig) {
|
|
3672
|
+
if (!CustomTask.is(task)) {
|
|
3673
|
+
return;
|
|
3674
|
+
}
|
|
3675
|
+
const configElement = {
|
|
3676
|
+
label: task._label
|
|
3677
|
+
};
|
|
3678
|
+
const oldTaskTypes = ( new Set(['gulp', 'jake', 'grunt']));
|
|
3679
|
+
if (Types.isString(task.command.name) && ( oldTaskTypes.has(task.command.name))) {
|
|
3680
|
+
configElement.type = task.command.name;
|
|
3681
|
+
configElement.task = task.command.args[0];
|
|
3682
|
+
}
|
|
3683
|
+
else {
|
|
3684
|
+
if (task.command.runtime === RuntimeType.Shell) {
|
|
3685
|
+
configElement.type = ( RuntimeType.toString(RuntimeType.Shell));
|
|
3686
|
+
}
|
|
3687
|
+
if (task.command.name && !suppressTaskName && !globalConfig.windows?.command && !globalConfig.osx?.command && !globalConfig.linux?.command) {
|
|
3688
|
+
configElement.command = task.command.name;
|
|
3689
|
+
}
|
|
3690
|
+
else if (suppressTaskName) {
|
|
3691
|
+
configElement.command = task._source.config.element.command;
|
|
3692
|
+
}
|
|
3693
|
+
if (task.command.args && (!Array.isArray(task.command.args) || (task.command.args.length > 0))) {
|
|
3694
|
+
if (!globalConfig.windows?.args && !globalConfig.osx?.args && !globalConfig.linux?.args) {
|
|
3695
|
+
configElement.args = task.command.args;
|
|
3696
|
+
}
|
|
3697
|
+
else {
|
|
3698
|
+
configElement.args = task._source.config.element.args;
|
|
3699
|
+
}
|
|
3700
|
+
}
|
|
3701
|
+
}
|
|
3702
|
+
if (task.configurationProperties.presentation) {
|
|
3703
|
+
configElement.presentation = task.configurationProperties.presentation;
|
|
3704
|
+
}
|
|
3705
|
+
if (task.configurationProperties.isBackground) {
|
|
3706
|
+
configElement.isBackground = task.configurationProperties.isBackground;
|
|
3707
|
+
}
|
|
3708
|
+
if (task.configurationProperties.problemMatchers) {
|
|
3709
|
+
configElement.problemMatcher = task._source.config.element.problemMatcher;
|
|
3710
|
+
}
|
|
3711
|
+
if (task.configurationProperties.group) {
|
|
3712
|
+
configElement.group = task.configurationProperties.group;
|
|
3713
|
+
}
|
|
3714
|
+
task._source.config.element = configElement;
|
|
3715
|
+
const tempTask = ( new CustomTask(
|
|
3716
|
+
task._id,
|
|
3717
|
+
task._source,
|
|
3718
|
+
task._label,
|
|
3719
|
+
task.type,
|
|
3720
|
+
task.command,
|
|
3721
|
+
task.hasDefinedMatchers,
|
|
3722
|
+
task.runOptions,
|
|
3723
|
+
task.configurationProperties
|
|
3724
|
+
));
|
|
3725
|
+
const configTask = this._createCustomizableTask(tempTask);
|
|
3726
|
+
if (configTask) {
|
|
3727
|
+
return configTask;
|
|
3728
|
+
}
|
|
3729
|
+
return;
|
|
3730
|
+
}
|
|
3731
|
+
async _upgrade() {
|
|
3732
|
+
if (this.schemaVersion === 2 ) {
|
|
3733
|
+
return;
|
|
3734
|
+
}
|
|
3735
|
+
if (!this._workspaceTrustManagementService.isWorkspaceTrusted()) {
|
|
3736
|
+
this._register(Event.once(this._workspaceTrustManagementService.onDidChangeTrust)(isTrusted => {
|
|
3737
|
+
if (isTrusted) {
|
|
3738
|
+
this._upgrade();
|
|
3739
|
+
}
|
|
3740
|
+
}));
|
|
3741
|
+
return;
|
|
3742
|
+
}
|
|
3743
|
+
const tasks = await this._getGroupedTasks();
|
|
3744
|
+
const fileDiffs = [];
|
|
3745
|
+
for (const folder of this.workspaceFolders) {
|
|
3746
|
+
const diff = await this._createTasksDotOld(folder);
|
|
3747
|
+
if (diff) {
|
|
3748
|
+
fileDiffs.push(diff);
|
|
3749
|
+
}
|
|
3750
|
+
if (!diff) {
|
|
3751
|
+
continue;
|
|
3752
|
+
}
|
|
3753
|
+
const configTasks = [];
|
|
3754
|
+
const suppressTaskName = !!this._configurationService.getValue("tasks.suppressTaskName" , { resource: folder.uri });
|
|
3755
|
+
const globalConfig = {
|
|
3756
|
+
windows: this._configurationService.getValue("tasks.windows" , { resource: folder.uri }),
|
|
3757
|
+
osx: this._configurationService.getValue("tasks.osx" , { resource: folder.uri }),
|
|
3758
|
+
linux: this._configurationService.getValue("tasks.linux" , { resource: folder.uri })
|
|
3759
|
+
};
|
|
3760
|
+
tasks.get(folder).forEach(task => {
|
|
3761
|
+
const configTask = this._upgradeTask(task, suppressTaskName, globalConfig);
|
|
3762
|
+
if (configTask) {
|
|
3763
|
+
configTasks.push(configTask);
|
|
3764
|
+
}
|
|
3765
|
+
});
|
|
3766
|
+
this._taskSystem = undefined;
|
|
3767
|
+
this._workspaceTasksPromise = undefined;
|
|
3768
|
+
await this._writeConfiguration(folder, 'tasks.tasks', configTasks);
|
|
3769
|
+
await this._writeConfiguration(folder, 'tasks.version', '2.0.0');
|
|
3770
|
+
if (this._configurationService.getValue("tasks.showOutput" , { resource: folder.uri })) {
|
|
3771
|
+
await this._configurationService.updateValue("tasks.showOutput" , undefined, { resource: folder.uri });
|
|
3772
|
+
}
|
|
3773
|
+
if (this._configurationService.getValue("tasks.isShellCommand" , { resource: folder.uri })) {
|
|
3774
|
+
await this._configurationService.updateValue("tasks.isShellCommand" , undefined, { resource: folder.uri });
|
|
3775
|
+
}
|
|
3776
|
+
if (this._configurationService.getValue("tasks.suppressTaskName" , { resource: folder.uri })) {
|
|
3777
|
+
await this._configurationService.updateValue("tasks.suppressTaskName" , undefined, { resource: folder.uri });
|
|
3778
|
+
}
|
|
3779
|
+
}
|
|
3780
|
+
this._updateSetup();
|
|
3781
|
+
this._notificationService.prompt(Severity.Warning, fileDiffs.length === 1 ?
|
|
3782
|
+
( nls.localizeWithPath(
|
|
3783
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
3784
|
+
'taskService.upgradeVersion',
|
|
3785
|
+
"The deprecated tasks version 0.1.0 has been removed. Your tasks have been upgraded to version 2.0.0. Open the diff to review the upgrade."
|
|
3786
|
+
))
|
|
3787
|
+
: ( nls.localizeWithPath(
|
|
3788
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
3789
|
+
'taskService.upgradeVersionPlural',
|
|
3790
|
+
"The deprecated tasks version 0.1.0 has been removed. Your tasks have been upgraded to version 2.0.0. Open the diffs to review the upgrade."
|
|
3791
|
+
)), [{
|
|
3792
|
+
label: fileDiffs.length === 1 ? ( nls.localizeWithPath(
|
|
3793
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
3794
|
+
'taskService.openDiff',
|
|
3795
|
+
"Open diff"
|
|
3796
|
+
)) : ( nls.localizeWithPath(
|
|
3797
|
+
'vs/workbench/contrib/tasks/browser/abstractTaskService',
|
|
3798
|
+
'taskService.openDiffs',
|
|
3799
|
+
"Open diffs"
|
|
3800
|
+
)),
|
|
3801
|
+
run: async () => {
|
|
3802
|
+
for (const upgrade of fileDiffs) {
|
|
3803
|
+
await this._editorService.openEditor({
|
|
3804
|
+
original: { resource: upgrade[0] },
|
|
3805
|
+
modified: { resource: upgrade[1] }
|
|
3806
|
+
});
|
|
3807
|
+
}
|
|
3808
|
+
}
|
|
3809
|
+
}]);
|
|
3810
|
+
}
|
|
3811
|
+
};
|
|
3812
|
+
AbstractTaskService = AbstractTaskService_1 = ( __decorate([
|
|
3813
|
+
( __param(0, IConfigurationService)),
|
|
3814
|
+
( __param(1, IMarkerService)),
|
|
3815
|
+
( __param(2, IOutputService)),
|
|
3816
|
+
( __param(3, IPaneCompositePartService)),
|
|
3817
|
+
( __param(4, IViewsService)),
|
|
3818
|
+
( __param(5, ICommandService)),
|
|
3819
|
+
( __param(6, IEditorService)),
|
|
3820
|
+
( __param(7, IFileService)),
|
|
3821
|
+
( __param(8, IWorkspaceContextService)),
|
|
3822
|
+
( __param(9, ITelemetryService)),
|
|
3823
|
+
( __param(10, ITextFileService)),
|
|
3824
|
+
( __param(11, IModelService)),
|
|
3825
|
+
( __param(12, IExtensionService)),
|
|
3826
|
+
( __param(13, IQuickInputService)),
|
|
3827
|
+
( __param(14, IConfigurationResolverService)),
|
|
3828
|
+
( __param(15, ITerminalService)),
|
|
3829
|
+
( __param(16, ITerminalGroupService)),
|
|
3830
|
+
( __param(17, IStorageService)),
|
|
3831
|
+
( __param(18, IProgressService)),
|
|
3832
|
+
( __param(19, IOpenerService)),
|
|
3833
|
+
( __param(20, IDialogService)),
|
|
3834
|
+
( __param(21, INotificationService)),
|
|
3835
|
+
( __param(22, IContextKeyService)),
|
|
3836
|
+
( __param(23, IWorkbenchEnvironmentService)),
|
|
3837
|
+
( __param(24, ITerminalProfileResolverService)),
|
|
3838
|
+
( __param(25, IPathService)),
|
|
3839
|
+
( __param(26, ITextModelService)),
|
|
3840
|
+
( __param(27, IPreferencesService)),
|
|
3841
|
+
( __param(28, IViewDescriptorService)),
|
|
3842
|
+
( __param(29, IWorkspaceTrustRequestService)),
|
|
3843
|
+
( __param(30, IWorkspaceTrustManagementService)),
|
|
3844
|
+
( __param(31, ILogService)),
|
|
3845
|
+
( __param(32, IThemeService)),
|
|
3846
|
+
( __param(33, ILifecycleService)),
|
|
3847
|
+
( __param(34, IRemoteAgentService)),
|
|
3848
|
+
( __param(35, IInstantiationService))
|
|
3849
|
+
], AbstractTaskService));
|
|
3850
|
+
|
|
3851
|
+
export { AbstractTaskService, ConfigureTaskAction };
|