package-versioner 0.6.3 → 0.7.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/README.md +13 -6
- package/dist/index.cjs +1072 -174
- package/dist/index.js +1063 -165
- package/docs/changelogs.md +65 -0
- package/docs/{VERSIONING_STRATEGIES.md → versioning.md} +1 -1
- package/package-versioner.schema.json +32 -1
- package/package.json +11 -7
package/dist/index.cjs
CHANGED
|
@@ -34,79 +34,14 @@ __export(index_exports, {
|
|
|
34
34
|
run: () => run
|
|
35
35
|
});
|
|
36
36
|
module.exports = __toCommonJS(index_exports);
|
|
37
|
-
var
|
|
38
|
-
var
|
|
37
|
+
var fs10 = __toESM(require("fs"), 1);
|
|
38
|
+
var import_node_path7 = __toESM(require("path"), 1);
|
|
39
39
|
var import_commander = require("commander");
|
|
40
40
|
|
|
41
|
-
// src/
|
|
42
|
-
var
|
|
43
|
-
var
|
|
44
|
-
|
|
45
|
-
const localProcess = (0, import_node_process.cwd)();
|
|
46
|
-
const filePath = configPath || `${localProcess}/version.config.json`;
|
|
47
|
-
return new Promise((resolve, reject) => {
|
|
48
|
-
fs.readFile(filePath, "utf-8", (err, data) => {
|
|
49
|
-
if (err) {
|
|
50
|
-
reject(new Error(`Could not locate the config file at ${filePath}: ${err.message}`));
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
try {
|
|
54
|
-
const config = JSON.parse(data);
|
|
55
|
-
resolve(config);
|
|
56
|
-
} catch (err2) {
|
|
57
|
-
const errorMessage = err2 instanceof Error ? err2.message : String(err2);
|
|
58
|
-
reject(new Error(`Failed to parse config file ${filePath}: ${errorMessage}`));
|
|
59
|
-
}
|
|
60
|
-
});
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// src/core/versionEngine.ts
|
|
65
|
-
var import_node_process5 = require("process");
|
|
66
|
-
var import_get_packages = require("@manypkg/get-packages");
|
|
67
|
-
|
|
68
|
-
// src/errors/gitError.ts
|
|
69
|
-
var GitError = class extends Error {
|
|
70
|
-
constructor(message, code) {
|
|
71
|
-
super(message);
|
|
72
|
-
this.code = code;
|
|
73
|
-
this.name = "GitError";
|
|
74
|
-
}
|
|
75
|
-
};
|
|
76
|
-
function createGitError(code, details) {
|
|
77
|
-
const messages = {
|
|
78
|
-
["NOT_GIT_REPO" /* NOT_GIT_REPO */]: "Not a git repository",
|
|
79
|
-
["GIT_PROCESS_ERROR" /* GIT_PROCESS_ERROR */]: "Failed to create new version",
|
|
80
|
-
["NO_FILES" /* NO_FILES */]: "No files specified for commit",
|
|
81
|
-
["NO_COMMIT_MESSAGE" /* NO_COMMIT_MESSAGE */]: "Commit message is required",
|
|
82
|
-
["GIT_ERROR" /* GIT_ERROR */]: "Git operation failed"
|
|
83
|
-
};
|
|
84
|
-
const baseMessage = messages[code];
|
|
85
|
-
const fullMessage = details ? `${baseMessage}: ${details}` : baseMessage;
|
|
86
|
-
return new GitError(fullMessage, code);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// src/errors/versionError.ts
|
|
90
|
-
var VersionError = class extends Error {
|
|
91
|
-
constructor(message, code) {
|
|
92
|
-
super(message);
|
|
93
|
-
this.code = code;
|
|
94
|
-
this.name = "VersionError";
|
|
95
|
-
}
|
|
96
|
-
};
|
|
97
|
-
function createVersionError(code, details) {
|
|
98
|
-
const messages = {
|
|
99
|
-
["CONFIG_REQUIRED" /* CONFIG_REQUIRED */]: "Configuration is required",
|
|
100
|
-
["PACKAGES_NOT_FOUND" /* PACKAGES_NOT_FOUND */]: "Failed to get packages information",
|
|
101
|
-
["WORKSPACE_ERROR" /* WORKSPACE_ERROR */]: "Failed to get workspace packages",
|
|
102
|
-
["INVALID_CONFIG" /* INVALID_CONFIG */]: "Invalid configuration",
|
|
103
|
-
["PACKAGE_NOT_FOUND" /* PACKAGE_NOT_FOUND */]: "Package not found",
|
|
104
|
-
["VERSION_CALCULATION_ERROR" /* VERSION_CALCULATION_ERROR */]: "Failed to calculate version"
|
|
105
|
-
};
|
|
106
|
-
const baseMessage = messages[code];
|
|
107
|
-
const fullMessage = details ? `${baseMessage}: ${details}` : baseMessage;
|
|
108
|
-
return new VersionError(fullMessage, code);
|
|
109
|
-
}
|
|
41
|
+
// src/changelog/changelogRegenerator.ts
|
|
42
|
+
var import_node_child_process2 = require("child_process");
|
|
43
|
+
var import_node_fs = __toESM(require("fs"), 1);
|
|
44
|
+
var import_node_path = __toESM(require("path"), 1);
|
|
110
45
|
|
|
111
46
|
// src/utils/logging.ts
|
|
112
47
|
var import_chalk = __toESM(require("chalk"), 1);
|
|
@@ -189,19 +124,518 @@ function log(message, level = "info") {
|
|
|
189
124
|
}
|
|
190
125
|
}
|
|
191
126
|
|
|
127
|
+
// src/changelog/commitParser.ts
|
|
128
|
+
var import_node_child_process = require("child_process");
|
|
129
|
+
var CONVENTIONAL_COMMIT_REGEX = /^(\w+)(?:\(([^)]+)\))?(!)?: (.+)(?:\n\n([\s\S]*))?/;
|
|
130
|
+
var BREAKING_CHANGE_REGEX = /BREAKING CHANGE: ([\s\S]+?)(?:\n\n|$)/;
|
|
131
|
+
function extractChangelogEntriesFromCommits(projectDir, revisionRange) {
|
|
132
|
+
try {
|
|
133
|
+
const command = `git log ${revisionRange} --pretty=format:"%B---COMMIT_DELIMITER---" --no-merges`;
|
|
134
|
+
const output = (0, import_node_child_process.execSync)(command, {
|
|
135
|
+
cwd: projectDir,
|
|
136
|
+
encoding: "utf8"
|
|
137
|
+
});
|
|
138
|
+
const commits = output.split("---COMMIT_DELIMITER---").filter((commit) => commit.trim() !== "");
|
|
139
|
+
return commits.map((commit) => parseCommitMessage(commit)).filter((entry) => entry !== null);
|
|
140
|
+
} catch (error) {
|
|
141
|
+
log(`Error extracting commits: ${error}`, "error");
|
|
142
|
+
return [];
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
function parseCommitMessage(message) {
|
|
146
|
+
const match = message.match(CONVENTIONAL_COMMIT_REGEX);
|
|
147
|
+
if (match) {
|
|
148
|
+
const [, type, scope, breakingMark, subject, body = ""] = match;
|
|
149
|
+
const breakingFromMark = breakingMark === "!";
|
|
150
|
+
const breakingChangeMatch = body.match(BREAKING_CHANGE_REGEX);
|
|
151
|
+
const hasBreakingChange = breakingFromMark || breakingChangeMatch !== null;
|
|
152
|
+
const changelogType = mapCommitTypeToChangelogType(type);
|
|
153
|
+
if (!changelogType) {
|
|
154
|
+
return null;
|
|
155
|
+
}
|
|
156
|
+
const issueIds = extractIssueIds(body);
|
|
157
|
+
let description = subject;
|
|
158
|
+
if (hasBreakingChange) {
|
|
159
|
+
description = `**BREAKING** ${description}`;
|
|
160
|
+
}
|
|
161
|
+
return {
|
|
162
|
+
type: changelogType,
|
|
163
|
+
description,
|
|
164
|
+
scope: scope || void 0,
|
|
165
|
+
issueIds: issueIds.length > 0 ? issueIds : void 0,
|
|
166
|
+
originalType: type
|
|
167
|
+
// Store original type for custom formatting
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
if (!message.startsWith("Merge") && !message.match(/^v?\d+\.\d+\.\d+/)) {
|
|
171
|
+
const firstLine = message.split("\n")[0].trim();
|
|
172
|
+
return {
|
|
173
|
+
type: "changed",
|
|
174
|
+
description: firstLine
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
179
|
+
function mapCommitTypeToChangelogType(type) {
|
|
180
|
+
switch (type) {
|
|
181
|
+
case "feat":
|
|
182
|
+
return "added";
|
|
183
|
+
case "fix":
|
|
184
|
+
return "fixed";
|
|
185
|
+
case "docs":
|
|
186
|
+
case "style":
|
|
187
|
+
case "refactor":
|
|
188
|
+
case "perf":
|
|
189
|
+
case "build":
|
|
190
|
+
case "ci":
|
|
191
|
+
return "changed";
|
|
192
|
+
case "revert":
|
|
193
|
+
return "removed";
|
|
194
|
+
case "chore":
|
|
195
|
+
return "changed";
|
|
196
|
+
case "test":
|
|
197
|
+
return null;
|
|
198
|
+
default:
|
|
199
|
+
return "changed";
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
function extractIssueIds(body) {
|
|
203
|
+
const issueRegex = /(?:fix|fixes|close|closes|resolve|resolves)\s+#(\d+)/gi;
|
|
204
|
+
const issueIds = [];
|
|
205
|
+
let match = issueRegex.exec(body);
|
|
206
|
+
while (match !== null) {
|
|
207
|
+
issueIds.push(`#${match[1]}`);
|
|
208
|
+
match = issueRegex.exec(body);
|
|
209
|
+
}
|
|
210
|
+
return issueIds;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// src/changelog/formatters.ts
|
|
214
|
+
function formatChangelogEntries(format, version, date, entries, packageName, repoUrl) {
|
|
215
|
+
const formattingEntries = entries.map((entry) => {
|
|
216
|
+
const hasBreaking = entry.description.includes("**BREAKING**");
|
|
217
|
+
return {
|
|
218
|
+
...entry,
|
|
219
|
+
breaking: hasBreaking
|
|
220
|
+
};
|
|
221
|
+
});
|
|
222
|
+
return format === "keep-a-changelog" ? formatKeepAChangelogEntries(version, date, formattingEntries, repoUrl) : formatAngularEntries(version, date, formattingEntries, packageName);
|
|
223
|
+
}
|
|
224
|
+
function formatKeepAChangelogEntries(version, date, entries, repoUrl) {
|
|
225
|
+
const added = [];
|
|
226
|
+
const changed = [];
|
|
227
|
+
const deprecated = [];
|
|
228
|
+
const removed = [];
|
|
229
|
+
const fixed = [];
|
|
230
|
+
const security = [];
|
|
231
|
+
for (const entry of entries) {
|
|
232
|
+
const entryText = entry.scope ? `- **${entry.scope}**: ${entry.description}` : `- ${entry.description}`;
|
|
233
|
+
const formattedEntry = entry.breaking ? entryText.replace(/^- /, "- **BREAKING** ") : entryText;
|
|
234
|
+
const entryType = entry.originalType || entry.type;
|
|
235
|
+
switch (entryType) {
|
|
236
|
+
case "feat":
|
|
237
|
+
added.push(formattedEntry);
|
|
238
|
+
break;
|
|
239
|
+
case "fix":
|
|
240
|
+
fixed.push(formattedEntry);
|
|
241
|
+
break;
|
|
242
|
+
case "docs":
|
|
243
|
+
case "style":
|
|
244
|
+
case "refactor":
|
|
245
|
+
case "perf":
|
|
246
|
+
case "build":
|
|
247
|
+
case "ci":
|
|
248
|
+
changed.push(formattedEntry);
|
|
249
|
+
break;
|
|
250
|
+
case "test":
|
|
251
|
+
break;
|
|
252
|
+
case "chore":
|
|
253
|
+
if (entry.description.toLowerCase().includes("deprecat")) {
|
|
254
|
+
deprecated.push(formattedEntry);
|
|
255
|
+
} else {
|
|
256
|
+
changed.push(formattedEntry);
|
|
257
|
+
}
|
|
258
|
+
break;
|
|
259
|
+
// Keep-a-changelog standard types
|
|
260
|
+
case "added":
|
|
261
|
+
added.push(formattedEntry);
|
|
262
|
+
break;
|
|
263
|
+
case "changed":
|
|
264
|
+
changed.push(formattedEntry);
|
|
265
|
+
break;
|
|
266
|
+
case "deprecated":
|
|
267
|
+
deprecated.push(formattedEntry);
|
|
268
|
+
break;
|
|
269
|
+
case "removed":
|
|
270
|
+
removed.push(formattedEntry);
|
|
271
|
+
break;
|
|
272
|
+
case "fixed":
|
|
273
|
+
fixed.push(formattedEntry);
|
|
274
|
+
break;
|
|
275
|
+
case "security":
|
|
276
|
+
security.push(formattedEntry);
|
|
277
|
+
break;
|
|
278
|
+
default:
|
|
279
|
+
changed.push(formattedEntry);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
let content = `## [${version}] - ${date}
|
|
283
|
+
|
|
284
|
+
`;
|
|
285
|
+
if (added.length > 0) {
|
|
286
|
+
content += `### Added
|
|
287
|
+
|
|
288
|
+
${added.join("\n")}
|
|
289
|
+
|
|
290
|
+
`;
|
|
291
|
+
}
|
|
292
|
+
if (changed.length > 0) {
|
|
293
|
+
content += `### Changed
|
|
294
|
+
|
|
295
|
+
${changed.join("\n")}
|
|
296
|
+
|
|
297
|
+
`;
|
|
298
|
+
}
|
|
299
|
+
if (deprecated.length > 0) {
|
|
300
|
+
content += `### Deprecated
|
|
301
|
+
|
|
302
|
+
${deprecated.join("\n")}
|
|
303
|
+
|
|
304
|
+
`;
|
|
305
|
+
}
|
|
306
|
+
if (removed.length > 0) {
|
|
307
|
+
content += `### Removed
|
|
308
|
+
|
|
309
|
+
${removed.join("\n")}
|
|
310
|
+
|
|
311
|
+
`;
|
|
312
|
+
}
|
|
313
|
+
if (fixed.length > 0) {
|
|
314
|
+
content += `### Fixed
|
|
315
|
+
|
|
316
|
+
${fixed.join("\n")}
|
|
317
|
+
|
|
318
|
+
`;
|
|
319
|
+
}
|
|
320
|
+
if (security.length > 0) {
|
|
321
|
+
content += `### Security
|
|
322
|
+
|
|
323
|
+
${security.join("\n")}
|
|
324
|
+
|
|
325
|
+
`;
|
|
326
|
+
}
|
|
327
|
+
if (repoUrl) {
|
|
328
|
+
content += `[${version}]: ${repoUrl}/compare/v${version}...HEAD
|
|
329
|
+
`;
|
|
330
|
+
}
|
|
331
|
+
return content.trim();
|
|
332
|
+
}
|
|
333
|
+
function formatAngularEntries(version, date, entries, packageName) {
|
|
334
|
+
const features = [];
|
|
335
|
+
const bugfixes = [];
|
|
336
|
+
const performance = [];
|
|
337
|
+
const breaking = [];
|
|
338
|
+
for (const entry of entries) {
|
|
339
|
+
if (entry.breaking) {
|
|
340
|
+
breaking.push(entry);
|
|
341
|
+
}
|
|
342
|
+
const entryType = entry.originalType || entry.type;
|
|
343
|
+
switch (entryType) {
|
|
344
|
+
case "feat":
|
|
345
|
+
case "added":
|
|
346
|
+
features.push(entry);
|
|
347
|
+
break;
|
|
348
|
+
case "fix":
|
|
349
|
+
case "fixed":
|
|
350
|
+
bugfixes.push(entry);
|
|
351
|
+
break;
|
|
352
|
+
case "perf":
|
|
353
|
+
performance.push(entry);
|
|
354
|
+
break;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
let content = `## [${version}]${packageName ? ` (${packageName})` : ""} (${date})
|
|
358
|
+
|
|
359
|
+
`;
|
|
360
|
+
if (features.length > 0) {
|
|
361
|
+
content += "### Features\n\n";
|
|
362
|
+
content += formatAngularTypeEntries(features);
|
|
363
|
+
content += "\n";
|
|
364
|
+
}
|
|
365
|
+
if (bugfixes.length > 0) {
|
|
366
|
+
content += "### Bug Fixes\n\n";
|
|
367
|
+
content += formatAngularTypeEntries(bugfixes);
|
|
368
|
+
content += "\n";
|
|
369
|
+
}
|
|
370
|
+
if (performance.length > 0) {
|
|
371
|
+
content += "### Performance Improvements\n\n";
|
|
372
|
+
content += formatAngularTypeEntries(performance);
|
|
373
|
+
content += "\n";
|
|
374
|
+
}
|
|
375
|
+
if (breaking.length > 0) {
|
|
376
|
+
content += "### BREAKING CHANGES\n\n";
|
|
377
|
+
content += formatAngularTypeEntries(breaking);
|
|
378
|
+
content += "\n";
|
|
379
|
+
}
|
|
380
|
+
return content.trim();
|
|
381
|
+
}
|
|
382
|
+
function formatAngularTypeEntries(entries) {
|
|
383
|
+
var _a;
|
|
384
|
+
const entriesByScope = /* @__PURE__ */ new Map();
|
|
385
|
+
for (const entry of entries) {
|
|
386
|
+
const scope = entry.scope || "";
|
|
387
|
+
if (!entriesByScope.has(scope)) {
|
|
388
|
+
entriesByScope.set(scope, []);
|
|
389
|
+
}
|
|
390
|
+
(_a = entriesByScope.get(scope)) == null ? void 0 : _a.push(entry);
|
|
391
|
+
}
|
|
392
|
+
const result = [];
|
|
393
|
+
for (const [scope, scopeEntries] of Object.entries(groupEntriesByScope(entries))) {
|
|
394
|
+
if (scope !== "undefined" && scope !== "") {
|
|
395
|
+
result.push(`* **${scope}:**`);
|
|
396
|
+
for (const entry of scopeEntries) {
|
|
397
|
+
const description = entry.description.replace("**BREAKING** ", "");
|
|
398
|
+
result.push(` * ${description}`);
|
|
399
|
+
}
|
|
400
|
+
} else {
|
|
401
|
+
for (const entry of scopeEntries) {
|
|
402
|
+
const description = entry.description.replace("**BREAKING** ", "");
|
|
403
|
+
result.push(`* ${description}`);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
return result.join("\n");
|
|
408
|
+
}
|
|
409
|
+
function groupEntriesByScope(entries) {
|
|
410
|
+
const result = {};
|
|
411
|
+
for (const entry of entries) {
|
|
412
|
+
const scope = entry.scope || "";
|
|
413
|
+
if (!result[scope]) {
|
|
414
|
+
result[scope] = [];
|
|
415
|
+
}
|
|
416
|
+
result[scope].push(entry);
|
|
417
|
+
}
|
|
418
|
+
return result;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// src/changelog/templates.ts
|
|
422
|
+
function getDefaultTemplate(format) {
|
|
423
|
+
return format === "keep-a-changelog" ? getKeepAChangelogTemplate() : getAngularTemplate();
|
|
424
|
+
}
|
|
425
|
+
function getKeepAChangelogTemplate() {
|
|
426
|
+
return `# Changelog
|
|
427
|
+
|
|
428
|
+
All notable changes to this project will be documented in this file.
|
|
429
|
+
|
|
430
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
431
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
432
|
+
|
|
433
|
+
`;
|
|
434
|
+
}
|
|
435
|
+
function getAngularTemplate() {
|
|
436
|
+
return `# Changelog
|
|
437
|
+
|
|
438
|
+
`;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
// src/changelog/changelogRegenerator.ts
|
|
442
|
+
function getAllVersionTags(since, versionPrefix = "v") {
|
|
443
|
+
try {
|
|
444
|
+
const command = since ? `git tag --list "${versionPrefix}*" --sort=creatordate --contains ${since}` : `git tag --list "${versionPrefix}*" --sort=creatordate`;
|
|
445
|
+
const tagOutput = (0, import_node_child_process2.execSync)(command, { encoding: "utf8" }).trim();
|
|
446
|
+
if (!tagOutput) {
|
|
447
|
+
return [];
|
|
448
|
+
}
|
|
449
|
+
const tags = tagOutput.split("\n").filter((tag) => !!tag);
|
|
450
|
+
return tags.map((tag) => {
|
|
451
|
+
try {
|
|
452
|
+
const date = (0, import_node_child_process2.execSync)(`git log -1 --format=%ad --date=short ${tag}`, {
|
|
453
|
+
encoding: "utf8"
|
|
454
|
+
}).trim();
|
|
455
|
+
const version = tag.replace(new RegExp(`^${versionPrefix}`), "");
|
|
456
|
+
return { tag, version, date };
|
|
457
|
+
} catch (error) {
|
|
458
|
+
log(`Failed to get date for tag ${tag}: ${error}`, "warning");
|
|
459
|
+
return { tag, version: tag.replace(new RegExp(`^${versionPrefix}`), ""), date: "Unknown" };
|
|
460
|
+
}
|
|
461
|
+
});
|
|
462
|
+
} catch (error) {
|
|
463
|
+
log(`Failed to get version tags: ${error}`, "error");
|
|
464
|
+
return [];
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
async function regenerateChangelog(options) {
|
|
468
|
+
const { format, since, projectDir } = options;
|
|
469
|
+
const packageJsonPath = import_node_path.default.join(projectDir, "package.json");
|
|
470
|
+
let packageName = "";
|
|
471
|
+
let repoUrl = options.repoUrl;
|
|
472
|
+
if (import_node_fs.default.existsSync(packageJsonPath)) {
|
|
473
|
+
try {
|
|
474
|
+
const packageJson = JSON.parse(import_node_fs.default.readFileSync(packageJsonPath, "utf8"));
|
|
475
|
+
packageName = packageJson.name || "";
|
|
476
|
+
if (!repoUrl && packageJson.repository) {
|
|
477
|
+
if (typeof packageJson.repository === "string") {
|
|
478
|
+
repoUrl = packageJson.repository;
|
|
479
|
+
} else if (packageJson.repository.url) {
|
|
480
|
+
repoUrl = packageJson.repository.url;
|
|
481
|
+
}
|
|
482
|
+
if ((repoUrl == null ? void 0 : repoUrl.startsWith("git+")) && (repoUrl == null ? void 0 : repoUrl.endsWith(".git"))) {
|
|
483
|
+
repoUrl = repoUrl.substring(4, repoUrl.length - 4);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
} catch (error) {
|
|
487
|
+
log(`Failed to read package.json: ${error}`, "warning");
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
let versionPrefix = "v";
|
|
491
|
+
try {
|
|
492
|
+
const allTags = (0, import_node_child_process2.execSync)("git tag --list", { encoding: "utf8" }).trim().split("\n");
|
|
493
|
+
const versionTag = allTags.find((tag) => /^[vV][0-9]/.test(tag));
|
|
494
|
+
if (versionTag) {
|
|
495
|
+
versionPrefix = versionTag.charAt(0);
|
|
496
|
+
}
|
|
497
|
+
} catch {
|
|
498
|
+
}
|
|
499
|
+
const tags = getAllVersionTags(since, versionPrefix);
|
|
500
|
+
if (!tags.length) {
|
|
501
|
+
throw new Error(
|
|
502
|
+
'No version tags found in git history. Make sure you have tags that start with the version prefix (usually "v").'
|
|
503
|
+
);
|
|
504
|
+
}
|
|
505
|
+
let changelogContent = getDefaultTemplate(format);
|
|
506
|
+
log(`Found ${tags.length} version tags, generating changelog...`, "info");
|
|
507
|
+
const versions = [];
|
|
508
|
+
for (let i = tags.length - 1; i >= 0; i--) {
|
|
509
|
+
const currentTag = tags[i];
|
|
510
|
+
const previousTag = i > 0 ? tags[i - 1].tag : null;
|
|
511
|
+
log(`Processing changes for ${currentTag.tag}...`, "info");
|
|
512
|
+
try {
|
|
513
|
+
const tagRange = previousTag ? `${previousTag}..${currentTag.tag}` : currentTag.tag;
|
|
514
|
+
const entries = extractChangelogEntriesFromCommits(projectDir, tagRange);
|
|
515
|
+
if (!entries.length) {
|
|
516
|
+
log(`No changelog entries found for ${currentTag.tag}, adding placeholder entry`, "info");
|
|
517
|
+
entries.push({
|
|
518
|
+
type: "changed",
|
|
519
|
+
description: `Release version ${currentTag.version}`
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
versions.unshift(
|
|
523
|
+
formatChangelogEntries(
|
|
524
|
+
format,
|
|
525
|
+
currentTag.version,
|
|
526
|
+
currentTag.date,
|
|
527
|
+
entries,
|
|
528
|
+
packageName,
|
|
529
|
+
repoUrl
|
|
530
|
+
)
|
|
531
|
+
);
|
|
532
|
+
} catch (error) {
|
|
533
|
+
log(`Failed to process version ${currentTag.tag}: ${error}`, "error");
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
changelogContent += versions.join("\n\n");
|
|
537
|
+
return changelogContent;
|
|
538
|
+
}
|
|
539
|
+
async function writeChangelog(content, outputPath, dryRun) {
|
|
540
|
+
if (dryRun) {
|
|
541
|
+
log("--- Changelog Preview ---", "info");
|
|
542
|
+
console.log(content);
|
|
543
|
+
log("--- End Preview ---", "info");
|
|
544
|
+
return;
|
|
545
|
+
}
|
|
546
|
+
try {
|
|
547
|
+
import_node_fs.default.writeFileSync(outputPath, content, "utf8");
|
|
548
|
+
log(`Changelog successfully written to ${outputPath}`, "success");
|
|
549
|
+
} catch (error) {
|
|
550
|
+
throw new Error(
|
|
551
|
+
`Failed to write changelog: ${error instanceof Error ? error.message : String(error)}`
|
|
552
|
+
);
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
// src/config.ts
|
|
557
|
+
var fs2 = __toESM(require("fs"), 1);
|
|
558
|
+
var import_node_process = require("process");
|
|
559
|
+
function loadConfig(configPath) {
|
|
560
|
+
const localProcess = (0, import_node_process.cwd)();
|
|
561
|
+
const filePath = configPath || `${localProcess}/version.config.json`;
|
|
562
|
+
return new Promise((resolve, reject) => {
|
|
563
|
+
fs2.readFile(filePath, "utf-8", (err, data) => {
|
|
564
|
+
if (err) {
|
|
565
|
+
reject(new Error(`Could not locate the config file at ${filePath}: ${err.message}`));
|
|
566
|
+
return;
|
|
567
|
+
}
|
|
568
|
+
try {
|
|
569
|
+
const config = JSON.parse(data);
|
|
570
|
+
resolve(config);
|
|
571
|
+
} catch (err2) {
|
|
572
|
+
const errorMessage = err2 instanceof Error ? err2.message : String(err2);
|
|
573
|
+
reject(new Error(`Failed to parse config file ${filePath}: ${errorMessage}`));
|
|
574
|
+
}
|
|
575
|
+
});
|
|
576
|
+
});
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
// src/core/versionEngine.ts
|
|
580
|
+
var import_node_process5 = require("process");
|
|
581
|
+
var import_get_packages = require("@manypkg/get-packages");
|
|
582
|
+
|
|
583
|
+
// src/errors/gitError.ts
|
|
584
|
+
var GitError = class extends Error {
|
|
585
|
+
constructor(message, code) {
|
|
586
|
+
super(message);
|
|
587
|
+
this.code = code;
|
|
588
|
+
this.name = "GitError";
|
|
589
|
+
}
|
|
590
|
+
};
|
|
591
|
+
function createGitError(code, details) {
|
|
592
|
+
const messages = {
|
|
593
|
+
["NOT_GIT_REPO" /* NOT_GIT_REPO */]: "Not a git repository",
|
|
594
|
+
["GIT_PROCESS_ERROR" /* GIT_PROCESS_ERROR */]: "Failed to create new version",
|
|
595
|
+
["NO_FILES" /* NO_FILES */]: "No files specified for commit",
|
|
596
|
+
["NO_COMMIT_MESSAGE" /* NO_COMMIT_MESSAGE */]: "Commit message is required",
|
|
597
|
+
["GIT_ERROR" /* GIT_ERROR */]: "Git operation failed"
|
|
598
|
+
};
|
|
599
|
+
const baseMessage = messages[code];
|
|
600
|
+
const fullMessage = details ? `${baseMessage}: ${details}` : baseMessage;
|
|
601
|
+
return new GitError(fullMessage, code);
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
// src/errors/versionError.ts
|
|
605
|
+
var VersionError = class extends Error {
|
|
606
|
+
constructor(message, code) {
|
|
607
|
+
super(message);
|
|
608
|
+
this.code = code;
|
|
609
|
+
this.name = "VersionError";
|
|
610
|
+
}
|
|
611
|
+
};
|
|
612
|
+
function createVersionError(code, details) {
|
|
613
|
+
const messages = {
|
|
614
|
+
["CONFIG_REQUIRED" /* CONFIG_REQUIRED */]: "Configuration is required",
|
|
615
|
+
["PACKAGES_NOT_FOUND" /* PACKAGES_NOT_FOUND */]: "Failed to get packages information",
|
|
616
|
+
["WORKSPACE_ERROR" /* WORKSPACE_ERROR */]: "Failed to get workspace packages",
|
|
617
|
+
["INVALID_CONFIG" /* INVALID_CONFIG */]: "Invalid configuration",
|
|
618
|
+
["PACKAGE_NOT_FOUND" /* PACKAGE_NOT_FOUND */]: "Package not found",
|
|
619
|
+
["VERSION_CALCULATION_ERROR" /* VERSION_CALCULATION_ERROR */]: "Failed to calculate version"
|
|
620
|
+
};
|
|
621
|
+
const baseMessage = messages[code];
|
|
622
|
+
const fullMessage = details ? `${baseMessage}: ${details}` : baseMessage;
|
|
623
|
+
return new VersionError(fullMessage, code);
|
|
624
|
+
}
|
|
625
|
+
|
|
192
626
|
// src/core/versionStrategies.ts
|
|
193
|
-
var
|
|
194
|
-
var
|
|
627
|
+
var import_node_fs7 = __toESM(require("fs"), 1);
|
|
628
|
+
var path7 = __toESM(require("path"), 1);
|
|
195
629
|
|
|
196
630
|
// src/git/commands.ts
|
|
197
631
|
var import_node_process2 = require("process");
|
|
198
632
|
|
|
199
633
|
// src/git/commandExecutor.ts
|
|
200
|
-
var
|
|
634
|
+
var import_node_child_process3 = require("child_process");
|
|
201
635
|
var execAsync = (command, options) => {
|
|
202
636
|
const defaultOptions = { maxBuffer: 1024 * 1024 * 10, ...options };
|
|
203
637
|
return new Promise((resolve, reject) => {
|
|
204
|
-
(0,
|
|
638
|
+
(0, import_node_child_process3.exec)(
|
|
205
639
|
command,
|
|
206
640
|
defaultOptions,
|
|
207
641
|
(error, stdout, stderr) => {
|
|
@@ -214,29 +648,29 @@ var execAsync = (command, options) => {
|
|
|
214
648
|
);
|
|
215
649
|
});
|
|
216
650
|
};
|
|
217
|
-
var
|
|
651
|
+
var execSync3 = (command, args) => (0, import_node_child_process3.execSync)(command, { maxBuffer: 1024 * 1024 * 10, ...args });
|
|
218
652
|
|
|
219
653
|
// src/git/repository.ts
|
|
220
|
-
var
|
|
221
|
-
var
|
|
654
|
+
var import_node_fs2 = require("fs");
|
|
655
|
+
var import_node_path2 = require("path");
|
|
222
656
|
function isGitRepository(directory) {
|
|
223
|
-
const gitDir = (0,
|
|
224
|
-
if (!(0,
|
|
657
|
+
const gitDir = (0, import_node_path2.join)(directory, ".git");
|
|
658
|
+
if (!(0, import_node_fs2.existsSync)(gitDir)) {
|
|
225
659
|
return false;
|
|
226
660
|
}
|
|
227
|
-
const stats = (0,
|
|
661
|
+
const stats = (0, import_node_fs2.statSync)(gitDir);
|
|
228
662
|
if (!stats.isDirectory()) {
|
|
229
663
|
return false;
|
|
230
664
|
}
|
|
231
665
|
try {
|
|
232
|
-
|
|
666
|
+
execSync3("git rev-parse --is-inside-work-tree", { cwd: directory });
|
|
233
667
|
return true;
|
|
234
668
|
} catch (_error) {
|
|
235
669
|
return false;
|
|
236
670
|
}
|
|
237
671
|
}
|
|
238
672
|
function getCurrentBranch() {
|
|
239
|
-
const result =
|
|
673
|
+
const result = execSync3("git rev-parse --abbrev-ref HEAD");
|
|
240
674
|
return result.toString().trim();
|
|
241
675
|
}
|
|
242
676
|
|
|
@@ -359,8 +793,12 @@ function formatVersionPrefix(versionPrefix, scope) {
|
|
|
359
793
|
}
|
|
360
794
|
return cleanPrefix;
|
|
361
795
|
}
|
|
362
|
-
function formatCommitMessage(template, version, scope) {
|
|
363
|
-
return createTemplateString(template, {
|
|
796
|
+
function formatCommitMessage(template, version, packageName, scope) {
|
|
797
|
+
return createTemplateString(template, {
|
|
798
|
+
version,
|
|
799
|
+
scope,
|
|
800
|
+
packageName: packageName || ""
|
|
801
|
+
});
|
|
364
802
|
}
|
|
365
803
|
function createTemplateString(template, variables) {
|
|
366
804
|
return Object.entries(variables).reduce((result, [key, value]) => {
|
|
@@ -376,7 +814,7 @@ function createTemplateString(template, variables) {
|
|
|
376
814
|
function getCommitsLength(pkgRoot) {
|
|
377
815
|
try {
|
|
378
816
|
const gitCommand = `git rev-list --count HEAD ^$(git describe --tags --abbrev=0) ${pkgRoot}`;
|
|
379
|
-
const amount =
|
|
817
|
+
const amount = execSync3(gitCommand).toString().trim();
|
|
380
818
|
return Number(amount);
|
|
381
819
|
} catch (error) {
|
|
382
820
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -473,21 +911,21 @@ async function getLatestTagForPackage(packageName, versionPrefix) {
|
|
|
473
911
|
}
|
|
474
912
|
|
|
475
913
|
// src/package/packageManagement.ts
|
|
476
|
-
var
|
|
477
|
-
var
|
|
914
|
+
var import_node_fs4 = __toESM(require("fs"), 1);
|
|
915
|
+
var import_node_path4 = __toESM(require("path"), 1);
|
|
478
916
|
|
|
479
917
|
// src/cargo/cargoHandler.ts
|
|
480
|
-
var
|
|
481
|
-
var
|
|
918
|
+
var import_node_fs3 = __toESM(require("fs"), 1);
|
|
919
|
+
var import_node_path3 = __toESM(require("path"), 1);
|
|
482
920
|
var TOML = __toESM(require("smol-toml"), 1);
|
|
483
921
|
function getCargoInfo(cargoPath) {
|
|
484
922
|
var _a;
|
|
485
|
-
if (!
|
|
923
|
+
if (!import_node_fs3.default.existsSync(cargoPath)) {
|
|
486
924
|
log(`Cargo.toml file not found at: ${cargoPath}`, "error");
|
|
487
925
|
throw new Error(`Cargo.toml file not found at: ${cargoPath}`);
|
|
488
926
|
}
|
|
489
927
|
try {
|
|
490
|
-
const fileContent =
|
|
928
|
+
const fileContent = import_node_fs3.default.readFileSync(cargoPath, "utf8");
|
|
491
929
|
const cargo = TOML.parse(fileContent);
|
|
492
930
|
if (!((_a = cargo.package) == null ? void 0 : _a.name)) {
|
|
493
931
|
log(`Package name not found in: ${cargoPath}`, "error");
|
|
@@ -497,7 +935,7 @@ function getCargoInfo(cargoPath) {
|
|
|
497
935
|
name: cargo.package.name,
|
|
498
936
|
version: cargo.package.version || "0.0.0",
|
|
499
937
|
path: cargoPath,
|
|
500
|
-
dir:
|
|
938
|
+
dir: import_node_path3.default.dirname(cargoPath),
|
|
501
939
|
content: cargo
|
|
502
940
|
};
|
|
503
941
|
} catch (error) {
|
|
@@ -510,12 +948,12 @@ function getCargoInfo(cargoPath) {
|
|
|
510
948
|
}
|
|
511
949
|
}
|
|
512
950
|
function isCargoToml(filePath) {
|
|
513
|
-
return
|
|
951
|
+
return import_node_path3.default.basename(filePath) === "Cargo.toml";
|
|
514
952
|
}
|
|
515
953
|
function updateCargoVersion(cargoPath, version) {
|
|
516
954
|
var _a;
|
|
517
955
|
try {
|
|
518
|
-
const originalContent =
|
|
956
|
+
const originalContent = import_node_fs3.default.readFileSync(cargoPath, "utf8");
|
|
519
957
|
const cargo = TOML.parse(originalContent);
|
|
520
958
|
const packageName = (_a = cargo.package) == null ? void 0 : _a.name;
|
|
521
959
|
if (!packageName) {
|
|
@@ -527,7 +965,7 @@ function updateCargoVersion(cargoPath, version) {
|
|
|
527
965
|
cargo.package.version = version;
|
|
528
966
|
}
|
|
529
967
|
const updatedContent = TOML.stringify(cargo);
|
|
530
|
-
|
|
968
|
+
import_node_fs3.default.writeFileSync(cargoPath, updatedContent);
|
|
531
969
|
addPackageUpdate(packageName, version, cargoPath);
|
|
532
970
|
log(`Updated Cargo.toml at ${cargoPath} to version ${version}`, "success");
|
|
533
971
|
} catch (error) {
|
|
@@ -546,11 +984,11 @@ function updatePackageVersion(packagePath, version) {
|
|
|
546
984
|
return;
|
|
547
985
|
}
|
|
548
986
|
try {
|
|
549
|
-
const packageContent =
|
|
987
|
+
const packageContent = import_node_fs4.default.readFileSync(packagePath, "utf8");
|
|
550
988
|
const packageJson = JSON.parse(packageContent);
|
|
551
989
|
const packageName = packageJson.name;
|
|
552
990
|
packageJson.version = version;
|
|
553
|
-
|
|
991
|
+
import_node_fs4.default.writeFileSync(packagePath, `${JSON.stringify(packageJson, null, 2)}
|
|
554
992
|
`);
|
|
555
993
|
addPackageUpdate(packageName, version, packagePath);
|
|
556
994
|
log(`Updated package.json at ${packagePath} to version ${version}`, "success");
|
|
@@ -564,24 +1002,349 @@ function updatePackageVersion(packagePath, version) {
|
|
|
564
1002
|
}
|
|
565
1003
|
|
|
566
1004
|
// src/package/packageProcessor.ts
|
|
567
|
-
var
|
|
568
|
-
var
|
|
1005
|
+
var fs8 = __toESM(require("fs"), 1);
|
|
1006
|
+
var import_node_path6 = __toESM(require("path"), 1);
|
|
569
1007
|
var import_node_process4 = require("process");
|
|
570
1008
|
|
|
1009
|
+
// src/changelog/changelogManager.ts
|
|
1010
|
+
var fs5 = __toESM(require("fs"), 1);
|
|
1011
|
+
var path4 = __toESM(require("path"), 1);
|
|
1012
|
+
function createChangelog(_packagePath, packageName) {
|
|
1013
|
+
return {
|
|
1014
|
+
projectName: packageName,
|
|
1015
|
+
unreleased: [],
|
|
1016
|
+
versions: []
|
|
1017
|
+
};
|
|
1018
|
+
}
|
|
1019
|
+
function parseChangelog(filePath) {
|
|
1020
|
+
try {
|
|
1021
|
+
if (!fs5.existsSync(filePath)) {
|
|
1022
|
+
return null;
|
|
1023
|
+
}
|
|
1024
|
+
fs5.readFileSync(filePath, "utf8");
|
|
1025
|
+
log(`Parsed changelog at ${filePath}`, "info");
|
|
1026
|
+
return {
|
|
1027
|
+
projectName: path4.basename(path4.dirname(filePath)),
|
|
1028
|
+
unreleased: [],
|
|
1029
|
+
versions: []
|
|
1030
|
+
};
|
|
1031
|
+
} catch (error) {
|
|
1032
|
+
log(
|
|
1033
|
+
`Error parsing changelog: ${error instanceof Error ? error.message : String(error)}`,
|
|
1034
|
+
"error"
|
|
1035
|
+
);
|
|
1036
|
+
return null;
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
function generateLinks(changelog, repoUrl) {
|
|
1040
|
+
var _a, _b;
|
|
1041
|
+
if (!repoUrl || changelog.versions.length === 0) {
|
|
1042
|
+
return "";
|
|
1043
|
+
}
|
|
1044
|
+
let links = "\n";
|
|
1045
|
+
if (changelog.unreleased.length > 0) {
|
|
1046
|
+
const latestVersion = ((_a = changelog.versions[0]) == null ? void 0 : _a.version) || "";
|
|
1047
|
+
links += `[unreleased]: ${repoUrl}/compare/v${latestVersion}...HEAD
|
|
1048
|
+
`;
|
|
1049
|
+
}
|
|
1050
|
+
for (let i = 0; i < changelog.versions.length; i++) {
|
|
1051
|
+
const currentVersion = changelog.versions[i].version;
|
|
1052
|
+
const previousVersion = (_b = changelog.versions[i + 1]) == null ? void 0 : _b.version;
|
|
1053
|
+
if (previousVersion) {
|
|
1054
|
+
links += `[${currentVersion}]: ${repoUrl}/compare/v${previousVersion}...v${currentVersion}
|
|
1055
|
+
`;
|
|
1056
|
+
} else if (i === changelog.versions.length - 1) {
|
|
1057
|
+
links += `[${currentVersion}]: ${repoUrl}/releases/tag/v${currentVersion}
|
|
1058
|
+
`;
|
|
1059
|
+
}
|
|
1060
|
+
}
|
|
1061
|
+
return links;
|
|
1062
|
+
}
|
|
1063
|
+
function generateAngularChangelogContent(changelog, repoUrl) {
|
|
1064
|
+
let content = "# Changelog\n\n";
|
|
1065
|
+
if (changelog.unreleased.length > 0) {
|
|
1066
|
+
content += "## [Unreleased]\n\n";
|
|
1067
|
+
const groupedByType = groupEntriesByAngularType(changelog.unreleased);
|
|
1068
|
+
for (const [type, entries] of Object.entries(groupedByType)) {
|
|
1069
|
+
content += `### ${formatAngularType(type)}
|
|
1070
|
+
|
|
1071
|
+
`;
|
|
1072
|
+
const groupedByScope = groupEntriesByScope2(entries);
|
|
1073
|
+
for (const [scope, scopeEntries] of Object.entries(groupedByScope)) {
|
|
1074
|
+
if (scope !== "undefined" && scope !== "") {
|
|
1075
|
+
content += `* **${scope}:**
|
|
1076
|
+
`;
|
|
1077
|
+
for (const entry of scopeEntries) {
|
|
1078
|
+
content += formatAngularEntry(entry, false);
|
|
1079
|
+
}
|
|
1080
|
+
content += "\n";
|
|
1081
|
+
} else {
|
|
1082
|
+
for (const entry of scopeEntries) {
|
|
1083
|
+
content += formatAngularEntry(entry, true);
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
content += "\n";
|
|
1088
|
+
}
|
|
1089
|
+
const breakingChanges = changelog.unreleased.filter(
|
|
1090
|
+
(entry) => entry.description.includes("**BREAKING**")
|
|
1091
|
+
);
|
|
1092
|
+
if (breakingChanges.length > 0) {
|
|
1093
|
+
content += "### BREAKING CHANGES\n\n";
|
|
1094
|
+
for (const entry of breakingChanges) {
|
|
1095
|
+
const description = entry.description.replace("**BREAKING** ", "");
|
|
1096
|
+
content += `* ${entry.scope ? `**${entry.scope}:** ` : ""}${description}`;
|
|
1097
|
+
if (entry.issueIds && entry.issueIds.length > 0) {
|
|
1098
|
+
content += ` (${entry.issueIds.join(", ")})`;
|
|
1099
|
+
}
|
|
1100
|
+
content += "\n";
|
|
1101
|
+
}
|
|
1102
|
+
content += "\n";
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
for (const version of changelog.versions) {
|
|
1106
|
+
content += `## [${version.version}] - ${version.date}
|
|
1107
|
+
|
|
1108
|
+
`;
|
|
1109
|
+
const groupedByType = groupEntriesByAngularType(version.entries);
|
|
1110
|
+
for (const [type, entries] of Object.entries(groupedByType)) {
|
|
1111
|
+
content += `### ${formatAngularType(type)}
|
|
1112
|
+
|
|
1113
|
+
`;
|
|
1114
|
+
const groupedByScope = groupEntriesByScope2(entries);
|
|
1115
|
+
for (const [scope, scopeEntries] of Object.entries(groupedByScope)) {
|
|
1116
|
+
if (scope !== "undefined" && scope !== "") {
|
|
1117
|
+
content += `* **${scope}:**
|
|
1118
|
+
`;
|
|
1119
|
+
for (const entry of scopeEntries) {
|
|
1120
|
+
content += formatAngularEntry(entry, false);
|
|
1121
|
+
}
|
|
1122
|
+
content += "\n";
|
|
1123
|
+
} else {
|
|
1124
|
+
for (const entry of scopeEntries) {
|
|
1125
|
+
content += formatAngularEntry(entry, true);
|
|
1126
|
+
}
|
|
1127
|
+
}
|
|
1128
|
+
}
|
|
1129
|
+
content += "\n";
|
|
1130
|
+
}
|
|
1131
|
+
const breakingChanges = version.entries.filter(
|
|
1132
|
+
(entry) => entry.description.includes("**BREAKING**")
|
|
1133
|
+
);
|
|
1134
|
+
if (breakingChanges.length > 0) {
|
|
1135
|
+
content += "### BREAKING CHANGES\n\n";
|
|
1136
|
+
for (const entry of breakingChanges) {
|
|
1137
|
+
const description = entry.description.replace("**BREAKING** ", "");
|
|
1138
|
+
content += `* ${entry.scope ? `**${entry.scope}:** ` : ""}${description}`;
|
|
1139
|
+
if (entry.issueIds && entry.issueIds.length > 0) {
|
|
1140
|
+
content += ` (${entry.issueIds.join(", ")})`;
|
|
1141
|
+
}
|
|
1142
|
+
content += "\n";
|
|
1143
|
+
}
|
|
1144
|
+
content += "\n";
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
1147
|
+
content += generateLinks(changelog, repoUrl);
|
|
1148
|
+
return content;
|
|
1149
|
+
}
|
|
1150
|
+
function groupEntriesByAngularType(entries) {
|
|
1151
|
+
const result = {};
|
|
1152
|
+
for (const entry of entries) {
|
|
1153
|
+
const type = entry.originalType || mapToAngularType(entry.type);
|
|
1154
|
+
if (!result[type]) {
|
|
1155
|
+
result[type] = [];
|
|
1156
|
+
}
|
|
1157
|
+
result[type].push(entry);
|
|
1158
|
+
}
|
|
1159
|
+
return result;
|
|
1160
|
+
}
|
|
1161
|
+
function mapToAngularType(type) {
|
|
1162
|
+
switch (type) {
|
|
1163
|
+
case "added":
|
|
1164
|
+
return "feat";
|
|
1165
|
+
case "fixed":
|
|
1166
|
+
return "fix";
|
|
1167
|
+
case "changed":
|
|
1168
|
+
return "perf";
|
|
1169
|
+
case "deprecated":
|
|
1170
|
+
case "removed":
|
|
1171
|
+
case "security":
|
|
1172
|
+
return type;
|
|
1173
|
+
default:
|
|
1174
|
+
return type;
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
function formatAngularType(type) {
|
|
1178
|
+
switch (type) {
|
|
1179
|
+
case "feat":
|
|
1180
|
+
return "Features";
|
|
1181
|
+
case "fix":
|
|
1182
|
+
return "Bug Fixes";
|
|
1183
|
+
case "perf":
|
|
1184
|
+
return "Performance Improvements";
|
|
1185
|
+
case "security":
|
|
1186
|
+
return "Security";
|
|
1187
|
+
case "deprecated":
|
|
1188
|
+
return "Deprecated";
|
|
1189
|
+
case "removed":
|
|
1190
|
+
return "Removed";
|
|
1191
|
+
default:
|
|
1192
|
+
return capitalizeFirstLetter(type);
|
|
1193
|
+
}
|
|
1194
|
+
}
|
|
1195
|
+
function groupEntriesByScope2(entries) {
|
|
1196
|
+
const result = {};
|
|
1197
|
+
for (const entry of entries) {
|
|
1198
|
+
const scope = entry.scope || "";
|
|
1199
|
+
if (!result[scope]) {
|
|
1200
|
+
result[scope] = [];
|
|
1201
|
+
}
|
|
1202
|
+
result[scope].push(entry);
|
|
1203
|
+
}
|
|
1204
|
+
return result;
|
|
1205
|
+
}
|
|
1206
|
+
function formatAngularEntry(entry, includeScope) {
|
|
1207
|
+
let result = " * ";
|
|
1208
|
+
if (includeScope && entry.scope) {
|
|
1209
|
+
result += `**${entry.scope}:** `;
|
|
1210
|
+
}
|
|
1211
|
+
let description = entry.description;
|
|
1212
|
+
if (!includeScope && entry.scope && description.startsWith(`**${entry.scope}**: `)) {
|
|
1213
|
+
description = description.substring(`**${entry.scope}**: `.length);
|
|
1214
|
+
}
|
|
1215
|
+
if (description.startsWith("**BREAKING** ")) {
|
|
1216
|
+
description = description.substring("**BREAKING** ".length);
|
|
1217
|
+
}
|
|
1218
|
+
result += description;
|
|
1219
|
+
if (entry.issueIds && entry.issueIds.length > 0) {
|
|
1220
|
+
result += ` (${entry.issueIds.join(", ")})`;
|
|
1221
|
+
}
|
|
1222
|
+
result += "\n";
|
|
1223
|
+
return result;
|
|
1224
|
+
}
|
|
1225
|
+
function generateChangelogContent(changelog, repoUrl, format = "keep-a-changelog") {
|
|
1226
|
+
if (format === "angular") {
|
|
1227
|
+
return generateAngularChangelogContent(changelog, repoUrl);
|
|
1228
|
+
}
|
|
1229
|
+
let content = "# Changelog\n\n";
|
|
1230
|
+
content += `All notable changes to ${changelog.projectName} will be documented in this file.
|
|
1231
|
+
|
|
1232
|
+
`;
|
|
1233
|
+
content += "The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),\n";
|
|
1234
|
+
content += "and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n\n";
|
|
1235
|
+
if (changelog.unreleased.length > 0) {
|
|
1236
|
+
content += "## [Unreleased]\n\n";
|
|
1237
|
+
const grouped = changelog.unreleased.reduce(
|
|
1238
|
+
(acc, entry) => {
|
|
1239
|
+
if (!acc[entry.type]) {
|
|
1240
|
+
acc[entry.type] = [];
|
|
1241
|
+
}
|
|
1242
|
+
acc[entry.type].push(entry);
|
|
1243
|
+
return acc;
|
|
1244
|
+
},
|
|
1245
|
+
{}
|
|
1246
|
+
);
|
|
1247
|
+
for (const [type, entries] of Object.entries(grouped)) {
|
|
1248
|
+
content += `### ${capitalizeFirstLetter(type)}
|
|
1249
|
+
|
|
1250
|
+
`;
|
|
1251
|
+
for (const entry of entries) {
|
|
1252
|
+
let entryText = `- ${entry.description}`;
|
|
1253
|
+
if (entry.issueIds && entry.issueIds.length > 0) {
|
|
1254
|
+
entryText += ` (${entry.issueIds.join(", ")})`;
|
|
1255
|
+
}
|
|
1256
|
+
content += `${entryText}.
|
|
1257
|
+
`;
|
|
1258
|
+
}
|
|
1259
|
+
content += "\n";
|
|
1260
|
+
}
|
|
1261
|
+
}
|
|
1262
|
+
for (const version of changelog.versions) {
|
|
1263
|
+
content += `## [${version.version}] - ${version.date}
|
|
1264
|
+
|
|
1265
|
+
`;
|
|
1266
|
+
const grouped = version.entries.reduce(
|
|
1267
|
+
(acc, entry) => {
|
|
1268
|
+
if (!acc[entry.type]) {
|
|
1269
|
+
acc[entry.type] = [];
|
|
1270
|
+
}
|
|
1271
|
+
acc[entry.type].push(entry);
|
|
1272
|
+
return acc;
|
|
1273
|
+
},
|
|
1274
|
+
{}
|
|
1275
|
+
);
|
|
1276
|
+
for (const [type, entries] of Object.entries(grouped)) {
|
|
1277
|
+
content += `### ${capitalizeFirstLetter(type)}
|
|
1278
|
+
|
|
1279
|
+
`;
|
|
1280
|
+
for (const entry of entries) {
|
|
1281
|
+
let entryText = `- ${entry.description}`;
|
|
1282
|
+
if (entry.issueIds && entry.issueIds.length > 0) {
|
|
1283
|
+
entryText += ` (${entry.issueIds.join(", ")})`;
|
|
1284
|
+
}
|
|
1285
|
+
content += `${entryText}.
|
|
1286
|
+
`;
|
|
1287
|
+
}
|
|
1288
|
+
content += "\n";
|
|
1289
|
+
}
|
|
1290
|
+
}
|
|
1291
|
+
content += generateLinks(changelog, repoUrl);
|
|
1292
|
+
return content;
|
|
1293
|
+
}
|
|
1294
|
+
function updateChangelog(packagePath, packageName, version, entries, repoUrl, format = "keep-a-changelog") {
|
|
1295
|
+
try {
|
|
1296
|
+
const changelogPath = path4.join(packagePath, "CHANGELOG.md");
|
|
1297
|
+
let changelog;
|
|
1298
|
+
if (fs5.existsSync(changelogPath)) {
|
|
1299
|
+
const existingChangelog = parseChangelog(changelogPath);
|
|
1300
|
+
if (existingChangelog) {
|
|
1301
|
+
changelog = existingChangelog;
|
|
1302
|
+
} else {
|
|
1303
|
+
changelog = createChangelog(packagePath, packageName);
|
|
1304
|
+
}
|
|
1305
|
+
} else {
|
|
1306
|
+
changelog = createChangelog(packagePath, packageName);
|
|
1307
|
+
}
|
|
1308
|
+
if (version) {
|
|
1309
|
+
const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
1310
|
+
const newVersion = {
|
|
1311
|
+
version,
|
|
1312
|
+
date: today,
|
|
1313
|
+
entries: [...changelog.unreleased, ...entries]
|
|
1314
|
+
};
|
|
1315
|
+
changelog.unreleased = [];
|
|
1316
|
+
changelog.versions.unshift(newVersion);
|
|
1317
|
+
} else {
|
|
1318
|
+
changelog.unreleased = [...changelog.unreleased, ...entries];
|
|
1319
|
+
}
|
|
1320
|
+
const content = generateChangelogContent(changelog, repoUrl, format);
|
|
1321
|
+
fs5.writeFileSync(changelogPath, content);
|
|
1322
|
+
log(`Updated changelog at ${changelogPath}`, "success");
|
|
1323
|
+
} catch (error) {
|
|
1324
|
+
log(
|
|
1325
|
+
`Error updating changelog: ${error instanceof Error ? error.message : String(error)}`,
|
|
1326
|
+
"error"
|
|
1327
|
+
);
|
|
1328
|
+
}
|
|
1329
|
+
}
|
|
1330
|
+
function capitalizeFirstLetter(input) {
|
|
1331
|
+
return input.charAt(0).toUpperCase() + input.slice(1);
|
|
1332
|
+
}
|
|
1333
|
+
|
|
571
1334
|
// src/core/versionCalculator.ts
|
|
572
1335
|
var import_node_process3 = require("process");
|
|
573
1336
|
var import_conventional_recommended_bump = require("conventional-recommended-bump");
|
|
574
1337
|
var import_semver2 = __toESM(require("semver"), 1);
|
|
575
1338
|
|
|
576
1339
|
// src/utils/manifestHelpers.ts
|
|
577
|
-
var
|
|
578
|
-
var
|
|
1340
|
+
var import_node_fs5 = __toESM(require("fs"), 1);
|
|
1341
|
+
var import_node_path5 = __toESM(require("path"), 1);
|
|
579
1342
|
function getVersionFromManifests(packageDir) {
|
|
580
|
-
const packageJsonPath =
|
|
581
|
-
const cargoTomlPath =
|
|
582
|
-
if (
|
|
1343
|
+
const packageJsonPath = import_node_path5.default.join(packageDir, "package.json");
|
|
1344
|
+
const cargoTomlPath = import_node_path5.default.join(packageDir, "Cargo.toml");
|
|
1345
|
+
if (import_node_fs5.default.existsSync(packageJsonPath)) {
|
|
583
1346
|
try {
|
|
584
|
-
const packageJson = JSON.parse(
|
|
1347
|
+
const packageJson = JSON.parse(import_node_fs5.default.readFileSync(packageJsonPath, "utf-8"));
|
|
585
1348
|
if (packageJson.version) {
|
|
586
1349
|
log(`Found version ${packageJson.version} in package.json`, "debug");
|
|
587
1350
|
return {
|
|
@@ -597,7 +1360,7 @@ function getVersionFromManifests(packageDir) {
|
|
|
597
1360
|
log(`Error reading package.json: ${errMsg}`, "warning");
|
|
598
1361
|
}
|
|
599
1362
|
}
|
|
600
|
-
if (
|
|
1363
|
+
if (import_node_fs5.default.existsSync(cargoTomlPath)) {
|
|
601
1364
|
try {
|
|
602
1365
|
const cargoInfo = getCargoInfo(cargoTomlPath);
|
|
603
1366
|
if (cargoInfo.version) {
|
|
@@ -623,15 +1386,15 @@ function getVersionFromManifests(packageDir) {
|
|
|
623
1386
|
};
|
|
624
1387
|
}
|
|
625
1388
|
function throwIfNoManifestsFound(packageDir) {
|
|
626
|
-
const packageJsonPath =
|
|
627
|
-
const cargoTomlPath =
|
|
1389
|
+
const packageJsonPath = import_node_path5.default.join(packageDir, "package.json");
|
|
1390
|
+
const cargoTomlPath = import_node_path5.default.join(packageDir, "Cargo.toml");
|
|
628
1391
|
throw new Error(
|
|
629
1392
|
`Neither package.json nor Cargo.toml found at ${packageDir}. Checked paths: ${packageJsonPath}, ${cargoTomlPath}. Cannot determine version.`
|
|
630
1393
|
);
|
|
631
1394
|
}
|
|
632
1395
|
|
|
633
1396
|
// src/utils/versionUtils.ts
|
|
634
|
-
var
|
|
1397
|
+
var import_node_fs6 = __toESM(require("fs"), 1);
|
|
635
1398
|
var import_semver = __toESM(require("semver"), 1);
|
|
636
1399
|
var TOML2 = __toESM(require("smol-toml"), 1);
|
|
637
1400
|
var STANDARD_BUMP_TYPES = ["major", "minor", "patch"];
|
|
@@ -880,7 +1643,7 @@ var PackageProcessor = class {
|
|
|
880
1643
|
* Process packages based on targeting criteria
|
|
881
1644
|
*/
|
|
882
1645
|
async processPackages(packages) {
|
|
883
|
-
var _a;
|
|
1646
|
+
var _a, _b, _c, _d, _e;
|
|
884
1647
|
const tags = [];
|
|
885
1648
|
const updatedPackagesInfo = [];
|
|
886
1649
|
if (!packages || !Array.isArray(packages)) {
|
|
@@ -965,13 +1728,81 @@ var PackageProcessor = class {
|
|
|
965
1728
|
if (!nextVersion) {
|
|
966
1729
|
continue;
|
|
967
1730
|
}
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
1731
|
+
if (this.fullConfig.updateChangelog !== false) {
|
|
1732
|
+
let changelogEntries = [];
|
|
1733
|
+
try {
|
|
1734
|
+
changelogEntries = extractChangelogEntriesFromCommits(pkgPath, latestTag);
|
|
1735
|
+
if (changelogEntries.length === 0) {
|
|
1736
|
+
changelogEntries = [
|
|
1737
|
+
{
|
|
1738
|
+
type: "changed",
|
|
1739
|
+
description: `Update version to ${nextVersion}`
|
|
1740
|
+
}
|
|
1741
|
+
];
|
|
1742
|
+
}
|
|
1743
|
+
} catch (error) {
|
|
1744
|
+
log(
|
|
1745
|
+
`Error extracting changelog entries: ${error instanceof Error ? error.message : String(error)}`,
|
|
1746
|
+
"warning"
|
|
1747
|
+
);
|
|
1748
|
+
changelogEntries = [
|
|
1749
|
+
{
|
|
1750
|
+
type: "changed",
|
|
1751
|
+
description: `Update version to ${nextVersion}`
|
|
1752
|
+
}
|
|
1753
|
+
];
|
|
1754
|
+
}
|
|
1755
|
+
let repoUrl;
|
|
1756
|
+
try {
|
|
1757
|
+
const packageJsonPath2 = import_node_path6.default.join(pkgPath, "package.json");
|
|
1758
|
+
if (fs8.existsSync(packageJsonPath2)) {
|
|
1759
|
+
const packageJson = JSON.parse(fs8.readFileSync(packageJsonPath2, "utf8"));
|
|
1760
|
+
if (packageJson.repository) {
|
|
1761
|
+
if (typeof packageJson.repository === "string") {
|
|
1762
|
+
repoUrl = packageJson.repository;
|
|
1763
|
+
} else if (packageJson.repository.url) {
|
|
1764
|
+
repoUrl = packageJson.repository.url;
|
|
1765
|
+
}
|
|
1766
|
+
if ((repoUrl == null ? void 0 : repoUrl.startsWith("git+")) && (repoUrl == null ? void 0 : repoUrl.endsWith(".git"))) {
|
|
1767
|
+
repoUrl = repoUrl.substring(4, repoUrl.length - 4);
|
|
1768
|
+
}
|
|
1769
|
+
}
|
|
1770
|
+
}
|
|
1771
|
+
} catch (error) {
|
|
1772
|
+
log(
|
|
1773
|
+
`Could not determine repository URL for changelog links: ${error instanceof Error ? error.message : String(error)}`,
|
|
1774
|
+
"warning"
|
|
1775
|
+
);
|
|
1776
|
+
}
|
|
1777
|
+
updateChangelog(
|
|
1778
|
+
pkgPath,
|
|
1779
|
+
name,
|
|
1780
|
+
nextVersion,
|
|
1781
|
+
changelogEntries,
|
|
1782
|
+
repoUrl,
|
|
1783
|
+
this.fullConfig.changelogFormat
|
|
1784
|
+
);
|
|
1785
|
+
}
|
|
1786
|
+
const packageJsonPath = import_node_path6.default.join(pkgPath, "package.json");
|
|
1787
|
+
if (fs8.existsSync(packageJsonPath)) {
|
|
971
1788
|
updatePackageVersion(packageJsonPath, nextVersion);
|
|
972
1789
|
}
|
|
973
|
-
|
|
974
|
-
|
|
1790
|
+
const cargoEnabled = ((_a = this.fullConfig.cargo) == null ? void 0 : _a.enabled) !== false;
|
|
1791
|
+
if (cargoEnabled) {
|
|
1792
|
+
const cargoPaths = (_b = this.fullConfig.cargo) == null ? void 0 : _b.paths;
|
|
1793
|
+
if (cargoPaths && cargoPaths.length > 0) {
|
|
1794
|
+
for (const cargoPath of cargoPaths) {
|
|
1795
|
+
const resolvedCargoPath = import_node_path6.default.resolve(pkgPath, cargoPath, "Cargo.toml");
|
|
1796
|
+
if (fs8.existsSync(resolvedCargoPath)) {
|
|
1797
|
+
updatePackageVersion(resolvedCargoPath, nextVersion);
|
|
1798
|
+
}
|
|
1799
|
+
}
|
|
1800
|
+
} else {
|
|
1801
|
+
const cargoTomlPath = import_node_path6.default.join(pkgPath, "Cargo.toml");
|
|
1802
|
+
if (fs8.existsSync(cargoTomlPath)) {
|
|
1803
|
+
updatePackageVersion(cargoTomlPath, nextVersion);
|
|
1804
|
+
}
|
|
1805
|
+
}
|
|
975
1806
|
}
|
|
976
1807
|
const packageTag = formatTag(
|
|
977
1808
|
nextVersion,
|
|
@@ -1003,12 +1834,37 @@ var PackageProcessor = class {
|
|
|
1003
1834
|
log("No targeted packages required a version update.", "info");
|
|
1004
1835
|
return { updatedPackages: [], tags };
|
|
1005
1836
|
}
|
|
1006
|
-
const filesToCommit =
|
|
1837
|
+
const filesToCommit = [];
|
|
1838
|
+
for (const info of updatedPackagesInfo) {
|
|
1839
|
+
const packageJsonPath = import_node_path6.default.join(info.path, "package.json");
|
|
1840
|
+
if (fs8.existsSync(packageJsonPath)) {
|
|
1841
|
+
filesToCommit.push(packageJsonPath);
|
|
1842
|
+
}
|
|
1843
|
+
const cargoEnabled = ((_c = this.fullConfig.cargo) == null ? void 0 : _c.enabled) !== false;
|
|
1844
|
+
if (cargoEnabled) {
|
|
1845
|
+
const cargoPaths = (_d = this.fullConfig.cargo) == null ? void 0 : _d.paths;
|
|
1846
|
+
if (cargoPaths && cargoPaths.length > 0) {
|
|
1847
|
+
for (const cargoPath of cargoPaths) {
|
|
1848
|
+
const resolvedCargoPath = import_node_path6.default.resolve(info.path, cargoPath, "Cargo.toml");
|
|
1849
|
+
if (fs8.existsSync(resolvedCargoPath)) {
|
|
1850
|
+
filesToCommit.push(resolvedCargoPath);
|
|
1851
|
+
}
|
|
1852
|
+
}
|
|
1853
|
+
} else {
|
|
1854
|
+
const cargoTomlPath = import_node_path6.default.join(info.path, "Cargo.toml");
|
|
1855
|
+
if (fs8.existsSync(cargoTomlPath)) {
|
|
1856
|
+
filesToCommit.push(cargoTomlPath);
|
|
1857
|
+
}
|
|
1858
|
+
}
|
|
1859
|
+
}
|
|
1860
|
+
}
|
|
1007
1861
|
const packageNames = updatedPackagesInfo.map((p) => p.name).join(", ");
|
|
1008
|
-
const representativeVersion = ((
|
|
1862
|
+
const representativeVersion = ((_e = updatedPackagesInfo[0]) == null ? void 0 : _e.version) || "multiple";
|
|
1009
1863
|
let commitMessage = this.commitMessageTemplate || "chore(release): publish packages";
|
|
1010
|
-
|
|
1011
|
-
|
|
1864
|
+
const placeholderRegex = /\$\{[^}]+\}/;
|
|
1865
|
+
if (updatedPackagesInfo.length === 1 && placeholderRegex.test(commitMessage)) {
|
|
1866
|
+
const packageName = updatedPackagesInfo[0].name;
|
|
1867
|
+
commitMessage = formatCommitMessage(commitMessage, representativeVersion, packageName);
|
|
1012
1868
|
} else {
|
|
1013
1869
|
commitMessage = `chore(release): ${packageNames} ${representativeVersion}`;
|
|
1014
1870
|
}
|
|
@@ -1080,20 +1936,21 @@ function createSyncedStrategy(config) {
|
|
|
1080
1936
|
const files = [];
|
|
1081
1937
|
const updatedPackages = [];
|
|
1082
1938
|
try {
|
|
1083
|
-
const rootPkgPath =
|
|
1084
|
-
if (
|
|
1939
|
+
const rootPkgPath = path7.join(packages.root, "package.json");
|
|
1940
|
+
if (import_node_fs7.default.existsSync(rootPkgPath)) {
|
|
1085
1941
|
updatePackageVersion(rootPkgPath, nextVersion);
|
|
1086
1942
|
files.push(rootPkgPath);
|
|
1087
1943
|
updatedPackages.push("root");
|
|
1088
1944
|
}
|
|
1089
|
-
} catch (
|
|
1090
|
-
|
|
1945
|
+
} catch (error) {
|
|
1946
|
+
const errMessage = error instanceof Error ? error.message : String(error);
|
|
1947
|
+
log(`Failed to update root package.json: ${errMessage}`, "error");
|
|
1091
1948
|
}
|
|
1092
1949
|
for (const pkg of packages.packages) {
|
|
1093
1950
|
if (!shouldProcessPackage(pkg, config)) {
|
|
1094
1951
|
continue;
|
|
1095
1952
|
}
|
|
1096
|
-
const packageJsonPath =
|
|
1953
|
+
const packageJsonPath = path7.join(pkg.dir, "package.json");
|
|
1097
1954
|
updatePackageVersion(packageJsonPath, nextVersion);
|
|
1098
1955
|
files.push(packageJsonPath);
|
|
1099
1956
|
updatedPackages.push(pkg.packageJson.name);
|
|
@@ -1166,7 +2023,7 @@ function createSingleStrategy(config) {
|
|
|
1166
2023
|
log(`No version change needed for ${packageName}`, "info");
|
|
1167
2024
|
return;
|
|
1168
2025
|
}
|
|
1169
|
-
const packageJsonPath =
|
|
2026
|
+
const packageJsonPath = path7.join(pkgPath, "package.json");
|
|
1170
2027
|
updatePackageVersion(packageJsonPath, nextVersion);
|
|
1171
2028
|
log(`Updated package ${packageName} to version ${nextVersion}`, "success");
|
|
1172
2029
|
const nextTag = formatTag(
|
|
@@ -1176,7 +2033,7 @@ function createSingleStrategy(config) {
|
|
|
1176
2033
|
tagTemplate,
|
|
1177
2034
|
packageTagTemplate
|
|
1178
2035
|
);
|
|
1179
|
-
const formattedCommitMessage = formatCommitMessage(commitMessage, nextVersion);
|
|
2036
|
+
const formattedCommitMessage = formatCommitMessage(commitMessage, nextVersion, packageName);
|
|
1180
2037
|
await createGitCommitAndTag(
|
|
1181
2038
|
[packageJsonPath],
|
|
1182
2039
|
nextTag,
|
|
@@ -1345,11 +2202,11 @@ var VersionEngine = class {
|
|
|
1345
2202
|
var import_meta = {};
|
|
1346
2203
|
function getPackageVersion() {
|
|
1347
2204
|
try {
|
|
1348
|
-
const packageJsonPath =
|
|
1349
|
-
|
|
2205
|
+
const packageJsonPath = import_node_path7.default.resolve(
|
|
2206
|
+
import_node_path7.default.dirname(import_meta.url.replace("file:", "")),
|
|
1350
2207
|
"../package.json"
|
|
1351
2208
|
);
|
|
1352
|
-
const packageJsonContent =
|
|
2209
|
+
const packageJsonContent = fs10.readFileSync(packageJsonPath, "utf-8");
|
|
1353
2210
|
const packageJson = JSON.parse(packageJsonContent);
|
|
1354
2211
|
return packageJson.version || "0.0.0";
|
|
1355
2212
|
} catch (error) {
|
|
@@ -1358,53 +2215,94 @@ function getPackageVersion() {
|
|
|
1358
2215
|
}
|
|
1359
2216
|
}
|
|
1360
2217
|
async function run() {
|
|
1361
|
-
const buildTimestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
1362
|
-
const packageVersion = getPackageVersion();
|
|
1363
|
-
log(`package-versioner v${packageVersion} (Build: ${buildTimestamp})`, "debug");
|
|
1364
|
-
const program = new import_commander.Command();
|
|
1365
|
-
program.name("package-versioner").description(
|
|
1366
|
-
"A lightweight yet powerful CLI tool for automated semantic versioning based on Git history and conventional commits."
|
|
1367
|
-
).version(packageVersion).option(
|
|
1368
|
-
"-c, --config <path>",
|
|
1369
|
-
"Path to config file (defaults to version.config.json in current directory)"
|
|
1370
|
-
).option("-d, --dry-run", "Dry run (no changes made)", false).option("-b, --bump <type>", "Specify bump type (patch|minor|major)").option("-p, --prerelease [identifier]", "Create prerelease version").option("-s, --synced", "Use synchronized versioning across all packages").option("-j, --json", "Output results as JSON", false).option("-t, --target <packages>", "Comma-delimited list of package names to target").parse(process.argv);
|
|
1371
|
-
const options = program.opts();
|
|
1372
|
-
if (options.json) {
|
|
1373
|
-
enableJsonOutput(options.dryRun);
|
|
1374
|
-
}
|
|
1375
2218
|
try {
|
|
1376
|
-
const
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
} else if (config.packages && config.packages.length === 1) {
|
|
1390
|
-
log("Using single package versioning strategy.", "info");
|
|
1391
|
-
if (cliTargets.length > 0) {
|
|
1392
|
-
log("--target flag is ignored for single package strategy.", "warning");
|
|
1393
|
-
}
|
|
1394
|
-
engine.setStrategy("single");
|
|
1395
|
-
await engine.run();
|
|
1396
|
-
} else {
|
|
1397
|
-
log("Using async versioning strategy.", "info");
|
|
1398
|
-
if (cliTargets.length > 0) {
|
|
1399
|
-
log(`Targeting specific packages: ${cliTargets.join(", ")}`, "info");
|
|
2219
|
+
const buildTimestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
2220
|
+
const packageVersion = getPackageVersion();
|
|
2221
|
+
log(`package-versioner v${packageVersion} (Build: ${buildTimestamp})`, "debug");
|
|
2222
|
+
const program = new import_commander.Command();
|
|
2223
|
+
program.name("package-versioner").description(
|
|
2224
|
+
"A lightweight yet powerful CLI tool for automated semantic versioning based on Git history and conventional commits."
|
|
2225
|
+
).version(packageVersion);
|
|
2226
|
+
program.command("version", { isDefault: true }).description("Version a package or packages based on configuration").option(
|
|
2227
|
+
"-c, --config <path>",
|
|
2228
|
+
"Path to config file (defaults to version.config.json in current directory)"
|
|
2229
|
+
).option("-d, --dry-run", "Dry run (no changes made)", false).option("-b, --bump <type>", "Specify bump type (patch|minor|major)").option("-p, --prerelease [identifier]", "Create prerelease version").option("-s, --synced", "Use synchronized versioning across all packages").option("-j, --json", "Output results as JSON", false).option("-t, --target <packages>", "Comma-delimited list of package names to target").action(async (options) => {
|
|
2230
|
+
if (options.json) {
|
|
2231
|
+
enableJsonOutput(options.dryRun);
|
|
1400
2232
|
}
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
2233
|
+
try {
|
|
2234
|
+
const config = await loadConfig(options.config);
|
|
2235
|
+
log(`Loaded configuration from ${options.config || "version.config.json"}`, "info");
|
|
2236
|
+
if (options.dryRun) config.dryRun = true;
|
|
2237
|
+
if (options.synced) config.synced = true;
|
|
2238
|
+
if (options.bump) config.type = options.bump;
|
|
2239
|
+
if (options.prerelease)
|
|
2240
|
+
config.prereleaseIdentifier = options.prerelease === true ? "next" : options.prerelease;
|
|
2241
|
+
const cliTargets = options.target ? options.target.split(",").map((t) => t.trim()) : [];
|
|
2242
|
+
const engine = new VersionEngine(config, !!options.json);
|
|
2243
|
+
if (config.synced) {
|
|
2244
|
+
log("Using synced versioning strategy.", "info");
|
|
2245
|
+
engine.setStrategy("synced");
|
|
2246
|
+
await engine.run();
|
|
2247
|
+
} else if (config.packages && config.packages.length === 1) {
|
|
2248
|
+
log("Using single package versioning strategy.", "info");
|
|
2249
|
+
if (cliTargets.length > 0) {
|
|
2250
|
+
log("--target flag is ignored for single package strategy.", "warning");
|
|
2251
|
+
}
|
|
2252
|
+
engine.setStrategy("single");
|
|
2253
|
+
await engine.run();
|
|
2254
|
+
} else {
|
|
2255
|
+
log("Using async versioning strategy.", "info");
|
|
2256
|
+
if (cliTargets.length > 0) {
|
|
2257
|
+
log(`Targeting specific packages: ${cliTargets.join(", ")}`, "info");
|
|
2258
|
+
}
|
|
2259
|
+
engine.setStrategy("async");
|
|
2260
|
+
await engine.run(cliTargets);
|
|
2261
|
+
}
|
|
2262
|
+
log("Versioning process completed.", "success");
|
|
2263
|
+
printJsonOutput();
|
|
2264
|
+
} catch (error) {
|
|
2265
|
+
log(error instanceof Error ? error.message : String(error), "error");
|
|
2266
|
+
process.exit(1);
|
|
2267
|
+
}
|
|
2268
|
+
});
|
|
2269
|
+
program.command("regenerate-changelog").description("Regenerate a complete changelog from git history").option("-o, --output <path>", "Output path for changelog file", "CHANGELOG.md").option(
|
|
2270
|
+
"-f, --format <format>",
|
|
2271
|
+
"Changelog format (keep-a-changelog|angular)",
|
|
2272
|
+
"keep-a-changelog"
|
|
2273
|
+
).option("-s, --since <tag>", "Start changelog from specific tag").option("-u, --repo-url <url>", "Repository URL for changelog links").option("-d, --dry-run", "Preview changelog without writing to file", false).option("-p, --project-dir <path>", "Project directory", process.cwd()).action(async (options) => {
|
|
2274
|
+
try {
|
|
2275
|
+
log("Regenerating changelog from git history...", "info");
|
|
2276
|
+
if (options.format !== "keep-a-changelog" && options.format !== "angular") {
|
|
2277
|
+
throw new Error(
|
|
2278
|
+
'Invalid format specified. Must be either "keep-a-changelog" or "angular"'
|
|
2279
|
+
);
|
|
2280
|
+
}
|
|
2281
|
+
const regenerateOptions = {
|
|
2282
|
+
format: options.format,
|
|
2283
|
+
since: options.since,
|
|
2284
|
+
output: options.output,
|
|
2285
|
+
dryRun: options.dryRun,
|
|
2286
|
+
projectDir: options.projectDir,
|
|
2287
|
+
repoUrl: options.repoUrl
|
|
2288
|
+
};
|
|
2289
|
+
const content = await regenerateChangelog(regenerateOptions);
|
|
2290
|
+
await writeChangelog(
|
|
2291
|
+
content,
|
|
2292
|
+
import_node_path7.default.resolve(options.projectDir, options.output),
|
|
2293
|
+
options.dryRun
|
|
2294
|
+
);
|
|
2295
|
+
if (!options.dryRun) {
|
|
2296
|
+
log(`Changelog successfully regenerated at ${options.output}`, "success");
|
|
2297
|
+
}
|
|
2298
|
+
} catch (error) {
|
|
2299
|
+
log(error instanceof Error ? error.message : String(error), "error");
|
|
2300
|
+
process.exit(1);
|
|
2301
|
+
}
|
|
2302
|
+
});
|
|
2303
|
+
program.parse(process.argv);
|
|
1406
2304
|
} catch (error) {
|
|
1407
|
-
|
|
2305
|
+
console.error("Fatal error:", error);
|
|
1408
2306
|
process.exit(1);
|
|
1409
2307
|
}
|
|
1410
2308
|
}
|