Skip to content

Commit 4c7014a

Browse files
committed
Opens all changes after open in worktree flow finished for PRs
1 parent 51d03bd commit 4c7014a

File tree

5 files changed

+91
-23
lines changed

5 files changed

+91
-23
lines changed

src/commands/git/worktree.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ interface OpenState {
128128
worktree: GitWorktree;
129129
flags: OpenFlags[];
130130

131+
prId?: string;
132+
131133
openOnly?: boolean;
132134
overrides?: {
133135
disallowBack?: boolean;

src/plus/launchpad/launchpadProvider.ts

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,7 @@ import { executeCommand, registerCommand } from '../../system/vscode/command';
3535
import { configuration } from '../../system/vscode/configuration';
3636
import { setContext } from '../../system/vscode/context';
3737
import { openUrl } from '../../system/vscode/utils';
38-
import type { UriTypes } from '../../uris/deepLinks/deepLink';
39-
import { DeepLinkActionType, DeepLinkType } from '../../uris/deepLinks/deepLink';
38+
import { DeepLinkActionType, DeepLinkType, UriTypes } from '../../uris/deepLinks/deepLink';
4039
import { showInspectView } from '../../webviews/commitDetails/actions';
4140
import type { ShowWipArgs } from '../../webviews/commitDetails/protocol';
4241
import type { IntegrationResult } from '../integrations/integration';
@@ -1023,17 +1022,27 @@ export function getPullRequestBranchDeepLink(
10231022
headRefBranchName: string,
10241023
remoteUrl: string,
10251024
action?: DeepLinkActionType,
1025+
prId?: string,
10261026
) {
10271027
const schemeOverride = configuration.get('deepLinks.schemeOverride');
10281028
const scheme = typeof schemeOverride === 'string' ? schemeOverride : env.uriScheme;
1029+
1030+
const searchParams = new URLSearchParams({
1031+
url: ensureRemoteUrl(remoteUrl),
1032+
});
1033+
if (action) {
1034+
searchParams.set('action', action);
1035+
}
1036+
if (prId) {
1037+
searchParams.set('prId', prId);
1038+
}
1039+
10291040
// TODO: Get the proper pull URL from the provider, rather than tacking .git at the end of the
10301041
// url from the head ref.
10311042
return Uri.parse(
1032-
`${scheme}://${container.context.extension.id}/${'link' satisfies UriTypes}/${DeepLinkType.Repository}/-/${
1043+
`${scheme}://${container.context.extension.id}/${UriTypes.link}/${DeepLinkType.Repository}/-/${
10331044
DeepLinkType.Branch
1034-
}/${encodeURIComponent(headRefBranchName)}?url=${encodeURIComponent(ensureRemoteUrl(remoteUrl))}${
1035-
action != null ? `&action=${action}` : ''
1036-
}`,
1045+
}/${encodeURIComponent(headRefBranchName)}?${searchParams.toString()}`,
10371046
);
10381047
}
10391048

src/uris/deepLinks/deepLink.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ import type { GitRemote } from '../../git/models/remote';
55
import type { Repository } from '../../git/models/repository';
66
import type { OpenWorkspaceLocation } from '../../system/vscode/utils';
77

8-
export type UriTypes = 'link';
8+
export enum UriTypes {
9+
link = 'link',
10+
}
911

1012
export enum DeepLinkType {
1113
Branch = 'b',
@@ -38,6 +40,7 @@ export enum DeepLinkActionType {
3840
SwitchToPullRequest = 'switch-to-pr',
3941
SwitchToPullRequestWorktree = 'switch-to-pr-worktree',
4042
SwitchToAndSuggestPullRequest = 'switch-to-and-suggest-pr',
43+
OpenAllPrChanges = 'open-all-pr-changes',
4144
}
4245

4346
export const AccountDeepLinkTypes: DeepLinkType[] = [DeepLinkType.Draft, DeepLinkType.Workspace];
@@ -92,6 +95,7 @@ export interface DeepLink {
9295
secondaryTargetId?: string;
9396
secondaryRemoteUrl?: string;
9497
action?: string;
98+
prId?: string;
9599
params?: URLSearchParams;
96100
}
97101

@@ -170,6 +174,7 @@ export function parseDeepLinkUri(uri: Uri): DeepLink | undefined {
170174
secondaryRemoteUrl: secondaryRemoteUrl,
171175
action: action,
172176
params: urlParams,
177+
prId: urlParams.get('prId') ?? undefined,
173178
};
174179
}
175180
case DeepLinkType.Draft: {
@@ -231,6 +236,7 @@ export const enum DeepLinkServiceState {
231236
OpenInspect,
232237
SwitchToRef,
233238
RunCommand,
239+
OpenAllPrChanges,
234240
}
235241

236242
export const enum DeepLinkServiceAction {
@@ -263,6 +269,7 @@ export const enum DeepLinkServiceAction {
263269
OpenFile,
264270
OpenInspect,
265271
OpenSwitch,
272+
OpenAllPrChanges,
266273
}
267274

268275
export type DeepLinkRepoOpenType = 'clone' | 'folder' | 'workspace' | 'current';
@@ -284,6 +291,7 @@ export interface DeepLinkServiceContext {
284291
targetSha?: string | undefined;
285292
secondaryTargetSha?: string | undefined;
286293
action?: string | undefined;
294+
prId?: string | undefined;
287295
repoOpenLocation?: OpenWorkspaceLocation | undefined;
288296
repoOpenUri?: Uri | undefined;
289297
params?: URLSearchParams | undefined;
@@ -379,6 +387,7 @@ export const deepLinkStateTransitionTable: Record<string, Record<string, DeepLin
379387
[DeepLinkServiceAction.OpenGraph]: DeepLinkServiceState.OpenGraph,
380388
[DeepLinkServiceAction.OpenFile]: DeepLinkServiceState.OpenFile,
381389
[DeepLinkServiceAction.OpenSwitch]: DeepLinkServiceState.SwitchToRef,
390+
[DeepLinkServiceAction.OpenAllPrChanges]: DeepLinkServiceState.OpenAllPrChanges,
382391
[DeepLinkServiceAction.OpenComparison]: DeepLinkServiceState.OpenComparison,
383392
[DeepLinkServiceAction.DeepLinkErrored]: DeepLinkServiceState.Idle,
384393
[DeepLinkServiceAction.DeepLinkCancelled]: DeepLinkServiceState.Idle,
@@ -409,6 +418,12 @@ export const deepLinkStateTransitionTable: Record<string, Record<string, DeepLin
409418
[DeepLinkServiceAction.DeepLinkCancelled]: DeepLinkServiceState.Idle,
410419
},
411420
[DeepLinkServiceState.OpenInspect]: {
421+
[DeepLinkServiceAction.OpenAllPrChanges]: DeepLinkServiceState.EnsureRemoteMatch,
422+
[DeepLinkServiceAction.DeepLinkResolved]: DeepLinkServiceState.Idle,
423+
[DeepLinkServiceAction.DeepLinkErrored]: DeepLinkServiceState.Idle,
424+
[DeepLinkServiceAction.DeepLinkCancelled]: DeepLinkServiceState.Idle,
425+
},
426+
[DeepLinkServiceState.OpenAllPrChanges]: {
412427
[DeepLinkServiceAction.DeepLinkResolved]: DeepLinkServiceState.Idle,
413428
[DeepLinkServiceAction.DeepLinkErrored]: DeepLinkServiceState.Idle,
414429
[DeepLinkServiceAction.DeepLinkCancelled]: DeepLinkServiceState.Idle,

src/uris/deepLinks/deepLinkService.ts

Lines changed: 57 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ import { Commands } from '../../constants.commands';
44
import type { StoredDeepLinkContext, StoredNamedRef } from '../../constants.storage';
55
import type { Container } from '../../container';
66
import { executeGitCommand } from '../../git/actions';
7-
import { openFileAtRevision } from '../../git/actions/commit';
7+
import { openComparisonChanges, openFileAtRevision } from '../../git/actions/commit';
88
import type { GitBranch } from '../../git/models/branch';
99
import { getBranchNameWithoutRemote } from '../../git/models/branch';
1010
import type { GitCommit } from '../../git/models/commit';
11+
import { getComparisonRefsForPullRequest } from '../../git/models/pullRequest';
1112
import type { GitReference } from '../../git/models/reference';
1213
import { createReference, isSha } from '../../git/models/reference';
1314
import type { Repository, RepositoryChangeEvent } from '../../git/models/repository';
@@ -19,6 +20,7 @@ import { missingRepositoryId } from '../../gk/models/repositoryIdentities';
1920
import { ensureAccount, ensurePaidPlan } from '../../plus/utils';
2021
import type { ShowInCommitGraphCommandArgs } from '../../plus/webviews/graph/protocol';
2122
import { createQuickPickSeparator } from '../../quickpicks/items/common';
23+
import { debug } from '../../system/decorators/log';
2224
import { once } from '../../system/event';
2325
import { Logger } from '../../system/logger';
2426
import { normalizePath } from '../../system/path';
@@ -29,7 +31,7 @@ import type { OpenWorkspaceLocation } from '../../system/vscode/utils';
2931
import { findOrOpenEditor, openWorkspace } from '../../system/vscode/utils';
3032
import { showInspectView } from '../../webviews/commitDetails/actions';
3133
import type { ShowWipArgs } from '../../webviews/commitDetails/protocol';
32-
import type { DeepLink, DeepLinkProgress, DeepLinkRepoOpenType, DeepLinkServiceContext, UriTypes } from './deepLink';
34+
import type { DeepLink, DeepLinkProgress, DeepLinkRepoOpenType, DeepLinkServiceContext } from './deepLink';
3335
import {
3436
AccountDeepLinkTypes,
3537
DeepLinkActionType,
@@ -43,6 +45,7 @@ import {
4345
isDeepLinkCommandType,
4446
PaidDeepLinkTypes,
4547
parseDeepLinkUri,
48+
UriTypes,
4649
} from './deepLink';
4750

4851
type OpenQuickPickItem = {
@@ -68,10 +71,7 @@ export class DeepLinkService implements Disposable {
6871
this._disposables.push(container.uri.onDidReceiveUri(async (uri: Uri) => this.processDeepLinkUri(uri)));
6972

7073
const pendingDeepLink = this.container.storage.get('deepLinks:pending');
71-
if (pendingDeepLink != null) {
72-
void this.container.storage.delete('deepLinks:pending');
73-
void this.processPendingDeepLink(pendingDeepLink);
74-
}
74+
void this.processPendingDeepLink(pendingDeepLink);
7575
}
7676

7777
dispose() {
@@ -114,6 +114,7 @@ export class DeepLinkService implements Disposable {
114114
targetId: link.targetId,
115115
secondaryTargetId: link.secondaryTargetId,
116116
secondaryRemoteUrl: link.secondaryRemoteUrl,
117+
prId: link.prId,
117118
action: link.action,
118119
params: link.params,
119120
};
@@ -241,9 +242,11 @@ export class DeepLinkService implements Disposable {
241242
}
242243
}
243244

244-
private async processPendingDeepLink(pendingDeepLink: StoredDeepLinkContext) {
245-
if (pendingDeepLink.url == null) return;
245+
@debug()
246+
private async processPendingDeepLink(pendingDeepLink: StoredDeepLinkContext | undefined) {
247+
void this.container.storage.delete('deepLinks:pending');
246248

249+
if (pendingDeepLink?.url == null) return;
247250
const link = parseDeepLinkUri(Uri.parse(pendingDeepLink.url));
248251
if (link == null) return;
249252

@@ -509,6 +512,7 @@ export class DeepLinkService implements Disposable {
509512
// TODO @axosoft-ramint: Move all the logic for matching a repo, prompting to add repo, matching remote, etc. for a target (branch, PR, etc.)
510513
// to a separate service where it can be used outside of the context of deep linking. Then the deep link service should leverage it,
511514
// and we should stop using deep links to process things like Launchpad switch actions, Open in Worktree command, etc.
515+
@debug()
512516
private async processDeepLink(
513517
initialAction: DeepLinkServiceAction = DeepLinkServiceAction.DeepLinkEventFired,
514518
useProgress: boolean = true,
@@ -562,6 +566,7 @@ export class DeepLinkService implements Disposable {
562566
remoteUrl,
563567
secondaryRemoteUrl,
564568
remote,
569+
prId,
565570
secondaryRemote,
566571
repoPath,
567572
filePath,
@@ -1077,7 +1082,11 @@ export class DeepLinkService implements Disposable {
10771082
return;
10781083
}
10791084
case DeepLinkServiceState.GoToTarget: {
1080-
// Need to re-fetch the remotes in case we opened in a new window
1085+
// Re-fetching the remotes in case we opened in a new window for specific actions
1086+
if (this._context.action === DeepLinkActionType.OpenAllPrChanges) {
1087+
action = DeepLinkServiceAction.OpenAllPrChanges;
1088+
break;
1089+
}
10811090

10821091
if (targetType === DeepLinkType.Repository) {
10831092
if (
@@ -1373,7 +1382,6 @@ export class DeepLinkService implements Disposable {
13731382
case DeepLinkServiceState.OpenInspect: {
13741383
// If we arrive at this step, clear any stored data used for the "new window" option
13751384
await this.container.storage.delete('deepLinks:pending');
1376-
13771385
if (!repo) {
13781386
action = DeepLinkServiceAction.DeepLinkErrored;
13791387
message = 'Missing repository.';
@@ -1386,6 +1394,43 @@ export class DeepLinkService implements Disposable {
13861394
repository: repo,
13871395
source: 'launchpad',
13881396
} satisfies ShowWipArgs);
1397+
if (this._context.prId) {
1398+
this._context.action = DeepLinkActionType.OpenAllPrChanges;
1399+
action = DeepLinkServiceAction.OpenAllPrChanges;
1400+
} else {
1401+
action = DeepLinkServiceAction.DeepLinkResolved;
1402+
}
1403+
break;
1404+
}
1405+
case DeepLinkServiceState.OpenAllPrChanges: {
1406+
if (!repoPath || !remote || !prId) {
1407+
action = DeepLinkServiceAction.DeepLinkErrored;
1408+
if (!repoPath) {
1409+
message = 'No repository path was provided.';
1410+
} else if (!remote) {
1411+
message = 'No remote was matched.';
1412+
} else {
1413+
message = 'No pull request id provided.';
1414+
}
1415+
break;
1416+
}
1417+
const pullRequestsOfRemote = await this.container.integrations.getMyPullRequestsForRemotes(remote);
1418+
const pullRequest = pullRequestsOfRemote?.value?.find(x => x.pullRequest.id === prId)?.pullRequest;
1419+
if (!pullRequest?.refs) {
1420+
action = DeepLinkServiceAction.DeepLinkErrored;
1421+
message = 'No pull request or pull request refs was found.';
1422+
break;
1423+
}
1424+
const refs = getComparisonRefsForPullRequest(repoPath, pullRequest.refs);
1425+
await openComparisonChanges(
1426+
this.container,
1427+
{
1428+
repoPath: refs.repoPath,
1429+
lhs: refs.base.ref,
1430+
rhs: refs.head.ref,
1431+
},
1432+
{ title: `Changes in Pull Request "${pullRequest.title}"` },
1433+
);
13891434
action = DeepLinkServiceAction.DeepLinkResolved;
13901435
break;
13911436
}
@@ -1522,9 +1567,7 @@ export class DeepLinkService implements Disposable {
15221567

15231568
// Start with the prefix, add the repo prefix and the repo ID to the URL, and then add the target tag and target ID to the URL (if applicable)
15241569
const deepLink = new URL(
1525-
`${scheme}://${this.container.context.extension.id}/${'link' satisfies UriTypes}/${
1526-
DeepLinkType.Repository
1527-
}/${repoId}${target}`,
1570+
`${scheme}://${this.container.context.extension.id}/${UriTypes.link}/${DeepLinkType.Repository}/${repoId}${target}`,
15281571
);
15291572

15301573
if (remoteUrl != null) {
@@ -1575,9 +1618,7 @@ export class DeepLinkService implements Disposable {
15751618
}
15761619

15771620
const deepLink = new URL(
1578-
`${scheme}://${this.container.context.extension.id}/${'link' satisfies UriTypes}/${
1579-
DeepLinkType.Repository
1580-
}/${repoId}/${targetType}/${targetId}`,
1621+
`${scheme}://${this.container.context.extension.id}/${UriTypes.link}/${DeepLinkType.Repository}/${repoId}/${targetType}/${targetId}`,
15811622
);
15821623

15831624
deepLink.searchParams.set('url', remoteUrl);

src/views/viewCommands.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -808,6 +808,7 @@ export class ViewCommands {
808808
pr.refs.head.branch,
809809
repoIdentity.remote.url,
810810
DeepLinkActionType.SwitchToPullRequestWorktree,
811+
pr.id,
811812
);
812813

813814
const prRepo = await getOrOpenPullRequestRepository(this.container, pr, {

0 commit comments

Comments
 (0)