forked from renovatebot/renovate
-
Notifications
You must be signed in to change notification settings - Fork 0
/
branch-name.ts
130 lines (115 loc) · 4.41 KB
/
branch-name.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// TODO #22198
import cleanGitRef from 'clean-git-ref';
import slugify from 'slugify';
import type { RenovateConfig } from '../../../config/types';
import { logger } from '../../../logger';
import { hash } from '../../../util/hash';
import { regEx } from '../../../util/regex';
import * as template from '../../../util/template';
const MIN_HASH_LENGTH = 6;
const RE_MULTIPLE_DASH = regEx(/--+/g);
const RE_SPECIAL_CHARS_STRICT = regEx(/[`~!@#$%^&*()_=+[\]\\|{};':",.<>?]/g);
/**
* Clean git branch name
*
* Remove what clean-git-ref fails to:
* - leading dot/leading dot after slash
* - trailing dot
* - whitespace
* - special characters
* - leading or trailing dashes
* - chained dashes(breaks markdown comments) are replaced by single dash
*/
function cleanBranchName(
branchName: string,
branchNameStrict?: boolean,
): string {
let cleanedBranchName = branchName;
if (branchNameStrict) {
cleanedBranchName = cleanedBranchName.replace(RE_SPECIAL_CHARS_STRICT, '-'); // massage out all special characters that slip through slugify
}
return cleanGitRef
.clean(cleanedBranchName)
.replace(regEx(/^\.|\.$/), '') // leading or trailing dot
.replace(regEx(/\/\./g), '/') // leading dot after slash
.replace(regEx(/\s/g), '') // whitespace
.replace(regEx(/[[\]?:\\^~]/g), '-') // massage out all these characters: [ ] ? : \ ^ ~
.replace(regEx(/(^|\/)-+/g), '$1') // leading dashes
.replace(regEx(/-+(\/|$)/g), '$1') // trailing dashes
.replace(RE_MULTIPLE_DASH, '-'); // chained dashes
}
export function generateBranchName(update: RenovateConfig): void {
// Check whether to use a group name
const newMajor = String(update.newMajor);
const newMinor = String(update.newMinor);
if (update.groupName) {
update.groupName = template.compile(update.groupName, update);
logger.trace('Using group branchName template');
// TODO: types (#22198)
logger.trace(
`Dependency ${update.depName!} is part of group ${update.groupName}`,
);
if (update.groupSlug) {
update.groupSlug = template.compile(update.groupSlug, update);
} else {
update.groupSlug = update.groupName;
}
update.groupSlug = slugify(update.groupSlug, {
lower: true,
});
if (update.updateType === 'major' && update.separateMajorMinor) {
if (update.separateMultipleMajor) {
update.groupSlug = `major-${newMajor}-${update.groupSlug}`;
} else {
update.groupSlug = `major-${update.groupSlug}`;
}
}
if (update.updateType === 'minor' && update.separateMultipleMinor) {
update.groupSlug = `minor-${newMajor}.${newMinor}-${update.groupSlug}`;
}
if (update.updateType === 'patch' && update.separateMinorPatch) {
update.groupSlug = `patch-${update.groupSlug}`;
}
update.branchTopic = update.group!.branchTopic ?? update.branchTopic;
update.branchName = update.group!.branchName ?? update.branchName;
}
if (update.hashedBranchLength) {
let hashLength = update.hashedBranchLength - update.branchPrefix!.length;
if (hashLength < MIN_HASH_LENGTH) {
logger.warn(
`\`hashedBranchLength\` must allow for at least ${MIN_HASH_LENGTH} characters hashing in addition to \`branchPrefix\`. Using ${MIN_HASH_LENGTH} character hash instead.`,
);
hashLength = MIN_HASH_LENGTH;
}
const additionalBranchPrefix = template.compile(
String(update.additionalBranchPrefix ?? ''),
update,
);
const branchTopic = template.compile(
String(update.branchTopic ?? ''),
update,
);
let hashInput = additionalBranchPrefix + branchTopic;
// Compile extra times in case of nested templates
hashInput = template.compile(hashInput, update);
hashInput = template.compile(hashInput, update);
const hashedInput = hash(hashInput);
// TODO: types (#22198)
update.branchName = `${update.branchPrefix!}${hashedInput.slice(
0,
hashLength,
)}`;
} else {
update.branchName = template.compile(update.branchName!, update);
// Compile extra times in case of nested templates
update.branchName = template.compile(update.branchName, update);
update.branchName = template.compile(update.branchName, update);
}
if (update.updateType === 'minor' && update.separateMultipleMinor) {
update.branchName = update.branchName.replace('.x', `.${newMinor}.x`);
}
update.branchName = cleanBranchName(
update.branchName,
update.branchNameStrict,
);
}