Skip to content

Commit f620cc4

Browse files
committed
Improves PR matching expression
(#3543)
1 parent d9cb63f commit f620cc4

File tree

2 files changed

+85
-3
lines changed

2 files changed

+85
-3
lines changed
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import * as assert from 'assert';
2+
import { suite, test } from 'mocha';
3+
import { getPullRequestIdentityValuesFromSearch } from '../github';
4+
5+
suite('Test GitHub PR URL parsing to identity: getPullRequestIdentityValuesFromSearch()', () => {
6+
function t(message: string, query: string, prNumber: string | undefined, ownerAndRepo?: string) {
7+
assert.deepStrictEqual(
8+
getPullRequestIdentityValuesFromSearch(query),
9+
{
10+
ownerAndRepo: ownerAndRepo,
11+
prNumber: prNumber,
12+
},
13+
message,
14+
);
15+
}
16+
17+
test('full URL or without protocol but with domain, should parse to ownerAndRepo and prNumber', () => {
18+
t('full URL', 'https://github.com/eamodio/vscode-gitlens/pull/1', '1', 'eamodio/vscode-gitlens');
19+
t(
20+
'with suffix',
21+
'https://github.com/eamodio/vscode-gitlens/pull/1/files?diff=unified#hello',
22+
'1',
23+
'eamodio/vscode-gitlens',
24+
);
25+
t(
26+
'with query',
27+
'https://github.com/eamodio/vscode-gitlens/pull/1?diff=unified#hello',
28+
'1',
29+
'eamodio/vscode-gitlens',
30+
);
31+
32+
t('with anchor', 'https://github.com/eamodio/vscode-gitlens/pull/1#hello', '1', 'eamodio/vscode-gitlens');
33+
t('a weird suffix', 'https://github.com/eamodio/vscode-gitlens/pull/1-files', '1', 'eamodio/vscode-gitlens');
34+
t('numeric repo name', 'https://github.com/sergeibbb/1/pull/16', '16', 'sergeibbb/1');
35+
36+
t('no protocol with leading slash', '/github.com/sergeibbb/1/pull/16?diff=unified', '16', 'sergeibbb/1');
37+
t('no protocol without leading slash', 'github.com/sergeibbb/1/pull/16/files', '16', 'sergeibbb/1');
38+
});
39+
40+
test('no domain, should parse to ownerAndRepo and prNumber', () => {
41+
t('with leading slash', '/sergeibbb/1/pull/16#hello', '16', 'sergeibbb/1');
42+
t('words in repo name', 'eamodio/vscode-gitlens/pull/1?diff=unified#hello', '1', 'eamodio/vscode-gitlens');
43+
t('numeric repo name', 'sergeibbb/1/pull/16/files', '16', 'sergeibbb/1');
44+
});
45+
46+
test('domain vs. no domain', () => {
47+
t(
48+
'with anchor',
49+
'https://github.com/eamodio/vscode-gitlens/pull/1#hello/sergeibbb/1/pull/16',
50+
'1',
51+
'eamodio/vscode-gitlens',
52+
);
53+
});
54+
55+
test('has "pull/" fragment', () => {
56+
t('with leading slash', '/pull/16/files#hello', '16');
57+
t('without leading slash', 'pull/16?diff=unified#hello', '16');
58+
t('with numeric repo name', '1/pull/16?diff=unified#hello', '16');
59+
t('with double slash', '1//pull/16?diff=unified#hello', '16');
60+
});
61+
62+
test('has "/<num>" or "#<num>" fragment', () => {
63+
t('with leading slash', '/16/files#hello', '16');
64+
});
65+
66+
test('does not match', () => {
67+
t('without leading slash', '16?diff=unified#hello', undefined);
68+
t('with a number', '1/16?diff=unified#hello', '16');
69+
t('with a number and slash', '/1/16?diff=unified#hello', '1');
70+
t('with a word', 'anything/16?diff=unified#hello', '16');
71+
72+
t('with a wrong character leading to pull', 'sergeibbb/1/-pull/16?diff=unified#hello', '1');
73+
t('with a wrong character leading to pull', 'sergeibbb/1-pull/16?diff=unified#hello', '1');
74+
});
75+
});

src/plus/integrations/providers/github.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -319,23 +319,30 @@ export class GitHubEnterpriseIntegration extends GitHubIntegrationBase<SelfHoste
319319
}
320320
}
321321

322-
const GitHubPullRequestUrlRegex = /github\.com\/([^/]+\/[^/]+)\/pull\/(\d+)/;
323322
export type GitHubPullRequestURLIdentity = {
324323
ownerAndRepo?: string;
325324
prNumber?: string;
326325
};
327326

328327
export function getPullRequestIdentityValuesFromSearch(search: string): GitHubPullRequestURLIdentity {
329-
let match = search.match(GitHubPullRequestUrlRegex);
330328
let ownerAndRepo: string | undefined = undefined;
331329
let prNumber: string | undefined = undefined;
330+
331+
let match = search.match(/([^/]+\/[^/]+)\/pull\/(\d+)/); // with org and rep name
332332
if (match != null) {
333333
ownerAndRepo = match[1];
334334
prNumber = match[2];
335335
}
336336

337337
if (prNumber == null) {
338-
match = search.match(/(?:#|\/)(\d+)/);
338+
match = search.match(/(?:\/|^)pull\/(\d+)/); // without repo name
339+
if (match != null) {
340+
prNumber = match[1];
341+
}
342+
}
343+
344+
if (prNumber == null) {
345+
match = search.match(/(?:#|\/)(\d+)/); // any number starting with # or /
339346
if (match != null) {
340347
prNumber = match[1];
341348
}

0 commit comments

Comments
 (0)