diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/workspace.tasks.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/workspace.tasks.test.ts index 3679062018f..3f38da006c9 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/workspace.tasks.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/workspace.tasks.test.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; -import { window, tasks, Disposable, TaskDefinition, Task, EventEmitter, CustomExecution, Pseudoterminal, TaskScope, commands, env, UIKind, ShellExecution, TaskExecution, Terminal, Event, workspace, ConfigurationTarget, TaskProcessStartEvent } from 'vscode'; +import { window, tasks, Disposable, TaskDefinition, Task, Task2, EventEmitter, CustomExecution, Pseudoterminal, TaskScope, commands, env, UIKind, ShellExecution, TaskExecution, Terminal, Event, workspace, ConfigurationTarget, TaskProcessStartEvent } from 'vscode'; import { assertNoRpc } from '../utils'; // Disable tasks tests: @@ -331,6 +331,38 @@ import { assertNoRpc } from '../utils'; } }); }); + + test('A task can be fetched with default task group information', () => { + return new Promise(async (resolve, reject) => { + // Add default to tasks.json since this is not possible using an API yet. + const tasksConfig = workspace.getConfiguration('tasks'); + await tasksConfig.update('version', '2.0.0', ConfigurationTarget.Workspace); + await tasksConfig.update('tasks', [ + { + label: 'Run this task', + type: 'shell', + command: 'sleep 1', + problemMatcher: [], + group: { + kind: 'build', + isDefault: 'true' + } + } + ], ConfigurationTarget.Workspace); + + const task = (await tasks.fetchTasks()); + + if (task && task.length > 0) { + const grp = task[0].group; + assert.strictEqual(grp?.isDefault, true); + resolve(); + } else { + reject('fetched task can\'t be undefined'); + } + // Reset tasks.json + await tasksConfig.update('tasks', []); + }); + }); }); }); }); diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index bcaf77863cf..0dcbece4db3 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -1001,6 +1001,20 @@ declare module 'vscode' { } //#endregion + export class TaskGroup2 { + static Clean: TaskGroup2; + static Build: TaskGroup2; + static Rebuild: TaskGroup2; + static Test: TaskGroup2; + readonly isDefault?: boolean; + readonly id: string; + private constructor(id: string, label: string); + } + + export class Task2 extends Task { + group?: TaskGroup2; + } + //#region Custom editor move https://github.com/microsoft/vscode/issues/86146 // TODO: Also for custom editor diff --git a/src/vs/workbench/api/browser/mainThreadTask.ts b/src/vs/workbench/api/browser/mainThreadTask.ts index 8944c4daf42..457402e8fcb 100644 --- a/src/vs/workbench/api/browser/mainThreadTask.ts +++ b/src/vs/workbench/api/browser/mainThreadTask.ts @@ -17,7 +17,7 @@ import { IWorkspace, IWorkspaceContextService, IWorkspaceFolder } from 'vs/platf import { ContributedTask, ConfiguringTask, KeyedTaskIdentifier, TaskExecution, Task, TaskEvent, TaskEventKind, PresentationOptions, CommandOptions, CommandConfiguration, RuntimeType, CustomTask, TaskScope, TaskSource, - TaskSourceKind, ExtensionTaskSource, RunOptions, TaskSet, TaskDefinition + TaskSourceKind, ExtensionTaskSource, RunOptions, TaskSet, TaskDefinition, TaskGroup } from 'vs/workbench/contrib/tasks/common/tasks'; @@ -320,9 +320,8 @@ namespace TaskDTO { hasDefinedMatchers: ContributedTask.is(task) ? task.hasDefinedMatchers : false, runOptions: RunOptionsDTO.from(task.runOptions), }; - if (task.configurationProperties.group) { - result.group = task.configurationProperties.group; - } + result.group = TaskGroup.from(task.configurationProperties.group); + if (task.configurationProperties.detail) { result.detail = task.configurationProperties.detail; } diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index b1d512084a8..753f3db414c 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -1227,7 +1227,9 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I SymbolKind: extHostTypes.SymbolKind, SymbolTag: extHostTypes.SymbolTag, Task: extHostTypes.Task, + Task2: extHostTypes.Task, TaskGroup: extHostTypes.TaskGroup, + TaskGroup2: extHostTypes.TaskGroup, TaskPanelKind: extHostTypes.TaskPanelKind, TaskRevealKind: extHostTypes.TaskRevealKind, TaskScope: extHostTypes.TaskScope, diff --git a/src/vs/workbench/api/common/extHostTask.ts b/src/vs/workbench/api/common/extHostTask.ts index 8f5d4a15977..90f8cf7df39 100644 --- a/src/vs/workbench/api/common/extHostTask.ts +++ b/src/vs/workbench/api/common/extHostTask.ts @@ -8,7 +8,7 @@ import { asPromise } from 'vs/base/common/async'; import { Event, Emitter } from 'vs/base/common/event'; import { MainContext, MainThreadTaskShape, ExtHostTaskShape } from 'vs/workbench/api/common/extHost.protocol'; - +import * as Objects from 'vs/base/common/objects'; import * as types from 'vs/workbench/api/common/extHostTypes'; import { IExtHostWorkspaceProvider, IExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace'; import type * as vscode from 'vscode'; @@ -213,6 +213,14 @@ export namespace TaskHandleDTO { }; } } +export namespace TaskGroupDTO { + export function from(value: vscode.TaskGroup2): tasks.TaskGroupDTO | undefined { + if (value === undefined || value === null) { + return undefined; + } + return { _id: value.id, isDefault: value.isDefault }; + } +} export namespace TaskDTO { export function fromMany(tasks: vscode.Task[], extension: IExtensionDescription): tasks.TaskDTO[] { @@ -257,7 +265,6 @@ export namespace TaskDTO { if (!definition || !scope) { return undefined; } - const group = (value.group as types.TaskGroup) ? (value.group as types.TaskGroup).id : undefined; const result: tasks.TaskDTO = { _id: (value as types.Task)._id!, definition, @@ -269,7 +276,7 @@ export namespace TaskDTO { }, execution: execution!, isBackground: value.isBackground, - group: group, + group: TaskGroupDTO.from(value.group as vscode.TaskGroup2), presentationOptions: TaskPresentationOptionsDTO.from(value.presentationOptions), problemMatchers: value.problemMatchers, hasDefinedMatchers: (value as types.Task).hasDefinedMatchers, @@ -311,7 +318,13 @@ export namespace TaskDTO { result.isBackground = value.isBackground; } if (value.group !== undefined) { - result.group = types.TaskGroup.from(value.group); + result.group = types.TaskGroup.from(value.group._id); + if (result.group) { + result.group = Objects.deepClone(result.group); + if (value.group.isDefault) { + result.group.isDefault = value.group.isDefault; + } + } } if (value.presentationOptions) { result.presentationOptions = TaskPresentationOptionsDTO.to(value.presentationOptions)!; diff --git a/src/vs/workbench/api/common/extHostTypes.ts b/src/vs/workbench/api/common/extHostTypes.ts index 59e5c7e9a8f..4ca4783febd 100644 --- a/src/vs/workbench/api/common/extHostTypes.ts +++ b/src/vs/workbench/api/common/extHostTypes.ts @@ -1762,8 +1762,9 @@ export enum TaskPanelKind { } @es5ClassCompat -export class TaskGroup implements vscode.TaskGroup { +export class TaskGroup implements vscode.TaskGroup2 { + isDefault?: boolean; private _id: string; public static Clean: TaskGroup = new TaskGroup('clean', 'Clean'); diff --git a/src/vs/workbench/api/common/shared/tasks.ts b/src/vs/workbench/api/common/shared/tasks.ts index 066b22f90ea..5f651acbc80 100644 --- a/src/vs/workbench/api/common/shared/tasks.ts +++ b/src/vs/workbench/api/common/shared/tasks.ts @@ -82,6 +82,11 @@ export interface TaskHandleDTO { workspaceFolder: UriComponents | string; } +export interface TaskGroupDTO { + isDefault?: boolean; + _id: string; +} + export interface TaskDTO { _id: string; name?: string; @@ -89,7 +94,7 @@ export interface TaskDTO { definition: TaskDefinitionDTO; isBackground?: boolean; source: TaskSourceDTO; - group?: string; + group?: TaskGroupDTO; detail?: string; presentationOptions?: TaskPresentationOptionsDTO; problemMatchers: string[]; diff --git a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts index 5aa40c75ea2..8b31cdab312 100644 --- a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts +++ b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts @@ -50,7 +50,7 @@ import { ITerminalProfileResolverService } from 'vs/workbench/contrib/terminal/c import { ITaskSystem, ITaskResolver, ITaskSummary, TaskExecuteKind, TaskError, TaskErrors, TaskTerminateResponse, TaskSystemInfo, ITaskExecuteResult } from 'vs/workbench/contrib/tasks/common/taskSystem'; import { Task, CustomTask, ConfiguringTask, ContributedTask, InMemoryTask, TaskEvent, - TaskSet, TaskGroup, GroupType, ExecutionEngine, JsonSchemaVersion, TaskSourceKind, + TaskSet, TaskGroup, ExecutionEngine, JsonSchemaVersion, TaskSourceKind, TaskSorter, TaskIdentifier, KeyedTaskIdentifier, TASK_RUNNING_STATE, TaskRunSource, KeyedTaskIdentifier as NKeyedTaskIdentifier, TaskDefinition, RuntimeType } from 'vs/workbench/contrib/tasks/common/tasks'; @@ -304,11 +304,11 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer this.configurationResolverService.contributeVariable('defaultBuildTask', async (): Promise => { let tasks = await this.getTasksForGroup(TaskGroup.Build); if (tasks.length > 0) { - let { defaults, users } = this.splitPerGroupType(tasks); + let { none, defaults } = this.splitPerGroupType(tasks); if (defaults.length === 1) { return defaults[0]._label; - } else if (defaults.length + users.length > 0) { - tasks = defaults.concat(users); + } else if (defaults.length + none.length > 0) { + tasks = defaults.concat(none); } } @@ -1100,12 +1100,13 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer return Promise.resolve(task); } - private getTasksForGroup(group: string): Promise { + private getTasksForGroup(group: TaskGroup): Promise { return this.getGroupedTasks().then((groups) => { let result: Task[] = []; groups.forEach((tasks) => { for (let task of tasks) { - if (task.configurationProperties.group === group) { + let configTaskGroup = TaskGroup.from(task.configurationProperties.group); + if (configTaskGroup?._id === group._id) { result.push(task); } } @@ -2600,20 +2601,17 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer }); } - private splitPerGroupType(tasks: Task[]): { none: Task[], defaults: Task[], users: Task[] } { + private splitPerGroupType(tasks: Task[]): { none: Task[], defaults: Task[] } { let none: Task[] = []; let defaults: Task[] = []; - let users: Task[] = []; for (let task of tasks) { - if (task.configurationProperties.groupType === GroupType.default) { + if ((task.configurationProperties.group as TaskGroup).isDefault) { defaults.push(task); - } else if (task.configurationProperties.groupType === GroupType.user) { - users.push(task); } else { none.push(task); } } - return { none, defaults, users }; + return { none, defaults }; } private runBuildCommand(): void { @@ -2632,9 +2630,12 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer const buildTasks: ConfiguringTask[] = []; for (const taskSource of tasks) { for (const task in taskSource[1].configurations?.byIdentifier) { - if ((taskSource[1].configurations?.byIdentifier[task].configurationProperties.group === TaskGroup.Build) && - (taskSource[1].configurations?.byIdentifier[task].configurationProperties.groupType === GroupType.default)) { - buildTasks.push(taskSource[1].configurations.byIdentifier[task]); + if (taskSource[1].configurations) { + const taskGroup: TaskGroup = taskSource[1].configurations.byIdentifier[task].configurationProperties.group as TaskGroup; + + if (taskGroup && taskGroup._id === TaskGroup.Build._id && taskGroup.isDefault) { + buildTasks.push(taskSource[1].configurations.byIdentifier[task]); + } } } } @@ -2649,14 +2650,14 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer return this.getTasksForGroup(TaskGroup.Build).then((tasks) => { if (tasks.length > 0) { - let { defaults, users } = this.splitPerGroupType(tasks); + let { none, defaults } = this.splitPerGroupType(tasks); if (defaults.length === 1) { this.run(defaults[0], undefined, TaskRunSource.User).then(undefined, reason => { // eat the error, it has already been surfaced to the user and we don't care about it here }); return; - } else if (defaults.length + users.length > 0) { - tasks = defaults.concat(users); + } else if (defaults.length + none.length > 0) { + tasks = defaults.concat(none); } } this.showIgnoredFoldersMessage().then(() => { @@ -2699,14 +2700,14 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer }; let promise = this.getTasksForGroup(TaskGroup.Test).then((tasks) => { if (tasks.length > 0) { - let { defaults, users } = this.splitPerGroupType(tasks); + let { none, defaults } = this.splitPerGroupType(tasks); if (defaults.length === 1) { this.run(defaults[0], undefined, TaskRunSource.User).then(undefined, reason => { // eat the error, it has already been surfaced to the user and we don't care about it here }); return; - } else if (defaults.length + users.length > 0) { - tasks = defaults.concat(users); + } else if (defaults.length + none.length > 0) { + tasks = defaults.concat(none); } } this.showIgnoredFoldersMessage().then(() => { @@ -3083,7 +3084,8 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer let selectedTask: Task | undefined; let selectedEntry: TaskQuickPickEntry; for (let task of tasks) { - if (task.configurationProperties.group === TaskGroup.Build && task.configurationProperties.groupType === GroupType.default) { + let taskGroup: TaskGroup | undefined = TaskGroup.from(task.configurationProperties.group); + if (taskGroup && taskGroup.isDefault && taskGroup._id === TaskGroup.Build._id) { selectedTask = task; break; } @@ -3135,7 +3137,8 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer let selectedEntry: TaskQuickPickEntry; for (let task of tasks) { - if (task.configurationProperties.group === TaskGroup.Test && task.configurationProperties.groupType === GroupType.default) { + let taskGroup: TaskGroup | undefined = TaskGroup.from(task.configurationProperties.group); + if (taskGroup && taskGroup.isDefault && taskGroup._id === TaskGroup.Test._id) { selectedTask = task; break; } diff --git a/src/vs/workbench/contrib/tasks/common/taskConfiguration.ts b/src/vs/workbench/contrib/tasks/common/taskConfiguration.ts index 7ef30c474d9..768091c597c 100644 --- a/src/vs/workbench/contrib/tasks/common/taskConfiguration.ts +++ b/src/vs/workbench/contrib/tasks/common/taskConfiguration.ts @@ -425,6 +425,7 @@ export interface BaseTaskRunnerConfiguration { * The group */ group?: string | GroupKind; + /** * Controls the behavior of the used terminal */ @@ -1230,24 +1231,18 @@ const partialSource: Partial = { }; namespace GroupKind { - export function from(this: void, external: string | GroupKind | undefined): [string, Tasks.GroupType] | undefined { + export function from(this: void, external: string | GroupKind | undefined): Tasks.TaskGroup | undefined { if (external === undefined) { return undefined; - } - if (Types.isString(external)) { - if (Tasks.TaskGroup.is(external)) { - return [external, Tasks.GroupType.user]; - } else { - return undefined; - } - } - if (!Types.isString(external.kind) || !Tasks.TaskGroup.is(external.kind)) { - return undefined; - } - let group: string = external.kind; - let isDefault: boolean = !!external.isDefault; + } else if (Types.isString(external) && Tasks.TaskGroup.is(external)) { + return { _id: external, isDefault: false }; + } else if (Types.isString(external.kind) && Tasks.TaskGroup.is(external.kind)) { + let group: string = external.kind; + let isDefault: boolean = !!external.isDefault; - return [group, isDefault ? Tasks.GroupType.default : Tasks.GroupType.user]; + return { _id: group, isDefault }; + } + return undefined; } } @@ -1325,18 +1320,7 @@ namespace ConfigurationProperties { if (external.promptOnClose !== undefined) { result.promptOnClose = !!external.promptOnClose; } - if (external.group !== undefined) { - if (Types.isString(external.group) && Tasks.TaskGroup.is(external.group)) { - result.group = external.group; - result.groupType = Tasks.GroupType.user; - } else { - let values = GroupKind.from(external.group); - if (values) { - result.group = values[0]; - result.groupType = values[1]; - } - } - } + result.group = GroupKind.from(external.group); if (external.dependsOn !== undefined) { if (Types.isArray(external.dependsOn)) { result.dependsOn = external.dependsOn.reduce((dependencies: Tasks.TaskDependency[], item): Tasks.TaskDependency[] => { @@ -1598,9 +1582,6 @@ namespace CustomTask { if (task.configurationProperties.problemMatchers === undefined) { task.configurationProperties.problemMatchers = EMPTY_ARRAY; } - if (task.configurationProperties.group !== undefined && task.configurationProperties.groupType === undefined) { - task.configurationProperties.groupType = Tasks.GroupType.user; - } } export function createCustomTask(contributedTask: Tasks.ContributedTask, configuredProps: Tasks.ConfiguringTask | Tasks.CustomTask): Tasks.CustomTask { @@ -1621,7 +1602,6 @@ namespace CustomTask { let resultConfigProps: Tasks.ConfigurationProperties = result.configurationProperties; assignProperty(resultConfigProps, configuredProps.configurationProperties, 'group'); - assignProperty(resultConfigProps, configuredProps.configurationProperties, 'groupType'); assignProperty(resultConfigProps, configuredProps.configurationProperties, 'isBackground'); assignProperty(resultConfigProps, configuredProps.configurationProperties, 'dependsOn'); assignProperty(resultConfigProps, configuredProps.configurationProperties, 'problemMatchers'); @@ -1634,7 +1614,6 @@ namespace CustomTask { let contributedConfigProps: Tasks.ConfigurationProperties = contributedTask.configurationProperties; fillProperty(resultConfigProps, contributedConfigProps, 'group'); - fillProperty(resultConfigProps, contributedConfigProps, 'groupType'); fillProperty(resultConfigProps, contributedConfigProps, 'isBackground'); fillProperty(resultConfigProps, contributedConfigProps, 'dependsOn'); fillProperty(resultConfigProps, contributedConfigProps, 'problemMatchers'); @@ -1752,10 +1731,8 @@ namespace TaskParser { } if ((defaultBuildTask.rank > -1) && (defaultBuildTask.rank < 2) && defaultBuildTask.task) { defaultBuildTask.task.configurationProperties.group = Tasks.TaskGroup.Build; - defaultBuildTask.task.configurationProperties.groupType = Tasks.GroupType.user; } else if ((defaultTestTask.rank > -1) && (defaultTestTask.rank < 2) && defaultTestTask.task) { defaultTestTask.task.configurationProperties.group = Tasks.TaskGroup.Test; - defaultTestTask.task.configurationProperties.groupType = Tasks.GroupType.user; } return result; @@ -2099,10 +2076,9 @@ class ConfigurationParser { problemMatchers: matchers, } ); - let value = GroupKind.from(fileConfig.group); - if (value) { - task.configurationProperties.group = value[0]; - task.configurationProperties.groupType = value[1]; + let taskGroupKind = GroupKind.from(fileConfig.group); + if (taskGroupKind !== undefined) { + task.configurationProperties.group = taskGroupKind; } else if (fileConfig.group === 'none') { task.configurationProperties.group = undefined; } diff --git a/src/vs/workbench/contrib/tasks/common/tasks.ts b/src/vs/workbench/contrib/tasks/common/tasks.ts index 5132be70c6d..44120aa2f58 100644 --- a/src/vs/workbench/contrib/tasks/common/tasks.ts +++ b/src/vs/workbench/contrib/tasks/common/tasks.ts @@ -365,21 +365,36 @@ export interface CommandConfiguration { } export namespace TaskGroup { - export const Clean: 'clean' = 'clean'; + export const Clean: TaskGroup = { _id: 'clean', isDefault: false }; - export const Build: 'build' = 'build'; + export const Build: TaskGroup = { _id: 'build', isDefault: false }; - export const Rebuild: 'rebuild' = 'rebuild'; + export const Rebuild: TaskGroup = { _id: 'rebuild', isDefault: false }; - export const Test: 'test' = 'test'; + export const Test: TaskGroup = { _id: 'test', isDefault: false }; - export function is(value: string): value is string { - return value === Clean || value === Build || value === Rebuild || value === Test; + export function is(value: any): value is string { + return value === Clean._id || value === Build._id || value === Rebuild._id || value === Test._id; + } + + export function from(value: string | TaskGroup | undefined): TaskGroup | undefined { + if (value === undefined) { + return undefined; + } else if (Types.isString(value)) { + if (is(value)) { + return { _id: value, isDefault: false }; + } + return undefined; + } else { + return value; + } } } -export type TaskGroup = 'clean' | 'build' | 'rebuild' | 'test'; - +export interface TaskGroup { + _id: string; + isDefault?: boolean; +} export const enum TaskScope { Global = 1, @@ -466,11 +481,6 @@ export interface TaskDependency { task: string | KeyedTaskIdentifier | undefined; } -export const enum GroupType { - default = 'default', - user = 'user' -} - export const enum DependsOrder { parallel = 'parallel', sequence = 'sequence' @@ -489,14 +499,9 @@ export interface ConfigurationProperties { identifier?: string; /** - * the task's group; + * The task's group; */ - group?: string; - - /** - * The group type - */ - groupType?: GroupType; + group?: string | TaskGroup; /** * The presentation options @@ -1076,7 +1081,7 @@ export interface TaskEvent { taskId?: string; taskName?: string; runType?: TaskRunType; - group?: string; + group?: string | TaskGroup; processId?: number; exitCode?: number; terminalId?: number; diff --git a/src/vs/workbench/contrib/tasks/test/common/configuration.test.ts b/src/vs/workbench/contrib/tasks/test/common/configuration.test.ts index 20833b41e47..003ddc19be1 100644 --- a/src/vs/workbench/contrib/tasks/test/common/configuration.test.ts +++ b/src/vs/workbench/contrib/tasks/test/common/configuration.test.ts @@ -7,6 +7,7 @@ import * as assert from 'assert'; import Severity from 'vs/base/common/severity'; import * as UUID from 'vs/base/common/uuid'; +import * as Types from 'vs/base/common/types'; import * as Platform from 'vs/base/common/platform'; import { ValidationStatus } from 'vs/base/common/parsers'; import { ProblemMatcher, FileLocationKind, ProblemPattern, ApplyToKind } from 'vs/workbench/contrib/tasks/common/problemMatcher'; @@ -214,14 +215,8 @@ class CustomTaskBuilder { return this; } - public group(value: Tasks.TaskGroup): CustomTaskBuilder { + public group(value: string | Tasks.TaskGroup): CustomTaskBuilder { this.result.configurationProperties.group = value; - this.result.configurationProperties.groupType = Tasks.GroupType.user; - return this; - } - - public groupType(value: Tasks.GroupType): CustomTaskBuilder { - this.result.configurationProperties.groupType = value; return this; } @@ -453,8 +448,10 @@ function assertConfiguration(result: ParseResult, expected: Tasks.Task[]): void assert.ok(!actualTasks[task.configurationProperties.name!]); actualTasks[task.configurationProperties.name!] = task; actualId2Name[task._id] = task.configurationProperties.name!; - if (task.configurationProperties.group) { - actualTaskGroups.add(task.configurationProperties.group, task); + + let taskId = Tasks.TaskGroup.from(task.configurationProperties.group)?._id; + if (taskId) { + actualTaskGroups.add(taskId, task); } }); let expectedTasks: { [key: string]: Tasks.Task; } = Object.create(null); @@ -462,8 +459,9 @@ function assertConfiguration(result: ParseResult, expected: Tasks.Task[]): void expected.forEach(task => { assert.ok(!expectedTasks[task.configurationProperties.name!]); expectedTasks[task.configurationProperties.name!] = task; - if (task.configurationProperties.group) { - expectedTaskGroup.add(task.configurationProperties.group, task); + let taskId = Tasks.TaskGroup.from(task.configurationProperties.group)?._id; + if (taskId) { + expectedTaskGroup.add(taskId, task); } }); let actualKeys = Object.keys(actualTasks); @@ -486,14 +484,22 @@ function assertTask(actual: Tasks.Task, expected: Tasks.Task) { assert.strictEqual(actual.configurationProperties.isBackground, expected.configurationProperties.isBackground, 'isBackground'); assert.strictEqual(typeof actual.configurationProperties.problemMatchers, typeof expected.configurationProperties.problemMatchers); assert.strictEqual(actual.configurationProperties.promptOnClose, expected.configurationProperties.promptOnClose, 'promptOnClose'); - assert.strictEqual(actual.configurationProperties.group, expected.configurationProperties.group, 'group'); - assert.strictEqual(actual.configurationProperties.groupType, expected.configurationProperties.groupType, 'groupType'); + assert.strictEqual(typeof actual.configurationProperties.group, typeof expected.configurationProperties.group, `group types unequal`); + if (actual.configurationProperties.problemMatchers && expected.configurationProperties.problemMatchers) { assert.strictEqual(actual.configurationProperties.problemMatchers.length, expected.configurationProperties.problemMatchers.length); for (let i = 0; i < actual.configurationProperties.problemMatchers.length; i++) { assertProblemMatcher(actual.configurationProperties.problemMatchers[i], expected.configurationProperties.problemMatchers[i]); } } + + if (actual.configurationProperties.group && expected.configurationProperties.group) { + if (Types.isString(actual.configurationProperties.group)) { + assert.strictEqual(actual.configurationProperties.group, expected.configurationProperties.group); + } else { + assertGroup(actual.configurationProperties.group as Tasks.TaskGroup, expected.configurationProperties.group as Tasks.TaskGroup); + } + } } function assertCommandConfiguration(actual: Tasks.CommandConfiguration, expected: Tasks.CommandConfiguration) { @@ -516,6 +522,14 @@ function assertCommandConfiguration(actual: Tasks.CommandConfiguration, expected } } +function assertGroup(actual: Tasks.TaskGroup, expected: Tasks.TaskGroup) { + assert.strictEqual(typeof actual, typeof expected); + if (actual && expected) { + assert.strictEqual(actual._id, expected._id, `group ids unequal. actual: ${actual._id} expected ${expected._id}`); + assert.strictEqual(actual.isDefault, expected.isDefault, `group defaults unequal. actual: ${actual.isDefault} expected ${expected.isDefault}`); + } +} + function assertPresentation(actual: Tasks.PresentationOptions, expected: Tasks.PresentationOptions) { assert.strictEqual(typeof actual, typeof expected); if (actual && expected) { @@ -1534,9 +1548,10 @@ suite('Tasks version 2.0.0', () => { group: { kind: 'build', isDefault: true } }; let builder = new ConfiguationBuilder(); + let taskGroup = Tasks.TaskGroup.Build; + taskGroup.isDefault = true; builder.task('dir', 'dir'). - group(Tasks.TaskGroup.Build). - groupType(Tasks.GroupType.default). + group(taskGroup). command().suppressTaskName(true). runtime(Tasks.RuntimeType.Shell). presentation().echo(true); @@ -1594,9 +1609,10 @@ suite('Tasks version 2.0.0', () => { ] }; let builder = new ConfiguationBuilder(); + let taskGroup = Tasks.TaskGroup.Build; + taskGroup.isDefault = true; builder.task('dir', 'dir'). - group(Tasks.TaskGroup.Build). - groupType(Tasks.GroupType.default). + group(taskGroup). command().suppressTaskName(true). runtime(Tasks.RuntimeType.Shell). presentation().echo(true);