@varlet/release 1.0.1 → 1.0.2

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/dist/cli.js CHANGED
@@ -3,7 +3,7 @@ import { changelog, commitLint, publish, release } from "./index.js";
3
3
  import { Command } from "commander";
4
4
 
5
5
  //#region package.json
6
- var version = "1.0.1";
6
+ var version = "1.0.2";
7
7
 
8
8
  //#endregion
9
9
  //#region src/cli.ts
package/dist/index.d.ts CHANGED
@@ -40,6 +40,7 @@ declare function changelog({
40
40
  }?: ChangelogCommandOptions): Promise<void>;
41
41
  //#endregion
42
42
  //#region src/commitLint.d.ts
43
+ declare const COMMIT_HEADER_RE: RegExp;
43
44
  declare const COMMIT_MESSAGE_RE: RegExp;
44
45
  declare function isVersionCommitMessage(message: string): boolean;
45
46
  declare function getCommitMessage(commitMessagePath: string): string;
@@ -51,4 +52,4 @@ interface CommitLintCommandOptions {
51
52
  }
52
53
  declare function commitLint(options: CommitLintCommandOptions): void;
53
54
  //#endregion
54
- export { COMMIT_MESSAGE_RE, ChangelogCommandOptions, CommitLintCommandOptions, PublishCommandOptions, ReleaseCommandOptions, changelog, commitLint, getAllPackageJsons, getCommitMessage, isSameVersion, isVersionCommitMessage, publish, release, updateVersion };
55
+ export { COMMIT_HEADER_RE, COMMIT_MESSAGE_RE, ChangelogCommandOptions, CommitLintCommandOptions, PublishCommandOptions, ReleaseCommandOptions, changelog, commitLint, getAllPackageJsons, getCommitMessage, isSameVersion, isVersionCommitMessage, publish, release, updateVersion };
package/dist/index.js CHANGED
@@ -7,57 +7,194 @@ import semver from "semver";
7
7
  import { x } from "tinyexec";
8
8
  import conventionalChangelog from "conventional-changelog";
9
9
 
10
+ //#region src/commitLint.ts
11
+ const { readFileSync } = fse;
12
+ const COMMIT_HEADER_RE = /^(revert|fix|feat|docs|perf|test|types|style|build|chore|release|refactor|merge|wip)(?:\(([^)]+)\))?(!)?:\s(.+)$/;
13
+ const COMMIT_MESSAGE_RE = new RegExp(COMMIT_HEADER_RE.source.replace(/\$$/, "") + "(?:\\n[\\s\\S]+)?$");
14
+ const ERROR_MESSAGE = "Commit message invalid.";
15
+ const WARNING_MESSAGE = `\
16
+ The rules for commit messages are as follows
17
+
18
+ Example:
19
+
20
+ feat: add a new feature
21
+ feat(ui/button): add a new feature in the ui/button scope
22
+
23
+ fix: fix a bug
24
+ fix(ui/button): fix a bug in the ui/button scope
25
+
26
+ docs: fix an error in the documentation
27
+ docs(ui/button): fix a documentation error in the ui/button scope
28
+
29
+ Allowed types:
30
+ - fix
31
+ - feat
32
+ - docs
33
+ - perf
34
+ - test
35
+ - types
36
+ - style
37
+ - build
38
+ - chore
39
+ - release
40
+ - refactor
41
+ - revert
42
+ - merge
43
+ - wip
44
+
45
+ Commit message reference: https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y
46
+ 参考阮一峰Commit message编写指南: https://www.ruanyifeng.com/blog/2016/01/commit_message_change_log.html`;
47
+ function isVersionCommitMessage(message) {
48
+ return Boolean(message.startsWith("v") && semver.valid(message.slice(1)));
49
+ }
50
+ function getCommitMessage(commitMessagePath) {
51
+ return readFileSync(commitMessagePath, "utf-8").trim();
52
+ }
53
+ function commitLint(options) {
54
+ const { commitMessagePath, commitMessageRe = COMMIT_MESSAGE_RE, errorMessage = ERROR_MESSAGE, warningMessage = WARNING_MESSAGE } = options;
55
+ if (!commitMessagePath) {
56
+ logger.error("commitMessagePath is required");
57
+ process.exit(1);
58
+ }
59
+ const commitMessage = getCommitMessage(commitMessagePath);
60
+ const isValidCommitMessage = new RegExp(commitMessageRe).test(commitMessage);
61
+ if (!isVersionCommitMessage(commitMessage) && !isValidCommitMessage) {
62
+ logger.error(errorMessage);
63
+ logger.warn(warningMessage);
64
+ process.exit(1);
65
+ }
66
+ }
67
+
68
+ //#endregion
10
69
  //#region src/changelog.ts
