diff --git a/CHANGELOG.md b/CHANGELOG.md index 37689bb96ee67..4a3e48df83c6c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,11 +5,13 @@ - [Previous Changelogs](https://github.com/eclipse-theia/theia/tree/master/doc/changelogs/) -## v1.38.0 - 04/27/2023 +## v1.38.0 - 05/25/2023 [Breaking Changes:](#breaking_changes_1.38.0) - [core] moved `ToolbarAwareTabBar.Styles` to `ScrollableTabBar.Styles` [12411](https://github.com/eclipse-theia/theia/pull/12411/) +- [debug] Change the return type of (method) `DebugConfigurationManager.provideDynamicDebugConfigurations()` to
+`Promise>` [#12482](https://github.com/eclipse-theia/theia/pull/12482) ## v1.37.0 - 04/27/2023 diff --git a/packages/debug/src/browser/debug-configuration-manager.ts b/packages/debug/src/browser/debug-configuration-manager.ts index c4996ba79318e..d9ee87e0756ff 100644 --- a/packages/debug/src/browser/debug-configuration-manager.ts +++ b/packages/debug/src/browser/debug-configuration-manager.ts @@ -178,8 +178,8 @@ export class DebugConfigurationManager { // Refresh a dynamic configuration from the provider. // This allow providers to update properties before the execution e.g. program - const { providerType, configuration: { name } } = this._currentOptions; - const configuration = await this.fetchDynamicDebugConfiguration(name, providerType); + const { providerType, workspaceFolderUri, configuration: { name } } = this._currentOptions; + const configuration = await this.fetchDynamicDebugConfiguration(name, providerType, workspaceFolderUri); if (!configuration) { const message = nls.localize( @@ -188,7 +188,7 @@ export class DebugConfigurationManager { throw new Error(message); } - return { name, configuration, providerType }; + return { name, configuration, providerType, workspaceFolderUri }; } set current(option: DebugSessionOptions | undefined) { @@ -215,7 +215,8 @@ export class DebugConfigurationManager { protected dynamicOptionsMatch(one: DynamicDebugConfigurationSessionOptions, other: DynamicDebugConfigurationSessionOptions): boolean { return one.providerType !== undefined && one.configuration.name === other.configuration.name - && one.providerType === other.providerType; + && one.providerType === other.providerType + && one.workspaceFolderUri === other.workspaceFolderUri; } get recentDynamicOptions(): readonly DynamicDebugConfigurationSessionOptions[] { @@ -462,14 +463,40 @@ export class DebugConfigurationManager { await WaitUntilEvent.fire(this.onWillProvideDebugConfigurationEmitter, {}); } - async provideDynamicDebugConfigurations(): Promise> { + async provideDynamicDebugConfigurations(): Promise> { await this.fireWillProvideDynamicDebugConfiguration(); - return this.debug.provideDynamicDebugConfigurations!(); + const roots = this.workspaceService.tryGetRoots(); + const promises = roots.map(async root => { + const configsMap = await this.debug.provideDynamicDebugConfigurations!(root.resource.toString()); + const optionsMap = Object.fromEntries(Object.entries(configsMap).map(([type, configs]) => { + const options = configs.map(config => ({ + name: config.name, + providerType: type, + configuration: config, + workspaceFolderUri: root.resource.toString() + })); + return [type, options]; + })); + return optionsMap; + }); + + const typesToOptionsRecords = await Promise.all(promises); + const consolidatedTypesToOptions: Record = {}; + + for (const typesToOptionsInstance of typesToOptionsRecords) { + for (const [providerType, configurationsOptions] of Object.entries(typesToOptionsInstance)) { + if (!consolidatedTypesToOptions[providerType]) { + consolidatedTypesToOptions[providerType] = []; + } + consolidatedTypesToOptions[providerType].push(...configurationsOptions); + } + } + return consolidatedTypesToOptions; } - async fetchDynamicDebugConfiguration(name: string, type: string): Promise { + async fetchDynamicDebugConfiguration(name: string, type: string, folder?: string): Promise { await this.fireWillProvideDynamicDebugConfiguration(); - return this.debug.fetchDynamicDebugConfiguration(name, type); + return this.debug.fetchDynamicDebugConfiguration(name, type, folder); } protected async fireWillProvideDynamicDebugConfiguration(): Promise { diff --git a/packages/debug/src/browser/debug-prefix-configuration.ts b/packages/debug/src/browser/debug-prefix-configuration.ts index 70bbcc6330f2e..613b5c4d71c47 100644 --- a/packages/debug/src/browser/debug-prefix-configuration.ts +++ b/packages/debug/src/browser/debug-prefix-configuration.ts @@ -107,6 +107,12 @@ export class DebugPrefixConfiguration implements CommandContribution, CommandHan }); } + protected resolveRootFolderName(uri: string | undefined): string | undefined { + return uri && this.workspaceService.isMultiRootWorkspaceOpened + ? this.labelProvider.getName(new URI(uri)) + : ''; + } + async getPicks(filter: string, token: CancellationToken): Promise { const items: QuickPickItemOrSeparator[] = []; const configurations = this.debugConfigurationManager.all; @@ -114,27 +120,26 @@ export class DebugPrefixConfiguration implements CommandContribution, CommandHan for (const config of configurations) { items.push({ label: config.name, - description: this.workspaceService.isMultiRootWorkspaceOpened - ? this.labelProvider.getName(new URI(config.workspaceFolderUri)) - : '', + description: this.resolveRootFolderName(config.workspaceFolderUri), execute: () => this.runConfiguration(config) }); } // Resolve dynamic configurations from providers const record = await this.debugConfigurationManager.provideDynamicDebugConfigurations(); - for (const [providerType, dynamicConfigurations] of Object.entries(record)) { - if (dynamicConfigurations.length > 0) { + for (const [providerType, configurationOptions] of Object.entries(record)) { + if (configurationOptions.length > 0) { items.push({ label: providerType, type: 'separator' }); } - for (const configuration of dynamicConfigurations) { + for (const options of configurationOptions) { items.push({ - label: configuration.name, - execute: () => this.runConfiguration({ name: configuration.name, configuration, providerType }) + label: options.name, + description: this.resolveRootFolderName(options.workspaceFolderUri), + execute: () => this.runConfiguration({ name: options.name, configuration: options.configuration, providerType, workspaceFolderUri: options.workspaceFolderUri }) }); } } diff --git a/packages/debug/src/browser/view/debug-configuration-select.tsx b/packages/debug/src/browser/view/debug-configuration-select.tsx index 091ef1b3b31e4..7e3f1537128ec 100644 --- a/packages/debug/src/browser/view/debug-configuration-select.tsx +++ b/packages/debug/src/browser/view/debug-configuration-select.tsx @@ -22,7 +22,7 @@ import { SelectComponent, SelectOption } from '@theia/core/lib/browser/widgets/s import { QuickInputService } from '@theia/core/lib/browser'; import { nls } from '@theia/core/lib/common/nls'; -interface DynamicPickItem { label: string, configurationType: string, request: string, providerType: string } +interface DynamicPickItem { label: string, configurationType: string, request: string, providerType: string, workspaceFolderUri?: string } export interface DebugConfigurationSelectProps { manager: DebugConfigurationManager, @@ -130,11 +130,13 @@ export class DebugConfigurationSelect extends React.Component ({ - label: configuration.name, - configurationType: configuration.type, - request: configuration.request, - providerType + return configurationsOfProviderType.map(options => ({ + label: options.configuration.name, + configurationType: options.configuration.type, + request: options.configuration.request, + providerType: options.providerType, + description: this.toBaseName(options.workspaceFolderUri), + workspaceFolderUri: options.workspaceFolderUri })); } @@ -161,15 +163,15 @@ export class DebugConfigurationSelect extends React.Component { - const configsPerType = await this.manager.provideDynamicDebugConfigurations(); + const configsOptionsPerType = await this.manager.provideDynamicDebugConfigurations(); const providerTypes = []; - for (const [type, configurations] of Object.entries(configsPerType)) { - if (configurations.length > 0) { + for (const [type, configurationsOptions] of Object.entries(configsOptionsPerType)) { + if (configurationsOptions.length > 0) { providerTypes.push(type); } } @@ -251,6 +253,10 @@ export class DebugConfigurationSelect extends React.Component>; + provideDynamicDebugConfigurations?(folder?: string): Promise>; /** * Provides a dynamic debug configuration matching the name and the provider debug type */ - fetchDynamicDebugConfiguration(name: string, type: string): Promise; + fetchDynamicDebugConfiguration(name: string, type: string, folder?: string): Promise; /** * Resolves a [debug configuration](#DebugConfiguration) by filling in missing values diff --git a/packages/debug/src/node/debug-service-impl.ts b/packages/debug/src/node/debug-service-impl.ts index c4304390b1947..f5e1e6aa1e054 100644 --- a/packages/debug/src/node/debug-service-impl.ts +++ b/packages/debug/src/node/debug-service-impl.ts @@ -71,7 +71,7 @@ export class DebugServiceImpl implements DebugService { // TODO: Support dynamic debug configurations through Theia extensions? return {}; } - fetchDynamicDebugConfiguration(name: string, type: string): Promise { + fetchDynamicDebugConfiguration(name: string, type: string, folder?: string): Promise { // TODO: Support dynamic debug configurations through Theia extensions? return Promise.resolve(undefined); } diff --git a/packages/plugin-ext/src/main/browser/debug/plugin-debug-service.ts b/packages/plugin-ext/src/main/browser/debug/plugin-debug-service.ts index 1e7576edeab2a..ecb575c109200 100644 --- a/packages/plugin-ext/src/main/browser/debug/plugin-debug-service.ts +++ b/packages/plugin-ext/src/main/browser/debug/plugin-debug-service.ts @@ -142,7 +142,7 @@ export class PluginDebugService implements DebugService { return results; } - async fetchDynamicDebugConfiguration(name: string, providerType: string): Promise { + async fetchDynamicDebugConfiguration(name: string, providerType: string, folder?: string): Promise { const pluginProviders = Array.from(this.configurationProviders.values()).filter(p => ( p.triggerKind === DebugConfigurationProviderTriggerKind.Dynamic && @@ -151,7 +151,7 @@ export class PluginDebugService implements DebugService { )); for (const provider of pluginProviders) { - const configurations = await provider.provideDebugConfigurations(undefined); + const configurations = await provider.provideDebugConfigurations(folder); for (const configuration of configurations) { if (configuration.name === name) { return configuration; @@ -160,7 +160,7 @@ export class PluginDebugService implements DebugService { } } - async provideDynamicDebugConfigurations(): Promise> { + async provideDynamicDebugConfigurations(folder?: string): Promise> { const pluginProviders = Array.from(this.configurationProviders.values()).filter(p => ( p.triggerKind === DebugConfigurationProviderTriggerKind.Dynamic && @@ -170,7 +170,7 @@ export class PluginDebugService implements DebugService { const configurationsRecord: Record = {}; await Promise.all(pluginProviders.map(async provider => { - const configurations = await provider.provideDebugConfigurations(undefined); + const configurations = await provider.provideDebugConfigurations(folder); let configurationsPerType = configurationsRecord[provider.type]; configurationsPerType = configurationsPerType ? configurationsPerType.concat(configurations) : configurations;