package-versioner 0.8.2 → 0.8.4

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/index.cjs CHANGED
@@ -35,7 +35,7 @@ __export(index_exports, {
35
35
  });
36
36
  module.exports = __toCommonJS(index_exports);
37
37
  var fs10 = __toESM(require("fs"), 1);
38
- var import_node_path7 = __toESM(require("path"), 1);
38
+ var import_node_path8 = __toESM(require("path"), 1);
39
39
  var import_commander = require("commander");
40
40
 
41
41
  // src/changelog/changelogRegenerator.ts
@@ -159,7 +159,8 @@ function extractChangelogEntriesFromCommits(projectDir, revisionRange) {
159
159
  }
160
160
  }
161
161
  function parseCommitMessage(message) {
162
- const match = message.match(CONVENTIONAL_COMMIT_REGEX);
162
+ const trimmedMessage = message.trim();
163
+ const match = trimmedMessage.match(CONVENTIONAL_COMMIT_REGEX);
163
164
  if (match) {
164
165
  const [, type, scope, breakingMark, subject, body = ""] = match;
165
166
  const breakingFromMark = breakingMark === "!";
@@ -183,8 +184,8 @@ function parseCommitMessage(message) {
183
184
  // Store original type for custom formatting
184
185
  };
185
186
  }
186
- if (!message.startsWith("Merge") && !message.match(/^v?\d+\.\d+\.\d+/)) {
187
- const firstLine = message.split("\n")[0].trim();
187
+ if (!trimmedMessage.startsWith("Merge") && !trimmedMessage.match(/^v?\d+\.\d+\.\d+/)) {
188
+ const firstLine = trimmedMessage.split("\n")[0].trim();
188
189
  return {
189
190
  type: "changed",
190
191
  description: firstLine
@@ -232,7 +233,9 @@ function formatChangelogEntries(format, version, date, entries, packageName, rep
232
233
  const hasBreaking = entry.description.includes("**BREAKING**");
233
234
  return {
234
235
  ...entry,
235
- breaking: hasBreaking
236
+ breaking: hasBreaking,
237
+ // Clean up the description to remove the **BREAKING** prefix since we'll handle it in formatting
238
+ description: hasBreaking ? entry.description.replace("**BREAKING** ", "") : entry.description
236
239
  };
237
240
  });
238
241
  return format === "keep-a-changelog" ? formatKeepAChangelogEntries(version, date, formattingEntries, repoUrl) : formatAngularEntries(version, date, formattingEntries, packageName);
@@ -245,15 +248,19 @@ function formatKeepAChangelogEntries(version, date, entries, repoUrl) {
245
248
  const fixed = [];
246
249
  const security = [];
247
250
  for (const entry of entries) {
248
- const entryText = entry.scope ? `- **${entry.scope}**: ${entry.description}` : `- ${entry.description}`;
249
- const formattedEntry = entry.breaking ? entryText.replace(/^- /, "- **BREAKING** ") : entryText;
251
+ let entryText;
252
+ if (entry.breaking) {
253
+ entryText = entry.scope ? `- **BREAKING** **${entry.scope}**: ${entry.description}` : `- **BREAKING** ${entry.description}`;
254
+ } else {
255
+ entryText = entry.scope ? `- **${entry.scope}**: ${entry.description}` : `- ${entry.description}`;
256
+ }
250
257
  const entryType = entry.originalType || entry.type;
251
258
  switch (entryType) {
252
259
  case "feat":
253
- added.push(formattedEntry);
260
+ added.push(entryText);
254
261
  break;
255
262
  case "fix":
256
- fixed.push(formattedEntry);
263
+ fixed.push(entryText);
257
264
  break;
258
265
  case "docs":
259
266
  case "style":
@@ -261,38 +268,38 @@ function formatKeepAChangelogEntries(version, date, entries, repoUrl) {
261
268
  case "perf":
262
269
  case "build":
263
270
  case "ci":
264
- changed.push(formattedEntry);
271
+ changed.push(entryText);
265
272
  break;
266
273
  case "test":
267
274
  break;
268
275
  case "chore":
269
276
  if (entry.description.toLowerCase().includes("deprecat")) {
270
- deprecated.push(formattedEntry);
277
+ deprecated.push(entryText);
271
278
  } else {
272
- changed.push(formattedEntry);
279
+ changed.push(entryText);
273
280
  }
274
281
  break;
275
282
  // Keep-a-changelog standard types
276
283
  case "added":
277
- added.push(formattedEntry);
284
+ added.push(entryText);
278
285
  break;
279
286
  case "changed":
280
- changed.push(formattedEntry);
287
+ changed.push(entryText);
281
288
  break;
282
289
  case "deprecated":
283
- deprecated.push(formattedEntry);
290
+ deprecated.push(entryText);
284
291
  break;
285
292
  case "removed":
286
- removed.push(formattedEntry);
293
+ removed.push(entryText);
287
294
  break;
288
295
  case "fixed":
289
- fixed.push(formattedEntry);
296
+ fixed.push(entryText);
290
297
  break;
291
298
  case "security":
292
- security.push(formattedEntry);
299
+ security.push(entryText);
293
300
  break;
294
301
  default:
295
- changed.push(formattedEntry);
302
+ changed.push(entryText);
296
303
  }
297
304
  }
298
305
  let content = `## [${version}] - ${date}
@@ -457,13 +464,25 @@ function getAngularTemplate() {
457
464
  // src/changelog/changelogRegenerator.ts
458
465
  function getAllVersionTags(since, versionPrefix = "v") {
459
466
  try {
460
- const command = since ? `git tag --list "${versionPrefix}*" --sort=creatordate --contains ${since}` : `git tag --list "${versionPrefix}*" --sort=creatordate`;
467
+ const command = `git tag --list "${versionPrefix}*" --sort=creatordate`;
461
468
  const tagOutput = (0, import_node_child_process2.execSync)(command, { encoding: "utf8" }).trim();
462
469
  if (!tagOutput) {
463
470
  return [];
464
471
  }
465
- const tags = tagOutput.split("\n").filter((tag) => !!tag);
466
- return tags.map((tag) => {
472
+ const allTags = tagOutput.split("\n").filter((tag) => !!tag);
473
+ let filteredTags = allTags;
474
+ if (since) {
475
+ const sinceIndex = allTags.findIndex((tag) => tag === since);
476
+ if (sinceIndex >= 0) {
477
+ filteredTags = allTags.slice(sinceIndex);
478
+ } else {
479
+ log(
480
+ `Warning: --since tag "${since}" not found in git history, including all tags`,
481
+ "warning"
482
+ );
483
+ }
484
+ }
485
+ return filteredTags.map((tag) => {
467
486
  try {
468
487
  const date = (0, import_node_child_process2.execSync)(`git log -1 --format=%ad --date=short ${tag}`, {
469
488
  encoding: "utf8"
@@ -512,7 +531,10 @@ async function regenerateChangelog(options) {
512
531
  }
513
532
  } catch {
514
533
  }
515
- const tags = getAllVersionTags(since, versionPrefix);
534
+ let tags = getAllVersionTags(since, versionPrefix);
535
+ if (!tags.length && since) {
536
+ tags = getAllVersionTags(void 0, versionPrefix);
537
+ }
516
538
  if (!tags.length) {
517
539
  throw new Error(
518
540
  'No version tags found in git history. Make sure you have tags that start with the version prefix (usually "v").'
@@ -526,7 +548,28 @@ async function regenerateChangelog(options) {
526
548
  const previousTag = i > 0 ? tags[i - 1].tag : null;
527
549
  log(`Processing changes for ${currentTag.tag}...`, "info");
528
550
  try {
529
- const tagRange = previousTag ? `${previousTag}..${currentTag.tag}` : currentTag.tag;
551
+ let tagRange;
552
+ if (previousTag) {
553
+ tagRange = `${previousTag}..${currentTag.tag}`;
554
+ } else if (since && currentTag.tag === since) {
555
+ try {
556
+ const allTagsCmd = `git tag --list "${versionPrefix}*" --sort=creatordate`;
557
+ const allTagsOutput = (0, import_node_child_process2.execSync)(allTagsCmd, { encoding: "utf8" }).trim();
558
+ const allTags = allTagsOutput.split("\n").filter((tag) => !!tag);
559
+ const sinceIndex = allTags.findIndex((tag) => tag === since);
560
+ const actualPreviousTag = sinceIndex > 0 ? allTags[sinceIndex - 1] : null;
561
+ if (actualPreviousTag) {
562
+ tagRange = `${actualPreviousTag}..${currentTag.tag}`;
563
+ } else {
564
+ tagRange = currentTag.tag;
565
+ }
566
+ } catch (error) {
567
+ log(`Failed to find previous tag for ${currentTag.tag}: ${error}`, "warning");
568
+ tagRange = currentTag.tag;
569
+ }
570
+ } else {
571
+ tagRange = currentTag.tag;
572
+ }
530
573
  const entries = extractChangelogEntriesFromCommits(projectDir, tagRange);
531
574
  if (!entries.length) {
532
575
  log(`No changelog entries found for ${currentTag.tag}, adding placeholder entry`, "info");
@@ -639,33 +682,163 @@ function createVersionError(code, details) {
639
682
  return new VersionError(fullMessage, code);
640
683
  }
641
684
 
642
- // src/utils/packageMatching.ts
643
- function matchesPackageTarget(packageName, target) {
644
- if (packageName === target) {
645
- return true;
685
+ // src/utils/packageFiltering.ts
686
+ var import_node_path2 = __toESM(require("path"), 1);
687
+ var import_micromatch = __toESM(require("micromatch"), 1);
688
+ function filterPackagesByConfig(packages, configTargets, workspaceRoot) {
689
+ if (configTargets.length === 0) {
690
+ log("No config targets specified, returning all packages", "debug");
691
+ return packages;
646
692
  }
647
- if (target.endsWith("/*")) {
648
- const scope = target.slice(0, -2);
649
- if (scope.startsWith("@")) {
650
- return packageName.startsWith(`${scope}/`);
651
- }
652
- return packageName.startsWith(`${scope}/`);
693
+ const matchedPackages = /* @__PURE__ */ new Set();
694
+ for (const target of configTargets) {
695
+ const dirMatches = filterByDirectoryPattern(packages, target, workspaceRoot);
696
+ const nameMatches = filterByPackageNamePattern(packages, target);
697
+ dirMatches.forEach((pkg) => matchedPackages.add(pkg));
698
+ nameMatches.forEach((pkg) => matchedPackages.add(pkg));
653
699
  }
654
- if (target === "*") {
655
- return true;
700
+ return Array.from(matchedPackages);
701
+ }
702
+ function filterByDirectoryPattern(packages, pattern, workspaceRoot) {
703
+ if (pattern === "./" || pattern === ".") {
704
+ return packages.filter((pkg) => pkg.dir === workspaceRoot);
656
705
  }
657
- return false;
706
+ const normalizedPattern = pattern.replace(/\\/g, "/");
707
+ return packages.filter((pkg) => {
708
+ const relativePath = import_node_path2.default.relative(workspaceRoot, pkg.dir);
709
+ const normalizedRelativePath = relativePath.replace(/\\/g, "/");
710
+ if (normalizedPattern === normalizedRelativePath) {
711
+ return true;
712
+ }
713
+ try {
714
+ return import_micromatch.default.isMatch(normalizedRelativePath, normalizedPattern, {
715
+ dot: true,
716
+ noglobstar: false,
717
+ bash: true
718
+ });
719
+ } catch (error) {
720
+ log(
721
+ `Invalid directory pattern "${pattern}": ${error instanceof Error ? error.message : String(error)}`,
722
+ "warning"
723
+ );
724
+ return false;
725
+ }
726
+ });
658
727
  }
659
- function shouldMatchPackageTargets(packageName, targets) {
660
- return targets.some((target) => matchesPackageTarget(packageName, target));
728
+ function filterByPackageNamePattern(packages, pattern) {
729
+ return packages.filter((pkg) => {
730
+ var _a;
731
+ if (!((_a = pkg.packageJson) == null ? void 0 : _a.name) || typeof pkg.packageJson.name !== "string") {
732
+ return false;
733
+ }
734
+ return matchesPackageNamePattern(pkg.packageJson.name, pattern);
735
+ });
661
736
  }
662
- function shouldProcessPackage(packageName, skip = []) {
663
- return !skip.includes(packageName);
737
+ function matchesPackageNamePattern(packageName, pattern) {
738
+ if (packageName === pattern) {
739
+ return true;
740
+ }
741
+ if (pattern.startsWith("@") && pattern.endsWith("/*") && !pattern.includes("**")) {
742
+ const scope = pattern.slice(0, -2);
743
+ return packageName.startsWith(`${scope}/`);
744
+ }
745
+ try {
746
+ return import_micromatch.default.isMatch(packageName, pattern, {
747
+ dot: true,
748
+ contains: false,
749
+ noglobstar: false,
750
+ bash: true
751
+ });
752
+ } catch (error) {
753
+ log(
754
+ `Invalid package name pattern "${pattern}": ${error instanceof Error ? error.message : String(error)}`,
755
+ "warning"
756
+ );
757
+ return false;
758
+ }
664
759
  }
665
760
 
666
761
  // src/core/versionStrategies.ts
762
+ var import_node_child_process5 = require("child_process");
667
763
  var import_node_fs7 = __toESM(require("fs"), 1);
668
- var path7 = __toESM(require("path"), 1);
764
+ var path8 = __toESM(require("path"), 1);
765
+
766
+ // src/changelog/changelogManager.ts
767
+ var fs3 = __toESM(require("fs"), 1);
768
+ var path3 = __toESM(require("path"), 1);
769
+ function updateChangelog(packagePath, packageName, version, entries, repoUrl, format = "keep-a-changelog") {
770
+ try {
771
+ const changelogPath = path3.join(packagePath, "CHANGELOG.md");
772
+ let existingContent = "";
773
+ if (fs3.existsSync(changelogPath)) {
774
+ existingContent = fs3.readFileSync(changelogPath, "utf8");
775
+ }
776
+ const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
777
+ const newVersionContent = formatChangelogEntries(
778
+ format,
779
+ version,
780
+ today,
781
+ entries,
782
+ packageName,
783
+ repoUrl
784
+ );
785
+ let finalContent;
786
+ if (existingContent) {
787
+ if (format === "keep-a-changelog") {
788
+ const headerEndIndex = existingContent.indexOf("\n## ");
789
+ if (headerEndIndex > 0) {
790
+ const beforeVersions = existingContent.substring(0, headerEndIndex);
791
+ const afterVersions = existingContent.substring(headerEndIndex);
792
+ finalContent = `${beforeVersions}
793
+ ${newVersionContent}
794
+ ${afterVersions}`;
795
+ } else {
796
+ finalContent = `${existingContent}
797
+ ${newVersionContent}
798
+ `;
799
+ }
800
+ } else {
801
+ const headerEndIndex = existingContent.indexOf("\n## ");
802
+ if (headerEndIndex > 0) {
803
+ const beforeVersions = existingContent.substring(0, headerEndIndex);
804
+ const afterVersions = existingContent.substring(headerEndIndex);
805
+ finalContent = `${beforeVersions}
806
+ ${newVersionContent}
807
+ ${afterVersions}`;
808
+ } else {
809
+ finalContent = `${existingContent}
810
+ ${newVersionContent}
811
+ `;
812
+ }
813
+ }
814
+ } else {
815
+ if (format === "keep-a-changelog") {
816
+ finalContent = `# Changelog
817
+
818
+ All notable changes to ${packageName} will be documented in this file.
819
+
820
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
821
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
822
+
823
+ ${newVersionContent}
824
+ `;
825
+ } else {
826
+ finalContent = `# Changelog
827
+
828
+ ${newVersionContent}
829
+ `;
830
+ }
831
+ }
832
+ log(`Writing changelog to: ${changelogPath}`, "info");
833
+ fs3.writeFileSync(changelogPath, finalContent);
834
+ log(`Updated changelog at ${changelogPath}`, "success");
835
+ } catch (error) {
836
+ log(
837
+ `Error updating changelog: ${error instanceof Error ? error.message : String(error)}`,
838
+ "error"
839
+ );
840
+ }
841
+ }
669
842
 
670
843
  // src/git/commands.ts
671
844
  var import_node_process2 = require("process");
@@ -692,9 +865,9 @@ var execSync3 = (command, args) => (0, import_node_child_process3.execSync)(comm
692
865
 
693
866
  // src/git/repository.ts
694
867
  var import_node_fs2 = require("fs");
695
- var import_node_path2 = require("path");
868
+ var import_node_path3 = require("path");
696
869
  function isGitRepository(directory) {
697
- const gitDir = (0, import_node_path2.join)(directory, ".git");
870
+ const gitDir = (0, import_node_path3.join)(directory, ".git");
698
871
  if (!(0, import_node_fs2.existsSync)(gitDir)) {
699
872
  return false;
700
873
  }
@@ -1054,11 +1227,11 @@ async function getLatestTagForPackage(packageName, versionPrefix, options) {
1054
1227
 
1055
1228
  // src/package/packageManagement.ts
1056
1229
  var import_node_fs4 = __toESM(require("fs"), 1);
1057
- var import_node_path4 = __toESM(require("path"), 1);
1230
+ var import_node_path5 = __toESM(require("path"), 1);
1058
1231
 
1059
1232
  // src/cargo/cargoHandler.ts
1060
1233
  var import_node_fs3 = __toESM(require("fs"), 1);
1061
- var import_node_path3 = __toESM(require("path"), 1);
1234
+ var import_node_path4 = __toESM(require("path"), 1);
1062
1235
  var TOML = __toESM(require("smol-toml"), 1);
1063
1236
  function getCargoInfo(cargoPath) {
1064
1237
  var _a;
@@ -1077,7 +1250,7 @@ function getCargoInfo(cargoPath) {
1077
1250
  name: cargo.package.name,
1078
1251
  version: cargo.package.version || "0.0.0",
1079
1252
  path: cargoPath,
1080
- dir: import_node_path3.default.dirname(cargoPath),
1253
+ dir: import_node_path4.default.dirname(cargoPath),
1081
1254
  content: cargo
1082
1255
  };
1083
1256
  } catch (error) {
@@ -1090,7 +1263,7 @@ function getCargoInfo(cargoPath) {
1090
1263
  }
1091
1264
  }
1092
1265
  function isCargoToml(filePath) {
1093
- return import_node_path3.default.basename(filePath) === "Cargo.toml";
1266
+ return import_node_path4.default.basename(filePath) === "Cargo.toml";
1094
1267
  }
1095
1268
  function updateCargoVersion(cargoPath, version) {
1096
1269
  var _a;
@@ -1146,334 +1319,9 @@ function updatePackageVersion(packagePath, version) {
1146
1319
  // src/package/packageProcessor.ts
1147
1320
  var import_node_child_process4 = require("child_process");
1148
1321
  var fs8 = __toESM(require("fs"), 1);
1149
- var import_node_path6 = __toESM(require("path"), 1);
1322
+ var import_node_path7 = __toESM(require("path"), 1);
1150
1323
  var import_node_process4 = require("process");
1151
1324
 
1152
- // src/changelog/changelogManager.ts
1153
- var fs5 = __toESM(require("fs"), 1);
1154
- var path4 = __toESM(require("path"), 1);
1155
- function createChangelog(_packagePath, packageName) {
1156
- return {
1157
- projectName: packageName,
1158
- unreleased: [],
1159
- versions: []
1160
- };
1161
- }
1162
- function parseChangelog(filePath) {
1163
- try {
1164
- if (!fs5.existsSync(filePath)) {
1165
- return null;
1166
- }
1167
- fs5.readFileSync(filePath, "utf8");
1168
- log(`Parsed changelog at ${filePath}`, "info");
1169
- return {
1170
- projectName: path4.basename(path4.dirname(filePath)),
1171
- unreleased: [],
1172
- versions: []
1173
- };
1174
- } catch (error) {
1175
- log(
1176
- `Error parsing changelog: ${error instanceof Error ? error.message : String(error)}`,
1177
- "error"
1178
- );
1179
- return null;
1180
- }
1181
- }
1182
- function generateLinks(changelog, repoUrl) {
1183
- var _a, _b;
1184
- if (!repoUrl || changelog.versions.length === 0) {
1185
- return "";
1186
- }
1187
- let links = "\n";
1188
- if (changelog.unreleased.length > 0) {
1189
- const latestVersion = ((_a = changelog.versions[0]) == null ? void 0 : _a.version) || "";
1190
- links += `[unreleased]: ${repoUrl}/compare/v${latestVersion}...HEAD
1191
- `;
1192
- }
1193
- for (let i = 0; i < changelog.versions.length; i++) {
1194
- const currentVersion = changelog.versions[i].version;
1195
- const previousVersion = (_b = changelog.versions[i + 1]) == null ? void 0 : _b.version;
1196
- if (previousVersion) {
1197
- links += `[${currentVersion}]: ${repoUrl}/compare/v${previousVersion}...v${currentVersion}
1198
- `;
1199
- } else if (i === changelog.versions.length - 1) {
1200
- links += `[${currentVersion}]: ${repoUrl}/releases/tag/v${currentVersion}
1201
- `;
1202
- }
1203
- }
1204
- return links;
1205
- }
1206
- function generateAngularChangelogContent(changelog, repoUrl) {
1207
- let content = "# Changelog\n\n";
1208
- if (changelog.unreleased.length > 0) {
1209
- content += "## [Unreleased]\n\n";
1210
- const groupedByType = groupEntriesByAngularType(changelog.unreleased);
1211
- for (const [type, entries] of Object.entries(groupedByType)) {
1212
- content += `### ${formatAngularType(type)}
1213
-
1214
- `;
1215
- const groupedByScope = groupEntriesByScope2(entries);
1216
- for (const [scope, scopeEntries] of Object.entries(groupedByScope)) {
1217
- if (scope !== "undefined" && scope !== "") {
1218
- content += `* **${scope}:**
1219
- `;
1220
- for (const entry of scopeEntries) {
1221
- content += formatAngularEntry(entry, false);
1222
- }
1223
- content += "\n";
1224
- } else {
1225
- for (const entry of scopeEntries) {
1226
- content += formatAngularEntry(entry, true);
1227
- }
1228
- }
1229
- }
1230
- content += "\n";
1231
- }
1232
- const breakingChanges = changelog.unreleased.filter(
1233
- (entry) => entry.description.includes("**BREAKING**")
1234
- );
1235
- if (breakingChanges.length > 0) {
1236
- content += "### BREAKING CHANGES\n\n";
1237
- for (const entry of breakingChanges) {
1238
- const description = entry.description.replace("**BREAKING** ", "");
1239
- content += `* ${entry.scope ? `**${entry.scope}:** ` : ""}${description}`;
1240
- if (entry.issueIds && entry.issueIds.length > 0) {
1241
- content += ` (${entry.issueIds.join(", ")})`;
1242
- }
1243
- content += "\n";
1244
- }
1245
- content += "\n";
1246
- }
1247
- }
1248
- for (const version of changelog.versions) {
1249
- content += `## [${version.version}] - ${version.date}
1250
-
1251
- `;
1252
- const groupedByType = groupEntriesByAngularType(version.entries);
1253
- for (const [type, entries] of Object.entries(groupedByType)) {
1254
- content += `### ${formatAngularType(type)}
1255
-
1256
- `;
1257
- const groupedByScope = groupEntriesByScope2(entries);
1258
- for (const [scope, scopeEntries] of Object.entries(groupedByScope)) {
1259
- if (scope !== "undefined" && scope !== "") {
1260
- content += `* **${scope}:**
1261
- `;
1262
- for (const entry of scopeEntries) {
1263
- content += formatAngularEntry(entry, false);
1264
- }
1265
- content += "\n";
1266
- } else {
1267
- for (const entry of scopeEntries) {
1268
- content += formatAngularEntry(entry, true);
1269
- }
1270
- }
1271
- }
1272
- content += "\n";
1273
- }
1274
- const breakingChanges = version.entries.filter(
1275
- (entry) => entry.description.includes("**BREAKING**")
1276
- );
1277
- if (breakingChanges.length > 0) {
1278
- content += "### BREAKING CHANGES\n\n";
1279
- for (const entry of breakingChanges) {
1280
- const description = entry.description.replace("**BREAKING** ", "");
1281
- content += `* ${entry.scope ? `**${entry.scope}:** ` : ""}${description}`;
1282
- if (entry.issueIds && entry.issueIds.length > 0) {
1283
- content += ` (${entry.issueIds.join(", ")})`;
1284
- }
1285
- content += "\n";
1286
- }
1287
- content += "\n";
1288
- }
1289
- }
1290
- content += generateLinks(changelog, repoUrl);
1291
- return content;
1292
- }
1293
- function groupEntriesByAngularType(entries) {
1294
- const result = {};
1295
- for (const entry of entries) {
1296
- const type = entry.originalType || mapToAngularType(entry.type);
1297
- if (!result[type]) {
1298
- result[type] = [];
1299
- }
1300
- result[type].push(entry);
1301
- }
1302
- return result;
1303
- }
1304
- function mapToAngularType(type) {
1305
- switch (type) {
1306
- case "added":
1307
- return "feat";
1308
- case "fixed":
1309
- return "fix";
1310
- case "changed":
1311
- return "perf";
1312
- case "deprecated":
1313
- case "removed":
1314
- case "security":
1315
- return type;
1316
- default:
1317
- return type;
1318
- }
1319
- }
1320
- function formatAngularType(type) {
1321
- switch (type) {
1322
- case "feat":
1323
- return "Features";
1324
- case "fix":
1325
- return "Bug Fixes";
1326
- case "perf":
1327
- return "Performance Improvements";
1328
- case "security":
1329
- return "Security";
1330
- case "deprecated":
1331
- return "Deprecated";
1332
- case "removed":
1333
- return "Removed";
1334
- default:
1335
- return capitalizeFirstLetter(type);
1336
- }
1337
- }
1338
- function groupEntriesByScope2(entries) {
1339
- const result = {};
1340
- for (const entry of entries) {
1341
- const scope = entry.scope || "";
1342
- if (!result[scope]) {
1343
- result[scope] = [];
1344
- }
1345
- result[scope].push(entry);
1346
- }
1347
- return result;
1348
- }
1349
- function formatAngularEntry(entry, includeScope) {
1350
- let result = " * ";
1351
- if (includeScope && entry.scope) {
1352
- result += `**${entry.scope}:** `;
1353
- }
1354
- let description = entry.description;
1355
- if (!includeScope && entry.scope && description.startsWith(`**${entry.scope}**: `)) {
1356
- description = description.substring(`**${entry.scope}**: `.length);
1357
- }
1358
- if (description.startsWith("**BREAKING** ")) {
1359
- description = description.substring("**BREAKING** ".length);
1360
- }
1361
- result += description;
1362
- if (entry.issueIds && entry.issueIds.length > 0) {
1363
- result += ` (${entry.issueIds.join(", ")})`;
1364
- }
1365
- result += "\n";
1366
- return result;
1367
- }
1368
- function generateChangelogContent(changelog, repoUrl, format = "keep-a-changelog") {
1369
- if (format === "angular") {
1370
- return generateAngularChangelogContent(changelog, repoUrl);
1371
- }
1372
- let content = "# Changelog\n\n";
1373
- content += `All notable changes to ${changelog.projectName} will be documented in this file.
1374
-
1375
- `;
1376
- content += "The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),\n";
1377
- content += "and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n\n";
1378
- if (changelog.unreleased.length > 0) {
1379
- content += "## [Unreleased]\n\n";
1380
- const grouped = changelog.unreleased.reduce(
1381
- (acc, entry) => {
1382
- if (!acc[entry.type]) {
1383
- acc[entry.type] = [];
1384
- }
1385
- acc[entry.type].push(entry);
1386
- return acc;
1387
- },
1388
- {}
1389
- );
1390
- for (const [type, entries] of Object.entries(grouped)) {
1391
- content += `### ${capitalizeFirstLetter(type)}
1392
-
1393
- `;
1394
- for (const entry of entries) {
1395
- let entryText = `- ${entry.description}`;
1396
- if (entry.issueIds && entry.issueIds.length > 0) {
1397
- entryText += ` (${entry.issueIds.join(", ")})`;
1398
- }
1399
- content += `${entryText}.
1400
- `;
1401
- }
1402
- content += "\n";
1403
- }
1404
- }
1405
- for (const version of changelog.versions) {
1406
- content += `## [${version.version}] - ${version.date}
1407
-
1408
- `;
1409
- const grouped = version.entries.reduce(
1410
- (acc, entry) => {
1411
- if (!acc[entry.type]) {
1412
- acc[entry.type] = [];
1413
- }
1414
- acc[entry.type].push(entry);
1415
- return acc;
1416
- },
1417
- {}
1418
- );
1419
- for (const [type, entries] of Object.entries(grouped)) {
1420
- content += `### ${capitalizeFirstLetter(type)}
1421
-
1422
- `;
1423
- for (const entry of entries) {
1424
- let entryText = `- ${entry.description}`;
1425
- if (entry.issueIds && entry.issueIds.length > 0) {
1426
- entryText += ` (${entry.issueIds.join(", ")})`;
1427
- }
1428
- content += `${entryText}.
1429
- `;
1430
- }
1431
- content += "\n";
1432
- }
1433
- }
1434
- content += generateLinks(changelog, repoUrl);
1435
- return content;
1436
- }
1437
- function updateChangelog(packagePath, packageName, version, entries, repoUrl, format = "keep-a-changelog") {
1438
- try {
1439
- const changelogPath = path4.join(packagePath, "CHANGELOG.md");
1440
- let changelog;
1441
- if (fs5.existsSync(changelogPath)) {
1442
- const existingChangelog = parseChangelog(changelogPath);
1443
- if (existingChangelog) {
1444
- changelog = existingChangelog;
1445
- } else {
1446
- changelog = createChangelog(packagePath, packageName);
1447
- }
1448
- } else {
1449
- changelog = createChangelog(packagePath, packageName);
1450
- }
1451
- if (version) {
1452
- const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
1453
- const newVersion = {
1454
- version,
1455
- date: today,
1456
- entries: [...changelog.unreleased, ...entries]
1457
- };
1458
- changelog.unreleased = [];
1459
- changelog.versions.unshift(newVersion);
1460
- } else {
1461
- changelog.unreleased = [...changelog.unreleased, ...entries];
1462
- }
1463
- const content = generateChangelogContent(changelog, repoUrl, format);
1464
- fs5.writeFileSync(changelogPath, content);
1465
- log(`Updated changelog at ${changelogPath}`, "success");
1466
- } catch (error) {
1467
- log(
1468
- `Error updating changelog: ${error instanceof Error ? error.message : String(error)}`,
1469
- "error"
1470
- );
1471
- }
1472
- }
1473
- function capitalizeFirstLetter(input) {
1474
- return input.charAt(0).toUpperCase() + input.slice(1);
1475
- }
1476
-
1477
1325
  // src/core/versionCalculator.ts
1478
1326
  var import_node_process3 = require("process");
1479
1327
  var import_conventional_recommended_bump = require("conventional-recommended-bump");
@@ -1481,10 +1329,10 @@ var import_semver3 = __toESM(require("semver"), 1);
1481
1329
 
1482
1330
  // src/utils/manifestHelpers.ts
1483
1331
  var import_node_fs5 = __toESM(require("fs"), 1);
1484
- var import_node_path5 = __toESM(require("path"), 1);
1332
+ var import_node_path6 = __toESM(require("path"), 1);
1485
1333
  function getVersionFromManifests(packageDir) {
1486
- const packageJsonPath = import_node_path5.default.join(packageDir, "package.json");
1487
- const cargoTomlPath = import_node_path5.default.join(packageDir, "Cargo.toml");
1334
+ const packageJsonPath = import_node_path6.default.join(packageDir, "package.json");
1335
+ const cargoTomlPath = import_node_path6.default.join(packageDir, "Cargo.toml");
1488
1336
  if (import_node_fs5.default.existsSync(packageJsonPath)) {
1489
1337
  try {
1490
1338
  const packageJson = JSON.parse(import_node_fs5.default.readFileSync(packageJsonPath, "utf-8"));
@@ -1529,8 +1377,8 @@ function getVersionFromManifests(packageDir) {
1529
1377
  };
1530
1378
  }
1531
1379
  function throwIfNoManifestsFound(packageDir) {
1532
- const packageJsonPath = import_node_path5.default.join(packageDir, "package.json");
1533
- const cargoTomlPath = import_node_path5.default.join(packageDir, "Cargo.toml");
1380
+ const packageJsonPath = import_node_path6.default.join(packageDir, "package.json");
1381
+ const cargoTomlPath = import_node_path6.default.join(packageDir, "Cargo.toml");
1534
1382
  throw new Error(
1535
1383
  `Neither package.json nor Cargo.toml found at ${packageDir}. Checked paths: ${packageJsonPath}, ${cargoTomlPath}. Cannot determine version.`
1536
1384
  );
@@ -1807,6 +1655,42 @@ function calculateNextVersion(version, manifestType, name, releaseType, prerelea
1807
1655
  return result || initialVersion;
1808
1656
  }
1809
1657
 
1658
+ // src/utils/packageMatching.ts
1659
+ var import_micromatch2 = __toESM(require("micromatch"), 1);
1660
+ function matchesPackageTarget(packageName, target) {
1661
+ if (packageName === target) {
1662
+ return true;
1663
+ }
1664
+ if (target.startsWith("@") && target.endsWith("/*") && !target.includes("**")) {
1665
+ const scope = target.slice(0, -2);
1666
+ return packageName.startsWith(`${scope}/`);
1667
+ }
1668
+ try {
1669
+ return import_micromatch2.default.isMatch(packageName, target, {
1670
+ dot: true,
1671
+ contains: false,
1672
+ // Changed to false to ensure full pattern matching
1673
+ noglobstar: false,
1674
+ bash: true
1675
+ });
1676
+ } catch (error) {
1677
+ log(
1678
+ `Invalid pattern "${target}": ${error instanceof Error ? error.message : String(error)}`,
1679
+ "warning"
1680
+ );
1681
+ return false;
1682
+ }
1683
+ }
1684
+ function shouldMatchPackageTargets(packageName, targets) {
1685
+ return targets.some((target) => matchesPackageTarget(packageName, target));
1686
+ }
1687
+ function shouldProcessPackage(packageName, skip = []) {
1688
+ if (skip.length === 0) {
1689
+ return true;
1690
+ }
1691
+ return !shouldMatchPackageTargets(packageName, skip);
1692
+ }
1693
+
1810
1694
  // src/package/packageProcessor.ts
1811
1695
  var PackageProcessor = class {
1812
1696
  skip;
@@ -1917,22 +1801,20 @@ var PackageProcessor = class {
1917
1801
  if (this.fullConfig.updateChangelog !== false) {
1918
1802
  let changelogEntries = [];
1919
1803
  try {
1920
- let revisionRange = latestTag;
1804
+ let revisionRange;
1921
1805
  if (latestTag) {
1922
1806
  try {
1923
1807
  (0, import_node_child_process4.execSync)(`git rev-parse --verify "${latestTag}"`, {
1924
1808
  cwd: pkgPath,
1925
1809
  stdio: "ignore"
1926
1810
  });
1811
+ revisionRange = `${latestTag}..HEAD`;
1927
1812
  } catch {
1928
- log(
1929
- `Tag ${latestTag} doesn't exist, using recent commits from HEAD for changelog`,
1930
- "debug"
1931
- );
1932
- revisionRange = "HEAD~10..HEAD";
1813
+ log(`Tag ${latestTag} doesn't exist, using all commits for changelog`, "debug");
1814
+ revisionRange = "HEAD";
1933
1815
  }
1934
1816
  } else {
1935
- revisionRange = "HEAD~10..HEAD";
1817
+ revisionRange = "HEAD";
1936
1818
  }
1937
1819
  changelogEntries = extractChangelogEntriesFromCommits(pkgPath, revisionRange);
1938
1820
  if (changelogEntries.length === 0) {
@@ -1957,7 +1839,7 @@ var PackageProcessor = class {
1957
1839
  }
1958
1840
  let repoUrl;
1959
1841
  try {
1960
- const packageJsonPath2 = import_node_path6.default.join(pkgPath, "package.json");
1842
+ const packageJsonPath2 = import_node_path7.default.join(pkgPath, "package.json");
1961
1843
  if (fs8.existsSync(packageJsonPath2)) {
1962
1844
  const packageJson = JSON.parse(fs8.readFileSync(packageJsonPath2, "utf8"));
1963
1845
  if (packageJson.repository) {
@@ -1986,7 +1868,7 @@ var PackageProcessor = class {
1986
1868
  this.fullConfig.changelogFormat
1987
1869
  );
1988
1870
  }
1989
- const packageJsonPath = import_node_path6.default.join(pkgPath, "package.json");
1871
+ const packageJsonPath = import_node_path7.default.join(pkgPath, "package.json");
1990
1872
  if (fs8.existsSync(packageJsonPath)) {
1991
1873
  updatePackageVersion(packageJsonPath, nextVersion);
1992
1874
  }
@@ -1995,13 +1877,13 @@ var PackageProcessor = class {
1995
1877
  const cargoPaths = (_b = this.fullConfig.cargo) == null ? void 0 : _b.paths;
1996
1878
  if (cargoPaths && cargoPaths.length > 0) {
1997
1879
  for (const cargoPath of cargoPaths) {
1998
- const resolvedCargoPath = import_node_path6.default.resolve(pkgPath, cargoPath, "Cargo.toml");
1880
+ const resolvedCargoPath = import_node_path7.default.resolve(pkgPath, cargoPath, "Cargo.toml");
1999
1881
  if (fs8.existsSync(resolvedCargoPath)) {
2000
1882
  updatePackageVersion(resolvedCargoPath, nextVersion);
2001
1883
  }
2002
1884
  }
2003
1885
  } else {
2004
- const cargoTomlPath = import_node_path6.default.join(pkgPath, "Cargo.toml");
1886
+ const cargoTomlPath = import_node_path7.default.join(pkgPath, "Cargo.toml");
2005
1887
  if (fs8.existsSync(cargoTomlPath)) {
2006
1888
  updatePackageVersion(cargoTomlPath, nextVersion);
2007
1889
  }
@@ -2039,7 +1921,7 @@ var PackageProcessor = class {
2039
1921
  }
2040
1922
  const filesToCommit = [];
2041
1923
  for (const info of updatedPackagesInfo) {
2042
- const packageJsonPath = import_node_path6.default.join(info.path, "package.json");
1924
+ const packageJsonPath = import_node_path7.default.join(info.path, "package.json");
2043
1925
  if (fs8.existsSync(packageJsonPath)) {
2044
1926
  filesToCommit.push(packageJsonPath);
2045
1927
  }
@@ -2048,13 +1930,13 @@ var PackageProcessor = class {
2048
1930
  const cargoPaths = (_d = this.fullConfig.cargo) == null ? void 0 : _d.paths;
2049
1931
  if (cargoPaths && cargoPaths.length > 0) {
2050
1932
  for (const cargoPath of cargoPaths) {
2051
- const resolvedCargoPath = import_node_path6.default.resolve(info.path, cargoPath, "Cargo.toml");
1933
+ const resolvedCargoPath = import_node_path7.default.resolve(info.path, cargoPath, "Cargo.toml");
2052
1934
  if (fs8.existsSync(resolvedCargoPath)) {
2053
1935
  filesToCommit.push(resolvedCargoPath);
2054
1936
  }
2055
1937
  }
2056
1938
  } else {
2057
- const cargoTomlPath = import_node_path6.default.join(info.path, "Cargo.toml");
1939
+ const cargoTomlPath = import_node_path7.default.join(info.path, "Cargo.toml");
2058
1940
  if (fs8.existsSync(cargoTomlPath)) {
2059
1941
  filesToCommit.push(cargoTomlPath);
2060
1942
  }
@@ -2117,7 +1999,7 @@ function createSyncedStrategy(config) {
2117
1999
  mainPackage
2118
2000
  } = config;
2119
2001
  const formattedPrefix = formatVersionPrefix(versionPrefix || "v");
2120
- const latestTag = await getLatestTag();
2002
+ let latestTag = await getLatestTag();
2121
2003
  let mainPkgPath = packages.root;
2122
2004
  let mainPkgName;
2123
2005
  if (mainPackage) {
@@ -2140,6 +2022,21 @@ function createSyncedStrategy(config) {
2140
2022
  "warning"
2141
2023
  );
2142
2024
  }
2025
+ if (mainPkgName) {
2026
+ const packageSpecificTag = await getLatestTagForPackage(mainPkgName, formattedPrefix, {
2027
+ tagTemplate,
2028
+ packageSpecificTags: config.packageSpecificTags
2029
+ });
2030
+ if (packageSpecificTag) {
2031
+ latestTag = packageSpecificTag;
2032
+ log(`Using package-specific tag for ${mainPkgName}: ${latestTag}`, "debug");
2033
+ } else {
2034
+ log(
2035
+ `No package-specific tag found for ${mainPkgName}, using global tag: ${latestTag}`,
2036
+ "debug"
2037
+ );
2038
+ }
2039
+ }
2143
2040
  const nextVersion = await calculateVersion(config, {
2144
2041
  latestTag,
2145
2042
  versionPrefix: formattedPrefix,
@@ -2151,7 +2048,8 @@ function createSyncedStrategy(config) {
2151
2048
  type: config.type
2152
2049
  });
2153
2050
  if (!nextVersion) {
2154
- log("No version change needed", "info");
2051
+ const msg = mainPkgName ? `No version change needed for ${mainPkgName}` : "No version change needed";
2052
+ log(msg, "info");
2155
2053
  return;
2156
2054
  }
2157
2055
  const files = [];
@@ -2159,7 +2057,7 @@ function createSyncedStrategy(config) {
2159
2057
  const processedPaths = /* @__PURE__ */ new Set();
2160
2058
  try {
2161
2059
  if (packages.root) {
2162
- const rootPkgPath = path7.join(packages.root, "package.json");
2060
+ const rootPkgPath = path8.join(packages.root, "package.json");
2163
2061
  if (import_node_fs7.default.existsSync(rootPkgPath)) {
2164
2062
  updatePackageVersion(rootPkgPath, nextVersion);
2165
2063
  files.push(rootPkgPath);
@@ -2177,7 +2075,7 @@ function createSyncedStrategy(config) {
2177
2075
  if (!shouldProcessPackage2(pkg, config)) {
2178
2076
  continue;
2179
2077
  }
2180
- const packageJsonPath = path7.join(pkg.dir, "package.json");
2078
+ const packageJsonPath = path8.join(pkg.dir, "package.json");
2181
2079
  if (processedPaths.has(packageJsonPath)) {
2182
2080
  continue;
2183
2081
  }
@@ -2193,7 +2091,7 @@ function createSyncedStrategy(config) {
2193
2091
  return;
2194
2092
  }
2195
2093
  let tagPackageName = null;
2196
- let commitPackageName = void 0;
2094
+ let commitPackageName;
2197
2095
  if (config.packageSpecificTags && packages.packages.length === 1) {
2198
2096
  tagPackageName = packages.packages[0].packageJson.name;
2199
2097
  commitPackageName = packages.packages[0].packageJson.name;
@@ -2227,7 +2125,6 @@ function createSingleStrategy(config) {
2227
2125
  return async (packages) => {
2228
2126
  try {
2229
2127
  const {
2230
- packages: configPackages,
2231
2128
  mainPackage,
2232
2129
  versionPrefix,
2233
2130
  tagTemplate,
@@ -2238,12 +2135,12 @@ function createSingleStrategy(config) {
2238
2135
  let packageName;
2239
2136
  if (mainPackage) {
2240
2137
  packageName = mainPackage;
2241
- } else if (configPackages && configPackages.length === 1) {
2242
- packageName = configPackages[0];
2138
+ } else if (packages.packages.length === 1) {
2139
+ packageName = packages.packages[0].packageJson.name;
2243
2140
  } else {
2244
2141
  throw createVersionError(
2245
2142
  "INVALID_CONFIG" /* INVALID_CONFIG */,
2246
- "Single mode requires either mainPackage or exactly one package in the packages array"
2143
+ "Single mode requires either mainPackage or exactly one resolved package"
2247
2144
  );
2248
2145
  }
2249
2146
  const pkg = packages.packages.find((p) => p.packageJson.name === packageName);
@@ -2261,50 +2158,114 @@ function createSingleStrategy(config) {
2261
2158
  latestTagResult = globalTagResult || "";
2262
2159
  }
2263
2160
  const latestTag = latestTagResult;
2264
- let nextVersion = void 0;
2265
- try {
2266
- nextVersion = await calculateVersion(config, {
2267
- latestTag,
2268
- versionPrefix: formattedPrefix,
2269
- path: pkgPath,
2270
- name: packageName,
2271
- type: config.type
2272
- });
2273
- } catch (error) {
2274
- const errorMessage = error instanceof Error ? error.message : String(error);
2275
- throw createVersionError("VERSION_CALCULATION_ERROR" /* VERSION_CALCULATION_ERROR */, errorMessage);
2276
- }
2277
- if (nextVersion === void 0 || nextVersion === "") {
2161
+ let nextVersion;
2162
+ nextVersion = await calculateVersion(config, {
2163
+ latestTag,
2164
+ versionPrefix: formattedPrefix,
2165
+ branchPattern: config.branchPattern,
2166
+ baseBranch: config.baseBranch,
2167
+ prereleaseIdentifier: config.prereleaseIdentifier,
2168
+ path: pkgPath,
2169
+ name: packageName,
2170
+ type: config.type
2171
+ });
2172
+ if (!nextVersion) {
2278
2173
  log(`No version change needed for ${packageName}`, "info");
2279
2174
  return;
2280
2175
  }
2281
- const packageJsonPath = path7.join(pkgPath, "package.json");
2176
+ if (config.updateChangelog !== false) {
2177
+ let changelogEntries = [];
2178
+ try {
2179
+ let revisionRange;
2180
+ if (latestTag) {
2181
+ try {
2182
+ (0, import_node_child_process5.execSync)(`git rev-parse --verify "${latestTag}"`, {
2183
+ cwd: pkgPath,
2184
+ stdio: "ignore"
2185
+ });
2186
+ revisionRange = `${latestTag}..HEAD`;
2187
+ } catch {
2188
+ log(`Tag ${latestTag} doesn't exist, using all commits for changelog`, "debug");
2189
+ revisionRange = "HEAD";
2190
+ }
2191
+ } else {
2192
+ revisionRange = "HEAD";
2193
+ }
2194
+ changelogEntries = extractChangelogEntriesFromCommits(pkgPath, revisionRange);
2195
+ if (changelogEntries.length === 0) {
2196
+ changelogEntries = [
2197
+ {
2198
+ type: "changed",
2199
+ description: `Update version to ${nextVersion}`
2200
+ }
2201
+ ];
2202
+ }
2203
+ } catch (error) {
2204
+ log(
2205
+ `Error extracting changelog entries: ${error instanceof Error ? error.message : String(error)}`,
2206
+ "warning"
2207
+ );
2208
+ changelogEntries = [
2209
+ {
2210
+ type: "changed",
2211
+ description: `Update version to ${nextVersion}`
2212
+ }
2213
+ ];
2214
+ }
2215
+ let repoUrl;
2216
+ try {
2217
+ const packageJsonPath2 = path8.join(pkgPath, "package.json");
2218
+ if (import_node_fs7.default.existsSync(packageJsonPath2)) {
2219
+ const packageJson = JSON.parse(import_node_fs7.default.readFileSync(packageJsonPath2, "utf8"));
2220
+ if (packageJson.repository) {
2221
+ if (typeof packageJson.repository === "string") {
2222
+ repoUrl = packageJson.repository;
2223
+ } else if (packageJson.repository.url) {
2224
+ repoUrl = packageJson.repository.url;
2225
+ }
2226
+ if ((repoUrl == null ? void 0 : repoUrl.startsWith("git+")) && (repoUrl == null ? void 0 : repoUrl.endsWith(".git"))) {
2227
+ repoUrl = repoUrl.substring(4, repoUrl.length - 4);
2228
+ }
2229
+ }
2230
+ }
2231
+ } catch (error) {
2232
+ log(
2233
+ `Could not determine repository URL for changelog links: ${error instanceof Error ? error.message : String(error)}`,
2234
+ "warning"
2235
+ );
2236
+ }
2237
+ updateChangelog(
2238
+ pkgPath,
2239
+ packageName,
2240
+ nextVersion,
2241
+ changelogEntries,
2242
+ repoUrl,
2243
+ config.changelogFormat
2244
+ );
2245
+ }
2246
+ const packageJsonPath = path8.join(pkgPath, "package.json");
2282
2247
  updatePackageVersion(packageJsonPath, nextVersion);
2283
2248
  log(`Updated package ${packageName} to version ${nextVersion}`, "success");
2284
- const nextTag = formatTag(
2249
+ const tagName = formatTag(
2285
2250
  nextVersion,
2286
2251
  formattedPrefix,
2287
2252
  packageName,
2288
2253
  tagTemplate,
2289
2254
  config.packageSpecificTags
2290
2255
  );
2291
- const formattedCommitMessage = formatCommitMessage(commitMessage, nextVersion, packageName);
2292
- await createGitCommitAndTag(
2293
- [packageJsonPath],
2294
- nextTag,
2295
- formattedCommitMessage,
2296
- skipHooks,
2297
- dryRun
2298
- );
2256
+ const commitMsg = formatCommitMessage(commitMessage, nextVersion, packageName);
2257
+ if (!dryRun) {
2258
+ await createGitCommitAndTag([packageJsonPath], tagName, commitMsg, skipHooks, dryRun);
2259
+ log(`Created tag: ${tagName}`, "success");
2260
+ } else {
2261
+ log(`Would create tag: ${tagName}`, "info");
2262
+ }
2299
2263
  } catch (error) {
2300
2264
  if (error instanceof VersionError || error instanceof GitError) {
2301
- log(
2302
- `Single Package Strategy failed: ${error.message} (${error.code || "UNKNOWN"})`,
2303
- "error"
2304
- );
2265
+ log(`Single Strategy failed: ${error.message} (${error.code || "UNKNOWN"})`, "error");
2305
2266
  } else {
2306
2267
  const errorMessage = error instanceof Error ? error.message : String(error);
2307
- log(`Single Package Strategy failed: ${errorMessage}`, "error");
2268
+ log(`Single Strategy failed: ${errorMessage}`, "error");
2308
2269
  }
2309
2270
  throw error;
2310
2271
  }
@@ -2360,13 +2321,9 @@ function createAsyncStrategy(config) {
2360
2321
  };
2361
2322
  }
2362
2323
  function createStrategy(config) {
2363
- var _a;
2364
2324
  if (config.synced) {
2365
2325
  return createSyncedStrategy(config);
2366
2326
  }
2367
- if (config.mainPackage || ((_a = config.packages) == null ? void 0 : _a.length) === 1) {
2368
- return createSingleStrategy(config);
2369
- }
2370
2327
  return createAsyncStrategy(config);
2371
2328
  }
2372
2329
  function createStrategyMap(config) {
@@ -2418,8 +2375,10 @@ var VersionEngine = class {
2418
2375
  }
2419
2376
  if (this.config.packages && this.config.packages.length > 0) {
2420
2377
  const originalCount = pkgsResult.packages.length;
2421
- const filteredPackages = pkgsResult.packages.filter(
2422
- (pkg) => shouldMatchPackageTargets(pkg.packageJson.name, this.config.packages)
2378
+ const filteredPackages = filterPackagesByConfig(
2379
+ pkgsResult.packages,
2380
+ this.config.packages,
2381
+ pkgsResult.root
2423
2382
  );
2424
2383
  pkgsResult.packages = filteredPackages;
2425
2384
  log(
@@ -2429,11 +2388,6 @@ var VersionEngine = class {
2429
2388
  if (filteredPackages.length === 0) {
2430
2389
  log("Warning: No packages matched the specified patterns in config.packages", "warning");
2431
2390
  }
2432
- } else {
2433
- log(
2434
- `Processing all ${pkgsResult.packages.length} workspace packages (no packages filter specified)`,
2435
- "info"
2436
- );
2437
2391
  }
2438
2392
  this.workspaceCache = pkgsResult;
2439
2393
  return pkgsResult;
@@ -2446,11 +2400,11 @@ var VersionEngine = class {
2446
2400
  }
2447
2401
  /**
2448
2402
  * Run the current strategy
2403
+ * @param packages Workspace packages to process
2449
2404
  * @param targets Optional package targets to process (only used by async strategy)
2450
2405
  */
2451
- async run(targets = []) {
2406
+ async run(packages, targets = []) {
2452
2407
  try {
2453
- const packages = await this.getWorkspacePackages();
2454
2408
  return this.currentStrategy(packages, targets);
2455
2409
  } catch (error) {
2456
2410
  if (error instanceof VersionError || error instanceof GitError) {
@@ -2488,8 +2442,8 @@ var VersionEngine = class {
2488
2442
  var import_meta = {};
2489
2443
  function getPackageVersion() {
2490
2444
  try {
2491
- const packageJsonPath = import_node_path7.default.resolve(
2492
- import_node_path7.default.dirname(import_meta.url.replace("file:", "")),
2445
+ const packageJsonPath = import_node_path8.default.resolve(
2446
+ import_node_path8.default.dirname(import_meta.url.replace("file:", "")),
2493
2447
  "../package.json"
2494
2448
  );
2495
2449
  const packageJsonContent = fs10.readFileSync(packageJsonPath, "utf-8");
@@ -2526,24 +2480,31 @@ async function run() {
2526
2480
  config.prereleaseIdentifier = options.prerelease === true ? "next" : options.prerelease;
2527
2481
  const cliTargets = options.target ? options.target.split(",").map((t) => t.trim()) : [];
2528
2482
  const engine = new VersionEngine(config, !!options.json);
2483
+ const pkgsResult = await engine.getWorkspacePackages();
2484
+ const resolvedCount = pkgsResult.packages.length;
2485
+ log(`Resolved ${resolvedCount} packages from workspace`, "debug");
2486
+ log(`Config packages: ${JSON.stringify(config.packages)}`, "debug");
2487
+ log(`Config synced: ${config.synced}`, "debug");
2529
2488
  if (config.synced) {
2530
2489
  log("Using synced versioning strategy.", "info");
2531
2490
  engine.setStrategy("synced");
2532
- await engine.run();
2533
- } else if (config.packages && config.packages.length === 1) {
2491
+ await engine.run(pkgsResult);
2492
+ } else if (resolvedCount === 1) {
2534
2493
  log("Using single package versioning strategy.", "info");
2535
2494
  if (cliTargets.length > 0) {
2536
2495
  log("--target flag is ignored for single package strategy.", "warning");
2537
2496
  }
2538
2497
  engine.setStrategy("single");
2539
- await engine.run();
2498
+ await engine.run(pkgsResult);
2499
+ } else if (resolvedCount === 0) {
2500
+ throw new Error("No packages found in workspace");
2540
2501
  } else {
2541
2502
  log("Using async versioning strategy.", "info");
2542
2503
  if (cliTargets.length > 0) {
2543
2504
  log(`Targeting specific packages: ${cliTargets.join(", ")}`, "info");
2544
2505
  }
2545
2506
  engine.setStrategy("async");
2546
- await engine.run(cliTargets);
2507
+ await engine.run(pkgsResult, cliTargets);
2547
2508
  }
2548
2509
  log("Versioning process completed.", "success");
2549
2510
  printJsonOutput();
@@ -2562,38 +2523,43 @@ async function run() {
2562
2523
  process.exit(1);
2563
2524
  }
2564
2525
  });
2565
- program.command("regenerate-changelog").description("Regenerate a complete changelog from git history").option("-o, --output <path>", "Output path for changelog file", "CHANGELOG.md").option(
2526
+ program.command("changelog").description("Changelog management commands").option("--regenerate", "Regenerate a complete changelog from git history").option("-o, --output <path>", "Output path for changelog file", "CHANGELOG.md").option(
2566
2527
  "-f, --format <format>",
2567
2528
  "Changelog format (keep-a-changelog|angular)",
2568
2529
  "keep-a-changelog"
2569
2530
  ).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) => {
2570
- try {
2571
- log("Regenerating changelog from git history...", "info");
2572
- if (options.format !== "keep-a-changelog" && options.format !== "angular") {
2573
- throw new Error(
2574
- 'Invalid format specified. Must be either "keep-a-changelog" or "angular"'
2531
+ var _a;
2532
+ if (options.regenerate) {
2533
+ try {
2534
+ log("Regenerating changelog from git history...", "info");
2535
+ if (options.format !== "keep-a-changelog" && options.format !== "angular") {
2536
+ throw new Error(
2537
+ 'Invalid format specified. Must be either "keep-a-changelog" or "angular"'
2538
+ );
2539
+ }
2540
+ const regenerateOptions = {
2541
+ format: options.format,
2542
+ since: options.since,
2543
+ output: options.output,
2544
+ dryRun: options.dryRun,
2545
+ projectDir: options.projectDir,
2546
+ repoUrl: options.repoUrl
2547
+ };
2548
+ const content = await regenerateChangelog(regenerateOptions);
2549
+ await writeChangelog(
2550
+ content,
2551
+ import_node_path8.default.resolve(options.projectDir, options.output),
2552
+ options.dryRun
2575
2553
  );
2554
+ if (!options.dryRun) {
2555
+ log(`Changelog successfully regenerated at ${options.output}`, "success");
2556
+ }
2557
+ } catch (error) {
2558
+ log(error instanceof Error ? error.message : String(error), "error");
2559
+ process.exit(1);
2576
2560
  }
2577
- const regenerateOptions = {
2578
- format: options.format,
2579
- since: options.since,
2580
- output: options.output,
2581
- dryRun: options.dryRun,
2582
- projectDir: options.projectDir,
2583
- repoUrl: options.repoUrl
2584
- };
2585
- const content = await regenerateChangelog(regenerateOptions);
2586
- await writeChangelog(
2587
- content,
2588
- import_node_path7.default.resolve(options.projectDir, options.output),
2589
- options.dryRun
2590
- );
2591
- if (!options.dryRun) {
2592
- log(`Changelog successfully regenerated at ${options.output}`, "success");
2593
- }
2594
- } catch (error) {
2595
- log(error instanceof Error ? error.message : String(error), "error");
2596
- process.exit(1);
2561
+ } else {
2562
+ (_a = program.commands.find((cmd) => cmd.name() === "changelog")) == null ? void 0 : _a.help();
2597
2563
  }
2598
2564
  });
2599
2565
  program.parse(process.argv);