11
70
  const { createWriteStream } = fse;
12
- function changelog({ releaseCount = 0, file = "CHANGELOG.md", preset = "angular", writerOpts = { transform(commit, context) {
71
+ const COMMIT_TYPE_MAP = {
72
+ feat: "Features",
73
+ fix: "Bug Fixes",
74
+ perf: "Performance Improvements",
75
+ revert: "Reverts",
76
+ refactor: "Code Refactoring",
77
+ docs: "Documentation",
78
+ style: "Styles",
79
+ test: "Tests",
80
+ build: "Build System",
81
+ ci: "Continuous Integration"
82
+ };
83
+ const ALWAYS_SHOW_TYPES = new Set([
84
+ "feat",
85
+ "fix",
86
+ "perf",
87
+ "revert",
88
+ "refactor"
89
+ ]);
90
+ const BREAKING_CHANGE_RE = /BREAKING CHANGES?:\s*([\s\S]+)/;
91
+ const MAIN_TEMPLATE = `{{> header}}
92
+
93
+ {{> footer}}
94
+ {{#each commitGroups}}
95
+
96
+ {{#if title}}
97
+ ### {{title}}
98
+
99
+ {{/if}}
100
+ {{#each commits}}
101
+ {{> commit root=@root}}
102
+ {{/each}}
103
+
104
+ {{/each}}
105
+ `;
106
+ function linkify(text, context, issues) {
107
+ let result = text;
108
+ const repoUrl = context.repository ? `${context.host}/${context.owner}/${context.repository}` : context.repoUrl;
109
+ if (repoUrl) {
110
+ const issueBaseUrl = `${repoUrl}/issues/`;
111
+ result = result.replace(/#([0-9]+)/g, (_, issue) => {
112
+ issues.push(issue);
113
+ return `[#${issue}](${issueBaseUrl}${issue})`;
114
+ });
115
+ }
116
+ if (context.host) result = result.replace(/\B@([a-z0-9](?:-?[a-z0-9/]){0,38})/g, (_, username) => username.includes("/") ? `@${username}` : `[@${username}](${context.host}/${username})`);
117
+ return result;
118
+ }
119
+ function extractBreakingText(commit) {
120
+ const body = typeof commit.body === "string" ? commit.body : "";
121
+ const footer = typeof commit.footer === "string" ? commit.footer : "";
122
+ const match = BREAKING_CHANGE_RE.exec(`${footer}\n${body}`);
123
+ if (match?.[1]) return match[1].trim();
124
+ if (typeof commit.subject === "string" && commit.subject) return commit.subject;
125
+ if (typeof commit.header === "string" && commit.header) return commit.header;
126
+ return "";
127
+ }
128
+ function tryParseHeader(commit) {
129
+ if (typeof commit.header !== "string") return null;
130
+ const match = COMMIT_HEADER_RE.exec(commit.header.trim());
131
+ if (!match) return null;
132
+ return {
133
+ type: match[1],
134
+ scope: match[2] || void 0,
135
+ subject: match[4] || void 0,
136
+ isBreaking: Boolean(match[3])
137
+ };
138
+ }
139
+ function processBreakingChanges(commit, context, issues) {
13
140
  let discard = true;
14
- const issues = [];
15
141
  commit.notes.forEach((note) => {
16
142
  note.title = "BREAKING CHANGES";
17
143
  discard = false;
18
144
  });
19
- const hasBreakingNotes = commit.notes.length > 0;
145
+ const hadBreakingNotes = commit.notes.length > 0;
146
+ const addBreakingNote = () => {
147
+ if (!hadBreakingNotes) {
148
+ const text = linkify(extractBreakingText(commit), context, issues);
149
+ commit.notes.push({
150
+ title: "BREAKING CHANGES",
151
+ text
152
+ });
153
+ }
154
+ discard = false;
155
+ };
156
+ const parsed = tryParseHeader(commit);
157
+ if (parsed) {
158
+ if (!commit.type) commit.type = parsed.type;
159
+ if (!commit.scope && parsed.scope) commit.scope = parsed.scope;
160
+ if (!commit.subject && parsed.subject) commit.subject = parsed.subject;
161
+ if (parsed.isBreaking) addBreakingNote();
162
+ }
20
163
  if (typeof commit.type === "string" && commit.type.endsWith("!")) {
21
164
  commit.type = commit.type.slice(0, -1);
22
- if (!hasBreakingNotes) commit.notes.push({
23
- title: "BREAKING CHANGES",
24
- text: ""
25
- });
26
- discard = false;
165
+ addBreakingNote();
27
166
  }
28
- if (commit.type === "feat") commit.type = "Features";
29
- else if (commit.type === "fix") commit.type = "Bug Fixes";
30
- else if (commit.type === "perf") commit.type = "Performance Improvements";
31
- else if (commit.type === "revert" || commit.revert) commit.type = "Reverts";
32
- else if (commit.type === "refactor") commit.type = "Code Refactoring";
33
- else if (discard) return false;
34
- else if (commit.type === "docs") commit.type = "Documentation";
35
- else if (commit.type === "style") commit.type = "Styles";
36
- else if (commit.type === "test") commit.type = "Tests";
37
- else if (commit.type === "build") commit.type = "Build System";
38
- else if (commit.type === "ci") commit.type = "Continuous Integration";
39
- if (commit.scope === "*") commit.scope = "";
40
- if (typeof commit.hash === "string") commit.shortHash = commit.hash.substring(0, 7);
41
- if (typeof commit.subject === "string") {
42
- let url = context.repository ? `${context.host}/${context.owner}/${context.repository}` : context.repoUrl;
43
- if (url) {
44
- url = `${url}/issues/`;
45
- commit.subject = commit.subject.replace(/#([0-9]+)/g, (_, issue) => {
46
- issues.push(issue);
47
- return `[#${issue}](${url}${issue})`;
48
- });
167
+ return discard;
168
+ }
169
+ function mapCommitType(commit, discard) {
170
+ if (commit.revert) {
171
+ commit.type = "Reverts";
172
+ return true;
173
+ }
174
+ const mapped = COMMIT_TYPE_MAP[commit.type];
175
+ if (mapped) {
176
+ if (ALWAYS_SHOW_TYPES.has(commit.type) || !discard) {
177
+ commit.type = mapped;
178
+ return true;
49
179
  }
50
- if (context.host) commit.subject = commit.subject.replace(/\B@([a-z0-9](?:-?[a-z0-9/]){0,38})/g, (_, username) => {
51
- if (username.includes("/")) return `@${username}`;
52
- return `[@${username}](${context.host}/${username})`;
53
- });
54
180
  }
55
- commit.references = commit.references.filter((reference) => {
56
- if (issues.indexOf(reference.issue) === -1) return true;
57
- return false;
58
- });
59
- return commit;
60
- } } } = {}) {
181
+ return !discard;
182
+ }
183
+ function createDefaultWriterOpts() {
184
+ return {
185
+ mainTemplate: MAIN_TEMPLATE,
186
+ transform(commit, context) {
187
+ const issues = [];
188
+ if (!mapCommitType(commit, processBreakingChanges(commit, context, issues))) return false;
189
+ if (commit.scope === "*") commit.scope = "";
190
+ if (typeof commit.hash === "string") commit.shortHash = commit.hash.substring(0, 7);
191
+ if (typeof commit.subject === "string") commit.subject = linkify(commit.subject, context, issues);
192
+ commit.references = commit.references.filter((ref) => !issues.includes(ref.issue));
193
+ return commit;
194
+ }
195
+ };
196
+ }
197
+ function changelog({ releaseCount = 0, file = "CHANGELOG.md", preset = "angular", writerOpts = createDefaultWriterOpts() } = {}) {
61
198
  const s = spinner();
62
199
  s.start("Generating changelog");
63
200
  return new Promise((resolve$1) => {
@@ -291,62 +428,4 @@ async function release(options) {
291
428
  }
292
429
 
293
430
  //#endregion
294
- //#region src/commitLint.ts
295
- const { readFileSync } = fse;
296
- const COMMIT_MESSAGE_RE = /^(revert|fix|feat|docs|perf|test|types|style|build|chore|release|refactor|merge|wip)(\(.+\))?!?: (.|\n)+/;
297
- const ERROR_MESSAGE = "Commit message invalid.";
298
- const WARNING_MESSAGE = `\
299
- The rules for commit messages are as follows
300
-
301
- Example:
302
-
303
- feat: add a new feature
304
- feat(ui/button): add a new feature in the ui/button scope
305
-
306
- fix: fix a bug
307
- fix(ui/button): fix a bug in the ui/button scope
308
-
309
- docs: fix an error in the documentation
310
- docs(ui/button): fix a documentation error in the ui/button scope
311
-
312
- Allowed types:
313
- - fix
314
- - feat
315
- - docs
316
- - perf
317
- - test
318
- - types
319
- - style
320
- - build
321
- - chore
322
- - release
323
- - refactor
324
- - revert
325
- - merge
326
- - wip
327
-
328
- Commit message reference: https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y
329
- 参考阮一峰Commit message编写指南: https://www.ruanyifeng.com/blog/2016/01/commit_message_change_log.html`;
330
- function isVersionCommitMessage(message) {
331
- return Boolean(message.startsWith("v") && semver.valid(message.slice(1)));
332
- }
333
- function getCommitMessage(commitMessagePath) {
334
- return readFileSync(commitMessagePath, "utf-8").trim();
335
- }
336
- function commitLint(options) {
337
- const { commitMessagePath, commitMessageRe = COMMIT_MESSAGE_RE, errorMessage = ERROR_MESSAGE, warningMessage = WARNING_MESSAGE } = options;
338
- if (!commitMessagePath) {
339
- logger.error("commitMessagePath is required");
340
- process.exit(1);
341
- }
342
- const commitMessage = getCommitMessage(commitMessagePath);
343
- const isValidCommitMessage = new RegExp(commitMessageRe).test(commitMessage);
344
- if (!isVersionCommitMessage(commitMessage) && !isValidCommitMessage) {
345
- logger.error(errorMessage);
346
- logger.warn(warningMessage);
347
- process.exit(1);
348
- }
349
- }
350
-
351
- //#endregion
352
- export { COMMIT_MESSAGE_RE, changelog, commitLint, getAllPackageJsons, getCommitMessage, isSameVersion, isVersionCommitMessage, publish, release, updateVersion };
431
+ export { COMMIT_HEADER_RE, COMMIT_MESSAGE_RE, changelog, commitLint, getAllPackageJsons, getCommitMessage, isSameVersion, isVersionCommitMessage, publish, release, updateVersion };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@varlet/release",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "publish all packages, generate changelogs and check commit messages",
5
5
  "keywords": [
6
6
  "changelog",