Skip to content

Commit 811ae3d

Browse files
Copilotalexr00
andauthored
Add URI handler for opening multidiff editor (#8310)
* Initial plan * Add URL handling for opening multidiff editor for a PR Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com> * Refactor: Extract common PR resolution logic into helper method Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com>
1 parent c4907c9 commit 811ae3d

File tree

3 files changed

+46
-4
lines changed

3 files changed

+46
-4
lines changed

src/common/uri.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -668,7 +668,8 @@ function validateOpenWebviewParams(owner?: string, repo?: string, number?: strin
668668
export enum UriHandlerPaths {
669669
OpenIssueWebview = '/open-issue-webview',
670670
OpenPullRequestWebview = '/open-pull-request-webview',
671-
CheckoutPullRequest = '/checkout-pull-request'
671+
CheckoutPullRequest = '/checkout-pull-request',
672+
OpenPullRequestChanges = '/open-pull-request-changes'
672673
}
673674

674675
export interface OpenIssueWebviewUriParams {
@@ -709,11 +710,16 @@ export async function toOpenPullRequestWebviewUri(params: OpenPullRequestWebview
709710
return vscode.env.asExternalUri(vscode.Uri.from({ scheme: vscode.env.uriScheme, authority: EXTENSION_ID, path: UriHandlerPaths.OpenPullRequestWebview, query }));
710711
}
711712

713+
export async function toOpenPullRequestChangesUri(params: OpenPullRequestWebviewUriParams): Promise<vscode.Uri> {
714+
const query = JSON.stringify(params);
715+
return vscode.env.asExternalUri(vscode.Uri.from({ scheme: vscode.env.uriScheme, authority: EXTENSION_ID, path: UriHandlerPaths.OpenPullRequestChanges, query }));
716+
}
717+
712718
export function fromOpenOrCheckoutPullRequestWebviewUri(uri: vscode.Uri): OpenPullRequestWebviewUriParams | undefined {
713719
if (compareIgnoreCase(uri.authority, EXTENSION_ID) !== 0) {
714720
return;
715721
}
716-
if (uri.path !== UriHandlerPaths.OpenPullRequestWebview && uri.path !== UriHandlerPaths.CheckoutPullRequest) {
722+
if (uri.path !== UriHandlerPaths.OpenPullRequestWebview && uri.path !== UriHandlerPaths.CheckoutPullRequest && uri.path !== UriHandlerPaths.OpenPullRequestChanges) {
717723
return;
718724
}
719725
try {

src/test/common/uri.test.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,5 +109,23 @@ describe('uri', () => {
109109
const result2 = fromOpenOrCheckoutPullRequestWebviewUri(uri2);
110110
assert.strictEqual(result2, undefined);
111111
});
112+
113+
it('should work for open-pull-request-changes path', () => {
114+
const uri = vscode.Uri.parse('vscode://github.vscode-pull-request-github/open-pull-request-changes?uri=https://github.com/test/example/pull/999');
115+
const result = fromOpenOrCheckoutPullRequestWebviewUri(uri);
116+
117+
assert.strictEqual(result?.owner, 'test');
118+
assert.strictEqual(result?.repo, 'example');
119+
assert.strictEqual(result?.pullRequestNumber, 999);
120+
});
121+
122+
it('should parse JSON format for open-pull-request-changes path', () => {
123+
const uri = vscode.Uri.parse('vscode://github.vscode-pull-request-github/open-pull-request-changes?%7B%22owner%22%3A%22testowner%22%2C%22repo%22%3A%22testrepo%22%2C%22pullRequestNumber%22%3A123%7D');
124+
const result = fromOpenOrCheckoutPullRequestWebviewUri(uri);
125+
126+
assert.strictEqual(result?.owner, 'testowner');
127+
assert.strictEqual(result?.repo, 'testrepo');
128+
assert.strictEqual(result?.pullRequestNumber, 123);
129+
});
112130
});
113131
});

src/uriHandler.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ export class UriHandler implements vscode.UriHandler {
118118
// Simplified format example: vscode-insiders://github.vscode-pull-request-github/checkout-pull-request?uri=https://github.com/microsoft/vscode-css-languageservice/pull/460
119119
// Legacy format example: vscode-insiders://github.vscode-pull-request-github/checkout-pull-request?%7B%22owner%22%3A%22alexr00%22%2C%22repo%22%3A%22playground%22%2C%22pullRequestNumber%22%3A714%7D
120120
return this._checkoutPullRequest(uri);
121+
case UriHandlerPaths.OpenPullRequestChanges:
122+
return this._openPullRequestChanges(uri);
121123
}
122124
}
123125

@@ -134,7 +136,7 @@ export class UriHandler implements vscode.UriHandler {
134136
return IssueOverviewPanel.createOrShow(this._telemetry, this._context.extensionUri, folderManager, issue);
135137
}
136138

137-
private async _openPullRequestWebview(uri: vscode.Uri): Promise<void> {
139+
private async _resolvePullRequestFromUri(uri: vscode.Uri): Promise<{ folderManager: FolderRepositoryManager; pullRequest: PullRequestModel } | undefined> {
138140
const params = fromOpenOrCheckoutPullRequestWebviewUri(uri);
139141
if (!params) {
140142
return;
@@ -144,7 +146,23 @@ export class UriHandler implements vscode.UriHandler {
144146
if (!pullRequest) {
145147
return;
146148
}
147-
return PullRequestOverviewPanel.createOrShow(this._telemetry, this._context.extensionUri, folderManager, pullRequest);
149+
return { folderManager, pullRequest };
150+
}
151+
152+
private async _openPullRequestWebview(uri: vscode.Uri): Promise<void> {
153+
const resolved = await this._resolvePullRequestFromUri(uri);
154+
if (!resolved) {
155+
return;
156+
}
157+
return PullRequestOverviewPanel.createOrShow(this._telemetry, this._context.extensionUri, resolved.folderManager, resolved.pullRequest);
158+
}
159+
160+
private async _openPullRequestChanges(uri: vscode.Uri): Promise<void> {
161+
const resolved = await this._resolvePullRequestFromUri(uri);
162+
if (!resolved) {
163+
return;
164+
}
165+
return PullRequestModel.openChanges(resolved.folderManager, resolved.pullRequest);
148166
}
149167

150168
private async _savePendingCheckoutAndOpenFolder(params: { owner: string; repo: string; pullRequestNumber: number }, folderUri: vscode.Uri): Promise<void> {

0 commit comments

Comments
 (0)