@taiga-ui/auto-changelog-config 0.494.0 → 0.496.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@taiga-ui/auto-changelog-config",
3
- "version": "0.494.0",
3
+ "version": "0.496.0",
4
4
  "description": "Taiga UI auto-changelog config",
5
5
  "keywords": [
6
6
  "auto-changelog"
package/setup.js CHANGED
@@ -3,6 +3,13 @@ module.exports = function (Handlebars) {
3
3
  const firstNonEmptyString = (...values) =>
4
4
  values.map((value) => String(value ?? '').trim()).find(Boolean) ?? '';
5
5
 
6
+ const toArray = (value) => (Array.isArray(value) ? value : []);
7
+
8
+ const escape = (value) => Handlebars.escapeExpression(String(value ?? ''));
9
+
10
+ const commitPattern =
11
+ /^(?:build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test)\s?(?:\((?<scope>[^)]*)\))?!?: (?<title>.*)$/;
12
+
6
13
  const getPullRequestId = (href) => {
7
14
  const [, id = ''] =
8
15
  String(href ?? '').match(
@@ -18,66 +25,17 @@ module.exports = function (Handlebars) {
18
25
  return id;
19
26
  };
20
27
 
21
- const isPullRequestHref = (href) =>
22
- /\/(?:pull|merge_requests|pull-requests)\/\d+(?:$|[/?#])/.test(
23
- String(href ?? ''),
24
- );
25
-
26
- const getCommitHashFromHref = (href) => {
27
- const [, hash = ''] =
28
- String(href ?? '').match(/\/commit\/([a-f\d]{7,40})(?:$|[/?#])/) ?? [];
29
-
30
- return hash;
31
- };
32
-
33
- const getRepositoryHref = (href) => {
34
- const [, repositoryHref = ''] =
35
- String(href ?? '').match(/^(https?:\/\/[^/]+\/[^/]+\/[^/]+)(?:\/|$)/) ?? [];
36
-
37
- return repositoryHref;
38
- };
39
-
40
- const getCommitHref = (commit, pullRequest) => {
41
- const href = firstNonEmptyString(commit.commitHref, commit.href);
42
-
43
- if (href.includes('/commit/')) {
44
- return href;
45
- }
46
-
47
- const hash = firstNonEmptyString(
48
- commit.hash,
49
- commit.shorthash,
50
- getCommitHashFromHref(href),
51
- );
52
-
53
- const repositoryHref = getRepositoryHref(
54
- firstNonEmptyString(pullRequest?.href, href),
55
- );
56
-
57
- return hash && repositoryHref ? `${repositoryHref}/commit/${hash}` : '';
58
- };
59
-
60
- const getCommitHash = (commit, commitHref) =>
61
- firstNonEmptyString(
62
- commit.commitHash,
63
- commit.shorthash,
64
- getCommitHashFromHref(commitHref),
65
- String(commit.hash ?? '').slice(0, 7),
66
- ).slice(0, 7);
67
-
68
- const normalizePullRequest = (commit, subject) => {
69
- const pullRequest = commit.pullRequest ?? {};
70
- const href = [pullRequest.href, commit.pullRequestHref, commit.href]
71
- .map(firstNonEmptyString)
72
- .find(isPullRequestHref);
28
+ const getPullRequest = (merge, subject) => {
29
+ const href = firstNonEmptyString(merge.href, merge.pullRequest?.href);
73
30
 
74
31
  const id = firstNonEmptyString(
75
- pullRequest.id,
76
- pullRequest.number,
32
+ merge.id,
33
+ merge.number,
34
+ merge.pullRequest?.id,
35
+ merge.pullRequest?.number,
77
36
  getPullRequestId(href),
37
+ getPullRequestIdFromText(merge.message),
78
38
  getPullRequestIdFromText(subject),
79
- getPullRequestIdFromText(commit.message),
80
- getPullRequestIdFromText(commit.title),
81
39
  );
82
40
 
83
41
  if (!id) {
@@ -85,155 +43,127 @@ module.exports = function (Handlebars) {
85
43
  }
86
44
 
87
45
  return {
88
- ...pullRequest,
89
46
  id,
90
- author: pullRequest.author ?? commit.author,
91
- href: href ?? '',
47
+ href,
92
48
  };
93
49
  };
94
50
 
95
- const normalizeCommit = (commit) => {
96
- const subject = firstNonEmptyString(
97
- commit.subject,
98
- commit.pullRequest?.title,
99
- commit.title,
100
- commit.message,
101
- );
51
+ const getPullRequestFromCommit = (commit) => {
52
+ const subject = firstNonEmptyString(commit.subject, commit.message);
53
+ const id = getPullRequestIdFromText(subject);
54
+
55
+ if (!id) {
56
+ return;
57
+ }
58
+
59
+ return {id};
60
+ };
102
61
 
103
- const pullRequest = normalizePullRequest(commit, subject);
104
- const commitHref = getCommitHref(commit, pullRequest);
105
- const commitHash = getCommitHash(commit, commitHref);
62
+ const normalizeMerge = (merge) => {
63
+ const commit = merge.commit ?? {};
64
+ const subject = firstNonEmptyString(commit.subject, merge.message);
106
65
 
107
66
  return {
108
67
  ...commit,
109
- commitHash,
110
- commitHref,
111
- message: firstNonEmptyString(commit.message, subject),
112
- pullRequest,
68
+ href: firstNonEmptyString(commit.href),
69
+ pullRequest: getPullRequest(merge, subject),
70
+ shorthash: firstNonEmptyString(commit.shorthash, merge.shorthash),
113
71
  subject,
114
72
  };
115
73
  };
116
74
 
75
+ const normalizeCommit = (commit) => ({
76
+ ...commit,
77
+ href: firstNonEmptyString(commit.href),
78
+ pullRequest: commit.pullRequest ?? getPullRequestFromCommit(commit),
79
+ shorthash: firstNonEmptyString(commit.shorthash),
80
+ subject: firstNonEmptyString(commit.subject, commit.message),
81
+ });
82
+
117
83
  const getCommitKey = (commit) =>
118
84
  firstNonEmptyString(
119
- commit.pullRequest?.id && `pr:${commit.pullRequest.id}`,
120
- commit.hash && `hash:${commit.hash}`,
121
- commit.commitHash && `hash:${commit.commitHash}`,
122
- commit.subject && `subject:${commit.subject}`,
85
+ commit.pullRequest?.id ? `pr:${commit.pullRequest.id}` : '',
86
+ commit.hash ? `hash:${commit.hash}` : '',
87
+ commit.shorthash ? `hash:${commit.shorthash}` : '',
88
+ commit.href,
89
+ commit.subject,
123
90
  );
124
91
 
125
- const mergePullRequests = (left, right) => {
126
- if (!left && !right) {
127
- return;
128
- }
92
+ const uniqueCommits = (commits) => [
93
+ ...commits
94
+ .reduce((map, commit) => {
95
+ const key = getCommitKey(commit);
129
96
 
130
- if (!left) {
131
- return right;
132
- }
97
+ if (key && !map.has(key)) {
98
+ map.set(key, commit);
99
+ }
100
+
101
+ return map;
102
+ }, new Map())
103
+ .values(),
104
+ ];
133
105
 
134
- if (!right) {
135
- return left;
106
+ const formatCommitTitle = (subject) => {
107
+ const string = String(subject ?? '').trim();
108
+ const {scope = '', title = ''} = commitPattern.exec(string)?.groups ?? {};
109
+ const cleanTitle = title.replace(/\s\(#\d+\)\s*$/, '');
110
+
111
+ if (!cleanTitle) {
112
+ return escape(string || 'empty commit name');
136
113
  }
137
114
 
138
- return {
139
- ...left,
140
- ...right,
141
- id: firstNonEmptyString(left.id, right.id),
142
- author: left.author ?? right.author,
143
- href: firstNonEmptyString(left.href, right.href),
144
- };
115
+ return scope
116
+ ? `**${escape(scope.toLowerCase())}**: ${escape(cleanTitle)}`
117
+ : escape(cleanTitle);
145
118
  };
146
119
 
147
- const mergeCommits = (left, right) => ({
148
- ...left,
149
- ...right,
150
- commitHash: firstNonEmptyString(left.commitHash, right.commitHash),
151
- commitHref: firstNonEmptyString(left.commitHref, right.commitHref),
152
- hash: firstNonEmptyString(left.hash, right.hash),
153
- href: firstNonEmptyString(left.href, right.href),
154
- message: firstNonEmptyString(left.message, right.message),
155
- pullRequest: mergePullRequests(left.pullRequest, right.pullRequest),
156
- shorthash: firstNonEmptyString(left.shorthash, right.shorthash),
157
- subject: firstNonEmptyString(left.subject, right.subject),
158
- });
120
+ const formatPullRequestReference = (commit) => {
121
+ const pullRequest = commit.pullRequest;
159
122
 
160
- const getCommitAuthor = (commit) =>
161
- commit.pullRequest?.author?.login ??
162
- commit.pullRequest?.user?.login ??
163
- commit.author?.login ??
164
- commit.user?.login ??
165
- commit.pullRequest?.author ??
166
- commit.author ??
167
- '';
168
-
169
- const isGithubLogin = (name) => /^[a-z\d](?:[a-z\d-]{0,37}[a-z\d])?$/i.test(name);
170
-
171
- const normalizeContributor = (author) => {
172
- const name = String(author).trim().replace(/^@/, '');
173
- const lowerName = name.toLowerCase();
174
-
175
- const isBot =
176
- lowerName.endsWith('[bot]') ||
177
- lowerName.endsWith('-bot') ||
178
- lowerName === 'dependabot' ||
179
- lowerName === 'renovatebot' ||
180
- lowerName === 'github-actions' ||
181
- lowerName === 'renovate' ||
182
- lowerName === 'gemini-code-assist';
183
-
184
- if (!name || isBot || !isGithubLogin(name)) {
123
+ if (!pullRequest?.id) {
185
124
  return '';
186
125
  }
187
126
 
188
- return `@${name}`;
127
+ const text = `#${escape(pullRequest.id)}`;
128
+
129
+ return pullRequest.href
130
+ ? `([${text}](${escape(pullRequest.href)}))`
131
+ : `(${text})`;
189
132
  };
190
133
 
191
- const formatContributors = (contributors) => {
192
- if (contributors.length === 1) {
193
- return contributors[0];
134
+ const formatCommitReference = (commit) => {
135
+ if (!commit.shorthash) {
136
+ return '';
194
137
  }
195
138
 
196
- if (contributors.length === 2) {
197
- return `${contributors[0]} and ${contributors[1]}`;
198
- }
139
+ const text = `(${escape(commit.shorthash)})`;
199
140
 
200
- return `${contributors.slice(0, -1).join(', ')} and ${
201
- contributors[contributors.length - 1]
202
- }`;
141
+ return commit.href ? `[${text}](${escape(commit.href)})` : text;
203
142
  };
204
143
 
205
- Handlebars.registerHelper('commit-parser', function (...args) {
206
- const options = args.pop();
207
-
208
- const commits = args.flat().filter(Boolean).map(normalizeCommit);
209
-
210
- const unique = commits.reduce((map, commit) => {
211
- const key = getCommitKey(commit);
212
-
213
- if (!key) {
214
- return map;
215
- }
216
-
217
- const previous = map.get(key);
218
-
219
- map.set(key, previous ? mergeCommits(previous, commit) : commit);
220
-
221
- return map;
222
- }, new Map());
223
-
224
- return options.fn([...unique.values()]);
144
+ const formatChangelogEntry = (commit) =>
145
+ [
146
+ formatCommitTitle(commit.subject),
147
+ formatPullRequestReference(commit),
148
+ formatCommitReference(commit),
149
+ ]
150
+ .filter(Boolean)
151
+ .join(' ');
152
+
153
+ Handlebars.registerHelper('commit-parser', function (merges, commits, options) {
154
+ const commitsFromMerges = toArray(merges).map(normalizeMerge);
155
+ const directCommits = toArray(commits).map(normalizeCommit);
156
+ const result = uniqueCommits(commitsFromMerges.concat(directCommits));
157
+
158
+ return options.fn(result);
225
159
  });
226
160
 
227
161
  Handlebars.registerHelper('replaceCommit', function (context) {
228
- const commit =
229
- /^(?:build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test)\s?(?:\((?<scope>[^)]*)\))?!?: (?<title>.*)$/;
230
-
231
- const string = String(context.fn(this)).trim();
232
- const {scope = '', title = ''} = commit.exec(string)?.groups ?? {};
233
- const cleanTitle = title.replace(/\s\(#\d+\)\s*$/, '');
234
- const result = scope ? `**${scope.toLowerCase()}**: ${cleanTitle}` : cleanTitle;
162
+ return new Handlebars.SafeString(formatCommitTitle(context.fn(this)));
163
+ });
235
164
 
236
- return result || string || 'empty commit name';
165
+ Handlebars.registerHelper('changelogEntry', function () {
166
+ return new Handlebars.SafeString(formatChangelogEntry(this));
237
167
  });
238
168
 
239
169
  Handlebars.registerHelper('replaceTitle', function (context) {
@@ -241,25 +171,4 @@ module.exports = function (Handlebars) {
241
171
 
242
172
  return string.replace(/^v/, '');
243
173
  });
244
-
245
- Handlebars.registerHelper('contributors', function (...args) {
246
- const options = args.pop();
247
-
248
- const commits = args.flat().filter(Boolean).map(normalizeCommit);
249
-
250
- const contributors = [
251
- ...new Set(
252
- commits.map(getCommitAuthor).map(normalizeContributor).filter(Boolean),
253
- ),
254
- ];
255
-
256
- if (!contributors.length) {
257
- return '';
258
- }
259
-
260
- return options.fn({
261
- contributors,
262
- text: `Thanks ${formatContributors(contributors)}!`,
263
- });
264
- });
265
174
  };
package/template.hbs CHANGED
@@ -7,15 +7,19 @@
7
7
  {{#commit-parser merges commits}}
8
8
 
9
9
  {{#commit-list this heading='### ⚠️ BREAKING CHANGES' message='^(feat|fix|perf)(\([^)]*\))!:' }}
10
- - {{#replaceCommit}}{{subject}}{{/replaceCommit}}{{#if pullRequest}}{{#if pullRequest.href}} ([#{{pullRequest.id}}]({{pullRequest.href}})){{else}} (#{{pullRequest.id}}){{/if}}{{/if}}{{#if commitHash}}{{#if commitHref}} [({{commitHash}})]({{commitHref}}){{else}} ({{commitHash}}){{/if}}{{/if}}
10
+ - {{changelogEntry}}
11
11
  {{/commit-list}}
12
12
 
13
13
  {{#commit-list this heading='### 🚀 Features' message='^feat:|^feat\(' exclude='^(feat|fix|perf)(\([^)]*\))!:'}}
14
- - {{#replaceCommit}}{{subject}}{{/replaceCommit}}{{#if pullRequest}}{{#if pullRequest.href}} ([#{{pullRequest.id}}]({{pullRequest.href}})){{else}} (#{{pullRequest.id}}){{/if}}{{/if}}{{#if commitHash}}{{#if commitHref}} [({{commitHash}})]({{commitHref}}){{else}} ({{commitHash}}){{/if}}{{/if}}
14
+ - {{changelogEntry}}
15
15
  {{/commit-list}}
16
16
 
17
17
  {{#commit-list this heading='### 🐞 Bug Fixes' message='^fix:|^fix\(' exclude='^(feat|fix|perf)(\([^)]*\))!:'}}
18
- - {{#replaceCommit}}{{subject}}{{/replaceCommit}}{{#if pullRequest}}{{#if pullRequest.href}} ([#{{pullRequest.id}}]({{pullRequest.href}})){{else}} (#{{pullRequest.id}}){{/if}}{{/if}}{{#if commitHash}}{{#if commitHref}} [({{commitHash}})]({{commitHref}}){{else}} ({{commitHash}}){{/if}}{{/if}}
18
+ - {{changelogEntry}}
19
+ {{/commit-list}}
20
+
21
+ {{#commit-list this heading='### ⚡ Performance Improvements' message='^perf:|^perf\(' exclude='^(feat|fix|perf)(\([^)]*\))!:'}}
22
+ - {{changelogEntry}}
19
23
  {{/commit-list}}
20
24
 
21
25
  {{/commit-parser}}
@@ -1,29 +0,0 @@
1
- {{! prettier-ignore }}
2
- {{#each releases}}
3
- {{#if tag}}
4
- ##{{#unless major}}#{{/unless}} [{{#replaceTitle}}{{title}}{{/replaceTitle}}]({{href}}) ({{isoDate}})
5
- {{/if}}
6
-
7
- {{#commit-parser merges commits}}
8
-
9
- {{#commit-list this heading='### ⚠️ BREAKING CHANGES' message='^(feat|fix|perf)(\([^)]*\))!:' }}
10
- - {{#replaceCommit}}{{subject}}{{/replaceCommit}}{{#if pullRequest}}{{#if pullRequest.href}} ([#{{pullRequest.id}}]({{pullRequest.href}})){{else}} (#{{pullRequest.id}}){{/if}}{{/if}}{{#if commitHash}}{{#if commitHref}} [({{commitHash}})]({{commitHref}}){{else}} ({{commitHash}}){{/if}}{{/if}}
11
- {{/commit-list}}
12
-
13
- {{#commit-list this heading='### 🚀 Features' message='^feat:|^feat\(' exclude='^(feat|fix|perf)(\([^)]*\))!:'}}
14
- - {{#replaceCommit}}{{subject}}{{/replaceCommit}}{{#if pullRequest}}{{#if pullRequest.href}} ([#{{pullRequest.id}}]({{pullRequest.href}})){{else}} (#{{pullRequest.id}}){{/if}}{{/if}}{{#if commitHash}}{{#if commitHref}} [({{commitHash}})]({{commitHref}}){{else}} ({{commitHash}}){{/if}}{{/if}}
15
- {{/commit-list}}
16
-
17
- {{#commit-list this heading='### 🐞 Bug Fixes' message='^fix:|^fix\(' exclude='^(feat|fix|perf)(\([^)]*\))!:'}}
18
- - {{#replaceCommit}}{{subject}}{{/replaceCommit}}{{#if pullRequest}}{{#if pullRequest.href}} ([#{{pullRequest.id}}]({{pullRequest.href}})){{else}} (#{{pullRequest.id}}){{/if}}{{/if}}{{#if commitHash}}{{#if commitHref}} [({{commitHash}})]({{commitHref}}){{else}} ({{commitHash}}){{/if}}{{/if}}
19
- {{/commit-list}}
20
-
21
- {{/commit-parser}}
22
-
23
- {{#contributors commits merges}}
24
- ### Contributors
25
-
26
- {{text}}
27
- {{/contributors}}
28
-
29
- {{/each}}