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.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  // src/index.ts
4
4
  import * as fs10 from "fs";
5
- import path8 from "path";
5
+ import path9 from "path";
6
6
  import { Command } from "commander";
7
7
 
8
8
  // src/changelog/changelogRegenerator.ts
@@ -126,7 +126,8 @@ function extractChangelogEntriesFromCommits(projectDir, revisionRange) {
126
126
  }
127
127
  }
128
128
  function parseCommitMessage(message) {
129
- const match = message.match(CONVENTIONAL_COMMIT_REGEX);
129
+ const trimmedMessage = message.trim();
130
+ const match = trimmedMessage.match(CONVENTIONAL_COMMIT_REGEX);
130
131
  if (match) {
131
132
  const [, type, scope, breakingMark, subject, body = ""] = match;
132
133
  const breakingFromMark = breakingMark === "!";
@@ -150,8 +151,8 @@ function parseCommitMessage(message) {
150
151
  // Store original type for custom formatting
151
152
  };
152
153
  }
153
- if (!message.startsWith("Merge") && !message.match(/^v?\d+\.\d+\.\d+/)) {
154
- const firstLine = message.split("\n")[0].trim();
154
+ if (!trimmedMessage.startsWith("Merge") && !trimmedMessage.match(/^v?\d+\.\d+\.\d+/)) {
155
+ const firstLine = trimmedMessage.split("\n")[0].trim();
155
156
  return {
156
157
  type: "changed",
157
158
  description: firstLine
@@ -199,7 +200,9 @@ function formatChangelogEntries(format, version, date, entries, packageName, rep
199
200
  const hasBreaking = entry.description.includes("**BREAKING**");
200
201
  return {
201
202
  ...entry,
202
- breaking: hasBreaking
203
+ breaking: hasBreaking,
204
+ // Clean up the description to remove the **BREAKING** prefix since we'll handle it in formatting
205
+ description: hasBreaking ? entry.description.replace("**BREAKING** ", "") : entry.description
203
206
  };
204
207
  });
205
208
  return format === "keep-a-changelog" ? formatKeepAChangelogEntries(version, date, formattingEntries, repoUrl) : formatAngularEntries(version, date, formattingEntries, packageName);
@@ -212,15 +215,19 @@ function formatKeepAChangelogEntries(version, date, entries, repoUrl) {
212
215
  const fixed = [];
213
216
  const security = [];
214
217
  for (const entry of entries) {
215
- const entryText = entry.scope ? `- **${entry.scope}**: ${entry.description}` : `- ${entry.description}`;
216
- const formattedEntry = entry.breaking ? entryText.replace(/^- /, "- **BREAKING** ") : entryText;
218
+ let entryText;
219
+ if (entry.breaking) {
220
+ entryText = entry.scope ? `- **BREAKING** **${entry.scope}**: ${entry.description}` : `- **BREAKING** ${entry.description}`;
221
+ } else {
222
+ entryText = entry.scope ? `- **${entry.scope}**: ${entry.description}` : `- ${entry.description}`;
223
+ }
217
224
  const entryType = entry.originalType || entry.type;
218
225
  switch (entryType) {
219
226
  case "feat":
220
- added.push(formattedEntry);
227
+ added.push(entryText);
221
228
  break;
222
229
  case "fix":
223
- fixed.push(formattedEntry);
230
+ fixed.push(entryText);
224
231
  break;
225
232
  case "docs":
226
233
  case "style":
@@ -228,38 +235,38 @@ function formatKeepAChangelogEntries(version, date, entries, repoUrl) {
228
235
  case "perf":
229
236
  case "build":
230
237
  case "ci":
231
- changed.push(formattedEntry);
238
+ changed.push(entryText);
232
239
  break;
233
240
  case "test":
234
241
  break;
235
242
  case "chore":
236
243
  if (entry.description.toLowerCase().includes("deprecat")) {
237
- deprecated.push(formattedEntry);
244
+ deprecated.push(entryText);
238
245
  } else {
239
- changed.push(formattedEntry);
246
+ changed.push(entryText);
240
247
  }
241
248
  break;
242
249
  // Keep-a-changelog standard types
243
250
  case "added":
244
- added.push(formattedEntry);
251
+ added.push(entryText);
245
252
  break;
246
253
  case "changed":
247
- changed.push(formattedEntry);
254
+ changed.push(entryText);
248
255
  break;
249
256
  case "deprecated":
250
- deprecated.push(formattedEntry);
257
+ deprecated.push(entryText);
251
258
  break;
252
259
  case "removed":
253
- removed.push(formattedEntry);
260
+ removed.push(entryText);
254
261
  break;
255
262
  case "fixed":
256
- fixed.push(formattedEntry);
263
+ fixed.push(entryText);
257
264
  break;
258
265
  case "security":
259
- security.push(formattedEntry);
266
+ security.push(entryText);
260
267
  break;
261
268
  default:
262
- changed.push(formattedEntry);
269
+ changed.push(entryText);
263
270
  }
264
271
  }
265
272
  let content = `## [${version}] - ${date}
@@ -424,13 +431,25 @@ function getAngularTemplate() {
424
431
  // src/changelog/changelogRegenerator.ts
425
432
  function getAllVersionTags(since, versionPrefix = "v") {
426
433
  try {
427
- const command = since ? `git tag --list "${versionPrefix}*" --sort=creatordate --contains ${since}` : `git tag --list "${versionPrefix}*" --sort=creatordate`;
434
+ const command = `git tag --list "${versionPrefix}*" --sort=creatordate`;
428
435
  const tagOutput = execSync2(command, { encoding: "utf8" }).trim();
429
436
  if (!tagOutput) {
430
437
  return [];
431
438
  }
432
- const tags = tagOutput.split("\n").filter((tag) => !!tag);
433
- return tags.map((tag) => {
439
+ const allTags = tagOutput.split("\n").filter((tag) => !!tag);
440
+ let filteredTags = allTags;
441
+ if (since) {
442
+ const sinceIndex = allTags.findIndex((tag) => tag === since);
443
+ if (sinceIndex >= 0) {
444
+ filteredTags = allTags.slice(sinceIndex);
445
+ } else {
446
+ log(
447
+ `Warning: --since tag "${since}" not found in git history, including all tags`,
448
+ "warning"
449
+ );
450
+ }
451
+ }
452
+ return filteredTags.map((tag) => {
434
453
  try {
435
454
  const date = execSync2(`git log -1 --format=%ad --date=short ${tag}`, {
436
455
  encoding: "utf8"
@@ -479,7 +498,10 @@ async function regenerateChangelog(options) {
479
498
  }
480
499
  } catch {
481
500
  }
482
- const tags = getAllVersionTags(since, versionPrefix);
501
+ let tags = getAllVersionTags(since, versionPrefix);
502
+ if (!tags.length && since) {
503
+ tags = getAllVersionTags(void 0, versionPrefix);
504
+ }
483
505
  if (!tags.length) {
484
506
  throw new Error(
485
507
  'No version tags found in git history. Make sure you have tags that start with the version prefix (usually "v").'
@@ -493,7 +515,28 @@ async function regenerateChangelog(options) {
493
515
  const previousTag = i > 0 ? tags[i - 1].tag : null;
494
516
  log(`Processing changes for ${currentTag.tag}...`, "info");
495
517
  try {
496
- const tagRange = previousTag ? `${previousTag}..${currentTag.tag}` : currentTag.tag;
518
+ let tagRange;
519
+ if (previousTag) {
520
+ tagRange = `${previousTag}..${currentTag.tag}`;
521
+ } else if (since && currentTag.tag === since) {
522
+ try {
523
+ const allTagsCmd = `git tag --list "${versionPrefix}*" --sort=creatordate`;
524
+ const allTagsOutput = execSync2(allTagsCmd, { encoding: "utf8" }).trim();
525
+ const allTags = allTagsOutput.split("\n").filter((tag) => !!tag);
526
+ const sinceIndex = allTags.findIndex((tag) => tag === since);
527
+ const actualPreviousTag = sinceIndex > 0 ? allTags[sinceIndex - 1] : null;
528
+ if (actualPreviousTag) {
529
+ tagRange = `${actualPreviousTag}..${currentTag.tag}`;
530
+ } else {
531
+ tagRange = currentTag.tag;
532
+ }
533
+ } catch (error) {
534
+ log(`Failed to find previous tag for ${currentTag.tag}: ${error}`, "warning");
535
+ tagRange = currentTag.tag;
536
+ }
537
+ } else {
538
+ tagRange = currentTag.tag;
539
+ }
497
540
  const entries = extractChangelogEntriesFromCommits(projectDir, tagRange);
498
541
  if (!entries.length) {
499
542
  log(`No changelog entries found for ${currentTag.tag}, adding placeholder entry`, "info");
@@ -606,9 +649,163 @@ function createVersionError(code, details) {
606
649
  return new VersionError(fullMessage, code);
607
650
  }
608
651
 
652
+ // src/utils/packageFiltering.ts
653
+ import path2 from "path";
654
+ import micromatch from "micromatch";
655
+ function filterPackagesByConfig(packages, configTargets, workspaceRoot) {
656
+ if (configTargets.length === 0) {
657
+ log("No config targets specified, returning all packages", "debug");
658
+ return packages;
659
+ }
660
+ const matchedPackages = /* @__PURE__ */ new Set();
661
+ for (const target of configTargets) {
662
+ const dirMatches = filterByDirectoryPattern(packages, target, workspaceRoot);
663
+ const nameMatches = filterByPackageNamePattern(packages, target);
664
+ dirMatches.forEach((pkg) => matchedPackages.add(pkg));
665
+ nameMatches.forEach((pkg) => matchedPackages.add(pkg));
666
+ }
667
+ return Array.from(matchedPackages);
668
+ }
669
+ function filterByDirectoryPattern(packages, pattern, workspaceRoot) {
670
+ if (pattern === "./" || pattern === ".") {
671
+ return packages.filter((pkg) => pkg.dir === workspaceRoot);
672
+ }
673
+ const normalizedPattern = pattern.replace(/\\/g, "/");
674
+ return packages.filter((pkg) => {
675
+ const relativePath = path2.relative(workspaceRoot, pkg.dir);
676
+ const normalizedRelativePath = relativePath.replace(/\\/g, "/");
677
+ if (normalizedPattern === normalizedRelativePath) {
678
+ return true;
679
+ }
680
+ try {
681
+ return micromatch.isMatch(normalizedRelativePath, normalizedPattern, {
682
+ dot: true,
683
+ noglobstar: false,
684
+ bash: true
685
+ });
686
+ } catch (error) {
687
+ log(
688
+ `Invalid directory pattern "${pattern}": ${error instanceof Error ? error.message : String(error)}`,
689
+ "warning"
690
+ );
691
+ return false;
692
+ }
693
+ });
694
+ }
695
+ function filterByPackageNamePattern(packages, pattern) {
696
+ return packages.filter((pkg) => {
697
+ var _a;
698
+ if (!((_a = pkg.packageJson) == null ? void 0 : _a.name) || typeof pkg.packageJson.name !== "string") {
699
+ return false;
700
+ }
701
+ return matchesPackageNamePattern(pkg.packageJson.name, pattern);
702
+ });
703
+ }
704
+ function matchesPackageNamePattern(packageName, pattern) {
705
+ if (packageName === pattern) {
706
+ return true;
707
+ }
708
+ if (pattern.startsWith("@") && pattern.endsWith("/*") && !pattern.includes("**")) {
709
+ const scope = pattern.slice(0, -2);
710
+ return packageName.startsWith(`${scope}/`);
711
+ }
712
+ try {
713
+ return micromatch.isMatch(packageName, pattern, {
714
+ dot: true,
715
+ contains: false,
716
+ noglobstar: false,
717
+ bash: true
718
+ });
719
+ } catch (error) {
720
+ log(
721
+ `Invalid package name pattern "${pattern}": ${error instanceof Error ? error.message : String(error)}`,
722
+ "warning"
723
+ );
724
+ return false;
725
+ }
726
+ }
727
+
609
728
  // src/core/versionStrategies.ts
729
+ import { execSync as execSync5 } from "child_process";
610
730
  import fs9 from "fs";
611
- import * as path7 from "path";
731
+ import * as path8 from "path";
732
+
733
+ // src/changelog/changelogManager.ts
734
+ import * as fs3 from "fs";
735
+ import * as path3 from "path";
736
+ function updateChangelog(packagePath, packageName, version, entries, repoUrl, format = "keep-a-changelog") {
737
+ try {
738
+ const changelogPath = path3.join(packagePath, "CHANGELOG.md");
739
+ let existingContent = "";
740
+ if (fs3.existsSync(changelogPath)) {
741
+ existingContent = fs3.readFileSync(changelogPath, "utf8");
742
+ }
743
+ const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
744
+ const newVersionContent = formatChangelogEntries(
745
+ format,
746
+ version,
747
+ today,
748
+ entries,
749
+ packageName,
750
+ repoUrl
751
+ );
752
+ let finalContent;
753
+ if (existingContent) {
754
+ if (format === "keep-a-changelog") {
755
+ const headerEndIndex = existingContent.indexOf("\n## ");
756
+ if (headerEndIndex > 0) {
757
+ const beforeVersions = existingContent.substring(0, headerEndIndex);
758
+ const afterVersions = existingContent.substring(headerEndIndex);
759
+ finalContent = `${beforeVersions}
760
+ ${newVersionContent}
761
+ ${afterVersions}`;
762
+ } else {
763
+ finalContent = `${existingContent}
764
+ ${newVersionContent}
765
+ `;
766
+ }
767
+ } else {
768
+ const headerEndIndex = existingContent.indexOf("\n## ");
769
+ if (headerEndIndex > 0) {
770
+ const beforeVersions = existingContent.substring(0, headerEndIndex);
771
+ const afterVersions = existingContent.substring(headerEndIndex);
772
+ finalContent = `${beforeVersions}
773
+ ${newVersionContent}
774
+ ${afterVersions}`;
775
+ } else {
776
+ finalContent = `${existingContent}
777
+ ${newVersionContent}
778
+ `;
779
+ }
780
+ }
781
+ } else {
782
+ if (format === "keep-a-changelog") {
783
+ finalContent = `# Changelog
784
+
785
+ All notable changes to ${packageName} will be documented in this file.
786
+
787
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
788
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
789
+
790
+ ${newVersionContent}
791
+ `;
792
+ } else {
793
+ finalContent = `# Changelog
794
+
795
+ ${newVersionContent}
796
+ `;
797
+ }
798
+ }
799
+ log(`Writing changelog to: ${changelogPath}`, "info");
800
+ fs3.writeFileSync(changelogPath, finalContent);
801
+ log(`Updated changelog at ${changelogPath}`, "success");
802
+ } catch (error) {
803
+ log(
804
+ `Error updating changelog: ${error instanceof Error ? error.message : String(error)}`,
805
+ "error"
806
+ );
807
+ }
808
+ }
612
809
 
613
810
  // src/git/commands.ts
614
811
  import { cwd as cwd2 } from "process";
@@ -634,11 +831,11 @@ var execAsync = (command, options) => {
634
831
  var execSync3 = (command, args) => nativeExecSync(command, { maxBuffer: 1024 * 1024 * 10, ...args });
635
832
 
636
833
  // src/git/repository.ts
637
- import { existsSync, statSync } from "fs";
638
- import { join } from "path";
834
+ import { existsSync as existsSync2, statSync } from "fs";
835
+ import { join as join2 } from "path";
639
836
  function isGitRepository(directory) {
640
- const gitDir = join(directory, ".git");
641
- if (!existsSync(gitDir)) {
837
+ const gitDir = join2(directory, ".git");
838
+ if (!existsSync2(gitDir)) {
642
839
  return false;
643
840
  }
644
841
  const stats = statSync(gitDir);
@@ -996,21 +1193,21 @@ async function getLatestTagForPackage(packageName, versionPrefix, options) {
996
1193
  }
997
1194
 
998
1195
  // src/package/packageManagement.ts
999
- import fs4 from "fs";
1000
- import path3 from "path";
1196
+ import fs5 from "fs";
1197
+ import path5 from "path";
1001
1198
 
1002
1199
  // src/cargo/cargoHandler.ts
1003
- import fs3 from "fs";
1004
- import path2 from "path";
1200
+ import fs4 from "fs";
1201
+ import path4 from "path";
1005
1202
  import * as TOML from "smol-toml";
1006
1203
  function getCargoInfo(cargoPath) {
1007
1204
  var _a;
1008
- if (!fs3.existsSync(cargoPath)) {
1205
+ if (!fs4.existsSync(cargoPath)) {
1009
1206
  log(`Cargo.toml file not found at: ${cargoPath}`, "error");
1010
1207
  throw new Error(`Cargo.toml file not found at: ${cargoPath}`);
1011
1208
  }
1012
1209
  try {
1013
- const fileContent = fs3.readFileSync(cargoPath, "utf8");
1210
+ const fileContent = fs4.readFileSync(cargoPath, "utf8");
1014
1211
  const cargo = TOML.parse(fileContent);
1015
1212
  if (!((_a = cargo.package) == null ? void 0 : _a.name)) {
1016
1213
  log(`Package name not found in: ${cargoPath}`, "error");
@@ -1020,7 +1217,7 @@ function getCargoInfo(cargoPath) {
1020
1217
  name: cargo.package.name,
1021
1218
  version: cargo.package.version || "0.0.0",
1022
1219
  path: cargoPath,
1023
- dir: path2.dirname(cargoPath),
1220
+ dir: path4.dirname(cargoPath),
1024
1221
  content: cargo
1025
1222
  };
1026
1223
  } catch (error) {
@@ -1033,12 +1230,12 @@ function getCargoInfo(cargoPath) {
1033
1230
  }
1034
1231
  }
1035
1232
  function isCargoToml(filePath) {
1036
- return path2.basename(filePath) === "Cargo.toml";
1233
+ return path4.basename(filePath) === "Cargo.toml";
1037
1234
  }
1038
1235
  function updateCargoVersion(cargoPath, version) {
1039
1236
  var _a;
1040
1237
  try {
1041
- const originalContent = fs3.readFileSync(cargoPath, "utf8");
1238
+ const originalContent = fs4.readFileSync(cargoPath, "utf8");
1042
1239
  const cargo = TOML.parse(originalContent);
1043
1240
  const packageName = (_a = cargo.package) == null ? void 0 : _a.name;
1044
1241
  if (!packageName) {
@@ -1050,7 +1247,7 @@ function updateCargoVersion(cargoPath, version) {
1050
1247
  cargo.package.version = version;
1051
1248
  }
1052
1249
  const updatedContent = TOML.stringify(cargo);
1053
- fs3.writeFileSync(cargoPath, updatedContent);
1250
+ fs4.writeFileSync(cargoPath, updatedContent);
1054
1251
  addPackageUpdate(packageName, version, cargoPath);
1055
1252
  log(`Updated Cargo.toml at ${cargoPath} to version ${version}`, "success");
1056
1253
  } catch (error) {
@@ -1069,11 +1266,11 @@ function updatePackageVersion(packagePath, version) {
1069
1266
  return;
1070
1267
  }
1071
1268
  try {
1072
- const packageContent = fs4.readFileSync(packagePath, "utf8");
1269
+ const packageContent = fs5.readFileSync(packagePath, "utf8");
1073
1270
  const packageJson = JSON.parse(packageContent);
1074
1271
  const packageName = packageJson.name;
1075
1272
  packageJson.version = version;
1076
- fs4.writeFileSync(packagePath, `${JSON.stringify(packageJson, null, 2)}
1273
+ fs5.writeFileSync(packagePath, `${JSON.stringify(packageJson, null, 2)}
1077
1274
  `);
1078
1275
  addPackageUpdate(packageName, version, packagePath);
1079
1276
  log(`Updated package.json at ${packagePath} to version ${version}`, "success");
@@ -1089,334 +1286,9 @@ function updatePackageVersion(packagePath, version) {
1089
1286
  // src/package/packageProcessor.ts
1090
1287
  import { execSync as execSync4 } from "child_process";
1091
1288
  import * as fs8 from "fs";
1092
- import path6 from "path";
1289
+ import path7 from "path";
1093
1290
  import { exit } from "process";
1094
1291
 
1095
- // src/changelog/changelogManager.ts
1096
- import * as fs5 from "fs";
1097
- import * as path4 from "path";
1098
- function createChangelog(_packagePath, packageName) {
1099
- return {
1100
- projectName: packageName,
1101
- unreleased: [],
1102
- versions: []
1103
- };
1104
- }
1105
- function parseChangelog(filePath) {
1106
- try {
1107
- if (!fs5.existsSync(filePath)) {
1108
- return null;
1109
- }
1110
- fs5.readFileSync(filePath, "utf8");
1111
- log(`Parsed changelog at ${filePath}`, "info");
1112
- return {
1113
- projectName: path4.basename(path4.dirname(filePath)),
1114
- unreleased: [],
1115
- versions: []
1116
- };
1117
- } catch (error) {
1118
- log(
1119
- `Error parsing changelog: ${error instanceof Error ? error.message : String(error)}`,
1120
- "error"
1121
- );
1122
- return null;
1123
- }
1124
- }
1125
- function generateLinks(changelog, repoUrl) {
1126
- var _a, _b;
1127
- if (!repoUrl || changelog.versions.length === 0) {
1128
- return "";
1129
- }
1130
- let links = "\n";
1131
- if (changelog.unreleased.length > 0) {
1132
- const latestVersion = ((_a = changelog.versions[0]) == null ? void 0 : _a.version) || "";
1133
- links += `[unreleased]: ${repoUrl}/compare/v${latestVersion}...HEAD
1134
- `;
1135
- }
1136
- for (let i = 0; i < changelog.versions.length; i++) {
1137
- const currentVersion = changelog.versions[i].version;
1138
- const previousVersion = (_b = changelog.versions[i + 1]) == null ? void 0 : _b.version;
1139
- if (previousVersion) {
1140
- links += `[${currentVersion}]: ${repoUrl}/compare/v${previousVersion}...v${currentVersion}
1141
- `;
1142
- } else if (i === changelog.versions.length - 1) {
1143
- links += `[${currentVersion}]: ${repoUrl}/releases/tag/v${currentVersion}
1144
- `;
1145
- }
1146
- }
1147
- return links;
1148
- }
1149
- function generateAngularChangelogContent(changelog, repoUrl) {
1150
- let content = "# Changelog\n\n";
1151
- if (changelog.unreleased.length > 0) {
1152
- content += "## [Unreleased]\n\n";
1153
- const groupedByType = groupEntriesByAngularType(changelog.unreleased);
1154
- for (const [type, entries] of Object.entries(groupedByType)) {
1155
- content += `### ${formatAngularType(type)}
1156
-
1157
- `;
1158
- const groupedByScope = groupEntriesByScope2(entries);
1159
- for (const [scope, scopeEntries] of Object.entries(groupedByScope)) {
1160
- if (scope !== "undefined" && scope !== "") {
1161
- content += `* **${scope}:**
1162
- `;
1163
- for (const entry of scopeEntries) {
1164
- content += formatAngularEntry(entry, false);
1165
- }
1166
- content += "\n";
1167
- } else {
1168
- for (const entry of scopeEntries) {
1169
- content += formatAngularEntry(entry, true);
1170
- }
1171
- }
1172
- }
1173
- content += "\n";
1174
- }
1175
- const breakingChanges = changelog.unreleased.filter(
1176
- (entry) => entry.description.includes("**BREAKING**")
1177
- );
1178
- if (breakingChanges.length > 0) {
1179
- content += "### BREAKING CHANGES\n\n";
1180
- for (const entry of breakingChanges) {
1181
- const description = entry.description.replace("**BREAKING** ", "");
1182
- content += `* ${entry.scope ? `**${entry.scope}:** ` : ""}${description}`;
1183
- if (entry.issueIds && entry.issueIds.length > 0) {
1184
- content += ` (${entry.issueIds.join(", ")})`;
1185
- }
1186
- content += "\n";
1187
- }
1188
- content += "\n";
1189
- }
1190
- }
1191
- for (const version of changelog.versions) {
1192
- content += `## [${version.version}] - ${version.date}
1193
-
1194
- `;
1195
- const groupedByType = groupEntriesByAngularType(version.entries);
1196
- for (const [type, entries] of Object.entries(groupedByType)) {
1197
- content += `### ${formatAngularType(type)}
1198
-
1199
- `;
1200
- const groupedByScope = groupEntriesByScope2(entries);
1201
- for (const [scope, scopeEntries] of Object.entries(groupedByScope)) {
1202
- if (scope !== "undefined" && scope !== "") {
1203
- content += `* **${scope}:**
1204
- `;
1205
- for (const entry of scopeEntries) {
1206
- content += formatAngularEntry(entry, false);
1207
- }
1208
- content += "\n";
1209
- } else {
1210
- for (const entry of scopeEntries) {
1211
- content += formatAngularEntry(entry, true);
1212
- }
1213
- }
1214
- }
1215
- content += "\n";
1216
- }
1217
- const breakingChanges = version.entries.filter(
1218
- (entry) => entry.description.includes("**BREAKING**")
1219
- );
1220
- if (breakingChanges.length > 0) {
1221
- content += "### BREAKING CHANGES\n\n";
1222
- for (const entry of breakingChanges) {
1223
- const description = entry.description.replace("**BREAKING** ", "");
1224
- content += `* ${entry.scope ? `**${entry.scope}:** ` : ""}${description}`;
1225
- if (entry.issueIds && entry.issueIds.length > 0) {
1226
- content += ` (${entry.issueIds.join(", ")})`;
1227
- }
1228
- content += "\n";
1229
- }
1230
- content += "\n";
1231
- }
1232
- }
1233
- content += generateLinks(changelog, repoUrl);
1234
- return content;
1235
- }
1236
- function groupEntriesByAngularType(entries) {
1237
- const result = {};
1238
- for (const entry of entries) {
1239
- const type = entry.originalType || mapToAngularType(entry.type);
1240
- if (!result[type]) {
1241
- result[type] = [];
1242
- }
1243
- result[type].push(entry);
1244
- }
1245
- return result;
1246
- }
1247
- function mapToAngularType(type) {
1248
- switch (type) {
1249
- case "added":
1250
- return "feat";
1251
- case "fixed":
1252
- return "fix";
1253
- case "changed":
1254
- return "perf";
1255
- case "deprecated":
1256
- case "removed":
1257
- case "security":
1258
- return type;
1259
- default:
1260
- return type;
1261
- }
1262
- }
1263
- function formatAngularType(type) {
1264
- switch (type) {
1265
- case "feat":
1266
- return "Features";
1267
- case "fix":
1268
- return "Bug Fixes";
1269
- case "perf":
1270
- return "Performance Improvements";
1271
- case "security":
1272
- return "Security";
1273
- case "deprecated":
1274
- return "Deprecated";
1275
- case "removed":
1276
- return "Removed";
1277
- default:
1278
- return capitalizeFirstLetter(type);
1279
- }
1280
- }
1281
- function groupEntriesByScope2(entries) {
1282
- const result = {};
1283
- for (const entry of entries) {
1284
- const scope = entry.scope || "";
1285
- if (!result[scope]) {
1286
- result[scope] = [];
1287
- }
1288
- result[scope].push(entry);
1289
- }
1290
- return result;
1291
- }
1292
- function formatAngularEntry(entry, includeScope) {
1293
- let result = " * ";
1294
- if (includeScope && entry.scope) {
1295
- result += `**${entry.scope}:** `;
1296
- }
1297
- let description = entry.description;
1298
- if (!includeScope && entry.scope && description.startsWith(`**${entry.scope}**: `)) {
1299
- description = description.substring(`**${entry.scope}**: `.length);
1300
- }
1301
- if (description.startsWith("**BREAKING** ")) {
1302
- description = description.substring("**BREAKING** ".length);
1303
- }
1304
- result += description;
1305
- if (entry.issueIds && entry.issueIds.length > 0) {
1306
- result += ` (${entry.issueIds.join(", ")})`;
1307
- }
1308
- result += "\n";
1309
- return result;
1310
- }
1311
- function generateChangelogContent(changelog, repoUrl, format = "keep-a-changelog") {
1312
- if (format === "angular") {
1313
- return generateAngularChangelogContent(changelog, repoUrl);
1314
- }
1315
- let content = "# Changelog\n\n";
1316
- content += `All notable changes to ${changelog.projectName} will be documented in this file.
1317
-
1318
- `;
1319
- content += "The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),\n";
1320
- content += "and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n\n";
1321
- if (changelog.unreleased.length > 0) {
1322
- content += "## [Unreleased]\n\n";
1323
- const grouped = changelog.unreleased.reduce(
1324
- (acc, entry) => {
1325
- if (!acc[entry.type]) {
1326
- acc[entry.type] = [];
1327
- }
1328
- acc[entry.type].push(entry);
1329
- return acc;
1330
- },
1331
- {}
1332
- );
1333
- for (const [type, entries] of Object.entries(grouped)) {
1334
- content += `### ${capitalizeFirstLetter(type)}
1335
-
1336
- `;
1337
- for (const entry of entries) {
1338
- let entryText = `- ${entry.description}`;
1339
- if (entry.issueIds && entry.issueIds.length > 0) {
1340
- entryText += ` (${entry.issueIds.join(", ")})`;
1341
- }
1342
- content += `${entryText}.
1343
- `;
1344
- }
1345
- content += "\n";
1346
- }
1347
- }
1348
- for (const version of changelog.versions) {
1349
- content += `## [${version.version}] - ${version.date}
1350
-
1351
- `;
1352
- const grouped = version.entries.reduce(
1353
- (acc, entry) => {
1354
- if (!acc[entry.type]) {
1355
- acc[entry.type] = [];
1356
- }
1357
- acc[entry.type].push(entry);
1358
- return acc;
1359
- },
1360
- {}
1361
- );
1362
- for (const [type, entries] of Object.entries(grouped)) {
1363
- content += `### ${capitalizeFirstLetter(type)}
1364
-
1365
- `;
1366
- for (const entry of entries) {
1367
- let entryText = `- ${entry.description}`;
1368
- if (entry.issueIds && entry.issueIds.length > 0) {
1369
- entryText += ` (${entry.issueIds.join(", ")})`;
1370
- }
1371
- content += `${entryText}.
1372
- `;
1373
- }
1374
- content += "\n";
1375
- }
1376
- }
1377
- content += generateLinks(changelog, repoUrl);
1378
- return content;
1379
- }
1380
- function updateChangelog(packagePath, packageName, version, entries, repoUrl, format = "keep-a-changelog") {
1381
- try {
1382
- const changelogPath = path4.join(packagePath, "CHANGELOG.md");
1383
- let changelog;
1384
- if (fs5.existsSync(changelogPath)) {
1385
- const existingChangelog = parseChangelog(changelogPath);
1386
- if (existingChangelog) {
1387
- changelog = existingChangelog;
1388
- } else {
1389
- changelog = createChangelog(packagePath, packageName);
1390
- }
1391
- } else {
1392
- changelog = createChangelog(packagePath, packageName);
1393
- }
1394
- if (version) {
1395
- const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
1396
- const newVersion = {
1397
- version,
1398
- date: today,
1399
- entries: [...changelog.unreleased, ...entries]
1400
- };
1401
- changelog.unreleased = [];
1402
- changelog.versions.unshift(newVersion);
1403
- } else {
1404
- changelog.unreleased = [...changelog.unreleased, ...entries];
1405
- }
1406
- const content = generateChangelogContent(changelog, repoUrl, format);
1407
- fs5.writeFileSync(changelogPath, content);
1408
- log(`Updated changelog at ${changelogPath}`, "success");
1409
- } catch (error) {
1410
- log(
1411
- `Error updating changelog: ${error instanceof Error ? error.message : String(error)}`,
1412
- "error"
1413
- );
1414
- }
1415
- }
1416
- function capitalizeFirstLetter(input) {
1417
- return input.charAt(0).toUpperCase() + input.slice(1);
1418
- }
1419
-
1420
1292
  // src/core/versionCalculator.ts
1421
1293
  import { cwd as cwd3 } from "process";
1422
1294
  import { Bumper } from "conventional-recommended-bump";
@@ -1424,10 +1296,10 @@ import semver3 from "semver";
1424
1296
 
1425
1297
  // src/utils/manifestHelpers.ts
1426
1298
  import fs6 from "fs";
1427
- import path5 from "path";
1299
+ import path6 from "path";
1428
1300
  function getVersionFromManifests(packageDir) {
1429
- const packageJsonPath = path5.join(packageDir, "package.json");
1430
- const cargoTomlPath = path5.join(packageDir, "Cargo.toml");
1301
+ const packageJsonPath = path6.join(packageDir, "package.json");
1302
+ const cargoTomlPath = path6.join(packageDir, "Cargo.toml");
1431
1303
  if (fs6.existsSync(packageJsonPath)) {
1432
1304
  try {
1433
1305
  const packageJson = JSON.parse(fs6.readFileSync(packageJsonPath, "utf-8"));
@@ -1472,8 +1344,8 @@ function getVersionFromManifests(packageDir) {
1472
1344
  };
1473
1345
  }
1474
1346
  function throwIfNoManifestsFound(packageDir) {
1475
- const packageJsonPath = path5.join(packageDir, "package.json");
1476
- const cargoTomlPath = path5.join(packageDir, "Cargo.toml");
1347
+ const packageJsonPath = path6.join(packageDir, "package.json");
1348
+ const cargoTomlPath = path6.join(packageDir, "Cargo.toml");
1477
1349
  throw new Error(
1478
1350
  `Neither package.json nor Cargo.toml found at ${packageDir}. Checked paths: ${packageJsonPath}, ${cargoTomlPath}. Cannot determine version.`
1479
1351
  );
@@ -1665,7 +1537,7 @@ To fix this mismatch:
1665
1537
  const bumper = new Bumper();
1666
1538
  bumper.loadPreset(preset);
1667
1539
  const recommendedBump = await bumper.bump();
1668
- const releaseTypeFromCommits = recommendedBump == null ? void 0 : recommendedBump.releaseType;
1540
+ const releaseTypeFromCommits = recommendedBump && "releaseType" in recommendedBump ? recommendedBump.releaseType : void 0;
1669
1541
  if (hasNoTags) {
1670
1542
  if (releaseTypeFromCommits) {
1671
1543
  return getPackageVersionFallback(
@@ -1751,36 +1623,44 @@ function calculateNextVersion(version, manifestType, name, releaseType, prerelea
1751
1623
  }
1752
1624
 
1753
1625
  // src/utils/packageMatching.ts
1626
+ import micromatch2 from "micromatch";
1754
1627
  function matchesPackageTarget(packageName, target) {
1755
1628
  if (packageName === target) {
1756
1629
  return true;
1757
1630
  }
1758
- if (target.endsWith("/*")) {
1631
+ if (target.startsWith("@") && target.endsWith("/*") && !target.includes("**")) {
1759
1632
  const scope = target.slice(0, -2);
1760
- if (scope.startsWith("@")) {
1761
- return packageName.startsWith(`${scope}/`);
1762
- }
1763
1633
  return packageName.startsWith(`${scope}/`);
1764
1634
  }
1765
- if (target === "*") {
1766
- return true;
1767
- }
1768
- return false;
1769
- }
1770
- function shouldProcessPackage(packageName, targets = [], skip = []) {
1771
- if (skip.includes(packageName)) {
1635
+ try {
1636
+ return micromatch2.isMatch(packageName, target, {
1637
+ dot: true,
1638
+ contains: false,
1639
+ // Changed to false to ensure full pattern matching
1640
+ noglobstar: false,
1641
+ bash: true
1642
+ });
1643
+ } catch (error) {
1644
+ log(
1645
+ `Invalid pattern "${target}": ${error instanceof Error ? error.message : String(error)}`,
1646
+ "warning"
1647
+ );
1772
1648
  return false;
1773
1649
  }
1774
- if (targets.length === 0) {
1650
+ }
1651
+ function shouldMatchPackageTargets(packageName, targets) {
1652
+ return targets.some((target) => matchesPackageTarget(packageName, target));
1653
+ }
1654
+ function shouldProcessPackage(packageName, skip = []) {
1655
+ if (skip.length === 0) {
1775
1656
  return true;
1776
1657
  }
1777
- return targets.some((target) => matchesPackageTarget(packageName, target));
1658
+ return !shouldMatchPackageTargets(packageName, skip);
1778
1659
  }
1779
1660
 
1780
1661
  // src/package/packageProcessor.ts
1781
1662
  var PackageProcessor = class {
1782
1663
  skip;
1783
- targets;
1784
1664
  versionPrefix;
1785
1665
  tagTemplate;
1786
1666
  commitMessageTemplate;
@@ -1792,7 +1672,6 @@ var PackageProcessor = class {
1792
1672
  fullConfig;
1793
1673
  constructor(options) {
1794
1674
  this.skip = options.skip || [];
1795
- this.targets = options.targets || [];
1796
1675
  this.versionPrefix = options.versionPrefix || "v";
1797
1676
  this.tagTemplate = options.tagTemplate;
1798
1677
  this.commitMessageTemplate = options.commitMessageTemplate || "";
@@ -1803,13 +1682,7 @@ var PackageProcessor = class {
1803
1682
  this.fullConfig = options.fullConfig;
1804
1683
  }
1805
1684
  /**
1806
- * Set package targets to process
1807
- */
1808
- setTargets(targets) {
1809
- this.targets = targets;
1810
- }
1811
- /**
1812
- * Process packages based on targeting criteria
1685
+ * Process packages based on skip list only (targeting handled at discovery time)
1813
1686
  */
1814
1687
  async processPackages(packages) {
1815
1688
  var _a, _b, _c, _d, _e;
@@ -1820,21 +1693,16 @@ var PackageProcessor = class {
1820
1693
  return { updatedPackages: [], tags: [] };
1821
1694
  }
1822
1695
  const pkgsToConsider = packages.filter((pkg) => {
1823
- var _a2;
1824
1696
  const pkgName = pkg.packageJson.name;
1825
- const shouldProcess = shouldProcessPackage(pkgName, this.targets, this.skip);
1697
+ const shouldProcess = shouldProcessPackage(pkgName, this.skip);
1826
1698
  if (!shouldProcess) {
1827
- if ((_a2 = this.skip) == null ? void 0 : _a2.includes(pkgName)) {
1828
- log(`Skipping package ${pkgName} as it's in the skip list.`, "info");
1829
- } else {
1830
- log(`Package ${pkgName} not in target list, skipping.`, "info");
1831
- }
1699
+ log(`Skipping package ${pkgName} as it's in the skip list.`, "info");
1832
1700
  }
1833
1701
  return shouldProcess;
1834
1702
  });
1835
- log(`Found ${pkgsToConsider.length} targeted package(s) to process after filtering.`, "info");
1703
+ log(`Found ${pkgsToConsider.length} package(s) to process after filtering.`, "info");
1836
1704
  if (pkgsToConsider.length === 0) {
1837
- log("No matching targeted packages found to process.", "info");
1705
+ log("No packages found to process.", "info");
1838
1706
  return { updatedPackages: [], tags: [] };
1839
1707
  }
1840
1708
  for (const pkg of pkgsToConsider) {
@@ -1900,22 +1768,20 @@ var PackageProcessor = class {
1900
1768
  if (this.fullConfig.updateChangelog !== false) {
1901
1769
  let changelogEntries = [];
1902
1770
  try {
1903
- let revisionRange = latestTag;
1771
+ let revisionRange;
1904
1772
  if (latestTag) {
1905
1773
  try {
1906
1774
  execSync4(`git rev-parse --verify "${latestTag}"`, {
1907
1775
  cwd: pkgPath,
1908
1776
  stdio: "ignore"
1909
1777
  });
1778
+ revisionRange = `${latestTag}..HEAD`;
1910
1779
  } catch {
1911
- log(
1912
- `Tag ${latestTag} doesn't exist, using recent commits from HEAD for changelog`,
1913
- "debug"
1914
- );
1915
- revisionRange = "HEAD~10..HEAD";
1780
+ log(`Tag ${latestTag} doesn't exist, using all commits for changelog`, "debug");
1781
+ revisionRange = "HEAD";
1916
1782
  }
1917
1783
  } else {
1918
- revisionRange = "HEAD~10..HEAD";
1784
+ revisionRange = "HEAD";
1919
1785
  }
1920
1786
  changelogEntries = extractChangelogEntriesFromCommits(pkgPath, revisionRange);
1921
1787
  if (changelogEntries.length === 0) {
@@ -1940,7 +1806,7 @@ var PackageProcessor = class {
1940
1806
  }
1941
1807
  let repoUrl;
1942
1808
  try {
1943
- const packageJsonPath2 = path6.join(pkgPath, "package.json");
1809
+ const packageJsonPath2 = path7.join(pkgPath, "package.json");
1944
1810
  if (fs8.existsSync(packageJsonPath2)) {
1945
1811
  const packageJson = JSON.parse(fs8.readFileSync(packageJsonPath2, "utf8"));
1946
1812
  if (packageJson.repository) {
@@ -1969,7 +1835,7 @@ var PackageProcessor = class {
1969
1835
  this.fullConfig.changelogFormat
1970
1836
  );
1971
1837
  }
1972
- const packageJsonPath = path6.join(pkgPath, "package.json");
1838
+ const packageJsonPath = path7.join(pkgPath, "package.json");
1973
1839
  if (fs8.existsSync(packageJsonPath)) {
1974
1840
  updatePackageVersion(packageJsonPath, nextVersion);
1975
1841
  }
@@ -1978,13 +1844,13 @@ var PackageProcessor = class {
1978
1844
  const cargoPaths = (_b = this.fullConfig.cargo) == null ? void 0 : _b.paths;
1979
1845
  if (cargoPaths && cargoPaths.length > 0) {
1980
1846
  for (const cargoPath of cargoPaths) {
1981
- const resolvedCargoPath = path6.resolve(pkgPath, cargoPath, "Cargo.toml");
1847
+ const resolvedCargoPath = path7.resolve(pkgPath, cargoPath, "Cargo.toml");
1982
1848
  if (fs8.existsSync(resolvedCargoPath)) {
1983
1849
  updatePackageVersion(resolvedCargoPath, nextVersion);
1984
1850
  }
1985
1851
  }
1986
1852
  } else {
1987
- const cargoTomlPath = path6.join(pkgPath, "Cargo.toml");
1853
+ const cargoTomlPath = path7.join(pkgPath, "Cargo.toml");
1988
1854
  if (fs8.existsSync(cargoTomlPath)) {
1989
1855
  updatePackageVersion(cargoTomlPath, nextVersion);
1990
1856
  }
@@ -2017,12 +1883,12 @@ var PackageProcessor = class {
2017
1883
  updatedPackagesInfo.push({ name, version: nextVersion, path: pkgPath });
2018
1884
  }
2019
1885
  if (updatedPackagesInfo.length === 0) {
2020
- log("No targeted packages required a version update.", "info");
1886
+ log("No packages required a version update.", "info");
2021
1887
  return { updatedPackages: [], tags };
2022
1888
  }
2023
1889
  const filesToCommit = [];
2024
1890
  for (const info of updatedPackagesInfo) {
2025
- const packageJsonPath = path6.join(info.path, "package.json");
1891
+ const packageJsonPath = path7.join(info.path, "package.json");
2026
1892
  if (fs8.existsSync(packageJsonPath)) {
2027
1893
  filesToCommit.push(packageJsonPath);
2028
1894
  }
@@ -2031,13 +1897,13 @@ var PackageProcessor = class {
2031
1897
  const cargoPaths = (_d = this.fullConfig.cargo) == null ? void 0 : _d.paths;
2032
1898
  if (cargoPaths && cargoPaths.length > 0) {
2033
1899
  for (const cargoPath of cargoPaths) {
2034
- const resolvedCargoPath = path6.resolve(info.path, cargoPath, "Cargo.toml");
1900
+ const resolvedCargoPath = path7.resolve(info.path, cargoPath, "Cargo.toml");
2035
1901
  if (fs8.existsSync(resolvedCargoPath)) {
2036
1902
  filesToCommit.push(resolvedCargoPath);
2037
1903
  }
2038
1904
  }
2039
1905
  } else {
2040
- const cargoTomlPath = path6.join(info.path, "Cargo.toml");
1906
+ const cargoTomlPath = path7.join(info.path, "Cargo.toml");
2041
1907
  if (fs8.existsSync(cargoTomlPath)) {
2042
1908
  filesToCommit.push(cargoTomlPath);
2043
1909
  }
@@ -2081,9 +1947,9 @@ var PackageProcessor = class {
2081
1947
  };
2082
1948
 
2083
1949
  // src/core/versionStrategies.ts
2084
- function shouldProcessPackage2(pkg, config, targets = []) {
1950
+ function shouldProcessPackage2(pkg, config) {
2085
1951
  const pkgName = pkg.packageJson.name;
2086
- return shouldProcessPackage(pkgName, targets, config.skip);
1952
+ return shouldProcessPackage(pkgName, config.skip);
2087
1953
  }
2088
1954
  function createSyncedStrategy(config) {
2089
1955
  return async (packages) => {
@@ -2134,7 +2000,8 @@ function createSyncedStrategy(config) {
2134
2000
  type: config.type
2135
2001
  });
2136
2002
  if (!nextVersion) {
2137
- log("No version change needed", "info");
2003
+ const msg = mainPkgName ? `No version change needed for ${mainPkgName}` : "No version change needed";
2004
+ log(msg, "info");
2138
2005
  return;
2139
2006
  }
2140
2007
  const files = [];
@@ -2142,7 +2009,7 @@ function createSyncedStrategy(config) {
2142
2009
  const processedPaths = /* @__PURE__ */ new Set();
2143
2010
  try {
2144
2011
  if (packages.root) {
2145
- const rootPkgPath = path7.join(packages.root, "package.json");
2012
+ const rootPkgPath = path8.join(packages.root, "package.json");
2146
2013
  if (fs9.existsSync(rootPkgPath)) {
2147
2014
  updatePackageVersion(rootPkgPath, nextVersion);
2148
2015
  files.push(rootPkgPath);
@@ -2160,7 +2027,7 @@ function createSyncedStrategy(config) {
2160
2027
  if (!shouldProcessPackage2(pkg, config)) {
2161
2028
  continue;
2162
2029
  }
2163
- const packageJsonPath = path7.join(pkg.dir, "package.json");
2030
+ const packageJsonPath = path8.join(pkg.dir, "package.json");
2164
2031
  if (processedPaths.has(packageJsonPath)) {
2165
2032
  continue;
2166
2033
  }
@@ -2176,7 +2043,7 @@ function createSyncedStrategy(config) {
2176
2043
  return;
2177
2044
  }
2178
2045
  let tagPackageName = null;
2179
- let commitPackageName = void 0;
2046
+ let commitPackageName;
2180
2047
  if (config.packageSpecificTags && packages.packages.length === 1) {
2181
2048
  tagPackageName = packages.packages[0].packageJson.name;
2182
2049
  commitPackageName = packages.packages[0].packageJson.name;
@@ -2210,7 +2077,6 @@ function createSingleStrategy(config) {
2210
2077
  return async (packages) => {
2211
2078
  try {
2212
2079
  const {
2213
- packages: configPackages,
2214
2080
  mainPackage,
2215
2081
  versionPrefix,
2216
2082
  tagTemplate,
@@ -2221,12 +2087,12 @@ function createSingleStrategy(config) {
2221
2087
  let packageName;
2222
2088
  if (mainPackage) {
2223
2089
  packageName = mainPackage;
2224
- } else if (configPackages && configPackages.length === 1) {
2225
- packageName = configPackages[0];
2090
+ } else if (packages.packages.length === 1) {
2091
+ packageName = packages.packages[0].packageJson.name;
2226
2092
  } else {
2227
2093
  throw createVersionError(
2228
2094
  "INVALID_CONFIG" /* INVALID_CONFIG */,
2229
- "Single mode requires either mainPackage or exactly one package in the packages array"
2095
+ "Single mode requires either mainPackage or exactly one resolved package"
2230
2096
  );
2231
2097
  }
2232
2098
  const pkg = packages.packages.find((p) => p.packageJson.name === packageName);
@@ -2244,50 +2110,114 @@ function createSingleStrategy(config) {
2244
2110
  latestTagResult = globalTagResult || "";
2245
2111
  }
2246
2112
  const latestTag = latestTagResult;
2247
- let nextVersion = void 0;
2248
- try {
2249
- nextVersion = await calculateVersion(config, {
2250
- latestTag,
2251
- versionPrefix: formattedPrefix,
2252
- path: pkgPath,
2253
- name: packageName,
2254
- type: config.type
2255
- });
2256
- } catch (error) {
2257
- const errorMessage = error instanceof Error ? error.message : String(error);
2258
- throw createVersionError("VERSION_CALCULATION_ERROR" /* VERSION_CALCULATION_ERROR */, errorMessage);
2259
- }
2260
- if (nextVersion === void 0 || nextVersion === "") {
2113
+ let nextVersion;
2114
+ nextVersion = await calculateVersion(config, {
2115
+ latestTag,
2116
+ versionPrefix: formattedPrefix,
2117
+ branchPattern: config.branchPattern,
2118
+ baseBranch: config.baseBranch,
2119
+ prereleaseIdentifier: config.prereleaseIdentifier,
2120
+ path: pkgPath,
2121
+ name: packageName,
2122
+ type: config.type
2123
+ });
2124
+ if (!nextVersion) {
2261
2125
  log(`No version change needed for ${packageName}`, "info");
2262
2126
  return;
2263
2127
  }
2264
- const packageJsonPath = path7.join(pkgPath, "package.json");
2128
+ if (config.updateChangelog !== false) {
2129
+ let changelogEntries = [];
2130
+ try {
2131
+ let revisionRange;
2132
+ if (latestTag) {
2133
+ try {
2134
+ execSync5(`git rev-parse --verify "${latestTag}"`, {
2135
+ cwd: pkgPath,
2136
+ stdio: "ignore"
2137
+ });
2138
+ revisionRange = `${latestTag}..HEAD`;
2139
+ } catch {
2140
+ log(`Tag ${latestTag} doesn't exist, using all commits for changelog`, "debug");
2141
+ revisionRange = "HEAD";
2142
+ }
2143
+ } else {
2144
+ revisionRange = "HEAD";
2145
+ }
2146
+ changelogEntries = extractChangelogEntriesFromCommits(pkgPath, revisionRange);
2147
+ if (changelogEntries.length === 0) {
2148
+ changelogEntries = [
2149
+ {
2150
+ type: "changed",
2151
+ description: `Update version to ${nextVersion}`
2152
+ }
2153
+ ];
2154
+ }
2155
+ } catch (error) {
2156
+ log(
2157
+ `Error extracting changelog entries: ${error instanceof Error ? error.message : String(error)}`,
2158
+ "warning"
2159
+ );
2160
+ changelogEntries = [
2161
+ {
2162
+ type: "changed",
2163
+ description: `Update version to ${nextVersion}`
2164
+ }
2165
+ ];
2166
+ }
2167
+ let repoUrl;
2168
+ try {
2169
+ const packageJsonPath2 = path8.join(pkgPath, "package.json");
2170
+ if (fs9.existsSync(packageJsonPath2)) {
2171
+ const packageJson = JSON.parse(fs9.readFileSync(packageJsonPath2, "utf8"));
2172
+ if (packageJson.repository) {
2173
+ if (typeof packageJson.repository === "string") {
2174
+ repoUrl = packageJson.repository;
2175
+ } else if (packageJson.repository.url) {
2176
+ repoUrl = packageJson.repository.url;
2177
+ }
2178
+ if ((repoUrl == null ? void 0 : repoUrl.startsWith("git+")) && (repoUrl == null ? void 0 : repoUrl.endsWith(".git"))) {
2179
+ repoUrl = repoUrl.substring(4, repoUrl.length - 4);
2180
+ }
2181
+ }
2182
+ }
2183
+ } catch (error) {
2184
+ log(
2185
+ `Could not determine repository URL for changelog links: ${error instanceof Error ? error.message : String(error)}`,
2186
+ "warning"
2187
+ );
2188
+ }
2189
+ updateChangelog(
2190
+ pkgPath,
2191
+ packageName,
2192
+ nextVersion,
2193
+ changelogEntries,
2194
+ repoUrl,
2195
+ config.changelogFormat
2196
+ );
2197
+ }
2198
+ const packageJsonPath = path8.join(pkgPath, "package.json");
2265
2199
  updatePackageVersion(packageJsonPath, nextVersion);
2266
2200
  log(`Updated package ${packageName} to version ${nextVersion}`, "success");
2267
- const nextTag = formatTag(
2201
+ const tagName = formatTag(
2268
2202
  nextVersion,
2269
2203
  formattedPrefix,
2270
2204
  packageName,
2271
2205
  tagTemplate,
2272
2206
  config.packageSpecificTags
2273
2207
  );
2274
- const formattedCommitMessage = formatCommitMessage(commitMessage, nextVersion, packageName);
2275
- await createGitCommitAndTag(
2276
- [packageJsonPath],
2277
- nextTag,
2278
- formattedCommitMessage,
2279
- skipHooks,
2280
- dryRun
2281
- );
2208
+ const commitMsg = formatCommitMessage(commitMessage, nextVersion, packageName);
2209
+ if (!dryRun) {
2210
+ await createGitCommitAndTag([packageJsonPath], tagName, commitMsg, skipHooks, dryRun);
2211
+ log(`Created tag: ${tagName}`, "success");
2212
+ } else {
2213
+ log(`Would create tag: ${tagName}`, "info");
2214
+ }
2282
2215
  } catch (error) {
2283
2216
  if (error instanceof VersionError || error instanceof GitError) {
2284
- log(
2285
- `Single Package Strategy failed: ${error.message} (${error.code || "UNKNOWN"})`,
2286
- "error"
2287
- );
2217
+ log(`Single Strategy failed: ${error.message} (${error.code || "UNKNOWN"})`, "error");
2288
2218
  } else {
2289
2219
  const errorMessage = error instanceof Error ? error.message : String(error);
2290
- log(`Single Package Strategy failed: ${errorMessage}`, "error");
2220
+ log(`Single Strategy failed: ${errorMessage}`, "error");
2291
2221
  }
2292
2222
  throw error;
2293
2223
  }
@@ -2299,7 +2229,6 @@ function createAsyncStrategy(config) {
2299
2229
  };
2300
2230
  const processorOptions = {
2301
2231
  skip: config.skip || [],
2302
- targets: config.packages || [],
2303
2232
  versionPrefix: config.versionPrefix || "v",
2304
2233
  tagTemplate: config.tagTemplate,
2305
2234
  commitMessageTemplate: config.commitMessage || "",
@@ -2316,15 +2245,9 @@ function createAsyncStrategy(config) {
2316
2245
  }
2317
2246
  };
2318
2247
  const packageProcessor = new PackageProcessor(processorOptions);
2319
- return async (packages, targets = []) => {
2248
+ return async (packages, _targets = []) => {
2320
2249
  try {
2321
- const targetPackages = targets.length > 0 ? targets : config.packages || [];
2322
- packageProcessor.setTargets(targetPackages);
2323
- if (targetPackages.length > 0) {
2324
- log(`Processing targeted packages: ${targetPackages.join(", ")}`, "info");
2325
- } else {
2326
- log("No targets specified, processing all non-skipped packages", "info");
2327
- }
2250
+ log(`Processing ${packages.packages.length} pre-filtered packages`, "info");
2328
2251
  const result = await packageProcessor.processPackages(packages.packages);
2329
2252
  if (result.updatedPackages.length === 0) {
2330
2253
  log("No packages required a version update.", "info");
@@ -2350,13 +2273,9 @@ function createAsyncStrategy(config) {
2350
2273
  };
2351
2274
  }
2352
2275
  function createStrategy(config) {
2353
- var _a;
2354
2276
  if (config.synced) {
2355
2277
  return createSyncedStrategy(config);
2356
2278
  }
2357
- if (config.mainPackage || ((_a = config.packages) == null ? void 0 : _a.length) === 1) {
2358
- return createSingleStrategy(config);
2359
- }
2360
2279
  return createAsyncStrategy(config);
2361
2280
  }
2362
2281
  function createStrategyMap(config) {
@@ -2406,6 +2325,22 @@ var VersionEngine = class {
2406
2325
  );
2407
2326
  pkgsResult.root = cwd4();
2408
2327
  }
2328
+ if (this.config.packages && this.config.packages.length > 0) {
2329
+ const originalCount = pkgsResult.packages.length;
2330
+ const filteredPackages = filterPackagesByConfig(
2331
+ pkgsResult.packages,
2332
+ this.config.packages,
2333
+ pkgsResult.root
2334
+ );
2335
+ pkgsResult.packages = filteredPackages;
2336
+ log(
2337
+ `Filtered ${originalCount} workspace packages to ${filteredPackages.length} based on packages config`,
2338
+ "info"
2339
+ );
2340
+ if (filteredPackages.length === 0) {
2341
+ log("Warning: No packages matched the specified patterns in config.packages", "warning");
2342
+ }
2343
+ }
2409
2344
  this.workspaceCache = pkgsResult;
2410
2345
  return pkgsResult;
2411
2346
  } catch (error) {
@@ -2417,11 +2352,11 @@ var VersionEngine = class {
2417
2352
  }
2418
2353
  /**
2419
2354
  * Run the current strategy
2355
+ * @param packages Workspace packages to process
2420
2356
  * @param targets Optional package targets to process (only used by async strategy)
2421
2357
  */
2422
- async run(targets = []) {
2358
+ async run(packages, targets = []) {
2423
2359
  try {
2424
- const packages = await this.getWorkspacePackages();
2425
2360
  return this.currentStrategy(packages, targets);
2426
2361
  } catch (error) {
2427
2362
  if (error instanceof VersionError || error instanceof GitError) {
@@ -2458,8 +2393,8 @@ var VersionEngine = class {
2458
2393
  // src/index.ts
2459
2394
  function getPackageVersion() {
2460
2395
  try {
2461
- const packageJsonPath = path8.resolve(
2462
- path8.dirname(import.meta.url.replace("file:", "")),
2396
+ const packageJsonPath = path9.resolve(
2397
+ path9.dirname(import.meta.url.replace("file:", "")),
2463
2398
  "../package.json"
2464
2399
  );
2465
2400
  const packageJsonContent = fs10.readFileSync(packageJsonPath, "utf-8");
@@ -2496,24 +2431,31 @@ async function run() {
2496
2431
  config.prereleaseIdentifier = options.prerelease === true ? "next" : options.prerelease;
2497
2432
  const cliTargets = options.target ? options.target.split(",").map((t) => t.trim()) : [];
2498
2433
  const engine = new VersionEngine(config, !!options.json);
2434
+ const pkgsResult = await engine.getWorkspacePackages();
2435
+ const resolvedCount = pkgsResult.packages.length;
2436
+ log(`Resolved ${resolvedCount} packages from workspace`, "debug");
2437
+ log(`Config packages: ${JSON.stringify(config.packages)}`, "debug");
2438
+ log(`Config synced: ${config.synced}`, "debug");
2499
2439
  if (config.synced) {
2500
2440
  log("Using synced versioning strategy.", "info");
2501
2441
  engine.setStrategy("synced");
2502
- await engine.run();
2503
- } else if (config.packages && config.packages.length === 1) {
2442
+ await engine.run(pkgsResult);
2443
+ } else if (resolvedCount === 1) {
2504
2444
  log("Using single package versioning strategy.", "info");
2505
2445
  if (cliTargets.length > 0) {
2506
2446
  log("--target flag is ignored for single package strategy.", "warning");
2507
2447
  }
2508
2448
  engine.setStrategy("single");
2509
- await engine.run();
2449
+ await engine.run(pkgsResult);
2450
+ } else if (resolvedCount === 0) {
2451
+ throw new Error("No packages found in workspace");
2510
2452
  } else {
2511
2453
  log("Using async versioning strategy.", "info");
2512
2454
  if (cliTargets.length > 0) {
2513
2455
  log(`Targeting specific packages: ${cliTargets.join(", ")}`, "info");
2514
2456
  }
2515
2457
  engine.setStrategy("async");
2516
- await engine.run(cliTargets);
2458
+ await engine.run(pkgsResult, cliTargets);
2517
2459
  }
2518
2460
  log("Versioning process completed.", "success");
2519
2461
  printJsonOutput();
@@ -2532,38 +2474,43 @@ async function run() {
2532
2474
  process.exit(1);
2533
2475
  }
2534
2476
  });
2535
- program.command("regenerate-changelog").description("Regenerate a complete changelog from git history").option("-o, --output <path>", "Output path for changelog file", "CHANGELOG.md").option(
2477
+ 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(
2536
2478
  "-f, --format <format>",
2537
2479
  "Changelog format (keep-a-changelog|angular)",
2538
2480
  "keep-a-changelog"
2539
2481
  ).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) => {
2540
- try {
2541
- log("Regenerating changelog from git history...", "info");
2542
- if (options.format !== "keep-a-changelog" && options.format !== "angular") {
2543
- throw new Error(
2544
- 'Invalid format specified. Must be either "keep-a-changelog" or "angular"'
2482
+ var _a;
2483
+ if (options.regenerate) {
2484
+ try {
2485
+ log("Regenerating changelog from git history...", "info");
2486
+ if (options.format !== "keep-a-changelog" && options.format !== "angular") {
2487
+ throw new Error(
2488
+ 'Invalid format specified. Must be either "keep-a-changelog" or "angular"'
2489
+ );
2490
+ }
2491
+ const regenerateOptions = {
2492
+ format: options.format,
2493
+ since: options.since,
2494
+ output: options.output,
2495
+ dryRun: options.dryRun,
2496
+ projectDir: options.projectDir,
2497
+ repoUrl: options.repoUrl
2498
+ };
2499
+ const content = await regenerateChangelog(regenerateOptions);
2500
+ await writeChangelog(
2501
+ content,
2502
+ path9.resolve(options.projectDir, options.output),
2503
+ options.dryRun
2545
2504
  );
2505
+ if (!options.dryRun) {
2506
+ log(`Changelog successfully regenerated at ${options.output}`, "success");
2507
+ }
2508
+ } catch (error) {
2509
+ log(error instanceof Error ? error.message : String(error), "error");
2510
+ process.exit(1);
2546
2511
  }
2547
- const regenerateOptions = {
2548
- format: options.format,
2549
- since: options.since,
2550
- output: options.output,
2551
- dryRun: options.dryRun,
2552
- projectDir: options.projectDir,
2553
- repoUrl: options.repoUrl
2554
- };
2555
- const content = await regenerateChangelog(regenerateOptions);
2556
- await writeChangelog(
2557
- content,
2558
- path8.resolve(options.projectDir, options.output),
2559
- options.dryRun
2560
- );
2561
- if (!options.dryRun) {
2562
- log(`Changelog successfully regenerated at ${options.output}`, "success");
2563
- }
2564
- } catch (error) {
2565
- log(error instanceof Error ? error.message : String(error), "error");
2566
- process.exit(1);
2512
+ } else {
2513
+ (_a = program.commands.find((cmd) => cmd.name() === "changelog")) == null ? void 0 : _a.help();
2567
2514
  }
2568
2515
  });
2569
2516
  program.parse(process.argv);