Skip to content

Commit 9e76710

Browse files
committed
Improves branch autolinks
1 parent bf3b6b4 commit 9e76710

File tree

5 files changed

+183
-88
lines changed

5 files changed

+183
-88
lines changed

ThirdPartyNotices.txt

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,9 @@ This project incorporates components from the projects listed below.
3232
27. react version 16.8.4 (https://github.com/facebook/react)
3333
28. signal-utils version 0.21.1 (https://github.com/proposal-signals/signal-utils)
3434
29. slug version 10.0.0 (https://github.com/Trott/slug)
35-
30. sortablejs version 1.15.0 (https://github.com/SortableJS/Sortable)
36-
31. xdg-basedir version 5.1.0 (https://github.com/sindresorhus/xdg-basedir)
35+
30. slugify version 1.6.6 (https://github.com/simov/slugify)
36+
31. sortablejs version 1.15.0 (https://github.com/SortableJS/Sortable)
37+
32. xdg-basedir version 5.1.0 (https://github.com/sindresorhus/xdg-basedir)
3738

3839
%% @gk-nzaytsev/fast-string-truncated-width NOTICES AND INFORMATION BEGIN HERE
3940
=========================================
@@ -2220,6 +2221,33 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
22202221
=========================================
22212222
END OF slug NOTICES AND INFORMATION
22222223

2224+
%% slugify NOTICES AND INFORMATION BEGIN HERE
2225+
=========================================
2226+
The MIT License (MIT)
2227+
2228+
Copyright (c) Simeon Velichkov <[email protected]>
2229+
2230+
Permission is hereby granted, free of charge, to any person obtaining a copy
2231+
of this software and associated documentation files (the "Software"), to deal
2232+
in the Software without restriction, including without limitation the rights
2233+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
2234+
copies of the Software, and to permit persons to whom the Software is
2235+
furnished to do so, subject to the following conditions:
2236+
2237+
The above copyright notice and this permission notice shall be included in all
2238+
copies or substantial portions of the Software.
2239+
2240+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2241+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2242+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2243+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2244+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2245+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2246+
SOFTWARE.
2247+
2248+
=========================================
2249+
END OF slugify NOTICES AND INFORMATION
2250+
22232251
%% sortablejs NOTICES AND INFORMATION BEGIN HERE
22242252
=========================================
22252253
MIT License

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20119,6 +20119,7 @@
2011920119
"react-dom": "16.8.4",
2012020120
"signal-utils": "0.21.1",
2012120121
"slug": "10.0.0",
20122+
"slugify": "1.6.6",
2012220123
"sortablejs": "1.15.0",
2012320124
"xdg-basedir": "5.1.0"
2012420125
},

pnpm-lock.yaml

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/autolinks/__tests__/autolinks.test.ts

Lines changed: 83 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2,88 +2,131 @@ import * as assert from 'assert';
22
import { suite, test } from 'mocha';
33
import { map } from '../../system/iterable';
44
import type { Autolink, RefSet } from '../autolinks.utils';
5-
import { getAutolinks, getBranchAutolinks } from '../autolinks.utils';
5+
import { calculatePriority, getAutolinks, getBranchAutolinks } from '../autolinks.utils';
66

7-
const mockRefSets = (prefixes: string[] = ['']): RefSet[] =>
7+
const mockRefSets = (prefixes: string[] = [''], title = 'test'): RefSet[] =>
88
prefixes.map(prefix => [
99
{ domain: 'test', icon: '1', id: '1', name: 'test' },
1010
[
1111
{
1212
alphanumeric: false,
1313
ignoreCase: false,
1414
prefix: prefix,
15-
title: 'test',
15+
title: title,
1616
url: '<num>',
1717
description: 'test',
1818
},
1919
],
2020
]);
2121

22-
function assertAutolinks(actual: Map<string, Autolink>, expected: Array<string>): void {
23-
assert.deepEqual([...map(actual.values(), x => x.url)], expected);
22+
function assertAutolinks(actual: Map<string, Autolink>, expected: Array<string>, message: string): void {
23+
assert.deepEqual([...map(actual.values(), x => x.url)], expected, message);
2424
}
2525

2626
suite('Autolinks Test Suite', () => {
2727
test('Branch name autolinks', () => {
28-
assertAutolinks(getBranchAutolinks('123', mockRefSets()), ['123']);
29-
assertAutolinks(getBranchAutolinks('feature/123', mockRefSets()), ['123']);
30-
assertAutolinks(getBranchAutolinks('feature/PRE-123', mockRefSets()), ['123']);
31-
assertAutolinks(getBranchAutolinks('123.2', mockRefSets()), ['123']);
32-
assertAutolinks(getBranchAutolinks('123', mockRefSets(['PRE-'])), []);
33-
assertAutolinks(getBranchAutolinks('feature/123', mockRefSets(['PRE-'])), []);
34-
assertAutolinks(getBranchAutolinks('feature/2-fa/123', mockRefSets([''])), ['123', '2']);
35-
assertAutolinks(getBranchAutolinks('feature/2-fa/123', mockRefSets([''])), ['123', '2']);
36-
assertAutolinks(getBranchAutolinks('feature/2-fa/3', mockRefSets([''])), ['3', '2']);
37-
assertAutolinks(getBranchAutolinks('feature/PRE-123', mockRefSets(['PRE-'])), ['123']);
38-
assertAutolinks(getBranchAutolinks('feature/PRE-123.2', mockRefSets(['PRE-'])), ['123']);
39-
assertAutolinks(getBranchAutolinks('feature/3-123-PRE-123', mockRefSets(['PRE-'])), ['123']);
28+
assertAutolinks(getBranchAutolinks('123', mockRefSets()), ['123'], 'test-1');
29+
assertAutolinks(getBranchAutolinks('feature/123', mockRefSets()), ['123'], 'test-2');
30+
assertAutolinks(getBranchAutolinks('feature/PRE-123', mockRefSets()), ['123'], 'test-3');
31+
assertAutolinks(getBranchAutolinks('123.2', mockRefSets()), ['123'], 'test-4');
32+
assertAutolinks(getBranchAutolinks('123', mockRefSets(['PRE-'])), [], 'test-5');
33+
assertAutolinks(getBranchAutolinks('feature/123', mockRefSets(['PRE-'])), [], 'test-6');
34+
assertAutolinks(getBranchAutolinks('feature/2-fa/123', mockRefSets([''])), ['123', '2'], 'test-7');
35+
assertAutolinks(getBranchAutolinks('feature/2-fa/123', mockRefSets([''])), ['123', '2'], 'test-8');
36+
assertAutolinks(getBranchAutolinks('feature/2-fa/3', mockRefSets([''])), ['3', '2'], 'test-9');
37+
assertAutolinks(getBranchAutolinks('feature/PRE-123', mockRefSets(['PRE-'])), ['123'], 'test-10');
38+
assertAutolinks(getBranchAutolinks('feature/PRE-123.2', mockRefSets(['PRE-'])), ['123'], 'test-11');
39+
assertAutolinks(getBranchAutolinks('feature/3-123-PRE-123', mockRefSets(['PRE-'])), ['123'], 'test-12');
4040
assertAutolinks(
4141
getBranchAutolinks('feature/3-123-PRE-123', mockRefSets(['', 'PRE-'])),
4242

4343
['123', '3'],
44+
'test-13',
4445
);
4546
});
4647

4748
test('Commit message autolinks', () => {
48-
assertAutolinks(getAutolinks('test message 123 sd', mockRefSets()), ['123']);
49+
assertAutolinks(getAutolinks('test message 123 sd', mockRefSets()), ['123'], 'test-14');
4950
});
5051

52+
test('Test autolink priority comparation', () => {
53+
assert.equal(calculatePriority('1', 0, '1', 1) > calculatePriority('1', 0, '1', 0), true, 'test-15');
54+
assert.equal(calculatePriority('1', 0, '1', 2) > calculatePriority('1', 1, '1', 0), true, 'test-16');
55+
assert.equal(calculatePriority('1', 0, '1', 2) > calculatePriority('1', 0, '1.1', 2), true, 'test-17');
56+
assert.equal(calculatePriority('2', 0, '2', 2) > calculatePriority('1', 0, '1', 2), true, 'test-19');
57+
});
5158
/**
5259
* 16.1.1^ - improved branch name autolinks matching
5360
*/
5461
test('Improved branch name autolinks matching', () => {
5562
// skip branch names chunks matching '^release(?=(-(?<number-chunk>))$` or other release-like values
5663
// skip pair in case of double chunk
57-
assertAutolinks(getBranchAutolinks('folder/release/16/issue-1', mockRefSets([''])), ['1']);
58-
assertAutolinks(getBranchAutolinks('folder/release/16.1/issue-1', mockRefSets([''])), ['1']);
59-
assertAutolinks(getBranchAutolinks('folder/release/16.1.1/1', mockRefSets([''])), ['1']);
60-
// skip one in case of single chunk
61-
assertAutolinks(getBranchAutolinks('folder/release-16/1', mockRefSets([''])), ['1']);
62-
assertAutolinks(getBranchAutolinks('folder/release-16.1/1', mockRefSets([''])), ['1']);
63-
assertAutolinks(getBranchAutolinks('folder/release-16.1.2/1', mockRefSets([''])), ['1']);
64+
assertAutolinks(getBranchAutolinks('folder/release/16/issue-1', mockRefSets([''])), ['1'], 'test-20');
65+
assertAutolinks(getBranchAutolinks('folder/release/16.1/issue-1', mockRefSets([''])), ['1'], 'test-21');
66+
assertAutolinks(getBranchAutolinks('folder/release/16.1.1/1', mockRefSets([''])), ['1'], 'test-22');
67+
assertAutolinks(getBranchAutolinks('release-2024', mockRefSets([''])), [], 'test-23');
68+
assertAutolinks(getBranchAutolinks('v-2024', mockRefSets([''])), [], 'test-24');
69+
assertAutolinks(getBranchAutolinks('v2024', mockRefSets([''])), [], 'test-25');
70+
// cannot be definitely handled
71+
assertAutolinks(getBranchAutolinks('some-issue-in-release-2024', mockRefSets([''])), ['2024'], 'test-26');
72+
assertAutolinks(getBranchAutolinks('folder/release-notes-16-1', mockRefSets([''])), ['16'], 'test-27');
73+
assertAutolinks(getBranchAutolinks('folder/16-1-release-notes', mockRefSets([''])), ['16'], 'test-28');
74+
// skip next in case of single chunk
75+
assertAutolinks(getBranchAutolinks('folder/release-16/1', mockRefSets([''])), ['1'], 'test-29');
76+
assertAutolinks(getBranchAutolinks('folder/release-16.1/1', mockRefSets([''])), ['1'], 'test-30');
77+
assertAutolinks(getBranchAutolinks('folder/release-16.1.2/1', mockRefSets([''])), ['1'], 'test-31');
6478

6579
/**
6680
* Added chunk matching logic for non-prefixed numbers:
6781
* - XX - is more likely issue number
6882
* - XX.XX - is less likely issue number, but still possible
69-
* - XX.XX.XX - is more likely not issue number
83+
* - XX.XX.XX - is more likely not issue number: seems like a date or version number
7084
*/
71-
assertAutolinks(getBranchAutolinks('some-issue-in-release-2024', mockRefSets([''])), ['2024']);
72-
assertAutolinks(getBranchAutolinks('some-issue-in-release-2024.1', mockRefSets([''])), ['2024']);
73-
assertAutolinks(getBranchAutolinks('some-issue-in-release-2024.1.1', mockRefSets([''])), []);
85+
assertAutolinks(getBranchAutolinks('issue-2024', mockRefSets([''])), ['2024'], 'test-32');
86+
assertAutolinks(getBranchAutolinks('issue-2024.1', mockRefSets([''])), ['2024'], 'test-33');
87+
assertAutolinks(getBranchAutolinks('issue-2024.1.1', mockRefSets([''])), [], 'test-34');
7488

75-
assertAutolinks(getBranchAutolinks('folder/release-notes-16-1', mockRefSets([''])), ['16']);
76-
assertAutolinks(getBranchAutolinks('folder/16-1-release-notes', mockRefSets([''])), ['16']);
89+
// the chunk that is more close to the end is more likely actual issue number
90+
assertAutolinks(
91+
getBranchAutolinks('1-epic-folder/10-issue/100-subissue', mockRefSets([''])),
92+
['100', '10', '1'],
93+
'test-35',
94+
);
7795

78-
// considered the distance from the edges of the chunk as a priority sign
79-
assertAutolinks(getBranchAutolinks('folder/16-content-1-content', mockRefSets([''])), ['16', '1']);
80-
assertAutolinks(getBranchAutolinks('folder/content-1-content-16', mockRefSets([''])), ['16', '1']);
96+
// ignore numbers from title
97+
assertAutolinks(
98+
getBranchAutolinks('folder/100-content-content-16', mockRefSets([''], '100-content-content')),
99+
['16'],
100+
'test-36',
101+
);
102+
assertAutolinks(
103+
getBranchAutolinks('folder/100-content-content-16', mockRefSets([''], 'content-content-16')),
104+
['100'],
105+
'test-37',
106+
);
81107

82-
// the chunk that is more close to the end is more likely actual issue number
83-
assertAutolinks(getBranchAutolinks('1-epic-folder/10-issue/100-subissue', mockRefSets([''])), [
84-
'100',
85-
'10',
86-
'1',
87-
]);
108+
// consider edge distance and issue key length to sort
109+
assertAutolinks(
110+
getBranchAutolinks('2-some-issue-in-release-2024', mockRefSets([''])),
111+
['2024', '2'],
112+
'test-38',
113+
);
114+
assertAutolinks(
115+
getBranchAutolinks('2024-some-issue-in-release-2', mockRefSets([''])),
116+
['2024', '2'],
117+
'test-39',
118+
);
119+
assertAutolinks(
120+
getBranchAutolinks('some-2-issue-in-release-2024', mockRefSets([''])),
121+
['2024', '2'],
122+
'test-40',
123+
);
124+
assertAutolinks(
125+
getBranchAutolinks('4048-issue-in-release-2024.1', mockRefSets([''])),
126+
['4048', '2024'],
127+
'test-41',
128+
);
129+
// less numbers - more likely issue key
130+
assertAutolinks(getBranchAutolinks('1-issue-in-release-2024.1', mockRefSets([''])), ['1', '2024'], 'test-42');
88131
});
89132
});

0 commit comments

Comments
 (0)