From f42682d725b5b62d2d381a982867a9af4ba460a0 Mon Sep 17 00:00:00 2001 From: Liang Huang Date: Sat, 7 Dec 2019 23:39:01 -0500 Subject: [PATCH] search detected tasks by scope This pull request adds the support of detected tasks that have - same label, and - different scopes in a multi-root workspace. This change fixes #6715. Signed-off-by: Liang Huang --- .../browser/provided-task-configurations.ts | 36 +++++++++++------ packages/task/src/browser/quick-open-task.ts | 39 +++++++++++-------- .../src/browser/task-frontend-contribution.ts | 4 +- packages/task/src/browser/task-service.ts | 8 ++-- 4 files changed, 54 insertions(+), 33 deletions(-) diff --git a/packages/task/src/browser/provided-task-configurations.ts b/packages/task/src/browser/provided-task-configurations.ts index cf40340081dc3..496d10220bd42 100644 --- a/packages/task/src/browser/provided-task-configurations.ts +++ b/packages/task/src/browser/provided-task-configurations.ts @@ -25,9 +25,10 @@ export class ProvidedTaskConfigurations { /** * Map of source (name of extension, or path of root folder that the task config comes from) and `task config map`. - * For the inner map (i.e., `task config map`), the key is task label and value TaskConfiguration + * For the second level of inner map, the key is task label. + * For the third level of inner map, the key is the task scope and value TaskConfiguration. */ - protected tasksMap = new Map>(); + protected tasksMap = new Map>>(); @inject(TaskProviderRegistry) protected readonly taskProviderRegistry: TaskProviderRegistry; @@ -45,13 +46,13 @@ export class ProvidedTaskConfigurations { } /** returns the task configuration for a given source and label or undefined if none */ - async getTask(source: string, taskLabel: string): Promise { - const task = this.getCachedTask(source, taskLabel); + async getTask(source: string, taskLabel: string, scope?: string): Promise { + const task = this.getCachedTask(source, taskLabel, scope); if (task) { return task; } else { await this.getTasks(); - return this.getCachedTask(source, taskLabel); + return this.getCachedTask(source, taskLabel, scope); } } @@ -100,10 +101,13 @@ export class ProvidedTaskConfigurations { return matchedTask; } - protected getCachedTask(source: string, taskLabel: string): TaskConfiguration | undefined { + protected getCachedTask(source: string, taskLabel: string, scope?: string): TaskConfiguration | undefined { const labelConfigMap = this.tasksMap.get(source); if (labelConfigMap) { - return labelConfigMap.get(taskLabel); + const scopeConfigMap = labelConfigMap.get(taskLabel); + if (scopeConfigMap) { + return scopeConfigMap.get(scope); + } } } @@ -111,12 +115,22 @@ export class ProvidedTaskConfigurations { for (const task of tasks) { const label = task.label; const source = task._source; + const scope = task._scope; if (this.tasksMap.has(source)) { - this.tasksMap.get(source)!.set(label, task); + const labelConfigMap = this.tasksMap.get(source)!; + if (labelConfigMap.has(label)) { + labelConfigMap.get(label)!.set(scope, task); + } else { + const newScopeConfigMap = new Map(); + newScopeConfigMap.set(scope, task); + labelConfigMap.set(label, newScopeConfigMap); + } } else { - const labelTaskMap = new Map(); - labelTaskMap.set(label, task); - this.tasksMap.set(source, labelTaskMap); + const newLabelConfigMap = new Map>(); + const newScopeConfigMap = new Map(); + newScopeConfigMap.set(scope, task); + newLabelConfigMap.set(label, newScopeConfigMap); + this.tasksMap.set(source, newLabelConfigMap); } } } diff --git a/packages/task/src/browser/quick-open-task.ts b/packages/task/src/browser/quick-open-task.ts index 8a4949d4e49e4..6d42684fdf6db 100644 --- a/packages/task/src/browser/quick-open-task.ts +++ b/packages/task/src/browser/quick-open-task.ts @@ -27,6 +27,7 @@ import { FileSystem } from '@theia/filesystem/lib/common'; import { QuickOpenModel, QuickOpenItem, QuickOpenActionProvider, QuickOpenMode, QuickOpenGroupItem, QuickOpenGroupItemOptions } from '@theia/core/lib/common/quick-open-model'; import { PreferenceService } from '@theia/core/lib/browser'; import { TaskNameResolver } from './task-name-resolver'; +import { TaskSourceResolver } from './task-source-resolver'; import { TaskConfigurationManager } from './task-configuration-manager'; @injectable() @@ -57,6 +58,9 @@ export class QuickOpenTask implements QuickOpenModel, QuickOpenHandler { @inject(TaskNameResolver) protected readonly taskNameResolver: TaskNameResolver; + @inject(TaskSourceResolver) + protected readonly taskSourceResolver: TaskSourceResolver; + @inject(FileSystem) protected readonly fileSystem: FileSystem; @@ -80,8 +84,7 @@ export class QuickOpenTask implements QuickOpenModel, QuickOpenHandler { const item = new TaskRunQuickOpenItem(task, this.taskService, isMulti, { groupLabel: index === 0 ? 'recently used tasks' : undefined, showBorder: false - }, this.taskNameResolver); - item['taskDefinitionRegistry'] = this.taskDefinitionRegistry; + }, this.taskDefinitionRegistry, this.taskNameResolver, this.taskSourceResolver); return item; }), ...filteredConfiguredTasks.map((task, index) => { @@ -92,8 +95,7 @@ export class QuickOpenTask implements QuickOpenModel, QuickOpenHandler { ? false : index === 0 ? true : false ) - }, this.taskNameResolver); - item['taskDefinitionRegistry'] = this.taskDefinitionRegistry; + }, this.taskDefinitionRegistry, this.taskNameResolver, this.taskSourceResolver); return item; }), ...filteredProvidedTasks.map((task, index) => { @@ -104,8 +106,7 @@ export class QuickOpenTask implements QuickOpenModel, QuickOpenHandler { ? false : index === 0 ? true : false ) - }, this.taskNameResolver); - item['taskDefinitionRegistry'] = this.taskDefinitionRegistry; + }, this.taskDefinitionRegistry, this.taskNameResolver, this.taskSourceResolver); return item; }) ); @@ -281,10 +282,12 @@ export class QuickOpenTask implements QuickOpenModel, QuickOpenHandler { if (defaultBuildOrTestTasks.length === 1) { // run the default build / test task const defaultBuildOrTestTask = defaultBuildOrTestTasks[0]; const taskToRun = (defaultBuildOrTestTask as TaskRunQuickOpenItem).getTask(); + const scope = this.taskSourceResolver.resolve(taskToRun); + if (this.taskDefinitionRegistry && !!this.taskDefinitionRegistry.getDefinition(taskToRun)) { - this.taskService.run(taskToRun.source, taskToRun.label); + this.taskService.run(taskToRun.source, taskToRun.label, scope); } else { - this.taskService.run(taskToRun._source, taskToRun.label); + this.taskService.run(taskToRun._source, taskToRun.label, scope); } return; } @@ -311,9 +314,10 @@ export class QuickOpenTask implements QuickOpenModel, QuickOpenHandler { item.options, this.taskNameResolver, shouldRunBuildTask, - this.taskConfigurationManager + this.taskConfigurationManager, + this.taskDefinitionRegistry, + this.taskSourceResolver ); - newItem['taskDefinitionRegistry'] = this.taskDefinitionRegistry; return newItem; }); this.quickOpenService.open(this, { @@ -408,14 +412,14 @@ export class QuickOpenTask implements QuickOpenModel, QuickOpenHandler { export class TaskRunQuickOpenItem extends QuickOpenGroupItem { - protected taskDefinitionRegistry: TaskDefinitionRegistry; - constructor( protected readonly task: TaskConfiguration, protected taskService: TaskService, protected isMulti: boolean, public readonly options: QuickOpenGroupItemOptions, + protected readonly taskDefinitionRegistry: TaskDefinitionRegistry, protected readonly taskNameResolver: TaskNameResolver, + protected readonly taskSourceResolver: TaskSourceResolver ) { super(options); } @@ -452,10 +456,11 @@ export class TaskRunQuickOpenItem extends QuickOpenGroupItem { return false; } + const scope = this.taskSourceResolver.resolve(this.task); if (this.taskDefinitionRegistry && !!this.taskDefinitionRegistry.getDefinition(this.task)) { - this.taskService.run(this.task.source || this.task._source, this.task.label); + this.taskService.run(this.task.source || this.task._source, this.task.label, scope); } else { - this.taskService.run(this.task._source, this.task.label); + this.taskService.run(this.task._source, this.task.label, scope); } return true; } @@ -469,9 +474,11 @@ export class ConfigureBuildOrTestTaskQuickOpenItem extends TaskRunQuickOpenItem public readonly options: QuickOpenGroupItemOptions, protected readonly taskNameResolver: TaskNameResolver, protected readonly isBuildTask: boolean, - protected taskConfigurationManager: TaskConfigurationManager + protected taskConfigurationManager: TaskConfigurationManager, + protected readonly taskDefinitionRegistry: TaskDefinitionRegistry, + protected readonly taskSourceResolver: TaskSourceResolver ) { - super(task, taskService, isMulti, options, taskNameResolver); + super(task, taskService, isMulti, options, taskDefinitionRegistry, taskNameResolver, taskSourceResolver); } run(mode: QuickOpenMode): boolean { diff --git a/packages/task/src/browser/task-frontend-contribution.ts b/packages/task/src/browser/task-frontend-contribution.ts index ff53f78064fcb..2106c0af76a0d 100644 --- a/packages/task/src/browser/task-frontend-contribution.ts +++ b/packages/task/src/browser/task-frontend-contribution.ts @@ -217,9 +217,9 @@ export class TaskFrontendContribution implements CommandContribution, MenuContri isEnabled: () => true, // tslint:disable-next-line:no-any execute: (...args: any[]) => { - const [source, label] = args; + const [source, label, scope] = args; if (source && label) { - return this.taskService.run(source, label); + return this.taskService.run(source, label, scope); } return this.quickOpenTask.open(); } diff --git a/packages/task/src/browser/task-service.ts b/packages/task/src/browser/task-service.ts index 7b6a00b39a1d6..809ca34f43139 100644 --- a/packages/task/src/browser/task-service.ts +++ b/packages/task/src/browser/task-service.ts @@ -318,8 +318,8 @@ export class TaskService implements TaskConfigurationClient { * Returns a task configuration provided by an extension by task source and label. * If there are no task configuration, returns undefined. */ - async getProvidedTask(source: string, label: string): Promise { - return this.providedTaskConfigurations.getTask(source, label); + async getProvidedTask(source: string, label: string, scope?: string): Promise { + return this.providedTaskConfigurations.getTask(source, label, scope); } /** Returns an array of running tasks 'TaskInfo' objects */ @@ -370,8 +370,8 @@ export class TaskService implements TaskConfigurationClient { * Runs a task, by the source and label of the task configuration. * It looks for configured and detected tasks. */ - async run(source: string, taskLabel: string): Promise { - let task = await this.getProvidedTask(source, taskLabel); + async run(source: string, taskLabel: string, scope?: string): Promise { + let task = await this.getProvidedTask(source, taskLabel, scope); if (!task) { // if a detected task cannot be found, search from tasks.json task = this.taskConfigurations.getTask(source, taskLabel); if (!task) {