Skip to content

Commit f0c137b

Browse files
committed
Fix review notes
1 parent a76a6a2 commit f0c137b

File tree

4 files changed

+59
-93
lines changed

4 files changed

+59
-93
lines changed

CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
66

77
## [Unreleased]
88

9+
### Added
10+
11+
- Adds the ability to get autolinks for branches using branch name [#3547](https://github.com/gitkraken/vscode-gitlens/issues/3547)
12+
913
## [16.0.2] - 2024-11-18
1014

1115
### Changed
@@ -132,7 +136,6 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
132136
- Adds new ability to force push from the _Commit Graph_ toolbar — closes [#3493](https://github.com/gitkraken/vscode-gitlens/issues/3493)
133137
- Adds a new `gitlens.launchpad.includedOrganizations` setting to specify which organizations to include in _Launchpad_ — closes [#3550](https://github.com/gitkraken/vscode-gitlens/issues/3550)
134138
- Adds repository owner/name and code suggest to hovers on the experimental Launchpad view
135-
- Adds getBranchAutolinks method to Autolinks class [#3547](https://github.com/gitkraken/vscode-gitlens/issues/3547)
136139

137140
### Changed
138141

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19602,7 +19602,7 @@
1960219602
"update-dts:main": "pushd \"src/@types\" && pnpx @vscode/dts main && popd",
1960319603
"update-emoji": "node ./scripts/generateEmojiShortcodeMap.mjs",
1960419604
"update-licenses": "node ./scripts/generateLicenses.mjs",
19605-
"pretest": "pnpm run build:tests",
19605+
"//pretest": "pnpm run build:tests",
1960619606
"vscode:prepublish": "pnpm run bundle"
1960719607
},
1960819608
"dependencies": {
Lines changed: 23 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as assert from 'assert';
22
import { suite, test } from 'mocha';
3-
import type { RefSet } from '../autolinks';
3+
import { map } from '../../system/iterable';
4+
import type { Autolink, RefSet } from '../autolinks';
45
import { Autolinks } from '../autolinks';
56

67
const mockRefSets = (prefixes: string[] = ['']): RefSet[] =>
@@ -18,54 +19,33 @@ const mockRefSets = (prefixes: string[] = ['']): RefSet[] =>
1819
],
1920
]);
2021

22+
function assertAutolinks(actual: Map<string, Autolink>, expected: Array<string>): void {
23+
assert.deepEqual([...map(actual.values(), x => x.url)], expected);
24+
}
25+
2126
suite('Autolinks Test Suite', () => {
2227
test('Branch name autolinks', () => {
23-
assert.deepEqual(
24-
Autolinks._getBranchAutolinks('123', mockRefSets()).map(x => x.url),
25-
['test/123'],
26-
);
27-
assert.deepEqual(
28-
Autolinks._getBranchAutolinks('feature/123', mockRefSets()).map(x => x.url),
29-
['test/123'],
30-
);
31-
assert.deepEqual(
32-
Autolinks._getBranchAutolinks('feature/PRE-123', mockRefSets()).map(x => x.url),
33-
['test/123'],
34-
);
35-
assert.deepEqual(
36-
Autolinks._getBranchAutolinks('123.2', mockRefSets()).map(x => x.url),
37-
['test/123', 'test/2'],
38-
);
39-
assert.deepEqual(
40-
Autolinks._getBranchAutolinks('123', mockRefSets(['PRE-'])).map(x => x.url),
41-
[],
42-
);
43-
assert.deepEqual(
44-
Autolinks._getBranchAutolinks('feature/123', mockRefSets(['PRE-'])).map(x => x.url),
45-
[],
46-
);
47-
assert.deepEqual(
48-
Autolinks._getBranchAutolinks('feature/PRE-123', mockRefSets(['PRE-'])).map(x => x.url),
49-
['test/123'],
50-
);
51-
assert.deepEqual(
52-
Autolinks._getBranchAutolinks('feature/PRE-123.2', mockRefSets(['PRE-'])).map(x => x.url),
53-
['test/123'],
54-
);
55-
assert.deepEqual(
56-
Autolinks._getBranchAutolinks('feature/3-123-PRE-123', mockRefSets(['PRE-'])).map(x => x.url),
57-
['test/123'],
58-
);
59-
assert.deepEqual(
60-
Autolinks._getBranchAutolinks('feature/3-123-PRE-123', mockRefSets(['', 'PRE-'])).map(x => x.url),
28+
assertAutolinks(Autolinks._getBranchAutolinks('123', mockRefSets()), ['test/123']);
29+
assertAutolinks(Autolinks._getBranchAutolinks('feature/123', mockRefSets()), ['test/123']);
30+
assertAutolinks(Autolinks._getBranchAutolinks('feature/PRE-123', mockRefSets()), ['test/123']);
31+
assertAutolinks(Autolinks._getBranchAutolinks('123.2', mockRefSets()), ['test/123', 'test/2']);
32+
assertAutolinks(Autolinks._getBranchAutolinks('123', mockRefSets(['PRE-'])), []);
33+
assertAutolinks(Autolinks._getBranchAutolinks('feature/123', mockRefSets(['PRE-'])), []);
34+
assertAutolinks(Autolinks._getBranchAutolinks('feature/2-fa/123', mockRefSets([''])), ['test/123', 'test/2']);
35+
assertAutolinks(Autolinks._getBranchAutolinks('feature/2-fa/123', mockRefSets([''])), ['test/123', 'test/2']);
36+
// incorrectly solved case, maybe it worths to compare the blocks length so that the less block size (without possible link) is more likely a link
37+
assertAutolinks(Autolinks._getBranchAutolinks('feature/2-fa/3', mockRefSets([''])), ['test/2', 'test/3']);
38+
assertAutolinks(Autolinks._getBranchAutolinks('feature/PRE-123', mockRefSets(['PRE-'])), ['test/123']);
39+
assertAutolinks(Autolinks._getBranchAutolinks('feature/PRE-123.2', mockRefSets(['PRE-'])), ['test/123']);
40+
assertAutolinks(Autolinks._getBranchAutolinks('feature/3-123-PRE-123', mockRefSets(['PRE-'])), ['test/123']);
41+
assertAutolinks(
42+
Autolinks._getBranchAutolinks('feature/3-123-PRE-123', mockRefSets(['', 'PRE-'])),
43+
6144
['test/123', 'test/3'],
6245
);
6346
});
6447

6548
test('Commit message autolinks', () => {
66-
assert.deepEqual(
67-
[...Autolinks._getAutolinks('test message 123 sd', mockRefSets()).values()].map(x => x.url),
68-
['test/123'],
69-
);
49+
assertAutolinks(Autolinks._getAutolinks('test message 123 sd', mockRefSets()), ['test/123']);
7050
});
7151
});

src/autolinks/autolinks.ts

Lines changed: 31 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ export interface AutolinkReference {
4646
export interface Autolink extends AutolinkReference {
4747
provider?: ProviderReference;
4848
id: string;
49+
index: number;
4950

5051
tokenize?:
5152
| ((
@@ -80,6 +81,7 @@ export function serializeAutolink(value: Autolink): Autolink {
8081
}
8182
: undefined,
8283
id: value.id,
84+
index: value.index,
8385
prefix: value.prefix,
8486
url: value.url,
8587
alphanumeric: value.alphanumeric,
@@ -126,7 +128,7 @@ export interface DynamicAutolinkReference {
126128

127129
export const supportedAutolinkIntegrations = [IssueIntegrationId.Jira];
128130

129-
export function isDynamic(ref: AutolinkReference | DynamicAutolinkReference): ref is DynamicAutolinkReference {
131+
function isDynamic(ref: AutolinkReference | DynamicAutolinkReference): ref is DynamicAutolinkReference {
130132
return !('prefix' in ref) && !('url' in ref);
131133
}
132134

@@ -139,14 +141,6 @@ export type RefSet = [
139141
(AutolinkReference | DynamicAutolinkReference)[] | CacheableAutolinkReference[],
140142
];
141143

142-
type ComparingAutolinkSet = {
143-
/** the place where the autolink is found from start-like symbol (/|_) */
144-
index: number;
145-
/** the place where the autolink is found from start */
146-
startIndex: number;
147-
autolink: Autolink;
148-
};
149-
150144
export class Autolinks implements Disposable {
151145
protected _disposable: Disposable | undefined;
152146
private _references: CacheableAutolinkReference[] = [];
@@ -223,7 +217,7 @@ export class Autolinks implements Disposable {
223217
/**
224218
* it should always return non-0 result that means a probability of the autolink `b` is more relevant of the autolink `a`
225219
*/
226-
private static compareAutolinks(a: ComparingAutolinkSet, b: ComparingAutolinkSet) {
220+
private static compareAutolinks(a: Autolink, b: Autolink) {
227221
// consider that if the number is in the start, it's the most relevant link
228222
if (b.index === 0) {
229223
return 1;
@@ -232,34 +226,35 @@ export class Autolinks implements Disposable {
232226
return -1;
233227
}
234228
// maybe it worths to use some weight function instead.
235-
return (
236-
b.autolink.prefix.length - a.autolink.prefix.length ||
237-
-(b.startIndex - a.startIndex) ||
238-
-(b.index - a.index)
239-
);
229+
return b.prefix.length - a.prefix.length || b.id.length - a.id.length || -(b.index - a.index);
240230
}
241231

242-
/**
243-
* returns sorted list of autolinks. the first is matched as the most relevant
244-
*/
245-
async getBranchAutolinks(
246-
branchName: string,
247-
remote?: GitRemote,
248-
options?: { excludeCustom: boolean },
249-
): Promise<undefined | Autolink[]> {
232+
private async getRefsets(remote?: GitRemote, options?: { excludeCustom?: boolean }) {
250233
const refsets: RefSet[] = [];
251234
await this.collectIntegrationAutolinks(refsets);
252235
await this.collectRemoteAutolinks(remote, refsets);
253236
if (!options?.excludeCustom) {
254237
this.collectCustomAutolinks(remote, refsets);
255238
}
256-
if (refsets.length === 0) return undefined;
239+
return refsets;
240+
}
241+
242+
/**
243+
* returns sorted list of autolinks. the first is matched as the most relevant
244+
*/
245+
async getBranchAutolinks(
246+
branchName: string,
247+
remote?: GitRemote,
248+
options?: { excludeCustom?: boolean },
249+
): Promise<Map<string, Autolink>> {
250+
const refsets = await this.getRefsets(remote, options);
251+
if (refsets.length === 0) return emptyAutolinkMap;
257252

258253
return Autolinks._getBranchAutolinks(branchName, refsets);
259254
}
260255

261256
static _getBranchAutolinks(branchName: string, refsets: Readonly<RefSet[]>) {
262-
const autolinks = new Map<string, ComparingAutolinkSet>();
257+
const autolinks = new Map<string, Autolink>();
263258

264259
let match;
265260
let num;
@@ -286,28 +281,20 @@ export class Autolinks implements Disposable {
286281
index = Math.min(index, autolinks.get(linkUrl)!.index);
287282
}
288283
autolinks.set(linkUrl, {
284+
...ref,
285+
provider: provider,
286+
id: num,
289287
index: index,
290-
// TODO: calc the distance from the nearest start-like symbol
291-
startIndex: 0,
292-
autolink: {
293-
...ref,
294-
provider: provider,
295-
id: num,
296-
297-
url: linkUrl,
298-
title: ref.title?.replace(numRegex, num),
299-
description: ref.description?.replace(numRegex, num),
300-
descriptor: ref.descriptor,
301-
},
288+
url: linkUrl,
289+
title: ref.title?.replace(numRegex, num),
290+
description: ref.description?.replace(numRegex, num),
291+
descriptor: ref.descriptor,
302292
});
303293
} while (!match.done);
304294
}
305295
}
306296

307-
return [...autolinks.values()]
308-
.flat()
309-
.sort(this.compareAutolinks)
310-
.map(x => x.autolink);
297+
return new Map([...autolinks.entries()].sort((a, b) => this.compareAutolinks(a[1], b[1])));
311298
}
312299

313300
async getAutolinks(message: string, remote?: GitRemote): Promise<Map<string, Autolink>>;
@@ -326,14 +313,9 @@ export class Autolinks implements Disposable {
326313
async getAutolinks(
327314
message: string,
328315
remote?: GitRemote,
329-
options?: { excludeCustom?: boolean; isBranchName?: boolean },
316+
options?: { excludeCustom?: boolean },
330317
): Promise<Map<string, Autolink>> {
331-
const refsets: RefSet[] = [];
332-
await this.collectIntegrationAutolinks(refsets);
333-
await this.collectRemoteAutolinks(remote, refsets);
334-
if (!options?.excludeCustom) {
335-
this.collectCustomAutolinks(remote, refsets);
336-
}
318+
const refsets = await this.getRefsets(remote, options);
337319
if (refsets.length === 0) return emptyAutolinkMap;
338320

339321
return Autolinks._getAutolinks(message, refsets);
@@ -363,6 +345,7 @@ export class Autolinks implements Disposable {
363345
autolinks.set(num, {
364346
provider: provider,
365347
id: num,
348+
index: match.index,
366349
prefix: ref.prefix,
367350
url: ref.url?.replace(numRegex, num),
368351
alphanumeric: ref.alphanumeric,

0 commit comments

Comments
 (0)