@logicseek/hello-cc 0.1.1 → 0.1.3
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/CHANGELOG.md +164 -0
- package/README.md +31 -6
- package/README.zh-CN.md +31 -7
- package/assets/logo.svg +84 -0
- package/bin/hcc.mjs +2388 -290
- package/docs/README.md +24 -0
- package/docs/README.zh-CN.md +24 -0
- package/docs/commands.md +135 -0
- package/docs/commands.zh-CN.md +126 -0
- package/docs/design.md +12 -4
- package/docs/guide.md +83 -71
- package/docs/guide.zh-CN.md +74 -68
- package/docs/implementation.md +21 -1
- package/package.json +7 -1
- package/scripts/github-release.mjs +190 -0
- package/scripts/regression.mjs +852 -31
- package/scripts/release-notes.mjs +112 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import process from 'node:process';
|
|
6
|
+
|
|
7
|
+
const repoRoot = path.resolve(import.meta.dirname, '..');
|
|
8
|
+
|
|
9
|
+
function usage() {
|
|
10
|
+
console.log(`release-notes
|
|
11
|
+
|
|
12
|
+
Usage:
|
|
13
|
+
node scripts/release-notes.mjs [--version VERSION] [--check]
|
|
14
|
+
|
|
15
|
+
Reads CHANGELOG.md and prints the section for VERSION. If VERSION is omitted,
|
|
16
|
+
the current package.json version is used.
|
|
17
|
+
|
|
18
|
+
Keep one top-level CHANGELOG.md file. For each release, add a new section:
|
|
19
|
+
|
|
20
|
+
## 0.1.3
|
|
21
|
+
|
|
22
|
+
The printed section is the source for GitHub Release notes and detailed npm
|
|
23
|
+
package release descriptions.
|
|
24
|
+
`);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function readJson(file) {
|
|
28
|
+
return JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function parseArgs(argv) {
|
|
32
|
+
const opts = { check: false, help: false, version: null };
|
|
33
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
34
|
+
const arg = argv[i];
|
|
35
|
+
if (arg === '--help' || arg === '-h') {
|
|
36
|
+
opts.help = true;
|
|
37
|
+
} else if (arg === '--check') {
|
|
38
|
+
opts.check = true;
|
|
39
|
+
} else if (arg === '--version') {
|
|
40
|
+
opts.version = argv[++i];
|
|
41
|
+
if (opts.version === undefined) throw new Error('Missing value for --version');
|
|
42
|
+
} else if (arg.startsWith('--version=')) {
|
|
43
|
+
opts.version = arg.slice('--version='.length);
|
|
44
|
+
} else {
|
|
45
|
+
throw new Error(`Unknown argument: ${arg}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return opts;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function releaseSection(markdown, version) {
|
|
52
|
+
const lines = markdown.split(/\r?\n/);
|
|
53
|
+
const heading = `## ${version}`;
|
|
54
|
+
const start = lines.findIndex((line) => line.trim() === heading);
|
|
55
|
+
if (start < 0) return null;
|
|
56
|
+
|
|
57
|
+
let end = lines.length;
|
|
58
|
+
for (let i = start + 1; i < lines.length; i += 1) {
|
|
59
|
+
if (/^##\s+/.test(lines[i])) {
|
|
60
|
+
end = i;
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return lines.slice(start, end).join('\n').trimEnd();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function validateSection(section, version) {
|
|
68
|
+
const problems = [];
|
|
69
|
+
if (!section) {
|
|
70
|
+
problems.push(`CHANGELOG.md is missing section ## ${version}`);
|
|
71
|
+
return problems;
|
|
72
|
+
}
|
|
73
|
+
if (!section.includes('### Summary')) problems.push(`## ${version} is missing ### Summary`);
|
|
74
|
+
if (!section.includes('### Highlights')) problems.push(`## ${version} is missing ### Highlights`);
|
|
75
|
+
if (section.includes('TODO') || section.includes('TBD')) problems.push(`## ${version} still contains TODO/TBD text`);
|
|
76
|
+
const bulletCount = (section.match(/^- /gm) || []).length;
|
|
77
|
+
if (bulletCount < 2) problems.push(`## ${version} should include at least two release-note bullets`);
|
|
78
|
+
return problems;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function main() {
|
|
82
|
+
const opts = parseArgs(process.argv.slice(2));
|
|
83
|
+
if (opts.help) {
|
|
84
|
+
usage();
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const pkg = readJson(path.join(repoRoot, 'package.json'));
|
|
89
|
+
const version = opts.version || pkg.version;
|
|
90
|
+
const changelog = fs.readFileSync(path.join(repoRoot, 'CHANGELOG.md'), 'utf8');
|
|
91
|
+
const section = releaseSection(changelog, version);
|
|
92
|
+
const problems = validateSection(section, version);
|
|
93
|
+
|
|
94
|
+
if (opts.check) {
|
|
95
|
+
if (problems.length) {
|
|
96
|
+
console.error(problems.join('\n'));
|
|
97
|
+
process.exitCode = 1;
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
console.log(`release notes ok: ${version}`);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (problems.length) {
|
|
105
|
+
console.error(problems.join('\n'));
|
|
106
|
+
process.exitCode = 1;
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
console.log(section);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
main();
|