diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b677c92cf925..334a8ab3eb2b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ Breaking changes: - [task] `TaskService.getConfiguredTasks()` returns `Promise` instead of `TaskConfiguration[]` [#5777](https://github.com/theia-ide/theia/pull/5777) - [plugin] files from 'plugin-ext/src/api' moved to 'plugin-ext/src/common', renamed 'model.ts' to 'plugin-api-rpc-model.ts', 'plugin-api.ts' to 'plugin-api-rpc.ts' +- [task] ensure that plugin tasks are registered before accessing them [5869](https://github.com/theia-ide/theia/pull/5869) + - `TaskProviderRegistry` and `TaskResolverRegistry` are promisified Breaking changes: - [shell][plugin] integrated view containers and views [#5665](https://github.com/theia-ide/theia/pull/5665) diff --git a/packages/cpp/src/browser/cpp-task-provider.ts b/packages/cpp/src/browser/cpp-task-provider.ts index 7bc023c9fb0af..1754dd7e60351 100644 --- a/packages/cpp/src/browser/cpp-task-provider.ts +++ b/packages/cpp/src/browser/cpp-task-provider.ts @@ -78,7 +78,7 @@ export class CppTaskProvider implements TaskContribution, TaskProvider, TaskReso } async resolveTask(task: CppBuildTaskConfiguration): Promise { - const resolver = this.taskResolverRegistry.getResolver('shell'); + const resolver = await this.taskResolverRegistry.getResolver('shell'); if (!resolver) { throw new Error('No shell resolver found, cannot build.'); } diff --git a/packages/plugin-ext/src/hosted/browser/hosted-plugin.ts b/packages/plugin-ext/src/hosted/browser/hosted-plugin.ts index 076a1a667eb87..bd4c86a261fe8 100644 --- a/packages/plugin-ext/src/hosted/browser/hosted-plugin.ts +++ b/packages/plugin-ext/src/hosted/browser/hosted-plugin.ts @@ -49,6 +49,7 @@ import { FileSearchService } from '@theia/file-search/lib/common/file-search-ser import { isCancelled } from '@theia/core'; import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state'; import { PluginViewRegistry } from '../../main/browser/view/plugin-view-registry'; +import { TaskProviderRegistry, TaskResolverRegistry } from '@theia/task/lib/browser/task-contribution'; export type PluginHost = 'frontend' | string; export type DebugActivationEvent = 'onDebugResolve' | 'onDebugInitialConfigurations' | 'onDebugAdapterProtocolTracker'; @@ -112,6 +113,12 @@ export class HostedPluginSupport { @inject(PluginViewRegistry) protected readonly viewRegistry: PluginViewRegistry; + @inject(TaskProviderRegistry) + protected readonly taskProviderRegistry: TaskProviderRegistry; + + @inject(TaskResolverRegistry) + protected readonly taskResolverRegistry: TaskResolverRegistry; + private theiaReadyPromise: Promise; protected readonly managers: PluginManagerExt[] = []; @@ -135,6 +142,8 @@ export class HostedPluginSupport { this.debugSessionManager.onWillResolveDebugConfiguration(event => this.ensureDebugActivation(event, 'onDebugResolve', event.debugType)); this.debugConfigurationManager.onWillProvideDebugConfiguration(event => this.ensureDebugActivation(event, 'onDebugInitialConfigurations')); this.viewRegistry.onDidExpandView(id => this.activateByView(id)); + this.taskProviderRegistry.onWillProvideTaskProvider(event => this.ensureTaskActivation(event)); + this.taskResolverRegistry.onWillProvideTaskResolver(event => this.ensureTaskActivation(event)); } checkAndLoadPlugin(container: interfaces.Container): void { @@ -290,6 +299,10 @@ export class HostedPluginSupport { event.waitUntil(p); } + protected ensureTaskActivation(event: WaitUntilEvent): void { + event.waitUntil(this.activateByCommand('workbench.action.tasks.runTask')); + } + protected ensureDebugActivation(event: WaitUntilEvent, activationEvent?: DebugActivationEvent, debugType?: string): void { event.waitUntil(this.activateByDebug(activationEvent, debugType)); } diff --git a/packages/task/src/browser/provided-task-configurations.ts b/packages/task/src/browser/provided-task-configurations.ts index 11dfee12c2432..cf40340081dc3 100644 --- a/packages/task/src/browser/provided-task-configurations.ts +++ b/packages/task/src/browser/provided-task-configurations.ts @@ -37,7 +37,7 @@ export class ProvidedTaskConfigurations { /** returns a list of provided tasks */ async getTasks(): Promise { - const providers = this.taskProviderRegistry.getProviders(); + const providers = await this.taskProviderRegistry.getProviders(); const providedTasks: TaskConfiguration[] = (await Promise.all(providers.map(p => p.provideTasks()))) .reduce((acc, taskArray) => acc.concat(taskArray), []); this.cacheTasks(providedTasks); diff --git a/packages/task/src/browser/task-contribution.ts b/packages/task/src/browser/task-contribution.ts index 7693e3119d644..8cd2df128857e 100644 --- a/packages/task/src/browser/task-contribution.ts +++ b/packages/task/src/browser/task-contribution.ts @@ -17,6 +17,7 @@ import { injectable, postConstruct } from 'inversify'; import { Disposable } from '@theia/core/lib/common/disposable'; import { TaskConfiguration } from '../common/task-protocol'; +import { WaitUntilEvent, Emitter } from '@theia/core/lib/common/event'; export const TaskContribution = Symbol('TaskContribution'); @@ -39,6 +40,9 @@ export interface TaskProvider { @injectable() export class TaskResolverRegistry { + protected readonly onWillProvideTaskResolverEmitter = new Emitter(); + readonly onWillProvideTaskResolver = this.onWillProvideTaskResolverEmitter.event; + protected resolvers: Map; @postConstruct() @@ -54,7 +58,8 @@ export class TaskResolverRegistry { }; } - getResolver(type: string): TaskResolver | undefined { + async getResolver(type: string): Promise { + await WaitUntilEvent.fire(this.onWillProvideTaskResolverEmitter, {}); return this.resolvers.get(type); } } @@ -62,6 +67,9 @@ export class TaskResolverRegistry { @injectable() export class TaskProviderRegistry { + protected readonly onWillProvideTaskProviderEmitter = new Emitter(); + readonly onWillProvideTaskProvider = this.onWillProvideTaskProviderEmitter.event; + protected providers: Map; @postConstruct() @@ -78,12 +86,14 @@ export class TaskProviderRegistry { }; } - getProvider(type: string): TaskProvider | undefined { + async getProvider(type: string): Promise { + await WaitUntilEvent.fire(this.onWillProvideTaskProviderEmitter, {}); return this.providers.get(type); } /** Returns all registered Task Providers. */ - getProviders(): TaskProvider[] { + async getProviders(): Promise { + await WaitUntilEvent.fire(this.onWillProvideTaskProviderEmitter, {}); return [...this.providers.values()]; } } diff --git a/packages/task/src/browser/task-service.ts b/packages/task/src/browser/task-service.ts index f98f6164ee02e..5ce0c6f31d288 100644 --- a/packages/task/src/browser/task-service.ts +++ b/packages/task/src/browser/task-service.ts @@ -366,7 +366,7 @@ export class TaskService implements TaskConfigurationClient { } } - const resolver = this.taskResolverRegistry.getResolver(task.type); + const resolver = await this.taskResolverRegistry.getResolver(task.type); let resolvedTask: TaskConfiguration; try { resolvedTask = resolver ? await resolver.resolveTask(task) : task; diff --git a/tsconfig.json b/tsconfig.json index 89626631288c6..fe54e5e4da180 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -126,6 +126,9 @@ ], "@theia/userstorage/lib/*": [ "packages/userstorage/src/*" + ], + "@theia/task/lib/*": [ + "packages/task/src/*" ] }, "plugins": [