-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Expand file tree
/
Copy pathextract-changelog.mjs
More file actions
79 lines (62 loc) · 2.19 KB
/
extract-changelog.mjs
File metadata and controls
79 lines (62 loc) · 2.19 KB
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
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
// extract-changelog.mjs <version-or-prefix> [changelog-path]
//
// Extracts the changelog content for a specific version from CHANGELOG.md.
// The version argument is matched as a prefix against version headers (## [VERSION...]).
// Uses String.startsWith() for literal matching so dots, hyphens, etc. are handled safely.
//
// Examples:
// node extract-changelog.mjs 16.3.0-rc1 → matches "## [16.3.0-rc1] - ..."
// node extract-changelog.mjs 16.3.0-rc → matches the first "## [16.3.0-rc*] - ..." entry
// node extract-changelog.mjs 16.3.0 → matches "## [16.3.0] - ..."
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const REPO_ROOT = path.resolve(__dirname, '../..');
const args = process.argv.slice(2);
const version = args[0];
const changelogPath = args[1] ?? path.join(REPO_ROOT, 'CHANGELOG.md');
if (!version) {
process.stderr.write(`Usage: node extract-changelog.mjs <version-or-prefix> [changelog-path]\n`);
process.exit(1);
}
if (!fs.existsSync(changelogPath)) {
process.stderr.write(`Error: CHANGELOG.md not found at: ${changelogPath}\n`);
process.exit(1);
}
const lines = fs.readFileSync(changelogPath, 'utf8').split('\n');
const header = `## [${version}`;
let startIndex = -1;
for (let i = 0; i < lines.length; i++) {
if (lines[i].startsWith(header)) {
startIndex = i + 1;
break;
}
}
if (startIndex === -1) {
process.stderr.write(`Error: No changelog entry found for version: ${version}\n`);
process.exit(1);
}
const sectionLines = [];
for (let i = startIndex; i < lines.length; i++) {
if (lines[i].startsWith('## [')) {
break;
}
sectionLines.push(lines[i]);
}
// Strip leading blank lines
let start = 0;
while (start < sectionLines.length && sectionLines[start].trim() === '') {
start++;
}
// Strip trailing blank lines
let end = sectionLines.length - 1;
while (end >= start && sectionLines[end].trim() === '') {
end--;
}
const result = sectionLines.slice(start, end + 1).join('\n');
if (!result) {
process.stderr.write(`Error: No changelog content found for version: ${version}\n`);
process.exit(1);
}
process.stdout.write(`${result}\n`);