taskConfiguration.ts ×80

Frontier kind: Code frontier

unlabeled · c_b05582c6cde1

59 tests · 20835 LOC · 80 files · introduces 0 tests · 2079 LOC · 4 files

Introduces — evidence that enters the hierarchy at this concept

Code
166 ranges2079 lines · 4 files
Tests
0 tests

Contains — complete concept membership

All code (extent)
2312 ranges20835 lines · 80 files · Browse complete extent
All tests (intent)
59 testsBrowse complete intent

Neighbourhood graph

The orange circle is the focus. Violet and green circles are every ancestor and descendant, broader and narrower, at any distance; blue squares and pink diamonds are the introduced files and exact introduced tests of every visible concept, not only the focus's. Arrows point from broader to narrower concepts and bridge only concepts omitted from this view. Undirected links show source or test introduction. Concept and file size follows LOC; exact test nodes use test-count units.

Introduced files, introduced tests, and structurally relevant concept specialization

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the native relationship evidence on this page.

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the native relationship evidence on this page while the interactive map is unavailable.

Native relationship evidence

Every exact file and test below is linked only from the concept that introduces it.

Introduced tests

Every collected test enters the hierarchy at exactly one concept.

No tests are introduced at this concept. Its intent tests are introduced by other concepts.

Introduced code

Every collected source range enters the hierarchy at exactly one concept.

4 files ranked by introduced lines: 2079 introduced LOC across 166 ranges. Expand a file to inspect source; the > gutter marks introduced lines.

src/vs/workbench/contrib/tasks/common/tasks.ts 961 introduced LOC · 77 ranges

Open complete file

