Skip to content

Commit a450c7d

Browse files
committed
Enhances PR search with multiple integrations instead of only GitHub
(#3788, #3795)
1 parent 3fe8c55 commit a450c7d

File tree

1 file changed

+47
-8
lines changed

1 file changed

+47
-8
lines changed

src/plus/launchpad/launchpadProvider.ts

Lines changed: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
getOrOpenPullRequestRepository,
2222
getRepositoryIdentityForPullRequest,
2323
} from '../../git/models/pullRequest';
24+
import type { PullRequestUrlIdentity } from '../../git/models/pullRequest.utils';
2425
import type { GitRemote } from '../../git/models/remote';
2526
import type { Repository } from '../../git/models/repository';
2627
import type { CodeSuggestionCounts, Draft } from '../../gk/models/drafts';
@@ -39,7 +40,7 @@ import type { UriTypes } from '../../uris/deepLinks/deepLink';
3940
import { DeepLinkActionType, DeepLinkType } from '../../uris/deepLinks/deepLink';
4041
import { showInspectView } from '../../webviews/commitDetails/actions';
4142
import type { ShowWipArgs } from '../../webviews/commitDetails/protocol';
42-
import type { IntegrationResult } from '../integrations/integration';
43+
import type { HostingIntegration, IntegrationResult } from '../integrations/integration';
4344
import type { ConnectionStateChangeEvent } from '../integrations/integrationService';
4445
import type { GitHubRepositoryDescriptor } from '../integrations/providers/github';
4546
import type { GitLabRepositoryDescriptor } from '../integrations/providers/gitlab';
@@ -214,9 +215,48 @@ export class LaunchpadProvider implements Disposable {
214215
// The current idea is that we should iterate the connected integrations and apply their parsing.
215216
// Probably we even want to build a map like this: { integrationId: identity }
216217
// Then we iterate connected integrations and search in each of them with the corresponding identity.
217-
const { ownerAndRepo, prNumber, provider } = getPullRequestIdentityFromMaybeUrl(search);
218-
let result: TimedResult<SearchedPullRequest[] | undefined> | undefined;
218+
const prUrlIdentity = getPullRequestIdentityFromMaybeUrl(search);
219+
const result: { readonly value: SearchedPullRequest[]; duration: number } = {
220+
value: [],
221+
duration: 0,
222+
};
223+
224+
const connectedIntegrations = await this.getConnectedIntegrations();
225+
226+
await Promise.allSettled(
227+
[...connectedIntegrations.keys()]
228+
.filter(
229+
(id: IntegrationId): id is SupportedLaunchpadIntegrationIds =>
230+
(connectedIntegrations.get(id) && isSupportedLaunchpadIntegrationId(id)) ?? false,
231+
)
232+
.map(async (id: HostingIntegrationId) => {
233+
const integration = await this.container.integrations.get(id);
234+
const searchResult = await this.searchIntegrationPRs(
235+
search,
236+
prUrlIdentity,
237+
integration,
238+
cancellation,
239+
);
240+
const prs = searchResult?.value;
241+
if (prs) {
242+
result.value?.push(...prs);
243+
result.duration = Math.max(result.duration, searchResult.duration);
244+
}
245+
}),
246+
);
247+
return {
248+
prs: result,
249+
suggestionCounts: undefined,
250+
};
251+
}
219252

253+
private async searchIntegrationPRs(
254+
search: string,
255+
{ ownerAndRepo, prNumber, provider }: PullRequestUrlIdentity,
256+
integration: HostingIntegration,
257+
cancellation: CancellationToken | undefined,
258+
): Promise<undefined | TimedResult<SearchedPullRequest[] | undefined>> {
259+
let result: TimedResult<SearchedPullRequest[] | undefined> | undefined;
220260
if (provider != null && prNumber != null && ownerAndRepo != null) {
221261
// TODO: This needs to be generalized to work outside of GitHub/GitLab
222262
const integration = await this.container.integrations.get(provider);
@@ -233,21 +273,20 @@ export class LaunchpadProvider implements Disposable {
233273
);
234274
if (pr?.value != null) {
235275
result = { value: [{ pullRequest: pr.value, reasons: [] }], duration: pr.duration };
236-
return { prs: result, suggestionCounts: undefined };
276+
return result;
237277
}
238278
} else {
239-
const integration = await this.container.integrations.get(HostingIntegrationId.GitHub);
240279
const prs = await withDurationAndSlowEventOnTimeout(
241-
integration?.searchPullRequests(search, undefined, cancellation),
280+
integration?.searchPullRequests(search, undefined, cancellation), //
242281
'searchPullRequests',
243282
this.container,
244283
);
245284
if (prs != null) {
246285
result = { value: prs.value?.map(pr => ({ pullRequest: pr, reasons: [] })), duration: prs.duration };
247-
return { prs: result, suggestionCounts: undefined };
286+
return result;
248287
}
249288
}
250-
return { prs: undefined, suggestionCounts: undefined };
289+
return undefined;
251290
}
252291

253292
private _enrichedItems: CachedLaunchpadPromise<TimedResult<EnrichedItem[]>> | undefined;

0 commit comments

Comments
 (0)