diff --git a/src/plus/launchpad/launchpadProvider.ts b/src/plus/launchpad/launchpadProvider.ts index ff8e34a1c0e75..3535ffb59390c 100644 --- a/src/plus/launchpad/launchpadProvider.ts +++ b/src/plus/launchpad/launchpadProvider.ts @@ -21,6 +21,7 @@ import { getOrOpenPullRequestRepository, getRepositoryIdentityForPullRequest, } from '../../git/models/pullRequest'; +import type { PullRequestURLIdentity } from '../../git/models/pullRequest.utils'; import { getPullRequestIdentityValuesFromSearch } from '../../git/models/pullRequest.utils'; import type { GitRemote } from '../../git/models/remote'; import type { Repository } from '../../git/models/repository'; @@ -40,7 +41,7 @@ import type { UriTypes } from '../../uris/deepLinks/deepLink'; import { DeepLinkActionType, DeepLinkType } from '../../uris/deepLinks/deepLink'; import { showInspectView } from '../../webviews/commitDetails/actions'; import type { ShowWipArgs } from '../../webviews/commitDetails/protocol'; -import type { IntegrationResult } from '../integrations/integration'; +import type { HostingIntegration, IntegrationResult } from '../integrations/integration'; import type { ConnectionStateChangeEvent } from '../integrations/integrationService'; import type { GitHubRepositoryDescriptor } from '../integrations/providers/github'; import type { EnrichablePullRequest, ProviderActionablePullRequest } from '../integrations/providers/models'; @@ -326,12 +327,49 @@ export class LaunchpadProvider implements Disposable { // The current idea is that we should iterate the connected integrations and apply their parsing. // Probably we even want to build a map like this: { integrationId: identity } // Then we iterate connected integrations and search in each of them with the corresponding identity. - const { ownerAndRepo, prNumber } = getPullRequestIdentityValuesFromSearch(search); - let result: TimedResult | undefined; + const prUrlIdentity = getPullRequestIdentityValuesFromSearch(search); + const result: { readonly value: SearchedPullRequest[]; duration: number } = { + value: [], + duration: 0, + }; + + const connectedIntegrations = await this.getConnectedIntegrations(); + + await Promise.allSettled( + [...connectedIntegrations.keys()] + .filter( + (id: IntegrationId): id is SupportedLaunchpadIntegrationIds => + (connectedIntegrations.get(id) && isSupportedLaunchpadIntegrationId(id)) ?? false, + ) + .map(async (id: HostingIntegrationId) => { + const integration = await this.container.integrations.get(id); + const searchResult = await this.searchIntegrationPRs( + search, + prUrlIdentity, + integration, + cancellation, + ); + const prs = searchResult?.value; + if (prs) { + result.value?.push(...prs); + result.duration = Math.max(result.duration, searchResult.duration); + } + }), + ); + return { + prs: result, + suggestionCounts: undefined, + }; + } + private async searchIntegrationPRs( + search: string, + { ownerAndRepo, prNumber }: PullRequestURLIdentity, + integration: HostingIntegration, + cancellation: CancellationToken | undefined, + ): Promise> { + let result: TimedResult | undefined; if (prNumber != null && ownerAndRepo != null) { - // TODO: This needs to be generalized to work outside of GitHub - const integration = await this.container.integrations.get(HostingIntegrationId.GitHub); const [owner, repo] = ownerAndRepo.split('/', 2); const descriptor: GitHubRepositoryDescriptor = { key: ownerAndRepo, @@ -345,21 +383,20 @@ export class LaunchpadProvider implements Disposable { ); if (pr?.value != null) { result = { value: [{ pullRequest: pr.value, reasons: [] }], duration: pr.duration }; - return { prs: result, suggestionCounts: undefined }; + return result; } } else { - const integration = await this.container.integrations.get(HostingIntegrationId.GitHub); const prs = await withDurationAndSlowEventOnTimeout( - integration?.searchPullRequests(search, undefined, cancellation), + integration?.searchPullRequests(search, undefined, cancellation), // 'searchPullRequests', this.container, ); if (prs != null) { result = { value: prs.value?.map(pr => ({ pullRequest: pr, reasons: [] })), duration: prs.duration }; - return { prs: result, suggestionCounts: undefined }; + return result; } } - return { prs: undefined, suggestionCounts: undefined }; + return undefined; } private _enrichedItems: CachedLaunchpadPromise> | undefined;