Skip to content

Commit 9ad9572

Browse files
Copilotalexr00
andcommitted
Implement PR checkout by URL support
Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com>
1 parent a4abc35 commit 9ad9572

File tree

2 files changed

+45
-7
lines changed

2 files changed

+45
-7
lines changed

src/commands.ts

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import { GHPRComment, GHPRCommentThread, TemporaryComment } from './github/prCom
2929
import { PullRequestModel } from './github/pullRequestModel';
3030
import { PullRequestOverviewPanel } from './github/pullRequestOverview';
3131
import { RepositoriesManager } from './github/repositoriesManager';
32-
import { getIssuesUrl, getPullsUrl, isInCodespaces, vscodeDevPrLink } from './github/utils';
32+
import { getIssuesUrl, getPullsUrl, isInCodespaces, vscodeDevPrLink, parseIssueExpressionOutput, ISSUE_OR_URL_EXPRESSION } from './github/utils';
3333
import { isNotificationTreeItem, NotificationTreeItem } from './notifications/notificationItem';
3434
import { PullRequestsTreeDataProvider } from './view/prsTreeDataProvider';
3535
import { ReviewCommentController } from './view/reviewCommentController';
@@ -1475,19 +1475,41 @@ ${contents}
14751475
}
14761476
const prNumberMatcher = /^#?(\d*)$/;
14771477
const prNumber = await vscode.window.showInputBox({
1478-
ignoreFocusOut: true, prompt: vscode.l10n.t('Enter the pull request number'),
1478+
ignoreFocusOut: true, prompt: vscode.l10n.t('Enter the pull request number or URL'),
14791479
validateInput: (input: string) => {
1480-
const matches = input.match(prNumberMatcher);
1481-
if (!matches || (matches.length !== 2) || Number.isNaN(Number(matches[1]))) {
1482-
return vscode.l10n.t('Value must be a number');
1480+
const numberMatches = input.match(prNumberMatcher);
1481+
if (numberMatches && (numberMatches.length === 2) && !Number.isNaN(Number(numberMatches[1]))) {
1482+
return undefined; // Valid number
14831483
}
1484-
return undefined;
1484+
1485+
const urlMatches = input.match(ISSUE_OR_URL_EXPRESSION);
1486+
const parsed = parseIssueExpressionOutput(urlMatches);
1487+
if (parsed && parsed.issueNumber) {
1488+
return undefined; // Valid URL
1489+
}
1490+
1491+
return vscode.l10n.t('Value must be a pull request number or GitHub URL');
14851492
}
14861493
});
14871494
if ((prNumber === undefined) || prNumber === '#') {
14881495
return;
14891496
}
1490-
const prModel = await githubRepo.manager.fetchById(githubRepo.repo, Number(prNumber.match(prNumberMatcher)![1]));
1497+
1498+
// Extract PR number from input (either direct number or URL)
1499+
let extractedPrNumber: number;
1500+
const numberMatches = prNumber.match(prNumberMatcher);
1501+
if (numberMatches && (numberMatches.length === 2) && !Number.isNaN(Number(numberMatches[1]))) {
1502+
extractedPrNumber = Number(numberMatches[1]);
1503+
} else {
1504+
const urlMatches = prNumber.match(ISSUE_OR_URL_EXPRESSION);
1505+
const parsed = parseIssueExpressionOutput(urlMatches);
1506+
if (!parsed || !parsed.issueNumber) {
1507+
return vscode.window.showErrorMessage(vscode.l10n.t('Invalid pull request number or URL'));
1508+
}
1509+
extractedPrNumber = parsed.issueNumber;
1510+
}
1511+
1512+
const prModel = await githubRepo.manager.fetchById(githubRepo.repo, extractedPrNumber);
14911513
if (prModel) {
14921514
return ReviewManager.getReviewManagerForFolderManager(reviewsManager.reviewManagers, githubRepo.manager)?.switch(prModel);
14931515
}

src/test/issues/issuesUtils.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,5 +48,21 @@ describe('Issues utilities', function () {
4848
const notIssue = '#a4';
4949
const notIssueParsed = parseIssueExpressionOutput(notIssue.match(ISSUE_OR_URL_EXPRESSION));
5050
assert.strictEqual(notIssueParsed, undefined);
51+
52+
// Test PR URL parsing
53+
const prUrl = 'https://github.com/microsoft/vscode/pull/123';
54+
const prUrlParsed = parseIssueExpressionOutput(prUrl.match(ISSUE_OR_URL_EXPRESSION));
55+
assert.strictEqual(prUrlParsed?.issueNumber, 123);
56+
assert.strictEqual(prUrlParsed?.commentNumber, undefined);
57+
assert.strictEqual(prUrlParsed?.name, 'vscode');
58+
assert.strictEqual(prUrlParsed?.owner, 'microsoft');
59+
60+
// Test HTTP PR URL (without S)
61+
const prUrlHttp = 'http://github.com/owner/repo/pull/456';
62+
const prUrlHttpParsed = parseIssueExpressionOutput(prUrlHttp.match(ISSUE_OR_URL_EXPRESSION));
63+
assert.strictEqual(prUrlHttpParsed?.issueNumber, 456);
64+
assert.strictEqual(prUrlHttpParsed?.commentNumber, undefined);
65+
assert.strictEqual(prUrlHttpParsed?.name, 'repo');
66+
assert.strictEqual(prUrlHttpParsed?.owner, 'owner');
5167
});
5268
});

0 commit comments

Comments
 (0)