1 > /*--------------------------------------------------------------------------------------------- tasks.ts
2 > * Copyright (c) Microsoft Corporation. All rights reserved.
3 > * Licensed under the MIT License. See License.txt in the project root for license information.
4 > *--------------------------------------------------------------------------------------------*/
5 >
6 > import * as nls from '../../../../nls.js';
7 > import * as Types from '../../../../base/common/types.js';
8 > import * as resources from '../../../../base/common/resources.js';
9 > import { IJSONSchemaMap } from '../../../../base/common/jsonSchema.js';
10 > import * as Objects from '../../../../base/common/objects.js';
11 > import { UriComponents, URI } from '../../../../base/common/uri.js';
12 >
13 > import { ProblemMatcher } from './problemMatcher.js';
14 > import { IWorkspaceFolder, IWorkspace } from '../../../../platform/workspace/common/workspace.js';
15 > import { RawContextKey, ContextKeyExpression } from '../../../../platform/contextkey/common/contextkey.js';
16 > import { TaskDefinitionRegistry } from './taskDefinitionRegistry.js';
17 > import { IExtensionDescription } from '../../../../platform/extensions/common/extensions.js';
18 > import { ConfigurationTarget } from '../../../../platform/configuration/common/configuration.js';
19 > import { TerminalExitReason } from '../../../../platform/terminal/common/terminal.js';
20 > import { Codicon } from '../../../../base/common/codicons.js';
21 > import { registerIcon } from '../../../../platform/theme/common/iconRegistry.js';
22 >
23 >
24 >
25 > export const USER_TASKS_GROUP_KEY = 'settings';
26 >
27 > export const TASK_RUNNING_STATE = new RawContextKey<boolean>('taskRunning', false, nls.localize('tasks.taskRunningContext', "Whether a task is currently running."));
28 > /** Whether the active terminal is a task terminal. */
29 > export const TASK_TERMINAL_ACTIVE = new RawContextKey<boolean>('taskTerminalActive', false, nls.localize('taskTerminalActive', "Whether the active terminal is a task terminal."));
30 > export const TASKS_CATEGORY = nls.localize2('tasksCategory', "Tasks");
31 >
32 > export enum ShellQuoting {
33 > /**
34 > * Use character escaping.
35 > */
36 > Escape = 1,
37 >
38 > /**
39 > * Use strong quoting
40 > */
41 > Strong = 2,
42 >
43 > /**
44 > * Use weak quoting.
45 > */
46 > Weak = 3,
47 > }
48 >
49 > export const CUSTOMIZED_TASK_TYPE = '$customized';
50 >
51 > export namespace ShellQuoting {
52 > export function from(this: void, value: string): ShellQuoting {
53 if (!value) {
54 return ShellQuoting.Strong;
65 }
66 }
67 > } tasks.ts
68 >
69 > export interface IShellQuotingOptions {
70 > /**
71 > * The character used to do character escaping.
72 > */
73 > escape?: string | {
74 > escapeChar: string;
75 > charsToEscape: string;
76 > };
77 >
78 > /**
79 > * The character used for string quoting.
80 > */
81 > strong?: string;
82 >
83 > /**
84 > * The character used for weak quoting.
85 > */
86 > weak?: string;
87 > }
88 >
89 > export interface IShellConfiguration {
90 > /**
91 > * The shell executable.
92 > */
93 > executable?: string;
94 >
95 > /**
96 > * The arguments to be passed to the shell executable.
97 > */
98 > args?: string[];
99 >
100 > /**
101 > * Which kind of quotes the shell supports.
102 > */
103 > quoting?: IShellQuotingOptions;
104 > }
105 >
106 > export interface CommandOptions {
107 >
108 > /**
109 > * The shell to use if the task is a shell command.
110 > */
111 > shell?: IShellConfiguration;
112 >
113 > /**
114 > * The current working directory of the executed program or shell.
115 > * If omitted VSCode's current workspace root is used.
116 > */
117 > cwd?: string;
118 >
119 > /**
120 > * The environment of the executed program or shell. If omitted
121 > * the parent process' environment is used.
122 > */
123 > env?: { [key: string]: string };
124 > }
125 >
126 > export namespace CommandOptions {
127 > export const defaults: CommandOptions = { cwd: '${workspaceFolder}' };
128 > }
129 >
130 > export enum RevealKind {
131 > /**
132 > * Always brings the terminal to front if the task is executed.
133 > */
134 > Always = 1,
135 >
136 > /**
137 > * Only brings the terminal to front if a problem is detected executing the task
138 > * e.g. the task couldn't be started,
139 > * the task ended with an exit code other than zero,
140 > * or the problem matcher found an error.
141 > */
142 > Silent = 2,
143 >
144 > /**
145 > * The terminal never comes to front when the task is executed.
146 > */
147 > Never = 3
148 > }
149 >
150 > export namespace RevealKind {
151 > export function fromString(this: void, value: string): RevealKind {
152 switch (value.toLowerCase()) {
153 case 'always':
161 }
162 }
163 > } tasks.ts
164 >
165 > export enum RevealProblemKind {
166 > /**
167 > * Never reveals the problems panel when this task is executed.
168 > */
169 > Never = 1,
170 >
171 >
172 > /**
173 > * Only reveals the problems panel if a problem is found.
174 > */
175 > OnProblem = 2,
176 >
177 > /**
178 > * Never reveals the problems panel when this task is executed.
179 > */
180 > Always = 3
181 > }
182 >
183 > export namespace RevealProblemKind {
184 > export function fromString(this: void, value: string): RevealProblemKind {
185 switch (value.toLowerCase()) {
186 case 'always':
194 }
195 }
196 > } tasks.ts
197 >
198 > export enum PanelKind {
199 >
200 > /**
201 > * Shares a panel with other tasks. This is the default.
202 > */
203 > Shared = 1,
204 >
205 > /**
206 > * Uses a dedicated panel for this tasks. The panel is not
207 > * shared with other tasks.
208 > */
209 > Dedicated = 2,
210 >
211 > /**
212 > * Creates a new panel whenever this task is executed.
213 > */
214 > New = 3
215 > }
216 >
217 > export namespace PanelKind {
218 > export function fromString(value: string): PanelKind {
219 switch (value.toLowerCase()) {
220 case 'shared':
228 }
229 }
230 > } tasks.ts
231 >
232 > export interface IPresentationOptions {
233 > /**
234 > * Controls whether the task output is reveal in the user interface.
235 > * Defaults to `RevealKind.Always`.
236 > */
237 > reveal: RevealKind;
238 >
239 > /**
240 > * Controls whether the problems pane is revealed when running this task or not.
241 > * Defaults to `RevealProblemKind.Never`.
242 > */
243 > revealProblems: RevealProblemKind;
244 >
245 > /**
246 > * Controls whether the command associated with the task is echoed
247 > * in the user interface.
248 > */
249 > echo: boolean;
250 >
251 > /**
252 > * Controls whether the panel showing the task output is taking focus.
253 > */
254 > focus: boolean;
255 >
256 > /**
257 > * Controls if the task panel is used for this task only (dedicated),
258 > * shared between tasks (shared) or if a new panel is created on
259 > * every task execution (new). Defaults to `TaskInstanceKind.Shared`
260 > */
261 > panel: PanelKind;
262 >
263 > /**
264 > * Controls whether to show the "Terminal will be reused by tasks, press any key to close it" message.
265 > */
266 > showReuseMessage: boolean;
267 >
268 > /**
269 > * Controls whether to clear the terminal before executing the task.
270 > */
271 > clear: boolean;
272 >
273 > /**
274 > * Controls whether the task is executed in a specific terminal group using split panes.
275 > */
276 > group?: string;
277 >
278 > /**
279 > * Controls whether the terminal that the task runs in is closed when the task completes.
280 > */
281 > close?: boolean;
282 >
283 > /**
284 > * Controls whether to preserve the task name in the terminal after task completion.
285 > */
286 > preserveTerminalName?: boolean;
287 > }
288 >
289 > export namespace PresentationOptions {
290 > export const defaults: IPresentationOptions = {
291 > echo: true, reveal: RevealKind.Always, revealProblems: RevealProblemKind.Never, focus: false, panel: PanelKind.Shared, showReuseMessage: true, clear: false, preserveTerminalName: false
292 > };
293 > }
294 >
295 > export enum RuntimeType {
296 > Shell = 1,
297 > Process = 2,
298 > CustomExecution = 3
299 > }
300 >
301 > export namespace RuntimeType {
302 > export function fromString(value: string): RuntimeType {
303 switch (value.toLowerCase()) {
304 case 'shell':
312 }
313 }
314 > export function toString(value: RuntimeType): string { tasks.ts
315 switch (value) {
316 case RuntimeType.Shell: return 'shell';
320 }
321 }
322 > } tasks.ts
323 >
324 > export interface IQuotedString {
325 > value: string;
326 > quoting: ShellQuoting;
327 > }
328 >
329 > export type CommandString = string | IQuotedString;
330 >
331 > export namespace CommandString {
332 > export function value(value: CommandString): string {
333 if (Types.isString(value)) {
334 return value;
337 }
338 }
339 > } tasks.ts
340 >
341 > export interface ICommandConfiguration {
342 >
343 > /**
344 > * The task type
345 > */
346 > runtime?: RuntimeType;
347 >
348 > /**
349 > * The command to execute
350 > */
351 > name?: CommandString;
352 >
353 > /**
354 > * Additional command options.
355 > */
356 > options?: CommandOptions;
357 >
358 > /**
359 > * Command arguments.
360 > */
361 > args?: CommandString[];
362 >
363 > /**
364 > * The task selector if needed.
365 > */
366 > taskSelector?: string;
367 >
368 > /**
369 > * Whether to suppress the task name when merging global args
370 > *
371 > */
372 > suppressTaskName?: boolean;
373 >
374 > /**
375 > * Describes how the task is presented in the UI.
376 > */
377 > presentation?: IPresentationOptions;
378 > }
379 >
380 > export namespace TaskGroup {
381 > export const Clean: TaskGroup = { _id: 'clean', isDefault: false };
382 >
383 > export const Build: TaskGroup = { _id: 'build', isDefault: false };
384 >
385 > export const Rebuild: TaskGroup = { _id: 'rebuild', isDefault: false };
386 >
387 > export const Test: TaskGroup = { _id: 'test', isDefault: false };
388 >
389 > export function is(value: unknown): value is string {
390 return value === Clean._id || value === Build._id || value === Rebuild._id || value === Test._id;
391 }
392 > tasks.ts
393 > export function from(value: string | TaskGroup | undefined): TaskGroup | undefined {
394 if (value === undefined) {
395 return undefined;
403 }
404 }
405 > } tasks.ts
406 >
407 > export interface TaskGroup {
408 > _id: string;
409 > isDefault?: boolean | string;
410 > }
411 >
412 > export const enum TaskScope {
413 > Global = 1,
414 > Workspace = 2,
415 > Folder = 3
416 > }
417 >
418 > export namespace TaskSourceKind {
419 > export const Workspace: 'workspace' = 'workspace';
420 > export const Extension: 'extension' = 'extension';
421 > export const InMemory: 'inMemory' = 'inMemory';
422 > export const WorkspaceFile: 'workspaceFile' = 'workspaceFile';
423 > export const User: 'user' = 'user';
424 >
425 > export function toConfigurationTarget(kind: string): ConfigurationTarget {
426 switch (kind) {
427 case TaskSourceKind.User: return ConfigurationTarget.USER;
430 }
431 }
432 > } tasks.ts
433 >
434 > export interface ITaskSourceConfigElement {
435 > workspaceFolder?: IWorkspaceFolder;
436 > workspace?: IWorkspace;
437 > file: string;
438 > index: number;
439 > element: unknown;
440 > }
441 >
442 > export interface ITaskConfig {
443 > label: string;
444 > task?: CommandString;
445 > type?: string;
446 > command?: string | CommandString;
447 > args?: string[] | CommandString[];
448 > presentation?: IPresentationOptions;
449 > isBackground?: boolean;
450 > problemMatcher?: Types.SingleOrMany<string>;
451 > group?: string | TaskGroup;
452 > }
453 >
454 > interface IBaseTaskSource {
455 > readonly kind: string;
456 > readonly label: string;
457 > }
458 >
459 > export interface IWorkspaceTaskSource extends IBaseTaskSource {
460 > readonly kind: 'workspace';
461 > readonly config: ITaskSourceConfigElement;
462 > readonly customizes?: KeyedTaskIdentifier;
463 > }
464 >
465 > export interface IExtensionTaskSource extends IBaseTaskSource {
466 > readonly kind: 'extension';
467 > readonly extension?: string;
468 > readonly scope: TaskScope;
469 > readonly workspaceFolder: IWorkspaceFolder | undefined;
470 > }
471 >
472 > export interface IExtensionTaskSourceTransfer {
473 > __workspaceFolder: UriComponents;
474 > __definition: { type: string;[name: string]: unknown };
475 > }
476 >
477 > export interface IInMemoryTaskSource extends IBaseTaskSource {
478 > readonly kind: 'inMemory';
479 > }
480 >
481 > export interface IUserTaskSource extends IBaseTaskSource {
482 > readonly kind: 'user';
483 > readonly config: ITaskSourceConfigElement;
484 > readonly customizes?: KeyedTaskIdentifier;
485 > }
486 >
487 > export interface WorkspaceFileTaskSource extends IBaseTaskSource {
488 > readonly kind: 'workspaceFile';
489 > readonly config: ITaskSourceConfigElement;
490 > readonly customizes?: KeyedTaskIdentifier;
491 > }
492 >
493 > export type TaskSource = IWorkspaceTaskSource | IExtensionTaskSource | IInMemoryTaskSource | IUserTaskSource | WorkspaceFileTaskSource;
494 > export type FileBasedTaskSource = IWorkspaceTaskSource | IUserTaskSource | WorkspaceFileTaskSource;
495 > export interface ITaskIdentifier {
496 > type: string;
497 > [name: string]: unknown;
498 > }
499 >
500 > export interface KeyedTaskIdentifier extends ITaskIdentifier {
501 > _key: string;
502 > }
503 >
504 > export interface ITaskDependency {
505 > uri: URI | string;
506 > task: string | KeyedTaskIdentifier | undefined;
507 > }
508 >
509 > export const enum DependsOrder {
510 > parallel = 'parallel',
511 > sequence = 'sequence'
512 > }
513 >
514 > export interface IConfigurationProperties {
515 >
516 > /**
517 > * The task's name
518 > */
519 > name?: string;
520 >
521 > /**
522 > * The task's name
523 > */
524 > identifier?: string;
525 >
526 > /**
527 > * The task's group;
528 > */
529 > group?: string | TaskGroup;
530 >
531 > /**
532 > * The presentation options
533 > */
534 > presentation?: IPresentationOptions;
535 >
536 > /**
537 > * The command options;
538 > */
539 > options?: CommandOptions;
540 >
541 > /**
542 > * Whether the task is a background task or not.
543 > */
544 > isBackground?: boolean;
545 >
546 > /**
547 > * Whether the task should prompt on close for confirmation if running.
548 > */
549 > promptOnClose?: boolean;
550 >
551 > /**
552 > * The other tasks this task depends on.
553 > */
554 > dependsOn?: ITaskDependency[];
555 >
556 > /**
557 > * The order the dependsOn tasks should be executed in.
558 > */
559 > dependsOrder?: DependsOrder;
560 >
561 > /**
562 > * A description of the task.
563 > */
564 > detail?: string;
565 >
566 > /**
567 > * The problem watchers to use for this task
568 > */
569 > problemMatchers?: Array<string | ProblemMatcher>;
570 >
571 > /**
572 > * The icon for this task in the terminal tabs list
573 > */
574 > icon?: { id?: string; color?: string };
575 >
576 > /**
577 > * Do not show this task in the run task quickpick
578 > */
579 > hide?: boolean;
580 >
581 > /**
582 > * Show this task in the Agents run action dropdown
583 > */
584 > inAgents?: boolean;
585 > }
586 >
587 > export enum RunOnOptions {
588 > default = 1,
589 > folderOpen = 2,
590 > worktreeCreated = 3
591 > }
592 >
593 > export const enum InstancePolicy {
594 > terminateNewest = 'terminateNewest',
595 > terminateOldest = 'terminateOldest',
596 > prompt = 'prompt',
597 > warn = 'warn',
598 > silent = 'silent'
599 > }
600 >
601 > export interface IRunOptions {
602 > reevaluateOnRerun?: boolean;
603 > runOn?: RunOnOptions;
604 > instanceLimit?: number;
605 > instancePolicy?: InstancePolicy;
606 > }
607 >
608 > export namespace RunOptions {
609 > export const defaults: IRunOptions = { reevaluateOnRerun: true, runOn: RunOnOptions.default, instanceLimit: 1, instancePolicy: InstancePolicy.prompt };
610 > }
611 >
612 > export abstract class CommonTask {
613 >
614 > /**
615 > * The task's internal id
616 > */
617 > readonly _id: string;
618 >
619 > /**
620 > * The cached label.
621 > */
622 > _label: string = '';
623 >
624 > type?: string;
625 >
626 > runOptions: IRunOptions;
627 >
628 > configurationProperties: IConfigurationProperties;
629 >
630 > _source: IBaseTaskSource;
631 >
632 > private _taskLoadMessages: string[] | undefined;
633 >
634 > protected constructor(id: string, label: string | undefined, type: string | undefined, runOptions: IRunOptions,
635 configurationProperties: IConfigurationProperties, source: IBaseTaskSource) {
636 this._id = id;
645 this._source = source;
646 }
647 > tasks.ts
648 > public getDefinition(useSource?: boolean): KeyedTaskIdentifier | undefined {
649 return undefined;
650 }
651 > tasks.ts
652 > public getMapKey(): string {
653 return this._id;
654 }
655 > tasks.ts
656 > public getKey(): string | undefined {
657 return undefined;
658 }
659 > tasks.ts
660 > protected abstract getFolderId(): string | undefined;
661 >
662 > public getCommonTaskId(): string {
663 interface IRecentTaskKey {
664 folder: string | undefined;
669 return JSON.stringify(key);
670 }
671 > tasks.ts
672 > public clone(): Task {
673 return this.fromObject(Object.assign({}, this as unknown as Record<string, unknown>));
674 }
675 > tasks.ts
676 > protected abstract fromObject(object: Record<string, unknown>): Task;
677 >
678 > public getWorkspaceFolder(): IWorkspaceFolder | undefined {
679 return undefined;
680 }
681 > tasks.ts
682 > public getWorkspaceFileName(): string | undefined {
683 return undefined;
684 }
685 > tasks.ts
686 > public getTelemetryKind(): string {
687 return 'unknown';
688 }
689 > tasks.ts
690 > public matches(key: string | KeyedTaskIdentifier | undefined, compareId: boolean = false): boolean {
691 if (key === undefined) {
692 return false;
698 return identifier !== undefined && identifier._key === key._key;
699 }
700 > tasks.ts
701 > public getQualifiedLabel(): string {
702 const workspaceFolder = this.getWorkspaceFolder();
703 if (workspaceFolder) {
707 }
708 }
709 > tasks.ts
710 > public getTaskExecution(): ITaskExecution {
711 const result: ITaskExecution = {
712 id: this._id,
715 return result;
716 }
717 > tasks.ts
718 > public addTaskLoadMessages(messages: string[] | undefined) {
719 if (this._taskLoadMessages === undefined) {
720 this._taskLoadMessages = [];
724 }
725 }
726 > tasks.ts
727 > get taskLoadMessages(): string[] | undefined {
728 return this._taskLoadMessages;
729 }
730 > } tasks.ts
731 >
732 > /**
733 > * For tasks of type shell or process, this is created upon parse
734 > * of the tasks.json or workspace file.
735 > * For ContributedTasks of all other types, this is the result of
736 > * resolving a ConfiguringTask.
737 > */
738 > export class CustomTask extends CommonTask {
739 >
740 > declare type: '$customized'; // CUSTOMIZED_TASK_TYPE
741 >
742 > instance: number | undefined;
743 >
744 > /**
745 > * Indicated the source of the task (e.g. tasks.json or extension)
746 > */
747 > override _source: FileBasedTaskSource;
748 >
749 > hasDefinedMatchers: boolean;
750 >
751 > /**
752 > * The command configuration
753 > */
754 > command: ICommandConfiguration = {};
755 >
756 > public constructor(id: string, source: FileBasedTaskSource, label: string, type: string, command: ICommandConfiguration | undefined,
757 hasDefinedMatchers: boolean, runOptions: IRunOptions, configurationProperties: IConfigurationProperties) {
758 super(id, label, undefined, runOptions, configurationProperties, source);
763 }
764 }
765 > tasks.ts
766 > public override clone(): CustomTask {
767 return new CustomTask(this._id, this._source, this._label, this.type, this.command, this.hasDefinedMatchers, this.runOptions, this.configurationProperties);
768 }
769 > tasks.ts
770 > public customizes(): KeyedTaskIdentifier | undefined {
771 if (this._source && this._source.customizes) {
772 return this._source.customizes;
774 return undefined;
775 }
776 > tasks.ts
777 > public override getDefinition(useSource: boolean = false): KeyedTaskIdentifier {
778 if (useSource && this._source.customizes !== undefined) {
779 return this._source.customizes;
810 }
811 }
812 > tasks.ts
813 > public static is(value: unknown): value is CustomTask {
814 return value instanceof CustomTask;
815 }
816 > tasks.ts
817 > public override getMapKey(): string {
818 const workspaceFolder = this._source.config.workspaceFolder;
819 return workspaceFolder ? `${workspaceFolder.uri.toString()}|${this._id}|${this.instance}` : `${this._id}|${this.instance}`;
820 }
821 > tasks.ts
822 > protected getFolderId(): string | undefined {
823 return this._source.kind === TaskSourceKind.User ? USER_TASKS_GROUP_KEY : this._source.config.workspaceFolder?.uri.toString();
824 }
825 > tasks.ts
826 > public override getCommonTaskId(): string {
827 return this._source.customizes ? super.getCommonTaskId() : (this.getKey() ?? super.getCommonTaskId());
828 }
829 > tasks.ts
830 > /**
831 > * @returns A key representing the task
832 > */
833 > public override getKey(): string | undefined {
834 interface ICustomKey {
835 type: string;
848 return JSON.stringify(key);
849 }
850 > tasks.ts
851 > public override getWorkspaceFolder(): IWorkspaceFolder | undefined {
852 return this._source.config.workspaceFolder;
853 }
854 > tasks.ts
855 > public override getWorkspaceFileName(): string | undefined {
856 return (this._source.config.workspace && this._source.config.workspace.configuration) ? resources.basename(this._source.config.workspace.configuration) : undefined;
857 }
858 > tasks.ts
859 > public override getTelemetryKind(): string {
860 if (this._source.customizes) {
861 return 'workspace>extension';
864 }
865 }
866 > tasks.ts
867 > protected fromObject(object: Record<string, unknown>): CustomTask {
868 const obj = object as unknown as CustomTask;
869 return new CustomTask(obj._id, obj._source, obj._label, obj.type, obj.command, obj.hasDefinedMatchers, obj.runOptions, obj.configurationProperties);
870 }
871 > } tasks.ts
872 >
873 > /**
874 > * After a contributed task has been parsed, but before
875 > * the task has been resolved via the extension, its properties
876 > * are stored in this
877 > */
878 > export class ConfiguringTask extends CommonTask {
879 >
880 > /**
881 > * Indicated the source of the task (e.g. tasks.json or extension)
882 > */
883 > override _source: FileBasedTaskSource;
884 >
885 > configures: KeyedTaskIdentifier;
886 >
887 > public constructor(id: string, source: FileBasedTaskSource, label: string | undefined, type: string | undefined,
888 configures: KeyedTaskIdentifier, runOptions: IRunOptions, configurationProperties: IConfigurationProperties) {
889 super(id, label, type, runOptions, configurationProperties, source);
891 this.configures = configures;
892 }
893 > tasks.ts
894 > public static is(value: unknown): value is ConfiguringTask {
895 return value instanceof ConfiguringTask;
896 }
897 > tasks.ts
898 > protected fromObject(object: Record<string, unknown>): Task {
899 return object as unknown as Task;
900 }
901 > tasks.ts
902 > public override getDefinition(): KeyedTaskIdentifier {
903 return this.configures;
904 }
905 > tasks.ts
906 > public override getWorkspaceFileName(): string | undefined {
907 return (this._source.config.workspace && this._source.config.workspace.configuration) ? resources.basename(this._source.config.workspace.configuration) : undefined;
908 }
909 > tasks.ts
910 > public override getWorkspaceFolder(): IWorkspaceFolder | undefined {
911 return this._source.config.workspaceFolder;
912 }
913 > tasks.ts
914 > protected getFolderId(): string | undefined {
915 return this._source.kind === TaskSourceKind.User ? USER_TASKS_GROUP_KEY : this._source.config.workspaceFolder?.uri.toString();
916 }
917 > tasks.ts
918 > public override getKey(): string | undefined {
919 interface ICustomKey {
920 type: string;
933 return JSON.stringify(key);
934 }
935 > } tasks.ts
936 >
937 > /**
938 > * A task from an extension created via resolveTask or provideTask
939 > */
940 > export class ContributedTask extends CommonTask {
941 >
942 > /**
943 > * Indicated the source of the task (e.g. tasks.json or extension)
944 > * Set in the super constructor
945 > */
946 > declare _source: IExtensionTaskSource;
947 >
948 > instance: number | undefined;
949 >
950 > defines: KeyedTaskIdentifier;
951 >
952 > hasDefinedMatchers: boolean;
953 >
954 > /**
955 > * The command configuration
956 > */
957 > command: ICommandConfiguration;
958 >
959 > /**
960 > * The icon for the task
961 > */
962 > icon: { id?: string; color?: string } | undefined;
963 >
964 > /**
965 > * Don't show the task in the run task quickpick
966 > */
967 > hide?: boolean;
968 >
969 > public constructor(id: string, source: IExtensionTaskSource, label: string, type: string | undefined, defines: KeyedTaskIdentifier,
970 command: ICommandConfiguration, hasDefinedMatchers: boolean, runOptions: IRunOptions,
971 configurationProperties: IConfigurationProperties) {
977 this.hide = configurationProperties.hide;
978 }
979 > tasks.ts
980 > public override clone(): ContributedTask {
981 return new ContributedTask(this._id, this._source, this._label, this.type, this.defines, this.command, this.hasDefinedMatchers, this.runOptions, this.configurationProperties);
982 }
983 > tasks.ts
984 > public override getDefinition(): KeyedTaskIdentifier {
985 return this.defines;
986 }
987 > tasks.ts
988 > public static is(value: unknown): value is ContributedTask {
989 return value instanceof ContributedTask;
990 }
991 > tasks.ts
992 > public override getMapKey(): string {
993 const workspaceFolder = this._source.workspaceFolder;
994 return workspaceFolder
996 : `${this._source.scope.toString()}|${this._id}|${this.instance}`;
997 }
998 > tasks.ts
999 > protected getFolderId(): string | undefined {
1000 if (this._source.scope === TaskScope.Folder && this._source.workspaceFolder) {
1001 return this._source.workspaceFolder.uri.toString();
1003 return undefined;
1004 }
1005 > tasks.ts
1006 > public override getKey(): string | undefined {
1007 interface IContributedKey {
1008 type: string;
1016 return JSON.stringify(key);
1017 }
1018 > tasks.ts
1019 > public override getWorkspaceFolder(): IWorkspaceFolder | undefined {
1020 return this._source.workspaceFolder;
1021 }
1022 > tasks.ts
1023 > public override getTelemetryKind(): string {
1024 return 'extension';
1025 }
1026 > tasks.ts
1027 > protected fromObject(object: Record<string, unknown>): ContributedTask {
1028 const obj = object as unknown as ContributedTask;
1029 return new ContributedTask(obj._id, obj._source, obj._label, obj.type, obj.defines, obj.command, obj.hasDefinedMatchers, obj.runOptions, obj.configurationProperties);
1030 }
1031 > } tasks.ts
1032 >
1033 > export class InMemoryTask extends CommonTask {
1034 > /**
1035 > * Indicated the source of the task (e.g. tasks.json or extension)
1036 > */
1037 > override _source: IInMemoryTaskSource;
1038 >
1039 > instance: number | undefined;
1040 >
1041 > declare type: 'inMemory';
1042 >
1043 > public constructor(id: string, source: IInMemoryTaskSource, label: string, type: string,
1044 runOptions: IRunOptions, configurationProperties: IConfigurationProperties) {
1045 super(id, label, type, runOptions, configurationProperties, source);
1046 this._source = source;
1047 }
1048 > tasks.ts
1049 > public override clone(): InMemoryTask {
1050 return new InMemoryTask(this._id, this._source, this._label, this.type, this.runOptions, this.configurationProperties);
1051 }
1052 > tasks.ts
1053 > public static is(value: unknown): value is InMemoryTask {
1054 return value instanceof InMemoryTask;
1055 }
1056 > tasks.ts
1057 > public override getTelemetryKind(): string {
1058 return 'composite';
1059 }
1060 > tasks.ts
1061 > public override getMapKey(): string {
1062 return `${this._id}|${this.instance}`;
1063 }
1064 > tasks.ts
1065 > protected getFolderId(): undefined {
1066 return undefined;
1067 }
1068 > tasks.ts
1069 > protected fromObject(object: Record<string, unknown>): InMemoryTask {
1070 const obj = object as unknown as InMemoryTask;
1071 return new InMemoryTask(obj._id, obj._source, obj._label, obj.type, obj.runOptions, obj.configurationProperties);
1072 }
1073 > } tasks.ts
1074 >
1075 > export type Task = CustomTask | ContributedTask | InMemoryTask;
1076 >
1077 > export interface ITaskExecution {
1078 > id: string;
1079 > task: Task;
1080 > }
1081 >
1082 > export enum ExecutionEngine {
1083 > Process = 1,
1084 > Terminal = 2
1085 > }
1086 >
1087 > export namespace ExecutionEngine {
1088 > export const _default: ExecutionEngine = ExecutionEngine.Terminal;
1089 > }
1090 >
1091 > export const enum JsonSchemaVersion {
1092 > V0_1_0 = 1,
1093 > V2_0_0 = 2
1094 > }
1095 >
1096 > export interface ITaskSet {
1097 > tasks: Task[];
1098 > extension?: IExtensionDescription;
1099 > }
1100 >
1101 > export interface ITaskDefinition {
1102 > extensionId: string;
1103 > taskType: string;
1104 > required: string[];
1105 > properties: IJSONSchemaMap;
1106 > when?: ContextKeyExpression;
1107 > }
1108 >
1109 > export class TaskSorter {
1110 >
1111 > private _order: Map<string, number> = new Map();
1112 >
1113 > constructor(workspaceFolders: IWorkspaceFolder[]) {
1114 for (let i = 0; i < workspaceFolders.length; i++) {
1115 this._order.set(workspaceFolders[i].uri.toString(), i);
1116 }
1117 }
1118 > tasks.ts
1119 > public compare(a: Task | ConfiguringTask, b: Task | ConfiguringTask): number {
1120 const aw = a.getWorkspaceFolder();
1121 const bw = b.getWorkspaceFolder();
1138 }
1139 }
1140 > } tasks.ts
1141 >
1142 >
1143 >
1144 > export const enum TaskRunType {
1145 > SingleRun = 'singleRun',
1146 > Background = 'background'
1147 > }
1148 >
1149 > export interface ITaskChangedEvent {
1150 > kind: TaskEventKind.Changed;
1151 > }
1152 >
1153 >
1154 >
1155 > export enum TaskEventKind {
1156 > /** Indicates that a task's properties or configuration have changed */
1157 > Changed = 'changed',
1158 >
1159 > /** Indicates that a task has begun executing */
1160 > ProcessStarted = 'processStarted',
1161 >
1162 > /** Indicates that a task process has completed */
1163 > ProcessEnded = 'processEnded',
1164 >
1165 > /** Indicates that a task was terminated, either by user action or by the system */
1166 > Terminated = 'terminated',
1167 >
1168 > /** Indicates that a task has started running */
1169 > Start = 'start',
1170 >
1171 > /** Indicates that a task has acquired all needed input/variables to execute */
1172 > AcquiredInput = 'acquiredInput',
1173 >
1174 > /** Indicates that a dependent task has started */
1175 > DependsOnStarted = 'dependsOnStarted',
1176 >
1177 > /** Indicates that a task is actively running/processing */
1178 > Active = 'active',
1179 >
1180 > /** Indicates that a task is paused/waiting but not complete */
1181 > Inactive = 'inactive',
1182 >
1183 > /** Indicates that a task has completed fully */
1184 > End = 'end',
1185 >
1186 > /** Indicates that a task's problem matcher has started */
1187 > ProblemMatcherStarted = 'problemMatcherStarted',
1188 >
1189 > /** Indicates that a task's problem matcher has ended */
1190 > ProblemMatcherEnded = 'problemMatcherEnded',
1191 >
1192 > /** Indicates that a task's problem matcher has found errors */
1193 > ProblemMatcherFoundErrors = 'problemMatcherFoundErrors'
1194 > }
1195 >
1196 > interface ITaskCommon {
1197 > taskId: string;
1198 > runType: TaskRunType;
1199 > taskName: string | undefined;
1200 > group: string | TaskGroup | undefined;
1201 > __task: Task;
1202 > }
1203 >
1204 > export interface ITaskProcessStartedEvent extends ITaskCommon {
1205 > kind: TaskEventKind.ProcessStarted;
1206 > terminalId: number;
1207 > processId: number;
1208 > }
1209 >
1210 > export interface ITaskProcessEndedEvent extends ITaskCommon {
1211 > kind: TaskEventKind.ProcessEnded;
1212 > terminalId: number | undefined;
1213 > exitCode?: number;
1214 > durationMs?: number;
1215 > }
1216 >
1217 > export interface ITaskInactiveEvent extends ITaskCommon {
1218 > kind: TaskEventKind.Inactive;
1219 > terminalId: number | undefined;
1220 > durationMs: number | undefined;
1221 > }
1222 >
1223 > export interface ITaskTerminatedEvent extends ITaskCommon {
1224 > kind: TaskEventKind.Terminated;
1225 > terminalId: number;
1226 > exitReason: TerminalExitReason | undefined;
1227 > }
1228 >
1229 > export interface ITaskStartedEvent extends ITaskCommon {
1230 > kind: TaskEventKind.Start;
1231 > terminalId: number;
1232 > resolvedVariables: Map<string, string>;
1233 > }
1234 >
1235 > export interface ITaskProblemMatcherEndedEvent extends ITaskCommon {
1236 > kind: TaskEventKind.ProblemMatcherEnded;
1237 > hasErrors: boolean;
1238 > }
1239 >
1240 > export interface ITaskGeneralEvent extends ITaskCommon {
1241 > kind: TaskEventKind.AcquiredInput | TaskEventKind.DependsOnStarted | TaskEventKind.Active | TaskEventKind.Inactive | TaskEventKind.End | TaskEventKind.ProblemMatcherStarted | TaskEventKind.ProblemMatcherFoundErrors;
1242 > terminalId: number | undefined;
1243 > }
1244 >
1245 > export type ITaskEvent =
1246 > | ITaskChangedEvent
1247 > | ITaskProcessStartedEvent
1248 > | ITaskProcessEndedEvent
1249 > | ITaskTerminatedEvent
1250 > | ITaskStartedEvent
1251 > | ITaskGeneralEvent
1252 > | ITaskProblemMatcherEndedEvent;
1253 >
1254 > export const enum TaskRunSource {
1255 > System,
1256 > User,
1257 > FolderOpen,
1258 > ConfigurationChange,
1259 > Reconnect,
1260 > ChatAgent
1261 > }
1262 >
1263 > export namespace TaskEvent {
1264 > function common(task: Task): ITaskCommon {
1265 return {
1266 taskId: task._id,
1271 };
1272 }
1273 > tasks.ts
1274 > export function start(task: Task, terminalId: number, resolvedVariables: Map<string, string>): ITaskStartedEvent {
1275 return {
1276 ...common(task),
1280 };
1281 }
1282 > tasks.ts
1283 > export function processStarted(task: Task, terminalId: number, processId: number): ITaskProcessStartedEvent {
1284 return {
1285 ...common(task),
1289 };
1290 }
1291 > export function processEnded(task: Task, terminalId: number | undefined, exitCode: number | undefined, durationMs?: number): ITaskProcessEndedEvent { tasks.ts
1292 return {
1293 ...common(task),
1298 };
1299 }
1300 > tasks.ts
1301 > export function inactive(task: Task, terminalId?: number, durationMs?: number): ITaskInactiveEvent {
1302 return {
1303 ...common(task),
1307 };
1308 }
1309 > tasks.ts
1310 > export function terminated(task: Task, terminalId: number, exitReason: TerminalExitReason | undefined): ITaskTerminatedEvent {
1311 return {
1312 ...common(task),
1316 };
1317 }
1318 > tasks.ts
1319 > export function general(kind: TaskEventKind.AcquiredInput | TaskEventKind.DependsOnStarted | TaskEventKind.Active | TaskEventKind.Inactive | TaskEventKind.End | TaskEventKind.ProblemMatcherStarted | TaskEventKind.ProblemMatcherFoundErrors, task: Task, terminalId?: number): ITaskGeneralEvent {
1320 return {
1321 ...common(task),
1324 };
1325 }
1326 > tasks.ts
1327 > export function problemMatcherEnded(task: Task, hasErrors: boolean, terminalId?: number): ITaskProblemMatcherEndedEvent {
1328 return {
1329 ...common(task),
1332 };
1333 }
1334 > tasks.ts
1335 > export function changed(): ITaskChangedEvent {
1336 return { kind: TaskEventKind.Changed };
1337 }
1338 > } tasks.ts
1339 >
1340 > export namespace KeyedTaskIdentifier {
1341 > function sortedStringify(literal: Record<string, unknown>): string {
1342 const keys = Object.keys(literal).sort();
1343 let result: string = '';
1353 return result;
1354 }
1355 > export function create(value: ITaskIdentifier): KeyedTaskIdentifier { tasks.ts
1356 const resultKey = sortedStringify(value);
1357 const result = { _key: resultKey, type: value.taskType as string };
1359 return result;
1360 }
1361 > } tasks.ts
1362 >
1363 > export const enum TaskSettingId {
1364 > AutoDetect = 'task.autoDetect',
1365 > SaveBeforeRun = 'task.saveBeforeRun',
1366 > ShowDecorations = 'task.showDecorations',
1367 > ProblemMatchersNeverPrompt = 'task.problemMatchers.neverPrompt',
1368 > SlowProviderWarning = 'task.slowProviderWarning',
1369 > QuickOpenHistory = 'task.quickOpen.history',
1370 > QuickOpenDetail = 'task.quickOpen.detail',
1371 > QuickOpenSkip = 'task.quickOpen.skip',
1372 > QuickOpenShowAll = 'task.quickOpen.showAll',
1373 > AllowAutomaticTasks = 'task.allowAutomaticTasks',
1374 > Reconnection = 'task.reconnection',
1375 > VerboseLogging = 'task.verboseLogging',
1376 > NotifyWindowOnTaskCompletion = 'task.notifyWindowOnTaskCompletion'
1377 > }
1378 >
1379 > export const enum TasksSchemaProperties {
1380 > Tasks = 'tasks',
1381 > SuppressTaskName = 'tasks.suppressTaskName',
1382 > Windows = 'tasks.windows',
1383 > Osx = 'tasks.osx',
1384 > Linux = 'tasks.linux',
1385 > ShowOutput = 'tasks.showOutput',
1386 > IsShellCommand = 'tasks.isShellCommand',
1387 > ServiceTestSetting = 'tasks.service.testSetting',
1388 > }
1389 >
1390 > export namespace TaskDefinition {
1391 > export function createTaskIdentifier(external: ITaskIdentifier, reporter: { error(message: string): void }): KeyedTaskIdentifier | undefined {
1392 const definition = TaskDefinitionRegistry.get(external.type);
1393 if (definition === undefined) {
1436 return KeyedTaskIdentifier.create(literal);
1437 }
1438 > } tasks.ts
1439 >
1440 > export const rerunTaskIcon = registerIcon('rerun-task', Codicon.refresh, nls.localize('rerunTaskIcon', 'View icon of the rerun task.'));
1441 > export const RerunForActiveTerminalCommandId = 'workbench.action.tasks.rerunForActiveTerminal';
1442 > export const RerunAllRunningTasksCommandId = 'workbench.action.tasks.rerunAllRunningTasks';
src/vs/workbench/contrib/tasks/common/taskConfiguration.ts 893 introduced LOC · 80 ranges

Open complete file

1 > /*--------------------------------------------------------------------------------------------- taskConfiguration.ts
2 > * Copyright (c) Microsoft Corporation. All rights reserved.
3 > * Licensed under the MIT License. See License.txt in the project root for license information.
4 > *--------------------------------------------------------------------------------------------*/
5 >
6 > import * as nls from '../../../../nls.js';
7 >
8 > import * as Objects from '../../../../base/common/objects.js';
9 > import { IStringDictionary } from '../../../../base/common/collections.js';
10 > import { IJSONSchemaMap } from '../../../../base/common/jsonSchema.js';
11 > import { Platform } from '../../../../base/common/platform.js';
12 > import * as Types from '../../../../base/common/types.js';
13 > import * as UUID from '../../../../base/common/uuid.js';
14 >
15 > import { ValidationStatus, IProblemReporter as IProblemReporterBase } from '../../../../base/common/parsers.js';
16 > import {
17 > INamedProblemMatcher, ProblemMatcherParser, Config as ProblemMatcherConfig,
18 > isNamedProblemMatcher, ProblemMatcherRegistry, ProblemMatcher
19 > } from './problemMatcher.js';
20 >
21 > import { IWorkspaceFolder, IWorkspace } from '../../../../platform/workspace/common/workspace.js';
22 > import * as Tasks from './tasks.js';
23 > import { ITaskDefinitionRegistry, TaskDefinitionRegistry } from './taskDefinitionRegistry.js';
24 > import { ConfiguredInput } from '../../../services/configurationResolver/common/configurationResolver.js';
25 > import { URI } from '../../../../base/common/uri.js';
26 > import { ShellExecutionSupportedContext, ProcessExecutionSupportedContext } from './taskService.js';
27 > import { IContextKeyService, RawContextKey } from '../../../../platform/contextkey/common/contextkey.js';
28 >
29 > export const enum ShellQuoting {
30 > /**
31 > * Default is character escaping.
32 > */
33 > escape = 1,
34 >
35 > /**
36 > * Default is strong quoting
37 > */
38 > strong = 2,
39 >
40 > /**
41 > * Default is weak quoting.
42 > */
43 > weak = 3
44 > }
45 >
46 > export interface IShellQuotingOptions {
47 > /**
48 > * The character used to do character escaping.
49 > */
50 > escape?: string | {
51 > escapeChar: string;
52 > charsToEscape: string;
53 > };
54 >
55 > /**
56 > * The character used for string quoting.
57 > */
58 > strong?: string;
59 >
60 > /**
61 > * The character used for weak quoting.
62 > */
63 > weak?: string;
64 > }
65 >
66 > export interface IShellConfiguration {
67 > executable?: string;
68 > args?: string[];
69 > quoting?: IShellQuotingOptions;
70 > }
71 >
72 > export interface ICommandOptionsConfig {
73 > /**
74 > * The current working directory of the executed program or shell.
75 > * If omitted VSCode's current workspace root is used.
76 > */
77 > cwd?: string;
78 >
79 > /**
80 > * The additional environment of the executed program or shell. If omitted
81 > * the parent process' environment is used.
82 > */
83 > env?: IStringDictionary<string>;
84 >
85 > /**
86 > * The shell configuration;
87 > */
88 > shell?: IShellConfiguration;
89 > }
90 >
91 > export interface IPresentationOptionsConfig {
92 > /**
93 > * Controls whether the terminal executing a task is brought to front or not.
94 > * Defaults to `RevealKind.Always`.
95 > */
96 > reveal?: string;
97 >
98 > /**
99 > * Controls whether the problems panel is revealed when running this task or not.
100 > * Defaults to `RevealKind.Never`.
101 > */
102 > revealProblems?: string;
103 >
104 > /**
105 > * Controls whether the executed command is printed to the output window or terminal as well.
106 > */
107 > echo?: boolean;
108 >
109 > /**
110 > * Controls whether the terminal is focus when this task is executed
111 > */
112 > focus?: boolean;
113 >
114 > /**
115 > * Controls whether the task runs in a new terminal
116 > */
117 > panel?: string;
118 >
119 > /**
120 > * Controls whether to show the "Terminal will be reused by tasks, press any key to close it" message.
121 > */
122 > showReuseMessage?: boolean;
123 >
124 > /**
125 > * Controls whether the terminal should be cleared before running the task.
126 > */
127 > clear?: boolean;
128 >
129 > /**
130 > * Controls whether the task is executed in a specific terminal group using split panes.
131 > */
132 > group?: string;
133 >
134 > /**
135 > * Controls whether the terminal that the task runs in is closed when the task completes.
136 > * Note that if the terminal process exits with a non-zero exit code, it will not close.
137 > */
138 > close?: boolean;
139 >
140 > /**
141 > * Controls whether to preserve the task name in the terminal after task completion.
142 > */
143 > preserveTerminalName?: boolean;
144 > }
145 >
146 > export interface IRunOptionsConfig {
147 > reevaluateOnRerun?: boolean;
148 > runOn?: string;
149 > instanceLimit?: number;
150 > instancePolicy?: Tasks.InstancePolicy;
151 > }
152 >
153 > export interface ITaskIdentifier {
154 > type?: string;
155 > [name: string]: unknown;
156 > }
157 >
158 > export namespace ITaskIdentifier {
159 > export function is(value: unknown): value is ITaskIdentifier {
160 const candidate: ITaskIdentifier = value as ITaskIdentifier;
161 return candidate !== undefined && Types.isString((value as ITaskIdentifier).type);
162 }
164 >
165 > export interface ILegacyTaskProperties {
166 > /**
167 > * @deprecated Use `isBackground` instead.
168 > * Whether the executed command is kept alive and is watching the file system.
169 > */
170 > isWatching?: boolean;
171 >
172 > /**
173 > * @deprecated Use `group` instead.
174 > * Whether this task maps to the default build command.
175 > */
176 > isBuildCommand?: boolean;
177 >
178 > /**
179 > * @deprecated Use `group` instead.
180 > * Whether this task maps to the default test command.
181 > */
182 > isTestCommand?: boolean;
183 > }
184 >
185 > export interface ILegacyCommandProperties {
186 >
187 > /**
188 > * Whether this is a shell or process
189 > */
190 > type?: string;
191 >
192 > /**
193 > * @deprecated Use presentation options
194 > * Controls whether the output view of the running tasks is brought to front or not.
195 > * See BaseTaskRunnerConfiguration#showOutput for details.
196 > */
197 > showOutput?: string;
198 >
199 > /**
200 > * @deprecated Use presentation options
201 > * Controls whether the executed command is printed to the output windows as well.
202 > */
203 > echoCommand?: boolean;
204 >
205 > /**
206 > * @deprecated Use presentation instead
207 > */
208 > terminal?: IPresentationOptionsConfig;
209 >
210 > /**
211 > * @deprecated Use inline commands.
212 > * See BaseTaskRunnerConfiguration#suppressTaskName for details.
213 > */
214 > suppressTaskName?: boolean;
215 >
216 > /**
217 > * Some commands require that the task argument is highlighted with a special
218 > * prefix (e.g. /t: for msbuild). This property can be used to control such
219 > * a prefix.
220 > */
221 > taskSelector?: string;
222 >
223 > /**
224 > * @deprecated use the task type instead.
225 > * Specifies whether the command is a shell command and therefore must
226 > * be executed in a shell interpreter (e.g. cmd.exe, bash, ...).
227 > *
228 > * Defaults to false if omitted.
229 > */
230 > isShellCommand?: boolean | IShellConfiguration;
231 > }
232 >
233 > export type CommandString = Types.SingleOrMany<string> | { value: Types.SingleOrMany<string>; quoting: 'escape' | 'strong' | 'weak' };
234 >
235 > export namespace CommandString {
236 > export function value(value: CommandString): string {
237 if (Types.isString(value)) {
238 return value;
247 }
248 }
250 >
251 > export interface IBaseCommandProperties {
252 >
253 > /**
254 > * The command to be executed. Can be an external program or a shell
255 > * command.
256 > */
257 > command?: CommandString;
258 >
259 > /**
260 > * The command options used when the command is executed. Can be omitted.
261 > */
262 > options?: ICommandOptionsConfig;
263 >
264 > /**
265 > * The arguments passed to the command or additional arguments passed to the
266 > * command when using a global command.
267 > */
268 > args?: CommandString[];
269 > }
270 >
271 >
272 > export interface ICommandProperties extends IBaseCommandProperties {
273 >
274 > /**
275 > * Windows specific command properties
276 > */
277 > windows?: IBaseCommandProperties;
278 >
279 > /**
280 > * OSX specific command properties
281 > */
282 > osx?: IBaseCommandProperties;
283 >
284 > /**
285 > * linux specific command properties
286 > */
287 > linux?: IBaseCommandProperties;
288 > }
289 >
290 > export interface IGroupKind {
291 > kind?: string;
292 > isDefault?: boolean | string;
293 > }
294 >
295 > export interface IConfigurationProperties {
296 > /**
297 > * The task's name
298 > */
299 > taskName?: string;
300 >
301 > /**
302 > * The UI label used for the task.
303 > */
304 > label?: string;
305 >
306 > /**
307 > * An optional identifier which can be used to reference a task
308 > * in a dependsOn or other attributes.
309 > */
310 > identifier?: string;
311 >
312 > /**
313 > * Whether the executed command is kept alive and runs in the background.
314 > */
315 > isBackground?: boolean;
316 >
317 > /**
318 > * Whether the task should prompt on close for confirmation if running.
319 > */
320 > promptOnClose?: boolean;
321 >
322 > /**
323 > * Defines the group the task belongs too.
324 > */
325 > group?: string | IGroupKind;
326 >
327 > /**
328 > * A description of the task.
329 > */
330 > detail?: string;
331 >
332 > /**
333 > * The other tasks the task depend on
334 > */
335 > dependsOn?: string | ITaskIdentifier | Array<string | ITaskIdentifier>;
336 >
337 > /**
338 > * The order the dependsOn tasks should be executed in.
339 > */
340 > dependsOrder?: string;
341 >
342 > /**
343 > * Controls the behavior of the used terminal
344 > */
345 > presentation?: IPresentationOptionsConfig;
346 >
347 > /**
348 > * Controls shell options.
349 > */
350 > options?: ICommandOptionsConfig;
351 >
352 > /**
353 > * The problem matcher(s) to use to capture problems in the tasks
354 > * output.
355 > */
356 > problemMatcher?: ProblemMatcherConfig.ProblemMatcherType;
357 >
358 > /**
359 > * Task run options. Control run related properties.
360 > */
361 > runOptions?: IRunOptionsConfig;
362 >
363 > /**
364 > * The icon for this task in the terminal tabs list
365 > */
366 > icon?: { id: string; color?: string };
367 >
368 > /**
369 > * The icon's color in the terminal tabs list
370 > */
371 > color?: string;
372 >
373 > /**
374 > * Do not show this task in the run task quickpick
375 > */
376 > hide?: boolean;
377 >
378 > /**
379 > * Show this task in the Agents run action dropdown
380 > */
381 > inAgents?: boolean;
382 > }
383 >
384 > export interface ICustomTask extends ICommandProperties, IConfigurationProperties {
385 > /**
386 > * Custom tasks have the type CUSTOMIZED_TASK_TYPE
387 > */
388 > type?: string;
389 >
390 > }
391 >
392 > export interface IConfiguringTask extends IConfigurationProperties {
393 > /**
394 > * The contributed type of the task
395 > */
396 > type?: string;
397 > }
398 >
399 > /**
400 > * The base task runner configuration
401 > */
402 > export interface IBaseTaskRunnerConfiguration {
403 >
404 > /**
405 > * The command to be executed. Can be an external program or a shell
406 > * command.
407 > */
408 > command?: CommandString;
409 >
410 > /**
411 > * @deprecated Use type instead
412 > *
413 > * Specifies whether the command is a shell command and therefore must
414 > * be executed in a shell interpreter (e.g. cmd.exe, bash, ...).
415 > *
416 > * Defaults to false if omitted.
417 > */
418 > isShellCommand?: boolean;
419 >
420 > /**
421 > * The task type
422 > */
423 > type?: string;
424 >
425 > /**
426 > * The command options used when the command is executed. Can be omitted.
427 > */
428 > options?: ICommandOptionsConfig;
429 >
430 > /**
431 > * The arguments passed to the command. Can be omitted.
432 > */
433 > args?: CommandString[];
434 >
435 > /**
436 > * Controls whether the output view of the running tasks is brought to front or not.
437 > * Valid values are:
438 > * "always": bring the output window always to front when a task is executed.
439 > * "silent": only bring it to front if no problem matcher is defined for the task executed.
440 > * "never": never bring the output window to front.
441 > *
442 > * If omitted "always" is used.
443 > */
444 > showOutput?: string;
445 >
446 > /**
447 > * Controls whether the executed command is printed to the output windows as well.
448 > */
449 > echoCommand?: boolean;
450 >
451 > /**
452 > * The group
453 > */
454 > group?: string | IGroupKind;
455 >
456 > /**
457 > * Controls the behavior of the used terminal
458 > */
459 > presentation?: IPresentationOptionsConfig;
460 >
461 > /**
462 > * If set to false the task name is added as an additional argument to the
463 > * command when executed. If set to true the task name is suppressed. If
464 > * omitted false is used.
465 > */
466 > suppressTaskName?: boolean;
467 >
468 > /**
469 > * Some commands require that the task argument is highlighted with a special
470 > * prefix (e.g. /t: for msbuild). This property can be used to control such
471 > * a prefix.
472 > */
473 > taskSelector?: string;
474 >
475 > /**
476 > * The problem matcher(s) to used if a global command is executed (e.g. no tasks
477 > * are defined). A tasks.json file can either contain a global problemMatcher
478 > * property or a tasks property but not both.
479 > */
480 > problemMatcher?: ProblemMatcherConfig.ProblemMatcherType;
481 >
482 > /**
483 > * @deprecated Use `isBackground` instead.
484 > *
485 > * Specifies whether a global command is a watching the filesystem. A task.json
486 > * file can either contain a global isWatching property or a tasks property
487 > * but not both.
488 > */
489 > isWatching?: boolean;
490 >
491 > /**
492 > * Specifies whether a global command is a background task.
493 > */
494 > isBackground?: boolean;
495 >
496 > /**
497 > * Whether the task should prompt on close for confirmation if running.
498 > */
499 > promptOnClose?: boolean;
500 >
501 > /**
502 > * The configuration of the available tasks. A tasks.json file can either
503 > * contain a global problemMatcher property or a tasks property but not both.
504 > */
505 > tasks?: Array<ICustomTask | IConfiguringTask>;
506 >
507 > /**
508 > * Problem matcher declarations.
509 > */
510 > declares?: ProblemMatcherConfig.INamedProblemMatcher[];
511 >
512 > /**
513 > * Optional user input variables.
514 > */
515 > inputs?: ConfiguredInput[];
516 > }
517 >
518 > /**
519 > * A configuration of an external build system. BuildConfiguration.buildSystem
520 > * must be set to 'program'
521 > */
522 > export interface IExternalTaskRunnerConfiguration extends IBaseTaskRunnerConfiguration {
523 >
524 > _runner?: string;
525 >
526 > /**
527 > * Determines the runner to use
528 > */
529 > runner?: string;
530 >
531 > /**
532 > * The config's version number
533 > */
534 > version: string;
535 >
536 > /**
537 > * Windows specific task configuration
538 > */
539 > windows?: IBaseTaskRunnerConfiguration;
540 >
541 > /**
542 > * Mac specific task configuration
543 > */
544 > osx?: IBaseTaskRunnerConfiguration;
545 >
546 > /**
547 > * Linux specific task configuration
548 > */
549 > linux?: IBaseTaskRunnerConfiguration;
550 > }
551 >
552 > enum ProblemMatcherKind {
553 > Unknown,
554 > String,
555 > ProblemMatcher,
556 > Array
557 > }
558 >
559 > type TaskConfigurationValueWithErrors<T> = {
560 > value?: T;
561 > errors?: string[];
562 > };
563 >
564 > const EMPTY_ARRAY: never[] = [];
565 > Object.freeze(EMPTY_ARRAY);
566 >
567 function assignProperty<T, K extends keyof T>(target: T, source: Partial<T>, key: K) {
568 const sourceAtKey = source[key];
571 }
572 }
574 function fillProperty<T, K extends keyof T>(target: T, source: Partial<T>, key: K) {
575 const sourceAtKey = source[key];
578 }
579 }
581 >
582 > interface IParserType<T> {
583 > isEmpty(value: T | undefined): boolean;
584 > assignProperties(target: T | undefined, source: T | undefined): T | undefined;
585 > fillProperties(target: T | undefined, source: T | undefined): T | undefined;
586 > fillDefaults(value: T | undefined, context: IParseContext): T | undefined;
587 > freeze(value: T): Readonly<T> | undefined;
588 > }
589 >
590 > interface IMetaData<T, U> {
591 > property: keyof T;
592 > type?: IParserType<U>;
593 > }
594 >
595 >
596 > // eslint-disable-next-line @typescript-eslint/no-explicit-any -- IMetaData array holds heterogeneous parser types
597 function _isEmpty<T>(this: void, value: T | undefined, properties: IMetaData<T, any>[] | undefined, allowEmptyArray: boolean = false): boolean {
598 if (value === undefined || value === null || properties === undefined) {
611 return true;
612 }
614 > // eslint-disable-next-line @typescript-eslint/no-explicit-any -- IMetaData array holds heterogeneous parser types
615 function _assignProperties<T>(this: void, target: T | undefined, source: T | undefined, properties: IMetaData<T, any>[]): T | undefined {
616 if (!source || _isEmpty(source, properties)) {
634 return target;
635 }
637 > // eslint-disable-next-line @typescript-eslint/no-explicit-any -- IMetaData array holds heterogeneous parser types
638 function _fillProperties<T>(this: void, target: T | undefined, source: T | undefined, properties: IMetaData<T, any>[] | undefined, allowEmptyArray: boolean = false): T | undefined {
639 if (!source || _isEmpty(source, properties)) {
657 return target;
658 }
660 > // eslint-disable-next-line @typescript-eslint/no-explicit-any -- IMetaData array holds heterogeneous parser types
661 function _fillDefaults<T>(this: void, target: T | undefined, defaults: T | undefined, properties: IMetaData<T, any>[], context: IParseContext): T | undefined {
662 if (target && Object.isFrozen(target)) {
688 return target;
689 }
691 > // eslint-disable-next-line @typescript-eslint/no-explicit-any -- IMetaData array holds heterogeneous parser types
692 function _freeze<T>(this: void, target: T, properties: IMetaData<T, any>[]): Readonly<T> | undefined {
693 if (target === undefined || target === null) {
708 return target;
709 }
711 > export namespace RunOnOptions {
712 > export function fromString(value: string | undefined): Tasks.RunOnOptions {
713 if (!value) {
714 return Tasks.RunOnOptions.default;
724 }
725 }
727 >
728 > export namespace RunOptions {
729 > const properties: IMetaData<Tasks.IRunOptions, void>[] = [{ property: 'reevaluateOnRerun' }, { property: 'runOn' }, { property: 'instanceLimit' }, { property: 'instancePolicy' }];
730 > export function fromConfiguration(value: IRunOptionsConfig | undefined): Tasks.IRunOptions {
731 return {
732 reevaluateOnRerun: value ? value.reevaluateOnRerun : true,
736 };
737 }
739 > export function assignProperties(target: Tasks.IRunOptions, source: Tasks.IRunOptions | undefined): Tasks.IRunOptions {
740 return _assignProperties(target, source, properties)!;
741 }
743 > export function fillProperties(target: Tasks.IRunOptions, source: Tasks.IRunOptions | undefined): Tasks.IRunOptions {
744 return _fillProperties(target, source, properties)!;
745 }
747 >
748 > export namespace InstancePolicy {
749 > export function fromString(value: string | undefined): Tasks.InstancePolicy {
750 if (!value) {
751 return Tasks.InstancePolicy.prompt;
765 }
766 }
768 >
769 > export interface IParseContext {
770 > workspaceFolder: IWorkspaceFolder;
771 > workspace: IWorkspace | undefined;
772 > problemReporter: IProblemReporter;
773 > namedProblemMatchers: IStringDictionary<INamedProblemMatcher>;
774 > uuidMap: UUIDMap;
775 > engine: Tasks.ExecutionEngine;
776 > schemaVersion: Tasks.JsonSchemaVersion;
777 > platform: Platform;
778 > taskLoadIssues: string[];
779 > contextKeyService: IContextKeyService;
780 > }
781 >
782 >
783 > namespace ShellConfiguration {
784 >
785 > const properties: IMetaData<Tasks.IShellConfiguration, void>[] = [{ property: 'executable' }, { property: 'args' }, { property: 'quoting' }];
786 >
787 > export function is(value: unknown): value is IShellConfiguration {
788 const candidate: IShellConfiguration = value as IShellConfiguration;
789 return candidate && (Types.isString(candidate.executable) || Types.isStringArray(candidate.args));
790 }
792 > export function from(this: void, config: IShellConfiguration | undefined, context: IParseContext): Tasks.IShellConfiguration | undefined {
793 if (!is(config)) {
794 return undefined;
807 return result;
808 }
810 > export function isEmpty(this: void, value: Tasks.IShellConfiguration): boolean {
811 return _isEmpty(value, properties, true);
812 }
814 > export function assignProperties(this: void, target: Tasks.IShellConfiguration | undefined, source: Tasks.IShellConfiguration | undefined): Tasks.IShellConfiguration | undefined {
815 return _assignProperties(target, source, properties);
816 }
818 > export function fillProperties(this: void, target: Tasks.IShellConfiguration, source: Tasks.IShellConfiguration): Tasks.IShellConfiguration | undefined {
819 return _fillProperties(target, source, properties, true);
820 }
822 > export function fillDefaults(this: void, value: Tasks.IShellConfiguration, context: IParseContext): Tasks.IShellConfiguration {
823 return value;
824 }
826 > export function freeze(this: void, value: Tasks.IShellConfiguration): Readonly<Tasks.IShellConfiguration> | undefined {
827 if (!value) {
828 return undefined;
830 return Object.freeze(value);
831 }
833 >
834 > namespace CommandOptions {
835 >
836 > const properties: IMetaData<Tasks.CommandOptions, Tasks.IShellConfiguration>[] = [{ property: 'cwd' }, { property: 'env' }, { property: 'shell', type: ShellConfiguration }];
837 > const defaults: ICommandOptionsConfig = { cwd: '${workspaceFolder}' };
838 >
839 > export function from(this: void, options: ICommandOptionsConfig, context: IParseContext): Tasks.CommandOptions | undefined {
840 const result: Tasks.CommandOptions = {};
841 if (options.cwd !== undefined) {
852 return isEmpty(result) ? undefined : result;
853 }
855 > export function isEmpty(value: Tasks.CommandOptions | undefined): boolean {
856 return _isEmpty(value, properties);
857 }
859 > export function assignProperties(target: Tasks.CommandOptions | undefined, source: Tasks.CommandOptions | undefined): Tasks.CommandOptions | undefined {
860 if ((source === undefined) || isEmpty(source)) {
861 return target;
880 return target;
881 }
883 > export function fillProperties(target: Tasks.CommandOptions | undefined, source: Tasks.CommandOptions | undefined): Tasks.CommandOptions | undefined {
884 return _fillProperties(target, source, properties);
885 }
887 > export function fillDefaults(value: Tasks.CommandOptions | undefined, context: IParseContext): Tasks.CommandOptions | undefined {
888 return _fillDefaults(value, defaults, properties, context);
889 }
891 > export function freeze(value: Tasks.CommandOptions): Readonly<Tasks.CommandOptions> | undefined {
892 return _freeze(value, properties);
893 }
895 >
896 > namespace CommandConfiguration {
897 >
898 > export namespace PresentationOptions {
899 > const properties: IMetaData<Tasks.IPresentationOptions, void>[] = [{ property: 'echo' }, { property: 'reveal' }, { property: 'revealProblems' }, { property: 'focus' }, { property: 'panel' }, { property: 'showReuseMessage' }, { property: 'clear' }, { property: 'group' }, { property: 'close' }, { property: 'preserveTerminalName' }];
900 >
901 > interface IPresentationOptionsShape extends ILegacyCommandProperties {
902 > presentation?: IPresentationOptionsConfig;
903 > }
904 >
905 > export function from(this: void, config: IPresentationOptionsShape, context: IParseContext): Tasks.IPresentationOptions | undefined {
906 let echo: boolean;
907 let reveal: Tasks.RevealKind;
962 return { echo: echo!, reveal: reveal!, revealProblems: revealProblems!, focus: focus!, panel: panel!, showReuseMessage: showReuseMessage!, clear: clear!, group, close: close, preserveTerminalName };
963 }
965 > export function assignProperties(target: Tasks.IPresentationOptions, source: Tasks.IPresentationOptions | undefined): Tasks.IPresentationOptions | undefined {
966 return _assignProperties(target, source, properties);
967 }
969 > export function fillProperties(target: Tasks.IPresentationOptions, source: Tasks.IPresentationOptions | undefined): Tasks.IPresentationOptions | undefined {
970 return _fillProperties(target, source, properties);
971 }
973 > export function fillDefaults(value: Tasks.IPresentationOptions, context: IParseContext): Tasks.IPresentationOptions | undefined {
974 const defaultEcho = context.engine === Tasks.ExecutionEngine.Terminal ? true : false;
975 return _fillDefaults(value, { echo: defaultEcho, reveal: Tasks.RevealKind.Always, revealProblems: Tasks.RevealProblemKind.Never, focus: false, panel: Tasks.PanelKind.Shared, showReuseMessage: true, clear: false, preserveTerminalName: false }, properties, context);
976 }
978 > export function freeze(value: Tasks.IPresentationOptions): Readonly<Tasks.IPresentationOptions> | undefined {
979 return _freeze(value, properties);
980 }
982 > export function isEmpty(this: void, value: Tasks.IPresentationOptions): boolean {
983 return _isEmpty(value, properties);
984 }
986 >
987 > namespace ShellString {
988 > export function from(this: void, value: CommandString | undefined): Tasks.CommandString | undefined {
989 if (value === undefined || value === null) {
990 return undefined;
1007 }
1008 }
1010 >
1011 > interface IBaseCommandConfigurationShape extends IBaseCommandProperties, ILegacyCommandProperties {
1012 > }
1013 >
1014 > interface ICommandConfigurationShape extends IBaseCommandConfigurationShape {
1015 > windows?: IBaseCommandConfigurationShape;
1016 > osx?: IBaseCommandConfigurationShape;
1017 > linux?: IBaseCommandConfigurationShape;
1018 > }
1019 >
1020 > // eslint-disable-next-line @typescript-eslint/no-explicit-any -- IMetaData array holds heterogeneous parser types
1021 > const properties: IMetaData<Tasks.ICommandConfiguration, any>[] = [
1022 > { property: 'runtime' }, { property: 'name' }, { property: 'options', type: CommandOptions },
1023 > { property: 'args' }, { property: 'taskSelector' }, { property: 'suppressTaskName' },
1024 > { property: 'presentation', type: PresentationOptions }
1025 > ];
1026 >
1027 > export function from(this: void, config: ICommandConfigurationShape, context: IParseContext): Tasks.ICommandConfiguration | undefined {
1028 let result: Tasks.ICommandConfiguration = fromBase(config, context)!;
1029
1041 return isEmpty(result) ? undefined : result;
1042 }
1044 > function fromBase(this: void, config: IBaseCommandConfigurationShape, context: IParseContext): Tasks.ICommandConfiguration | undefined {
1045 const name: Tasks.CommandString | undefined = ShellString.from(config.command);
1046 let runtime: Tasks.RuntimeType;
1097 return isEmpty(result) ? undefined : result;
1098 }
1100 > export function hasCommand(value: Tasks.ICommandConfiguration): boolean {
1101 return value && !!value.name;
1102 }
1104 > export function isEmpty(value: Tasks.ICommandConfiguration | undefined): boolean {
1105 return _isEmpty(value, properties);
1106 }
1108 > export function assignProperties(target: Tasks.ICommandConfiguration, source: Tasks.ICommandConfiguration, overwriteArgs: boolean): Tasks.ICommandConfiguration {
1109 if (isEmpty(source)) {
1110 return target;
1128 return target;
1129 }
1131 > export function fillProperties(target: Tasks.ICommandConfiguration, source: Tasks.ICommandConfiguration): Tasks.ICommandConfiguration | undefined {
1132 return _fillProperties(target, source, properties);
1133 }
1135 > export function fillGlobals(target: Tasks.ICommandConfiguration, source: Tasks.ICommandConfiguration | undefined, taskName: string | undefined): Tasks.ICommandConfiguration {
1136 if ((source === undefined) || isEmpty(source)) {
1137 return target;
1166 return target;
1167 }
1169 > export function fillDefaults(value: Tasks.ICommandConfiguration | undefined, context: IParseContext): void {
1170 if (!value || Object.isFrozen(value)) {
1171 return;
1185 }
1186 }
1188 > export function freeze(value: Tasks.ICommandConfiguration): Readonly<Tasks.ICommandConfiguration> | undefined {
1189 return _freeze(value, properties);
1190 }
1192 >
1193 > export namespace ProblemMatcherConverter {
1194 >
1195 > export function namedFrom(this: void, declares: ProblemMatcherConfig.INamedProblemMatcher[] | undefined, context: IParseContext): IStringDictionary<INamedProblemMatcher> {
1196 const result: IStringDictionary<INamedProblemMatcher> = Object.create(null);
1197
1209 return result;
1210 }
1212 > export function fromWithOsConfig(this: void, external: IConfigurationProperties & { [key: string]: unknown }, context: IParseContext): TaskConfigurationValueWithErrors<ProblemMatcher[]> {
1213 let result: TaskConfigurationValueWithErrors<ProblemMatcher[]> = {};
1214 const osExternal = external as unknown as { windows?: { problemMatcher?: ProblemMatcherConfig.ProblemMatcherType }; osx?: { problemMatcher?: ProblemMatcherConfig.ProblemMatcherType }; linux?: { problemMatcher?: ProblemMatcherConfig.ProblemMatcherType } };
1224 return result;
1225 }
1227 > export function from(this: void, config: ProblemMatcherConfig.ProblemMatcherType | undefined, context: IParseContext): TaskConfigurationValueWithErrors<ProblemMatcher[]> {
1228 const result: ProblemMatcher[] = [];
1229 if (config === undefined) {
1256 return { value: result, errors };
1257 }
1259 > function getProblemMatcherKind(this: void, value: ProblemMatcherConfig.ProblemMatcherType): ProblemMatcherKind {
1260 if (Types.isString(value)) {
1261 return ProblemMatcherKind.String;
1268 }
1269 }
1271 > function resolveProblemMatcher(this: void, value: string | ProblemMatcherConfig.ProblemMatcher, context: IParseContext): TaskConfigurationValueWithErrors<ProblemMatcher> {
1272 if (Types.isString(value)) {
1273 let variableName = <string>value;
1292 }
1293 }
1295 >
1296 > export namespace GroupKind {
1297 > export function from(this: void, external: string | IGroupKind | undefined): Tasks.TaskGroup | undefined {
1298 if (external === undefined) {
1299 return undefined;
1308 return undefined;
1309 }
1311 > export function to(group: Tasks.TaskGroup | string): IGroupKind | string {
1312 if (Types.isString(group)) {
1313 return group;
1320 };
1321 }
1323 >
1324 > namespace TaskDependency {
1325 > function uriFromSource(context: IParseContext, source: TaskConfigSource): URI | string {
1326 switch (source) {
1327 case TaskConfigSource.User: return Tasks.USER_TASKS_GROUP_KEY;
1330 }
1331 }
1333 > export function from(this: void, external: string | ITaskIdentifier, context: IParseContext, source: TaskConfigSource): Tasks.ITaskDependency | undefined {
1334 if (Types.isString(external)) {
1335 return { uri: uriFromSource(context, source), task: external };
1343 }
1344 }
1346 >
1347 > namespace DependsOrder {
1348 > export function from(order: string | undefined): Tasks.DependsOrder {
1349 switch (order) {
1350 case Tasks.DependsOrder.sequence:
1355 }
1356 }
1358 >
1359 > namespace ConfigurationProperties {
1360 >
1361 > // eslint-disable-next-line @typescript-eslint/no-explicit-any -- IMetaData array holds heterogeneous parser types
1362 > const properties: IMetaData<Tasks.IConfigurationProperties, any>[] = [
1363 > { property: 'name' },
1364 > { property: 'identifier' },
1365 > { property: 'group' },
1366 > { property: 'isBackground' },
1367 > { property: 'promptOnClose' },
1368 > { property: 'dependsOn' },
1369 > { property: 'presentation', type: CommandConfiguration.PresentationOptions },
1370 > { property: 'problemMatchers' },
1371 > { property: 'options' },
1372 > { property: 'icon' },
1373 > { property: 'hide' },
1374 > { property: 'inAgents' }
1375 > ];
1376 >
1377 > export function from(this: void, external: IConfigurationProperties & { [key: string]: unknown }, context: IParseContext,
1378 includeCommandOptions: boolean, source: TaskConfigSource, properties?: IJSONSchemaMap): TaskConfigurationValueWithErrors<Tasks.IConfigurationProperties> {
1379 if (!external) {
1439 return isEmpty(result) ? {} : { value: result, errors: configProblemMatcher.errors };
1440 }
1442 > export function isEmpty(this: void, value: Tasks.IConfigurationProperties): boolean {
1443 return _isEmpty(value, properties);
1444 }
1446 > const label = 'Workspace';
1447 >
1448 > namespace ConfiguringTask {
1449 >
1450 > const grunt = 'grunt.';
1451 > const jake = 'jake.';
1452 > const gulp = 'gulp.';
1453 > const npm = 'vscode.npm.';
1454 > const typescript = 'vscode.typescript.';
1455 >
1456 > interface ICustomizeShape {
1457 > customize: string;
1458 > }
1459 >
1460 > export function from(this: void, external: IConfiguringTask, context: IParseContext, index: number, source: TaskConfigSource, registry?: Partial<ITaskDefinitionRegistry>): Tasks.ConfiguringTask | undefined {
1461 if (!external) {
1462 return undefined;
1562 return result;
1563 }
1565 >
1566 > namespace CustomTask {
1567 > export function from(this: void, external: ICustomTask, context: IParseContext, index: number, source: TaskConfigSource): Tasks.CustomTask | undefined {
1568 if (!external) {
1569 return undefined;
1645 return result;
1646 }
1648 > export function fillGlobals(task: Tasks.CustomTask, globals: IGlobals): void {
1649 // We only merge a command from a global definition if there is no dependsOn
1650 // or there is a dependsOn and a defined command.
1661 }
1662 }
1664 > export function fillDefaults(task: Tasks.CustomTask, context: IParseContext): void {
1665 CommandConfiguration.fillDefaults(task.command, context);
1666 if (task.configurationProperties.promptOnClose === undefined) {
1674 }
1675 }
1677 > export function createCustomTask(contributedTask: Tasks.ContributedTask, configuredProps: Tasks.ConfiguringTask | Tasks.CustomTask): Tasks.CustomTask {
1678 const result: Tasks.CustomTask = new Tasks.CustomTask(
1679 configuredProps._id,
1725 return result;
1726 }
1728 >
1729 > export interface ITaskParseResult {
1730 > custom: Tasks.CustomTask[];
1731 > configured: Tasks.ConfiguringTask[];
1732 > }
1733 >
1734 > export namespace TaskParser {
1735 >
1736 > function isCustomTask(value: ICustomTask | IConfiguringTask): value is ICustomTask {
1737 const type = value.type;
1738 const customize = (value as unknown as Record<string, unknown>).customize;
1739 return customize === undefined && (type === undefined || type === null || type === Tasks.CUSTOMIZED_TASK_TYPE || type === 'shell' || type === 'process');
1740 }
1742 > const builtinTypeContextMap: IStringDictionary<RawContextKey<boolean>> = {
1743 > shell: ShellExecutionSupportedContext,
1744 > process: ProcessExecutionSupportedContext
1745 > };
1746 >
1747 > export function from(this: void, externals: Array<ICustomTask | IConfiguringTask> | undefined, globals: IGlobals, context: IParseContext, source: TaskConfigSource, registry?: Partial<ITaskDefinitionRegistry>): ITaskParseResult {
1748 const result: ITaskParseResult = { custom: [], configured: [] };
1749 if (!externals) {
1837 return result;
1838 }
1840 > export function assignTasks(target: Tasks.CustomTask[], source: Tasks.CustomTask[]): Tasks.CustomTask[] {
1841 if (source === undefined || source.length === 0) {
1842 return target;
1866 return target;
1867 }
1869 >
1870 > export interface IGlobals {
1871 > command?: Tasks.ICommandConfiguration;
1872 > problemMatcher?: ProblemMatcher[];
1873 > promptOnClose?: boolean;
1874 > suppressTaskName?: boolean;
1875 > }
1876 >
1877 > namespace Globals {
1878 >
1879 > export function from(config: IExternalTaskRunnerConfiguration, context: IParseContext): IGlobals {
1880 let result = fromBase(config, context);
1881 let osGlobals: IGlobals | undefined = undefined;
1898 return result;
1899 }
1901 > export function fromBase(this: void, config: IBaseTaskRunnerConfiguration, context: IParseContext): IGlobals {
1902 const result: IGlobals = {};
1903 if (config.suppressTaskName !== undefined) {
1912 return result;
1913 }
1915 > export function isEmpty(value: IGlobals): boolean {
1916 return !value || value.command === undefined && value.promptOnClose === undefined && value.suppressTaskName === undefined;
1917 }
1919 > export function assignProperties(target: IGlobals, source: IGlobals): IGlobals {
1920 if (isEmpty(source)) {
1921 return target;
1928 return target;
1929 }
1931 > export function fillDefaults(value: IGlobals, context: IParseContext): void {
1932 if (!value) {
1933 return;
1941 }
1942 }
1944 > export function freeze(value: IGlobals): void {
1945 Object.freeze(value);
1946 if (value.command) {
1948 }
1949 }
1951 >
1952 > export namespace ExecutionEngine {
1953 >
1954 > export function from(config: IExternalTaskRunnerConfiguration): Tasks.ExecutionEngine {
1955 const runner = config.runner || config._runner;
1956 let result: Tasks.ExecutionEngine | undefined;
1974 }
1975 }
1977 >
1978 > export namespace JsonSchemaVersion {
1979 >
1980 > const _default: Tasks.JsonSchemaVersion = Tasks.JsonSchemaVersion.V2_0_0;
1981 >
1982 > export function from(config: IExternalTaskRunnerConfiguration): Tasks.JsonSchemaVersion {
1983 const version = config.version;
1984 if (!version) {
1994 }
1995 }
1997 >
1998 > export interface IParseResult {
1999 > validationStatus: ValidationStatus;
2000 > custom: Tasks.CustomTask[];
2001 > configured: Tasks.ConfiguringTask[];
2002 > engine: Tasks.ExecutionEngine;
2003 > }
2004 >
2005 > export interface IProblemReporter extends IProblemReporterBase {
2006 > }
2007 >
2008 > export class UUIDMap {
2009 >
2010 > private last: IStringDictionary<Types.SingleOrMany<string>> | undefined;
2011 > private current: IStringDictionary<Types.SingleOrMany<string>>;
2012 >
2013 > constructor(other?: UUIDMap) {
2014 > this.current = Object.create(null);
2015 > if (other) {
2016 for (const key of Object.keys(other.current)) {
2017 const value = other.current[key];
2023 }
2024 }
2026 >
2027 > public start(): void {
2028 this.last = this.current;
2029 this.current = Object.create(null);
2030 }
2032 > public getUUID(identifier: string): string {
2033 const lastValue = this.last ? this.last[identifier] : undefined;
2034 let result: string | undefined = undefined;
2061 return result;
2062 }
2064 > public finish(): void {
2065 this.last = undefined;
2066 }
2068 >
2069 > export enum TaskConfigSource {
2070 > TasksJson,
2071 > WorkspaceFile,
2072 > User
2073 > }
2074 >
2075 > class ConfigurationParser {
2076 >
2077 > private workspaceFolder: IWorkspaceFolder;
2078 > private workspace: IWorkspace | undefined;
2079 > private problemReporter: IProblemReporter;
2080 > private uuidMap: UUIDMap;
2081 > private platform: Platform;
2082 >
2083 > constructor(workspaceFolder: IWorkspaceFolder, workspace: IWorkspace | undefined, platform: Platform, problemReporter: IProblemReporter, uuidMap: UUIDMap) {
2084 this.workspaceFolder = workspaceFolder;
2085 this.workspace = workspace;
2088 this.uuidMap = uuidMap;
2089 }
2091 > public run(fileConfig: IExternalTaskRunnerConfiguration, source: TaskConfigSource, contextKeyService: IContextKeyService): IParseResult {
2092 const engine = ExecutionEngine.from(fileConfig);
2093 const schemaVersion = JsonSchemaVersion.from(fileConfig);
2112 };
2113 }
2115 > private createTaskRunnerConfiguration(fileConfig: IExternalTaskRunnerConfiguration, context: IParseContext, source: TaskConfigSource): ITaskParseResult {
2116 const globals = Globals.from(fileConfig, context);
2117 if (this.problemReporter.status.isFatal()) {
2190 return result;
2191 }
2193 >
2194 > const uuidMaps: Map<TaskConfigSource, Map<string, UUIDMap>> = new Map();
2195 > const recentUuidMaps: Map<TaskConfigSource, Map<string, UUIDMap>> = new Map();
2196 > export function parse(workspaceFolder: IWorkspaceFolder, workspace: IWorkspace | undefined, platform: Platform, configuration: IExternalTaskRunnerConfiguration, logger: IProblemReporter, source: TaskConfigSource, contextKeyService: IContextKeyService, isRecents: boolean = false): IParseResult {
2197 const recentOrOtherMaps = isRecents ? recentUuidMaps : uuidMaps;
2198 let selectedUuidMaps = recentOrOtherMaps.get(source);
2213 }
2214 }
2216 >
2217 >
2218 > export function createCustomTask(contributedTask: Tasks.ContributedTask, configuredProps: Tasks.ConfiguringTask | Tasks.CustomTask): Tasks.CustomTask {
2219 return CustomTask.createCustomTask(contributedTask, configuredProps);
2220 }
src/vs/workbench/contrib/tasks/common/taskService.ts 119 introduced LOC · 1 range

Open complete file

1 > /*--------------------------------------------------------------------------------------------- taskService.ts
2 > * Copyright (c) Microsoft Corporation. All rights reserved.
3 > * Licensed under the MIT License. See License.txt in the project root for license information.
4 > *--------------------------------------------------------------------------------------------*/
5 >
6 > import * as nls from '../../../../nls.js';
7 > import { Action } from '../../../../base/common/actions.js';
8 > import { Event } from '../../../../base/common/event.js';
9 > import { createDecorator } from '../../../../platform/instantiation/common/instantiation.js';
10 > import { IDisposable } from '../../../../base/common/lifecycle.js';
11 > import { IWorkspaceFolder, IWorkspace } from '../../../../platform/workspace/common/workspace.js';
12 > import { Task, ContributedTask, CustomTask, ITaskSet, TaskSorter, ITaskEvent, ITaskIdentifier, ConfiguringTask, TaskRunSource } from './tasks.js';
13 > import { ITaskSummary, ITaskTerminateResponse, ITaskSystemInfo } from './taskSystem.js';
14 > import { IStringDictionary } from '../../../../base/common/collections.js';
15 > import { RawContextKey, ContextKeyExpr } from '../../../../platform/contextkey/common/contextkey.js';
16 > import { URI } from '../../../../base/common/uri.js';
17 > import { IMarkerData } from '../../../../platform/markers/common/markers.js';
18 > import type { SingleOrMany } from '../../../../base/common/types.js';
19 > export type { ITaskSummary, Task, ITaskTerminateResponse as TaskTerminateResponse };
20 > export const CustomExecutionSupportedContext = new RawContextKey<boolean>('customExecutionSupported', false, nls.localize('tasks.customExecutionSupported', "Whether CustomExecution tasks are supported. Consider using in the when clause of a \'taskDefinition\' contribution."));
21 > export const ShellExecutionSupportedContext = new RawContextKey<boolean>('shellExecutionSupported', false, nls.localize('tasks.shellExecutionSupported', "Whether ShellExecution tasks are supported. Consider using in the when clause of a \'taskDefinition\' contribution."));
22 > export const TaskCommandsRegistered = new RawContextKey<boolean>('taskCommandsRegistered', false, nls.localize('tasks.taskCommandsRegistered', "Whether the task commands have been registered yet"));
23 > export const ProcessExecutionSupportedContext = new RawContextKey<boolean>('processExecutionSupported', false, nls.localize('tasks.processExecutionSupported', "Whether ProcessExecution tasks are supported. Consider using in the when clause of a \'taskDefinition\' contribution."));
24 > export const ServerlessWebContext = new RawContextKey<boolean>('serverlessWebContext', false, nls.localize('tasks.serverlessWebContext', "True when in the web with no remote authority."));
25 > export const TasksAvailableContext = new RawContextKey<boolean>('tasksAvailable', false, nls.localize('tasks.tasksAvailable', "Whether any tasks are available in the workspace."));
26 > export const TaskExecutionSupportedContext = ContextKeyExpr.or(ContextKeyExpr.and(ShellExecutionSupportedContext, ProcessExecutionSupportedContext), CustomExecutionSupportedContext);
27 >
28 > export const ITaskService = createDecorator<ITaskService>('taskService');
29 >
30 > export interface ITaskProvider {
31 > provideTasks(validTypes: IStringDictionary<boolean>): Promise<ITaskSet>;
32 > resolveTask(task: ConfiguringTask): Promise<ContributedTask | undefined>;
33 > }
34 >
35 > export interface IProblemMatcherRunOptions {
36 > attachProblemMatcher?: boolean;
37 > }
38 >
39 > export interface ICustomizationProperties {
40 > group?: string | { kind?: string; isDefault?: boolean };
41 > problemMatcher?: SingleOrMany<string>;
42 > isBackground?: boolean;
43 > color?: string;
44 > icon?: string;
45 > inAgents?: boolean;
46 > }
47 >
48 > export interface ITaskFilter {
49 > version?: string;
50 > type?: string;
51 > task?: string;
52 > }
53 >
54 > interface IWorkspaceTaskResult {
55 > set: ITaskSet | undefined;
56 > configurations: {
57 > byIdentifier: IStringDictionary<ConfiguringTask>;
58 > } | undefined;
59 > hasErrors: boolean;
60 > }
61 >
62 > export interface IWorkspaceFolderTaskResult extends IWorkspaceTaskResult {
63 > workspaceFolder: IWorkspaceFolder;
64 > }
65 >
66 > export interface ITaskService {
67 > readonly _serviceBrand: undefined;
68 > readonly onDidStateChange: Event<ITaskEvent>;
69 > /** Fired when task providers are registered or unregistered */
70 > readonly onDidChangeTaskProviders: Event<void>;
71 > isReconnected: boolean;
72 > readonly onDidReconnectToTasks: Event<void>;
73 > supportsMultipleTaskExecutions: boolean;
74 >
75 > configureAction(): Action;
76 > run(task: Task | undefined, options?: IProblemMatcherRunOptions, runSource?: TaskRunSource): Promise<ITaskSummary | undefined>;
77 > inTerminal(): boolean;
78 > getActiveTasks(): Promise<Task[]>;
79 > getBusyTasks(): Promise<Task[]>;
80 > terminate(task: Task): Promise<ITaskTerminateResponse>;
81 > tasks(filter?: ITaskFilter): Promise<Task[]>;
82 > rerun(terminalInstanceId: number): void;
83 > /**
84 > * Gets tasks currently known to the task system. Unlike {@link tasks},
85 > * this does not activate extensions or prompt for workspace trust.
86 > */
87 > getKnownTasks(filter?: ITaskFilter): Promise<Task[]>;
88 > taskTypes(): string[];
89 > getWorkspaceTasks(runSource?: TaskRunSource): Promise<Map<string, IWorkspaceFolderTaskResult>>;
90 > getSavedTasks(type: 'persistent' | 'historical'): Promise<(Task | ConfiguringTask)[]>;
91 > removeRecentlyUsedTask(taskRecentlyUsedKey: string): void;
92 > getTerminalsForTasks(tasks: SingleOrMany<Task>): URI[] | undefined;
93 > getTaskProblems(instanceId: number): Map<string, { resources: URI[]; markers: IMarkerData[] }> | undefined;
94 > /**
95 > * @param alias The task's name, label or defined identifier.
96 > */
97 > getTask(workspaceFolder: IWorkspace | IWorkspaceFolder | string, alias: string | ITaskIdentifier, compareId?: boolean): Promise<Task | undefined>;
98 > tryResolveTask(configuringTask: ConfiguringTask): Promise<Task | undefined>;
99 > createSorter(): TaskSorter;
100 >
101 > getTaskDescription(task: Task | ConfiguringTask): string | undefined;
102 > customize(task: ContributedTask | CustomTask | ConfiguringTask, properties?: {}, openConfig?: boolean): Promise<void>;
103 > openConfig(task: CustomTask | ConfiguringTask | undefined): Promise<boolean>;
104 >
105 > registerTaskProvider(taskProvider: ITaskProvider, type: string): IDisposable;
106 >
107 > registerTaskSystem(scheme: string, taskSystemInfo: ITaskSystemInfo): void;
108 > readonly onDidChangeTaskSystemInfo: Event<void>;
109 > readonly onDidChangeTaskConfig: Event<void>;
110 > readonly hasTaskSystemInfo: boolean;
111 > registerSupportedExecutions(custom?: boolean, shell?: boolean, process?: boolean): void;
112 >
113 > extensionCallbackTaskComplete(task: Task, result: number | undefined): Promise<void>;
114 > }
115 >
116 > export interface ITaskTerminalStatus {
117 > terminalId: number;
118 > status: string;
119 > }
src/vs/workbench/contrib/tasks/common/taskDefinitionRegistry.ts 106 introduced LOC · 8 ranges

Open complete file

1 > /*--------------------------------------------------------------------------------------------- taskDefinitionRegistry.ts
2 > * Copyright (c) Microsoft Corporation. All rights reserved.
3 > * Licensed under the MIT License. See License.txt in the project root for license information.
4 > *--------------------------------------------------------------------------------------------*/
5 >
6 > import * as nls from '../../../../nls.js';
7 > import { IJSONSchema, IJSONSchemaMap } from '../../../../base/common/jsonSchema.js';
8 > import { IStringDictionary } from '../../../../base/common/collections.js';
9 > import * as Types from '../../../../base/common/types.js';
10 > import * as Objects from '../../../../base/common/objects.js';
11 >
12 > import { ExtensionsRegistry, ExtensionMessageCollector } from '../../../services/extensions/common/extensionsRegistry.js';
13 >
14 > import * as Tasks from './tasks.js';
15 > import { ExtensionIdentifier } from '../../../../platform/extensions/common/extensions.js';
16 > import { ContextKeyExpr } from '../../../../platform/contextkey/common/contextkey.js';
17 > import { Emitter, Event } from '../../../../base/common/event.js';
18 >
19 >
20 > const taskDefinitionSchema: IJSONSchema = {
21 > type: 'object',
22 > additionalProperties: false,
23 > properties: {
24 > type: {
25 > type: 'string',
26 > description: nls.localize('TaskDefinition.description', 'The actual task type. Please note that types starting with a \'$\' are reserved for internal usage.')
27 > },
28 > required: {
29 > type: 'array',
30 > markdownDescription: nls.localize('TaskDefinition.required', 'The names of the properties from the `properties` object that must be provided for a task of this type to be considered a match. Used by VS Code to associate a `tasks.json` entry with a registered task provider.'),
31 > items: {
32 > type: 'string'
33 > }
34 > },
35 > properties: {
36 > type: 'object',
37 > description: nls.localize('TaskDefinition.properties', 'Additional properties of the task type'),
38 > additionalProperties: {
39 > $ref: 'http://json-schema.org/draft-07/schema#'
40 > }
41 > },
42 > when: {
43 > type: 'string',
44 > markdownDescription: nls.localize('TaskDefinition.when', 'Condition which must be true to enable this type of task. Consider using `shellExecutionSupported`, `processExecutionSupported`, and `customExecutionSupported` as appropriate for this task definition. See the [API documentation](https://code.visualstudio.com/api/extension-guides/task-provider#when-clause) for more information.'),
45 > default: ''
46 > }
47 > }
48 > };
49 >
50 > namespace Configuration {
51 > export interface ITaskDefinition {
52 > type?: string;
53 > required?: string[];
54 > properties?: IJSONSchemaMap;
55 > when?: string;
56 > }
57 >
58 > export function from(value: ITaskDefinition, extensionId: ExtensionIdentifier, messageCollector: ExtensionMessageCollector): Tasks.ITaskDefinition | undefined {
59 if (!value) {
60 return undefined;
80 };
81 }
83 >
84 >
85 > const taskDefinitionsExtPoint = ExtensionsRegistry.registerExtensionPoint<Configuration.ITaskDefinition[]>({
86 > extensionPoint: 'taskDefinitions',
87 > activationEventsGenerator: function* (contributions: readonly Configuration.ITaskDefinition[]) {
88 for (const task of contributions) {
89 if (task.type) {
92 }
93 },
94 > jsonSchema: { taskDefinitionRegistry.ts
95 > description: nls.localize('TaskDefinitionExtPoint', 'Contributes task kinds'),
96 > type: 'array',
97 > items: taskDefinitionSchema
98 > }
99 > });
100 >
101 > export interface ITaskDefinitionRegistry {
102 > onReady(): Promise<void>;
103 >
104 > get(key: string): Tasks.ITaskDefinition;
105 > all(): Tasks.ITaskDefinition[];
106 > getJsonSchema(): IJSONSchema;
107 > readonly onDefinitionsChanged: Event<void>;
108 > }
109 >
110 > class TaskDefinitionRegistryImpl implements ITaskDefinitionRegistry {
111 >
112 > private taskTypes: IStringDictionary<Tasks.ITaskDefinition>;
113 > private readyPromise: Promise<void>;
114 > private _schema: IJSONSchema | undefined;
115 > private _onDefinitionsChanged: Emitter<void> = new Emitter();
116 > public onDefinitionsChanged: Event<void> = this._onDefinitionsChanged.event;
117 >
118 > constructor() {
119 > this.taskTypes = Object.create(null);
120 > this.readyPromise = new Promise<void>((resolve, reject) => {
121 > taskDefinitionsExtPoint.setHandler((extensions, delta) => {
122 this._schema = undefined;
123 try {
145 }
146 resolve(undefined);
148 > });
149 > }
150 >
151 > public onReady(): Promise<void> {
152 return this.readyPromise;
153 }
155 > public get(key: string): Tasks.ITaskDefinition {
156 return this.taskTypes[key];
157 }
159 > public all(): Tasks.ITaskDefinition[] {
160 return Object.keys(this.taskTypes).map(key => this.taskTypes[key]);
161 }
163 > public getJsonSchema(): IJSONSchema {
164 if (this._schema === undefined) {
165 const schemas: IJSONSchema[] = [];
187 return this._schema;
188 }
190 >
191 > export const TaskDefinitionRegistry: ITaskDefinitionRegistry = new TaskDefinitionRegistryImpl();