Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 24 additions & 4 deletions src/plus/launchpad/launchpadProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -540,7 +540,13 @@ export class LaunchpadProvider implements Disposable {
? item.openRepository.localBranch.name
: item.headRef.name;

return getPullRequestBranchDeepLink(this.container, branchName, item.repoIdentity.remote.url, action);
return getPullRequestBranchDeepLink(
this.container,
branchName,
item.repoIdentity.remote.url,
action,
item.underlyingPullRequest,
);
}

private async getMatchingOpenRepository(
Expand Down Expand Up @@ -1023,17 +1029,31 @@ export function getPullRequestBranchDeepLink(
headRefBranchName: string,
remoteUrl: string,
action?: DeepLinkActionType,
pr?: PullRequest,
) {
const schemeOverride = configuration.get('deepLinks.schemeOverride');
const scheme = typeof schemeOverride === 'string' ? schemeOverride : env.uriScheme;

const searchParams = new URLSearchParams({
url: ensureRemoteUrl(remoteUrl),
});
if (action) {
searchParams.set('action', action);
}
if (pr) {
searchParams.set('prId', pr.id);
searchParams.set('prTitle', pr.title);
}
if (pr?.refs) {
searchParams.set('prBaseRef', pr.refs.base.sha);
searchParams.set('prHeadRef', pr.refs.head.sha);
}
// TODO: Get the proper pull URL from the provider, rather than tacking .git at the end of the
// url from the head ref.
return Uri.parse(
`${scheme}://${container.context.extension.id}/${'link' satisfies UriTypes}/${DeepLinkType.Repository}/-/${
DeepLinkType.Branch
}/${encodeURIComponent(headRefBranchName)}?url=${encodeURIComponent(ensureRemoteUrl(remoteUrl))}${
action != null ? `&action=${action}` : ''
}`,
}/${encodeURIComponent(headRefBranchName)}?${searchParams.toString()}`,
);
}

Expand Down
11 changes: 11 additions & 0 deletions src/uris/deepLinks/deepLink.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ export interface DeepLink {
secondaryTargetId?: string;
secondaryRemoteUrl?: string;
action?: string;
prId?: string;
params?: URLSearchParams;
}

Expand Down Expand Up @@ -178,6 +179,7 @@ export function parseDeepLinkUri(uri: Uri): DeepLink | undefined {
secondaryRemoteUrl: secondaryRemoteUrl,
action: action,
params: urlParams,
prId: urlParams.get('prId') ?? undefined,
};
}
case DeepLinkType.Draft: {
Expand Down Expand Up @@ -239,6 +241,7 @@ export const enum DeepLinkServiceState {
OpenInspect,
SwitchToRef,
RunCommand,
OpenAllPrChanges,
}

export const enum DeepLinkServiceAction {
Expand Down Expand Up @@ -271,6 +274,7 @@ export const enum DeepLinkServiceAction {
OpenFile,
OpenInspect,
OpenSwitch,
OpenAllPrChanges,
}

export type DeepLinkRepoOpenType = 'clone' | 'folder' | 'workspace' | 'current';
Expand Down Expand Up @@ -387,6 +391,7 @@ export const deepLinkStateTransitionTable: Record<string, Record<string, DeepLin
[DeepLinkServiceAction.OpenGraph]: DeepLinkServiceState.OpenGraph,
[DeepLinkServiceAction.OpenFile]: DeepLinkServiceState.OpenFile,
[DeepLinkServiceAction.OpenSwitch]: DeepLinkServiceState.SwitchToRef,
[DeepLinkServiceAction.OpenAllPrChanges]: DeepLinkServiceState.OpenAllPrChanges,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This transition is no longer necessary since it would/should only be reachable from OpenInspect

[DeepLinkServiceAction.OpenComparison]: DeepLinkServiceState.OpenComparison,
[DeepLinkServiceAction.DeepLinkErrored]: DeepLinkServiceState.Idle,
[DeepLinkServiceAction.DeepLinkCancelled]: DeepLinkServiceState.Idle,
Expand Down Expand Up @@ -417,6 +422,12 @@ export const deepLinkStateTransitionTable: Record<string, Record<string, DeepLin
[DeepLinkServiceAction.DeepLinkCancelled]: DeepLinkServiceState.Idle,
},
[DeepLinkServiceState.OpenInspect]: {
[DeepLinkServiceAction.OpenAllPrChanges]: DeepLinkServiceState.OpenAllPrChanges,
[DeepLinkServiceAction.DeepLinkResolved]: DeepLinkServiceState.Idle,
[DeepLinkServiceAction.DeepLinkErrored]: DeepLinkServiceState.Idle,
[DeepLinkServiceAction.DeepLinkCancelled]: DeepLinkServiceState.Idle,
},
[DeepLinkServiceState.OpenAllPrChanges]: {
[DeepLinkServiceAction.DeepLinkResolved]: DeepLinkServiceState.Idle,
[DeepLinkServiceAction.DeepLinkErrored]: DeepLinkServiceState.Idle,
[DeepLinkServiceAction.DeepLinkCancelled]: DeepLinkServiceState.Idle,
Expand Down
47 changes: 37 additions & 10 deletions src/uris/deepLinks/deepLinkService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Commands } from '../../constants.commands';
import type { StoredDeepLinkContext, StoredNamedRef } from '../../constants.storage';
import type { Container } from '../../container';
import { executeGitCommand } from '../../git/actions';
import { openFileAtRevision } from '../../git/actions/commit';
import { openComparisonChanges, openFileAtRevision } from '../../git/actions/commit';
import type { GitBranch } from '../../git/models/branch';
import { getBranchNameWithoutRemote } from '../../git/models/branch';
import type { GitCommit } from '../../git/models/commit';
Expand All @@ -19,6 +19,7 @@ import { missingRepositoryId } from '../../gk/models/repositoryIdentities';
import { ensureAccount, ensurePaidPlan } from '../../plus/utils';
import type { ShowInCommitGraphCommandArgs } from '../../plus/webviews/graph/protocol';
import { createQuickPickSeparator } from '../../quickpicks/items/common';
import { debug } from '../../system/decorators/log';
import { once } from '../../system/event';
import { Logger } from '../../system/logger';
import { normalizePath } from '../../system/path';
Expand Down Expand Up @@ -68,10 +69,7 @@ export class DeepLinkService implements Disposable {
this._disposables.push(container.uri.onDidReceiveUri(async (uri: Uri) => this.processDeepLinkUri(uri)));

const pendingDeepLink = this.container.storage.get('deepLinks:pending');
if (pendingDeepLink != null) {
void this.container.storage.delete('deepLinks:pending');
void this.processPendingDeepLink(pendingDeepLink);
}
void this.processPendingDeepLink(pendingDeepLink);
}

dispose() {
Expand Down Expand Up @@ -241,9 +239,11 @@ export class DeepLinkService implements Disposable {
}
}

private async processPendingDeepLink(pendingDeepLink: StoredDeepLinkContext) {
if (pendingDeepLink.url == null) return;

@debug()
private async processPendingDeepLink(pendingDeepLink: StoredDeepLinkContext | undefined) {
if (pendingDeepLink == null) return;
void this.container.storage.delete('deepLinks:pending');
if (pendingDeepLink?.url == null) return;
const link = parseDeepLinkUri(Uri.parse(pendingDeepLink.url));
if (link == null) return;

Expand Down Expand Up @@ -509,6 +509,7 @@ export class DeepLinkService implements Disposable {
// TODO @axosoft-ramint: Move all the logic for matching a repo, prompting to add repo, matching remote, etc. for a target (branch, PR, etc.)
// to a separate service where it can be used outside of the context of deep linking. Then the deep link service should leverage it,
// and we should stop using deep links to process things like Launchpad switch actions, Open in Worktree command, etc.
@debug()
private async processDeepLink(
initialAction: DeepLinkServiceAction = DeepLinkServiceAction.DeepLinkEventFired,
useProgress: boolean = true,
Expand Down Expand Up @@ -1078,7 +1079,6 @@ export class DeepLinkService implements Disposable {
}
case DeepLinkServiceState.GoToTarget: {
// Need to re-fetch the remotes in case we opened in a new window

if (targetType === DeepLinkType.Repository) {
if (
this._context.action === DeepLinkActionType.Switch ||
Expand Down Expand Up @@ -1373,7 +1373,6 @@ export class DeepLinkService implements Disposable {
case DeepLinkServiceState.OpenInspect: {
// If we arrive at this step, clear any stored data used for the "new window" option
await this.container.storage.delete('deepLinks:pending');

if (!repo) {
action = DeepLinkServiceAction.DeepLinkErrored;
message = 'Missing repository.';
Expand All @@ -1386,6 +1385,34 @@ export class DeepLinkService implements Disposable {
repository: repo,
source: 'launchpad',
} satisfies ShowWipArgs);
action = DeepLinkServiceAction.OpenAllPrChanges;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right now this would work because we really only open inspect on PR switches, in which case all the info is there to show the PR changes. Would be a nice additional touch though to check the action type in this._context.action though and maybe restrict/guard against any non-PR case.

break;
}
case DeepLinkServiceState.OpenAllPrChanges: {
const prId = this._context.params?.get('prId');
const prHeadRef = this._context.params?.get('prHeadRef');
const prBaseRef = this._context.params?.get('prBaseRef');
const prTitle = this._context.params?.get('prTitle');
if (!repoPath || !prId || !prHeadRef || !prBaseRef) {
action = DeepLinkServiceAction.DeepLinkErrored;
if (!repoPath) {
message = 'No repository path was provided.';
} else if (!prId) {
message = 'No pull request id provided.';
} else {
message = 'No pull request refs was provided.';
}
break;
}
await openComparisonChanges(
this.container,
{
repoPath: repoPath,
lhs: prBaseRef,
rhs: prHeadRef,
},
{ title: `Changes in Pull Request ${prTitle ? `"${prTitle}"` : `#${prId}`}` },
);
action = DeepLinkServiceAction.DeepLinkResolved;
break;
}
Expand Down
1 change: 1 addition & 0 deletions src/views/viewCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -808,6 +808,7 @@ export class ViewCommands {
pr.refs.head.branch,
repoIdentity.remote.url,
DeepLinkActionType.SwitchToPullRequestWorktree,
pr,
);

const prRepo = await getOrOpenPullRequestRepository(this.container, pr, {
Expand Down
Loading