From 48975dc0802f01b021d7d49baaafc1a85e66caf8 Mon Sep 17 00:00:00 2001 From: headerjson <86501330+headerjson@users.noreply.github.com> Date: Thu, 15 Jul 2021 06:42:12 -0700 Subject: [PATCH] Add isDefault to TaskGroup API (#128596) * first pass at adding api (cherry picked from commit 8a583c52ee747568537ff24829342d4c1e4b0f05) * add task2 remaining changes * remove unnecessary changes * modify tasks.json directly for test * reset tasks in test * Fix compilation errors Co-authored-by: Alex Ross --- .../workspace.tasks.test.ts | 34 ++++++++++++++++++- src/vs/vscode.proposed.d.ts | 14 ++++++++ .../workbench/api/common/extHost.api.impl.ts | 2 ++ src/vs/workbench/api/common/extHostTask.ts | 21 +++++++++--- src/vs/workbench/api/common/extHostTypes.ts | 3 +- src/vs/workbench/api/common/shared/tasks.ts | 7 +++- .../tasks/browser/abstractTaskService.ts | 4 +-- .../contrib/tasks/common/taskConfiguration.ts | 6 ++-- .../workbench/contrib/tasks/common/tasks.ts | 24 +++++++------ .../tasks/test/common/configuration.test.ts | 4 +-- 10 files changed, 94 insertions(+), 25 deletions(-) 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 722b387e3a7..7df258b41d3 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -933,6 +933,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/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index aa809be5a6b..dc6d45f3483 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -1223,7 +1223,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 c7611205f4d..ecccb1ab076 100644 --- a/src/vs/workbench/api/common/extHostTypes.ts +++ b/src/vs/workbench/api/common/extHostTypes.ts @@ -1755,8 +1755,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..b0bc626e7d8 100644 --- a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts +++ b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts @@ -1100,12 +1100,12 @@ 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) { + if (task.configurationProperties.group?._id === group._id) { result.push(task); } } diff --git a/src/vs/workbench/contrib/tasks/common/taskConfiguration.ts b/src/vs/workbench/contrib/tasks/common/taskConfiguration.ts index 7ef30c474d9..8636375b478 100644 --- a/src/vs/workbench/contrib/tasks/common/taskConfiguration.ts +++ b/src/vs/workbench/contrib/tasks/common/taskConfiguration.ts @@ -1230,7 +1230,7 @@ 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, Tasks.GroupType] | undefined { if (external === undefined) { return undefined; } @@ -1247,7 +1247,7 @@ namespace GroupKind { let group: string = external.kind; let isDefault: boolean = !!external.isDefault; - return [group, isDefault ? Tasks.GroupType.default : Tasks.GroupType.user]; + return [{ _id: group, isDefault }, isDefault ? Tasks.GroupType.default : Tasks.GroupType.user]; } } @@ -1326,7 +1326,7 @@ namespace ConfigurationProperties { result.promptOnClose = !!external.promptOnClose; } if (external.group !== undefined) { - if (Types.isString(external.group) && Tasks.TaskGroup.is(external.group)) { + if ((external.group as Tasks.TaskGroup) && Tasks.TaskGroup.is(external.group)) { result.group = external.group; result.groupType = Tasks.GroupType.user; } else { diff --git a/src/vs/workbench/contrib/tasks/common/tasks.ts b/src/vs/workbench/contrib/tasks/common/tasks.ts index 9bbb50cfdfa..9c4af5e78fc 100644 --- a/src/vs/workbench/contrib/tasks/common/tasks.ts +++ b/src/vs/workbench/contrib/tasks/common/tasks.ts @@ -365,21 +365,23 @@ 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 TaskGroup { + return value === Clean._id || value === Build._id || value === Rebuild._id || value === Test._id; } } -export type TaskGroup = 'clean' | 'build' | 'rebuild' | 'test'; - +export interface TaskGroup { + _id: string; + isDefault?: boolean; +} export const enum TaskScope { Global = 1, @@ -489,9 +491,9 @@ export interface ConfigurationProperties { identifier?: string; /** - * the task's group; + * The task's group; */ - group?: string; + group?: TaskGroup; /** * The group type @@ -1076,7 +1078,7 @@ export interface TaskEvent { taskId?: string; taskName?: string; runType?: TaskRunType; - group?: string; + group?: 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 9b1a369523a..fa3320d504f 100644 --- a/src/vs/workbench/contrib/tasks/test/common/configuration.test.ts +++ b/src/vs/workbench/contrib/tasks/test/common/configuration.test.ts @@ -454,7 +454,7 @@ function assertConfiguration(result: ParseResult, expected: Tasks.Task[]): void actualTasks[task.configurationProperties.name!] = task; actualId2Name[task._id] = task.configurationProperties.name!; if (task.configurationProperties.group) { - actualTaskGroups.add(task.configurationProperties.group, task); + actualTaskGroups.add(task.configurationProperties.group._id, task); } }); let expectedTasks: { [key: string]: Tasks.Task; } = Object.create(null); @@ -463,7 +463,7 @@ function assertConfiguration(result: ParseResult, expected: Tasks.Task[]): void assert.ok(!expectedTasks[task.configurationProperties.name!]); expectedTasks[task.configurationProperties.name!] = task; if (task.configurationProperties.group) { - expectedTaskGroup.add(task.configurationProperties.group, task); + expectedTaskGroup.add(task.configurationProperties.group._id, task); } }); let actualKeys = Object.keys(actualTasks);