package-versioner 0.8.1 → 0.8.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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,9 +682,163 @@ function createVersionError(code, details) {
639
682
  return new VersionError(fullMessage, code);
640
683
  }
641
684
 
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;
692
+ }
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));
699
+ }
700
+ return Array.from(matchedPackages);
701
+ }
702
+ function filterByDirectoryPattern(packages, pattern, workspaceRoot) {
703
+ if (pattern === "./" || pattern === ".") {
704
+ return packages.filter((pkg) => pkg.dir === workspaceRoot);
705
+ }
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
+ });
727
+ }
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
+ });
736
+ }
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
+ }
759
+ }
760
+
642
761
  // src/core/versionStrategies.ts
762
+ var import_node_child_process5 = require("child_process");
643
763
  var import_node_fs7 = __toESM(require("fs"), 1);
644
- 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
+ }
645
842
 
646
843
  // src/git/commands.ts
647
844
  var import_node_process2 = require("process");
@@ -668,9 +865,9 @@ var execSync3 = (command, args) => (0, import_node_child_process3.execSync)(comm
668
865
 
669
866
  // src/git/repository.ts
670
867
  var import_node_fs2 = require("fs");
671
- var import_node_path2 = require("path");
868
+ var import_node_path3 = require("path");
672
869
  function isGitRepository(directory) {
673
- const gitDir = (0, import_node_path2.join)(directory, ".git");
870
+ const gitDir = (0, import_node_path3.join)(directory, ".git");
674
871
  if (!(0, import_node_fs2.existsSync)(gitDir)) {
675
872
  return false;
676
873
  }
@@ -1030,11 +1227,11 @@ async function getLatestTagForPackage(packageName, versionPrefix, options) {
1030
1227
 
1031
1228
  // src/package/packageManagement.ts
1032
1229
  var import_node_fs4 = __toESM(require("fs"), 1);
1033
- var import_node_path4 = __toESM(require("path"), 1);
1230
+ var import_node_path5 = __toESM(require("path"), 1);
1034
1231
 
1035
1232
  // src/cargo/cargoHandler.ts
1036
1233
  var import_node_fs3 = __toESM(require("fs"), 1);
1037
- var import_node_path3 = __toESM(require("path"), 1);
1234
+ var import_node_path4 = __toESM(require("path"), 1);
1038
1235
  var TOML = __toESM(require("smol-toml"), 1);
1039
1236
  function getCargoInfo(cargoPath) {
1040
1237
  var _a;
@@ -1053,7 +1250,7 @@ function getCargoInfo(cargoPath) {
1053
1250
  name: cargo.package.name,
1054
1251
  version: cargo.package.version || "0.0.0",
1055
1252
  path: cargoPath,
1056
- dir: import_node_path3.default.dirname(cargoPath),
1253
+ dir: import_node_path4.default.dirname(cargoPath),
1057
1254
  content: cargo
1058
1255
  };
1059
1256
  } catch (error) {
@@ -1066,7 +1263,7 @@ function getCargoInfo(cargoPath) {
1066
1263
  }
1067
1264
  }
1068
1265
  function isCargoToml(filePath) {
1069
- return import_node_path3.default.basename(filePath) === "Cargo.toml";
1266
+ return import_node_path4.default.basename(filePath) === "Cargo.toml";
1070
1267
  }
1071
1268
  function updateCargoVersion(cargoPath, version) {
1072
1269
  var _a;
@@ -1122,334 +1319,9 @@ function updatePackageVersion(packagePath, version) {
1122
1319
  // src/package/packageProcessor.ts
1123
1320
  var import_node_child_process4 = require("child_process");
1124
1321
  var fs8 = __toESM(require("fs"), 1);
1125
- var import_node_path6 = __toESM(require("path"), 1);
1322
+ var import_node_path7 = __toESM(require("path"), 1);
1126
1323
  var import_node_process4 = require("process");
1127
1324
 
1128
- // src/changelog/changelogManager.ts
1129
- var fs5 = __toESM(require("fs"), 1);
1130
- var path4 = __toESM(require("path"), 1);
1131
- function createChangelog(_packagePath, packageName) {
1132
- return {
1133
- projectName: packageName,
1134
- unreleased: [],
1135
- versions: []
1136
- };
1137
- }
1138
- function parseChangelog(filePath) {
1139
- try {
1140
- if (!fs5.existsSync(filePath)) {
1141
- return null;
1142
- }
1143
- fs5.readFileSync(filePath, "utf8");
1144
- log(`Parsed changelog at ${filePath}`, "info");
1145
- return {
1146
- projectName: path4.basename(path4.dirname(filePath)),
1147
- unreleased: [],
1148
- versions: []
1149
- };
1150
- } catch (error) {
1151
- log(
1152
- `Error parsing changelog: ${error instanceof Error ? error.message : String(error)}`,
1153
- "error"
1154
- );
1155
- return null;
1156
- }
1157
- }
1158
- function generateLinks(changelog, repoUrl) {
1159
- var _a, _b;
1160
- if (!repoUrl || changelog.versions.length === 0) {
1161
- return "";
1162
- }
1163
- let links = "\n";
1164
- if (changelog.unreleased.length > 0) {
1165
- const latestVersion = ((_a = changelog.versions[0]) == null ? void 0 : _a.version) || "";
1166
- links += `[unreleased]: ${repoUrl}/compare/v${latestVersion}...HEAD
1167
- `;
1168
- }
1169
- for (let i = 0; i < changelog.versions.length; i++) {
1170
- const currentVersion = changelog.versions[i].version;
1171
- const previousVersion = (_b = changelog.versions[i + 1]) == null ? void 0 : _b.version;
1172
- if (previousVersion) {
1173
- links += `[${currentVersion}]: ${repoUrl}/compare/v${previousVersion}...v${currentVersion}
1174
- `;
1175
- } else if (i === changelog.versions.length - 1) {
1176
- links += `[${currentVersion}]: ${repoUrl}/releases/tag/v${currentVersion}
1177
- `;
1178
- }
1179
- }
1180
- return links;
1181
- }
1182
- function generateAngularChangelogContent(changelog, repoUrl) {
1183
- let content = "# Changelog\n\n";
1184
- if (changelog.unreleased.length > 0) {
1185
- content += "## [Unreleased]\n\n";
1186
- const groupedByType = groupEntriesByAngularType(changelog.unreleased);
1187
- for (const [type, entries] of Object.entries(groupedByType)) {
1188
- content += `### ${formatAngularType(type)}
1189
-
1190
- `;
1191
- const groupedByScope = groupEntriesByScope2(entries);
1192
- for (const [scope, scopeEntries] of Object.entries(groupedByScope)) {
1193
- if (scope !== "undefined" && scope !== "") {
1194
- content += `* **${scope}:**
1195
- `;
1196
- for (const entry of scopeEntries) {
1197
- content += formatAngularEntry(entry, false);
1198
- }
1199
- content += "\n";
1200
- } else {
1201
- for (const entry of scopeEntries) {
1202
- content += formatAngularEntry(entry, true);
1203
- }
1204
- }
1205
- }
1206
- content += "\n";
1207
- }
1208
- const breakingChanges = changelog.unreleased.filter(
1209
- (entry) => entry.description.includes("**BREAKING**")
1210
- );
1211
- if (breakingChanges.length > 0) {
1212
- content += "### BREAKING CHANGES\n\n";
1213
- for (const entry of breakingChanges) {
1214
- const description = entry.description.replace("**BREAKING** ", "");
1215
- content += `* ${entry.scope ? `**${entry.scope}:** ` : ""}${description}`;
1216
- if (entry.issueIds && entry.issueIds.length > 0) {
1217
- content += ` (${entry.issueIds.join(", ")})`;
1218
- }
1219
- content += "\n";
1220
- }
1221
- content += "\n";
1222
- }
1223
- }
1224
- for (const version of changelog.versions) {
1225
- content += `## [${version.version}] - ${version.date}
1226
-
1227
- `;
1228
- const groupedByType = groupEntriesByAngularType(version.entries);
1229
- for (const [type, entries] of Object.entries(groupedByType)) {
1230
- content += `### ${formatAngularType(type)}
1231
-
1232
- `;
1233
- const groupedByScope = groupEntriesByScope2(entries);
1234
- for (const [scope, scopeEntries] of Object.entries(groupedByScope)) {
1235
- if (scope !== "undefined" && scope !== "") {
1236
- content += `* **${scope}:**
1237
- `;
1238
- for (const entry of scopeEntries) {
1239
- content += formatAngularEntry(entry, false);
1240
- }
1241
- content += "\n";
1242
- } else {
1243
- for (const entry of scopeEntries) {
1244
- content += formatAngularEntry(entry, true);
1245
- }
1246
- }
1247
- }
1248
- content += "\n";
1249
- }
1250
- const breakingChanges = version.entries.filter(
1251
- (entry) => entry.description.includes("**BREAKING**")
1252
- );
1253
- if (breakingChanges.length > 0) {
1254
- content += "### BREAKING CHANGES\n\n";
1255
- for (const entry of breakingChanges) {
1256
- const description = entry.description.replace("**BREAKING** ", "");
1257
- content += `* ${entry.scope ? `**${entry.scope}:** ` : ""}${description}`;
1258
- if (entry.issueIds && entry.issueIds.length > 0) {
1259
- content += ` (${entry.issueIds.join(", ")})`;
1260
- }
1261
- content += "\n";
1262
- }
1263
- content += "\n";
1264
- }
1265
- }
1266
- content += generateLinks(changelog, repoUrl);
1267
- return content;
1268
- }
1269
- function groupEntriesByAngularType(entries) {
1270
- const result = {};
1271
- for (const entry of entries) {
1272
- const type = entry.originalType || mapToAngularType(entry.type);
1273
- if (!result[type]) {
1274
- result[type] = [];
1275
- }
1276
- result[type].push(entry);
1277
- }
1278
- return result;
1279
- }
1280
- function mapToAngularType(type) {
1281
- switch (type) {
1282
- case "added":
1283
- return "feat";
1284
- case "fixed":
1285
- return "fix";
1286
- case "changed":
1287
- return "perf";
1288
- case "deprecated":
1289
- case "removed":
1290
- case "security":
1291
- return type;
1292
- default:
1293
- return type;
1294
- }
1295
- }
1296
- function formatAngularType(type) {
1297
- switch (type) {
1298
- case "feat":
1299
- return "Features";
1300
- case "fix":
1301
- return "Bug Fixes";
1302
- case "perf":
1303
- return "Performance Improvements";
1304
- case "security":
1305
- return "Security";
1306
- case "deprecated":
1307
- return "Deprecated";
1308
- case "removed":
1309
- return "Removed";
1310
- default:
1311
- return capitalizeFirstLetter(type);
1312
- }
1313
- }
1314
- function groupEntriesByScope2(entries) {
1315
- const result = {};
1316
- for (const entry of entries) {
1317
- const scope = entry.scope || "";
1318
- if (!result[scope]) {
1319
- result[scope] = [];
1320
- }
1321
- result[scope].push(entry);
1322
- }
1323
- return result;
1324
- }
1325
- function formatAngularEntry(entry, includeScope) {
1326
- let result = " * ";
1327
- if (includeScope && entry.scope) {
1328
- result += `**${entry.scope}:** `;
1329
- }
1330
- let description = entry.description;
1331
- if (!includeScope && entry.scope && description.startsWith(`**${entry.scope}**: `)) {
1332
- description = description.substring(`**${entry.scope}**: `.length);
1333
- }
1334
- if (description.startsWith("**BREAKING** ")) {
1335
- description = description.substring("**BREAKING** ".length);
1336
- }
1337
- result += description;
1338
- if (entry.issueIds && entry.issueIds.length > 0) {
1339
- result += ` (${entry.issueIds.join(", ")})`;
1340
- }
1341
- result += "\n";
1342
- return result;
1343
- }
1344
- function generateChangelogContent(changelog, repoUrl, format = "keep-a-changelog") {
1345
- if (format === "angular") {
1346
- return generateAngularChangelogContent(changelog, repoUrl);
1347
- }
1348
- let content = "# Changelog\n\n";
1349
- content += `All notable changes to ${changelog.projectName} will be documented in this file.
1350
-
1351
- `;
1352
- content += "The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),\n";
1353
- content += "and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n\n";
1354
- if (changelog.unreleased.length > 0) {
1355
- content += "## [Unreleased]\n\n";
1356
- const grouped = changelog.unreleased.reduce(
1357
- (acc, entry) => {
1358
- if (!acc[entry.type]) {
1359
- acc[entry.type] = [];
1360
- }
1361
- acc[entry.type].push(entry);
1362
- return acc;
1363
- },
1364
- {}
1365
- );
1366
- for (const [type, entries] of Object.entries(grouped)) {
1367
- content += `### ${capitalizeFirstLetter(type)}
1368
-
1369
- `;
1370
- for (const entry of entries) {
1371
- let entryText = `- ${entry.description}`;
1372
- if (entry.issueIds && entry.issueIds.length > 0) {
1373
- entryText += ` (${entry.issueIds.join(", ")})`;
1374
- }
1375
- content += `${entryText}.
1376
- `;
1377
- }
1378
- content += "\n";
1379
- }
1380
- }
1381
- for (const version of changelog.versions) {
1382
- content += `## [${version.version}] - ${version.date}
1383
-
1384
- `;
1385
- const grouped = version.entries.reduce(
1386
- (acc, entry) => {
1387
- if (!acc[entry.type]) {
1388
- acc[entry.type] = [];
1389
- }
1390
- acc[entry.type].push(entry);
1391
- return acc;
1392
- },
1393
- {}
1394
- );
1395
- for (const [type, entries] of Object.entries(grouped)) {
1396
- content += `### ${capitalizeFirstLetter(type)}
1397
-
1398
- `;
1399
- for (const entry of entries) {
1400
- let entryText = `- ${entry.description}`;
1401
- if (entry.issueIds && entry.issueIds.length > 0) {
1402
- entryText += ` (${entry.issueIds.join(", ")})`;
1403
- }
1404
- content += `${entryText}.
1405
- `;
1406
- }
1407
- content += "\n";
1408
- }
1409
- }
1410
- content += generateLinks(changelog, repoUrl);
1411
- return content;
1412
- }
1413
- function updateChangelog(packagePath, packageName, version, entries, repoUrl, format = "keep-a-changelog") {
1414
- try {
1415
- const changelogPath = path4.join(packagePath, "CHANGELOG.md");
1416
- let changelog;
1417
- if (fs5.existsSync(changelogPath)) {
1418
- const existingChangelog = parseChangelog(changelogPath);
1419
- if (existingChangelog) {
1420
- changelog = existingChangelog;
1421
- } else {
1422
- changelog = createChangelog(packagePath, packageName);
1423
- }
1424
- } else {
1425
- changelog = createChangelog(packagePath, packageName);
1426
- }
1427
- if (version) {
1428
- const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
1429
- const newVersion = {
1430
- version,
1431
- date: today,
1432
- entries: [...changelog.unreleased, ...entries]
1433
- };
1434
- changelog.unreleased = [];
1435
- changelog.versions.unshift(newVersion);
1436
- } else {
1437
- changelog.unreleased = [...changelog.unreleased, ...entries];
1438
- }
1439
- const content = generateChangelogContent(changelog, repoUrl, format);
1440
- fs5.writeFileSync(changelogPath, content);
1441
- log(`Updated changelog at ${changelogPath}`, "success");
1442
- } catch (error) {
1443
- log(
1444
- `Error updating changelog: ${error instanceof Error ? error.message : String(error)}`,
1445
- "error"
1446
- );
1447
- }
1448
- }
1449
- function capitalizeFirstLetter(input) {
1450
- return input.charAt(0).toUpperCase() + input.slice(1);
1451
- }
1452
-
1453
1325
  // src/core/versionCalculator.ts
1454
1326
  var import_node_process3 = require("process");
1455
1327
  var import_conventional_recommended_bump = require("conventional-recommended-bump");
@@ -1457,10 +1329,10 @@ var import_semver3 = __toESM(require("semver"), 1);
1457
1329
 
1458
1330
  // src/utils/manifestHelpers.ts
1459
1331
  var import_node_fs5 = __toESM(require("fs"), 1);
1460
- var import_node_path5 = __toESM(require("path"), 1);
1332
+ var import_node_path6 = __toESM(require("path"), 1);
1461
1333
  function getVersionFromManifests(packageDir) {
1462
- const packageJsonPath = import_node_path5.default.join(packageDir, "package.json");
1463
- 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");
1464
1336
  if (import_node_fs5.default.existsSync(packageJsonPath)) {
1465
1337
  try {
1466
1338
  const packageJson = JSON.parse(import_node_fs5.default.readFileSync(packageJsonPath, "utf-8"));
@@ -1505,8 +1377,8 @@ function getVersionFromManifests(packageDir) {
1505
1377
  };
1506
1378
  }
1507
1379
  function throwIfNoManifestsFound(packageDir) {
1508
- const packageJsonPath = import_node_path5.default.join(packageDir, "package.json");
1509
- 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");
1510
1382
  throw new Error(
1511
1383
  `Neither package.json nor Cargo.toml found at ${packageDir}. Checked paths: ${packageJsonPath}, ${cargoTomlPath}. Cannot determine version.`
1512
1384
  );
@@ -1698,7 +1570,7 @@ To fix this mismatch:
1698
1570
  const bumper = new import_conventional_recommended_bump.Bumper();
1699
1571
  bumper.loadPreset(preset);
1700
1572
  const recommendedBump = await bumper.bump();
1701
- const releaseTypeFromCommits = recommendedBump == null ? void 0 : recommendedBump.releaseType;
1573
+ const releaseTypeFromCommits = recommendedBump && "releaseType" in recommendedBump ? recommendedBump.releaseType : void 0;
1702
1574
  if (hasNoTags) {
1703
1575
  if (releaseTypeFromCommits) {
1704
1576
  return getPackageVersionFallback(
@@ -1784,36 +1656,44 @@ function calculateNextVersion(version, manifestType, name, releaseType, prerelea
1784
1656
  }
1785
1657
 
1786
1658
  // src/utils/packageMatching.ts
1659
+ var import_micromatch2 = __toESM(require("micromatch"), 1);
1787
1660
  function matchesPackageTarget(packageName, target) {
1788
1661
  if (packageName === target) {
1789
1662
  return true;
1790
1663
  }
1791
- if (target.endsWith("/*")) {
1664
+ if (target.startsWith("@") && target.endsWith("/*") && !target.includes("**")) {
1792
1665
  const scope = target.slice(0, -2);
1793
- if (scope.startsWith("@")) {
1794
- return packageName.startsWith(`${scope}/`);
1795
- }
1796
1666
  return packageName.startsWith(`${scope}/`);
1797
1667
  }
1798
- if (target === "*") {
1799
- return true;
1800
- }
1801
- return false;
1802
- }
1803
- function shouldProcessPackage(packageName, targets = [], skip = []) {
1804
- if (skip.includes(packageName)) {
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
+ );
1805
1681
  return false;
1806
1682
  }
1807
- if (targets.length === 0) {
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) {
1808
1689
  return true;
1809
1690
  }
1810
- return targets.some((target) => matchesPackageTarget(packageName, target));
1691
+ return !shouldMatchPackageTargets(packageName, skip);
1811
1692
  }
1812
1693
 
1813
1694
  // src/package/packageProcessor.ts
1814
1695
  var PackageProcessor = class {
1815
1696
  skip;
1816
- targets;
1817
1697
  versionPrefix;
1818
1698
  tagTemplate;
1819
1699
  commitMessageTemplate;
@@ -1825,7 +1705,6 @@ var PackageProcessor = class {
1825
1705
  fullConfig;
1826
1706
  constructor(options) {
1827
1707
  this.skip = options.skip || [];
1828
- this.targets = options.targets || [];
1829
1708
  this.versionPrefix = options.versionPrefix || "v";
1830
1709
  this.tagTemplate = options.tagTemplate;
1831
1710
  this.commitMessageTemplate = options.commitMessageTemplate || "";
@@ -1836,13 +1715,7 @@ var PackageProcessor = class {
1836
1715
  this.fullConfig = options.fullConfig;
1837
1716
  }
1838
1717
  /**
1839
- * Set package targets to process
1840
- */
1841
- setTargets(targets) {
1842
- this.targets = targets;
1843
- }
1844
- /**
1845
- * Process packages based on targeting criteria
1718
+ * Process packages based on skip list only (targeting handled at discovery time)
1846
1719
  */
1847
1720
  async processPackages(packages) {
1848
1721
  var _a, _b, _c, _d, _e;
@@ -1853,21 +1726,16 @@ var PackageProcessor = class {
1853
1726
  return { updatedPackages: [], tags: [] };
1854
1727
  }
1855
1728
  const pkgsToConsider = packages.filter((pkg) => {
1856
- var _a2;
1857
1729
  const pkgName = pkg.packageJson.name;
1858
- const shouldProcess = shouldProcessPackage(pkgName, this.targets, this.skip);
1730
+ const shouldProcess = shouldProcessPackage(pkgName, this.skip);
1859
1731
  if (!shouldProcess) {
1860
- if ((_a2 = this.skip) == null ? void 0 : _a2.includes(pkgName)) {
1861
- log(`Skipping package ${pkgName} as it's in the skip list.`, "info");
1862
- } else {
1863
- log(`Package ${pkgName} not in target list, skipping.`, "info");
1864
- }
1732
+ log(`Skipping package ${pkgName} as it's in the skip list.`, "info");
1865
1733
  }
1866
1734
  return shouldProcess;
1867
1735
  });
1868
- log(`Found ${pkgsToConsider.length} targeted package(s) to process after filtering.`, "info");
1736
+ log(`Found ${pkgsToConsider.length} package(s) to process after filtering.`, "info");
1869
1737
  if (pkgsToConsider.length === 0) {
1870
- log("No matching targeted packages found to process.", "info");
1738
+ log("No packages found to process.", "info");
1871
1739
  return { updatedPackages: [], tags: [] };
1872
1740
  }
1873
1741
  for (const pkg of pkgsToConsider) {
@@ -1933,22 +1801,20 @@ var PackageProcessor = class {
1933
1801
  if (this.fullConfig.updateChangelog !== false) {
1934
1802
  let changelogEntries = [];
1935
1803
  try {
1936
- let revisionRange = latestTag;
1804
+ let revisionRange;
1937
1805
  if (latestTag) {
1938
1806
  try {
1939
1807
  (0, import_node_child_process4.execSync)(`git rev-parse --verify "${latestTag}"`, {
1940
1808
  cwd: pkgPath,
1941
1809
  stdio: "ignore"
1942
1810
  });
1811
+ revisionRange = `${latestTag}..HEAD`;
1943
1812
  } catch {
1944
- log(
1945
- `Tag ${latestTag} doesn't exist, using recent commits from HEAD for changelog`,
1946
- "debug"
1947
- );
1948
- revisionRange = "HEAD~10..HEAD";
1813
+ log(`Tag ${latestTag} doesn't exist, using all commits for changelog`, "debug");
1814
+ revisionRange = "HEAD";
1949
1815
  }
1950
1816
  } else {
1951
- revisionRange = "HEAD~10..HEAD";
1817
+ revisionRange = "HEAD";
1952
1818
  }
1953
1819
  changelogEntries = extractChangelogEntriesFromCommits(pkgPath, revisionRange);
1954
1820
  if (changelogEntries.length === 0) {
@@ -1973,7 +1839,7 @@ var PackageProcessor = class {
1973
1839
  }
1974
1840
  let repoUrl;
1975
1841
  try {
1976
- const packageJsonPath2 = import_node_path6.default.join(pkgPath, "package.json");
1842
+ const packageJsonPath2 = import_node_path7.default.join(pkgPath, "package.json");
1977
1843
  if (fs8.existsSync(packageJsonPath2)) {
1978
1844
  const packageJson = JSON.parse(fs8.readFileSync(packageJsonPath2, "utf8"));
1979
1845
  if (packageJson.repository) {
@@ -2002,7 +1868,7 @@ var PackageProcessor = class {
2002
1868
  this.fullConfig.changelogFormat
2003
1869
  );
2004
1870
  }
2005
- const packageJsonPath = import_node_path6.default.join(pkgPath, "package.json");
1871
+ const packageJsonPath = import_node_path7.default.join(pkgPath, "package.json");
2006
1872
  if (fs8.existsSync(packageJsonPath)) {
2007
1873
  updatePackageVersion(packageJsonPath, nextVersion);
2008
1874
  }
@@ -2011,13 +1877,13 @@ var PackageProcessor = class {
2011
1877
  const cargoPaths = (_b = this.fullConfig.cargo) == null ? void 0 : _b.paths;
2012
1878
  if (cargoPaths && cargoPaths.length > 0) {
2013
1879
  for (const cargoPath of cargoPaths) {
2014
- const resolvedCargoPath = import_node_path6.default.resolve(pkgPath, cargoPath, "Cargo.toml");
1880
+ const resolvedCargoPath = import_node_path7.default.resolve(pkgPath, cargoPath, "Cargo.toml");
2015
1881
  if (fs8.existsSync(resolvedCargoPath)) {
2016
1882
  updatePackageVersion(resolvedCargoPath, nextVersion);
2017
1883
  }
2018
1884
  }
2019
1885
  } else {
2020
- const cargoTomlPath = import_node_path6.default.join(pkgPath, "Cargo.toml");
1886
+ const cargoTomlPath = import_node_path7.default.join(pkgPath, "Cargo.toml");
2021
1887
  if (fs8.existsSync(cargoTomlPath)) {
2022
1888
  updatePackageVersion(cargoTomlPath, nextVersion);
2023
1889
  }
@@ -2050,12 +1916,12 @@ var PackageProcessor = class {
2050
1916
  updatedPackagesInfo.push({ name, version: nextVersion, path: pkgPath });
2051
1917
  }
2052
1918
  if (updatedPackagesInfo.length === 0) {
2053
- log("No targeted packages required a version update.", "info");
1919
+ log("No packages required a version update.", "info");
2054
1920
  return { updatedPackages: [], tags };
2055
1921
  }
2056
1922
  const filesToCommit = [];
2057
1923
  for (const info of updatedPackagesInfo) {
2058
- const packageJsonPath = import_node_path6.default.join(info.path, "package.json");
1924
+ const packageJsonPath = import_node_path7.default.join(info.path, "package.json");
2059
1925
  if (fs8.existsSync(packageJsonPath)) {
2060
1926
  filesToCommit.push(packageJsonPath);
2061
1927
  }
@@ -2064,13 +1930,13 @@ var PackageProcessor = class {
2064
1930
  const cargoPaths = (_d = this.fullConfig.cargo) == null ? void 0 : _d.paths;
2065
1931
  if (cargoPaths && cargoPaths.length > 0) {
2066
1932
  for (const cargoPath of cargoPaths) {
2067
- 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");
2068
1934
  if (fs8.existsSync(resolvedCargoPath)) {
2069
1935
  filesToCommit.push(resolvedCargoPath);
2070
1936
  }
2071
1937
  }
2072
1938
  } else {
2073
- const cargoTomlPath = import_node_path6.default.join(info.path, "Cargo.toml");
1939
+ const cargoTomlPath = import_node_path7.default.join(info.path, "Cargo.toml");
2074
1940
  if (fs8.existsSync(cargoTomlPath)) {
2075
1941
  filesToCommit.push(cargoTomlPath);
2076
1942
  }
@@ -2114,9 +1980,9 @@ var PackageProcessor = class {
2114
1980
  };
2115
1981
 
2116
1982
  // src/core/versionStrategies.ts
2117
- function shouldProcessPackage2(pkg, config, targets = []) {
1983
+ function shouldProcessPackage2(pkg, config) {
2118
1984
  const pkgName = pkg.packageJson.name;
2119
- return shouldProcessPackage(pkgName, targets, config.skip);
1985
+ return shouldProcessPackage(pkgName, config.skip);
2120
1986
  }
2121
1987
  function createSyncedStrategy(config) {
2122
1988
  return async (packages) => {
@@ -2167,7 +2033,8 @@ function createSyncedStrategy(config) {
2167
2033
  type: config.type
2168
2034
  });
2169
2035
  if (!nextVersion) {
2170
- log("No version change needed", "info");
2036
+ const msg = mainPkgName ? `No version change needed for ${mainPkgName}` : "No version change needed";
2037
+ log(msg, "info");
2171
2038
  return;
2172
2039
  }
2173
2040
  const files = [];
@@ -2175,7 +2042,7 @@ function createSyncedStrategy(config) {
2175
2042
  const processedPaths = /* @__PURE__ */ new Set();
2176
2043
  try {
2177
2044
  if (packages.root) {
2178
- const rootPkgPath = path7.join(packages.root, "package.json");
2045
+ const rootPkgPath = path8.join(packages.root, "package.json");
2179
2046
  if (import_node_fs7.default.existsSync(rootPkgPath)) {
2180
2047
  updatePackageVersion(rootPkgPath, nextVersion);
2181
2048
  files.push(rootPkgPath);
@@ -2193,7 +2060,7 @@ function createSyncedStrategy(config) {
2193
2060
  if (!shouldProcessPackage2(pkg, config)) {
2194
2061
  continue;
2195
2062
  }
2196
- const packageJsonPath = path7.join(pkg.dir, "package.json");
2063
+ const packageJsonPath = path8.join(pkg.dir, "package.json");
2197
2064
  if (processedPaths.has(packageJsonPath)) {
2198
2065
  continue;
2199
2066
  }
@@ -2209,7 +2076,7 @@ function createSyncedStrategy(config) {
2209
2076
  return;
2210
2077
  }
2211
2078
  let tagPackageName = null;
2212
- let commitPackageName = void 0;
2079
+ let commitPackageName;
2213
2080
  if (config.packageSpecificTags && packages.packages.length === 1) {
2214
2081
  tagPackageName = packages.packages[0].packageJson.name;
2215
2082
  commitPackageName = packages.packages[0].packageJson.name;
@@ -2243,7 +2110,6 @@ function createSingleStrategy(config) {
2243
2110
  return async (packages) => {
2244
2111
  try {
2245
2112
  const {
2246
- packages: configPackages,
2247
2113
  mainPackage,
2248
2114
  versionPrefix,
2249
2115
  tagTemplate,
@@ -2254,12 +2120,12 @@ function createSingleStrategy(config) {
2254
2120
  let packageName;
2255
2121
  if (mainPackage) {
2256
2122
  packageName = mainPackage;
2257
- } else if (configPackages && configPackages.length === 1) {
2258
- packageName = configPackages[0];
2123
+ } else if (packages.packages.length === 1) {
2124
+ packageName = packages.packages[0].packageJson.name;
2259
2125
  } else {
2260
2126
  throw createVersionError(
2261
2127
  "INVALID_CONFIG" /* INVALID_CONFIG */,
2262
- "Single mode requires either mainPackage or exactly one package in the packages array"
2128
+ "Single mode requires either mainPackage or exactly one resolved package"
2263
2129
  );
2264
2130
  }
2265
2131
  const pkg = packages.packages.find((p) => p.packageJson.name === packageName);
@@ -2277,50 +2143,114 @@ function createSingleStrategy(config) {
2277
2143
  latestTagResult = globalTagResult || "";
2278
2144
  }
2279
2145
  const latestTag = latestTagResult;
2280
- let nextVersion = void 0;
2281
- try {
2282
- nextVersion = await calculateVersion(config, {
2283
- latestTag,
2284
- versionPrefix: formattedPrefix,
2285
- path: pkgPath,
2286
- name: packageName,
2287
- type: config.type
2288
- });
2289
- } catch (error) {
2290
- const errorMessage = error instanceof Error ? error.message : String(error);
2291
- throw createVersionError("VERSION_CALCULATION_ERROR" /* VERSION_CALCULATION_ERROR */, errorMessage);
2292
- }
2293
- if (nextVersion === void 0 || nextVersion === "") {
2146
+ let nextVersion;
2147
+ nextVersion = await calculateVersion(config, {
2148
+ latestTag,
2149
+ versionPrefix: formattedPrefix,
2150
+ branchPattern: config.branchPattern,
2151
+ baseBranch: config.baseBranch,
2152
+ prereleaseIdentifier: config.prereleaseIdentifier,
2153
+ path: pkgPath,
2154
+ name: packageName,
2155
+ type: config.type
2156
+ });
2157
+ if (!nextVersion) {
2294
2158
  log(`No version change needed for ${packageName}`, "info");
2295
2159
  return;
2296
2160
  }
2297
- const packageJsonPath = path7.join(pkgPath, "package.json");
2161
+ if (config.updateChangelog !== false) {
2162
+ let changelogEntries = [];
2163
+ try {
2164
+ let revisionRange;
2165
+ if (latestTag) {
2166
+ try {
2167
+ (0, import_node_child_process5.execSync)(`git rev-parse --verify "${latestTag}"`, {
2168
+ cwd: pkgPath,
2169
+ stdio: "ignore"
2170
+ });
2171
+ revisionRange = `${latestTag}..HEAD`;
2172
+ } catch {
2173
+ log(`Tag ${latestTag} doesn't exist, using all commits for changelog`, "debug");
2174
+ revisionRange = "HEAD";
2175
+ }
2176
+ } else {
2177
+ revisionRange = "HEAD";
2178
+ }
2179
+ changelogEntries = extractChangelogEntriesFromCommits(pkgPath, revisionRange);
2180
+ if (changelogEntries.length === 0) {
2181
+ changelogEntries = [
2182
+ {
2183
+ type: "changed",
2184
+ description: `Update version to ${nextVersion}`
2185
+ }
2186
+ ];
2187
+ }
2188
+ } catch (error) {
2189
+ log(
2190
+ `Error extracting changelog entries: ${error instanceof Error ? error.message : String(error)}`,
2191
+ "warning"
2192
+ );
2193
+ changelogEntries = [
2194
+ {
2195
+ type: "changed",
2196
+ description: `Update version to ${nextVersion}`
2197
+ }
2198
+ ];
2199
+ }
2200
+ let repoUrl;
2201
+ try {
2202
+ const packageJsonPath2 = path8.join(pkgPath, "package.json");
2203
+ if (import_node_fs7.default.existsSync(packageJsonPath2)) {
2204
+ const packageJson = JSON.parse(import_node_fs7.default.readFileSync(packageJsonPath2, "utf8"));
2205
+ if (packageJson.repository) {
2206
+ if (typeof packageJson.repository === "string") {
2207
+ repoUrl = packageJson.repository;
2208
+ } else if (packageJson.repository.url) {
2209
+ repoUrl = packageJson.repository.url;
2210
+ }
2211
+ if ((repoUrl == null ? void 0 : repoUrl.startsWith("git+")) && (repoUrl == null ? void 0 : repoUrl.endsWith(".git"))) {
2212
+ repoUrl = repoUrl.substring(4, repoUrl.length - 4);
2213
+ }
2214
+ }
2215
+ }
2216
+ } catch (error) {
2217
+ log(
2218
+ `Could not determine repository URL for changelog links: ${error instanceof Error ? error.message : String(error)}`,
2219
+ "warning"
2220
+ );
2221
+ }
2222
+ updateChangelog(
2223
+ pkgPath,
2224
+ packageName,
2225
+ nextVersion,
2226
+ changelogEntries,
2227
+ repoUrl,
2228
+ config.changelogFormat
2229
+ );
2230
+ }
2231
+ const packageJsonPath = path8.join(pkgPath, "package.json");
2298
2232
  updatePackageVersion(packageJsonPath, nextVersion);
2299
2233
  log(`Updated package ${packageName} to version ${nextVersion}`, "success");
2300
- const nextTag = formatTag(
2234
+ const tagName = formatTag(
2301
2235
  nextVersion,
2302
2236
  formattedPrefix,
2303
2237
  packageName,
2304
2238
  tagTemplate,
2305
2239
  config.packageSpecificTags
2306
2240
  );
2307
- const formattedCommitMessage = formatCommitMessage(commitMessage, nextVersion, packageName);
2308
- await createGitCommitAndTag(
2309
- [packageJsonPath],
2310
- nextTag,
2311
- formattedCommitMessage,
2312
- skipHooks,
2313
- dryRun
2314
- );
2241
+ const commitMsg = formatCommitMessage(commitMessage, nextVersion, packageName);
2242
+ if (!dryRun) {
2243
+ await createGitCommitAndTag([packageJsonPath], tagName, commitMsg, skipHooks, dryRun);
2244
+ log(`Created tag: ${tagName}`, "success");
2245
+ } else {
2246
+ log(`Would create tag: ${tagName}`, "info");
2247
+ }
2315
2248
  } catch (error) {
2316
2249
  if (error instanceof VersionError || error instanceof GitError) {
2317
- log(
2318
- `Single Package Strategy failed: ${error.message} (${error.code || "UNKNOWN"})`,
2319
- "error"
2320
- );
2250
+ log(`Single Strategy failed: ${error.message} (${error.code || "UNKNOWN"})`, "error");
2321
2251
  } else {
2322
2252
  const errorMessage = error instanceof Error ? error.message : String(error);
2323
- log(`Single Package Strategy failed: ${errorMessage}`, "error");
2253
+ log(`Single Strategy failed: ${errorMessage}`, "error");
2324
2254
  }
2325
2255
  throw error;
2326
2256
  }
@@ -2332,7 +2262,6 @@ function createAsyncStrategy(config) {
2332
2262
  };
2333
2263
  const processorOptions = {
2334
2264
  skip: config.skip || [],
2335
- targets: config.packages || [],
2336
2265
  versionPrefix: config.versionPrefix || "v",
2337
2266
  tagTemplate: config.tagTemplate,
2338
2267
  commitMessageTemplate: config.commitMessage || "",
@@ -2349,15 +2278,9 @@ function createAsyncStrategy(config) {
2349
2278
  }
2350
2279
  };
2351
2280
  const packageProcessor = new PackageProcessor(processorOptions);
2352
- return async (packages, targets = []) => {
2281
+ return async (packages, _targets = []) => {
2353
2282
  try {
2354
- const targetPackages = targets.length > 0 ? targets : config.packages || [];
2355
- packageProcessor.setTargets(targetPackages);
2356
- if (targetPackages.length > 0) {
2357
- log(`Processing targeted packages: ${targetPackages.join(", ")}`, "info");
2358
- } else {
2359
- log("No targets specified, processing all non-skipped packages", "info");
2360
- }
2283
+ log(`Processing ${packages.packages.length} pre-filtered packages`, "info");
2361
2284
  const result = await packageProcessor.processPackages(packages.packages);
2362
2285
  if (result.updatedPackages.length === 0) {
2363
2286
  log("No packages required a version update.", "info");
@@ -2383,13 +2306,9 @@ function createAsyncStrategy(config) {
2383
2306
  };
2384
2307
  }
2385
2308
  function createStrategy(config) {
2386
- var _a;
2387
2309
  if (config.synced) {
2388
2310
  return createSyncedStrategy(config);
2389
2311
  }
2390
- if (config.mainPackage || ((_a = config.packages) == null ? void 0 : _a.length) === 1) {
2391
- return createSingleStrategy(config);
2392
- }
2393
2312
  return createAsyncStrategy(config);
2394
2313
  }
2395
2314
  function createStrategyMap(config) {
@@ -2439,6 +2358,22 @@ var VersionEngine = class {
2439
2358
  );
2440
2359
  pkgsResult.root = (0, import_node_process5.cwd)();
2441
2360
  }
2361
+ if (this.config.packages && this.config.packages.length > 0) {
2362
+ const originalCount = pkgsResult.packages.length;
2363
+ const filteredPackages = filterPackagesByConfig(
2364
+ pkgsResult.packages,
2365
+ this.config.packages,
2366
+ pkgsResult.root
2367
+ );
2368
+ pkgsResult.packages = filteredPackages;
2369
+ log(
2370
+ `Filtered ${originalCount} workspace packages to ${filteredPackages.length} based on packages config`,
2371
+ "info"
2372
+ );
2373
+ if (filteredPackages.length === 0) {
2374
+ log("Warning: No packages matched the specified patterns in config.packages", "warning");
2375
+ }
2376
+ }
2442
2377
  this.workspaceCache = pkgsResult;
2443
2378
  return pkgsResult;
2444
2379
  } catch (error) {
@@ -2450,11 +2385,11 @@ var VersionEngine = class {
2450
2385
  }
2451
2386
  /**
2452
2387
  * Run the current strategy
2388
+ * @param packages Workspace packages to process
2453
2389
  * @param targets Optional package targets to process (only used by async strategy)
2454
2390
  */
2455
- async run(targets = []) {
2391
+ async run(packages, targets = []) {
2456
2392
  try {
2457
- const packages = await this.getWorkspacePackages();
2458
2393
  return this.currentStrategy(packages, targets);
2459
2394
  } catch (error) {
2460
2395
  if (error instanceof VersionError || error instanceof GitError) {
@@ -2492,8 +2427,8 @@ var VersionEngine = class {
2492
2427
  var import_meta = {};
2493
2428
  function getPackageVersion() {
2494
2429
  try {
2495
- const packageJsonPath = import_node_path7.default.resolve(
2496
- import_node_path7.default.dirname(import_meta.url.replace("file:", "")),
2430
+ const packageJsonPath = import_node_path8.default.resolve(
2431
+ import_node_path8.default.dirname(import_meta.url.replace("file:", "")),
2497
2432
  "../package.json"
2498
2433
  );
2499
2434
  const packageJsonContent = fs10.readFileSync(packageJsonPath, "utf-8");
@@ -2530,24 +2465,31 @@ async function run() {
2530
2465
  config.prereleaseIdentifier = options.prerelease === true ? "next" : options.prerelease;
2531
2466
  const cliTargets = options.target ? options.target.split(",").map((t) => t.trim()) : [];
2532
2467
  const engine = new VersionEngine(config, !!options.json);
2468
+ const pkgsResult = await engine.getWorkspacePackages();
2469
+ const resolvedCount = pkgsResult.packages.length;
2470
+ log(`Resolved ${resolvedCount} packages from workspace`, "debug");
2471
+ log(`Config packages: ${JSON.stringify(config.packages)}`, "debug");
2472
+ log(`Config synced: ${config.synced}`, "debug");
2533
2473
  if (config.synced) {
2534
2474
  log("Using synced versioning strategy.", "info");
2535
2475
  engine.setStrategy("synced");
2536
- await engine.run();
2537
- } else if (config.packages && config.packages.length === 1) {
2476
+ await engine.run(pkgsResult);
2477
+ } else if (resolvedCount === 1) {
2538
2478
  log("Using single package versioning strategy.", "info");
2539
2479
  if (cliTargets.length > 0) {
2540
2480
  log("--target flag is ignored for single package strategy.", "warning");
2541
2481
  }
2542
2482
  engine.setStrategy("single");
2543
- await engine.run();
2483
+ await engine.run(pkgsResult);
2484
+ } else if (resolvedCount === 0) {
2485
+ throw new Error("No packages found in workspace");
2544
2486
  } else {
2545
2487
  log("Using async versioning strategy.", "info");
2546
2488
  if (cliTargets.length > 0) {
2547
2489
  log(`Targeting specific packages: ${cliTargets.join(", ")}`, "info");
2548
2490
  }
2549
2491
  engine.setStrategy("async");
2550
- await engine.run(cliTargets);
2492
+ await engine.run(pkgsResult, cliTargets);
2551
2493
  }
2552
2494
  log("Versioning process completed.", "success");
2553
2495
  printJsonOutput();
@@ -2566,38 +2508,43 @@ async function run() {
2566
2508
  process.exit(1);
2567
2509
  }
2568
2510
  });
2569
- program.command("regenerate-changelog").description("Regenerate a complete changelog from git history").option("-o, --output <path>", "Output path for changelog file", "CHANGELOG.md").option(
2511
+ 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(
2570
2512
  "-f, --format <format>",
2571
2513
  "Changelog format (keep-a-changelog|angular)",
2572
2514
  "keep-a-changelog"
2573
2515
  ).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) => {
2574
- try {
2575
- log("Regenerating changelog from git history...", "info");
2576
- if (options.format !== "keep-a-changelog" && options.format !== "angular") {
2577
- throw new Error(
2578
- 'Invalid format specified. Must be either "keep-a-changelog" or "angular"'
2516
+ var _a;
2517
+ if (options.regenerate) {
2518
+ try {
2519
+ log("Regenerating changelog from git history...", "info");
2520
+ if (options.format !== "keep-a-changelog" && options.format !== "angular") {
2521
+ throw new Error(
2522
+ 'Invalid format specified. Must be either "keep-a-changelog" or "angular"'
2523
+ );
2524
+ }
2525
+ const regenerateOptions = {
2526
+ format: options.format,
2527
+ since: options.since,
2528
+ output: options.output,
2529
+ dryRun: options.dryRun,
2530
+ projectDir: options.projectDir,
2531
+ repoUrl: options.repoUrl
2532
+ };
2533
+ const content = await regenerateChangelog(regenerateOptions);
2534
+ await writeChangelog(
2535
+ content,
2536
+ import_node_path8.default.resolve(options.projectDir, options.output),
2537
+ options.dryRun
2579
2538
  );
2539
+ if (!options.dryRun) {
2540
+ log(`Changelog successfully regenerated at ${options.output}`, "success");
2541
+ }
2542
+ } catch (error) {
2543
+ log(error instanceof Error ? error.message : String(error), "error");
2544
+ process.exit(1);
2580
2545
  }
2581
- const regenerateOptions = {
2582
- format: options.format,
2583
- since: options.since,
2584
- output: options.output,
2585
- dryRun: options.dryRun,
2586
- projectDir: options.projectDir,
2587
- repoUrl: options.repoUrl
2588
- };
2589
- const content = await regenerateChangelog(regenerateOptions);
2590
- await writeChangelog(
2591
- content,
2592
- import_node_path7.default.resolve(options.projectDir, options.output),
2593
- options.dryRun
2594
- );
2595
- if (!options.dryRun) {
2596
- log(`Changelog successfully regenerated at ${options.output}`, "success");
2597
- }
2598
- } catch (error) {
2599
- log(error instanceof Error ? error.message : String(error), "error");
2600
- process.exit(1);
2546
+ } else {
2547
+ (_a = program.commands.find((cmd) => cmd.name() === "changelog")) == null ? void 0 : _a.help();
2601
2548
  }
2602
2549
  });
2603
2550
  program.parse(process.argv);