package-versioner 0.8.2 → 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,33 +649,163 @@ function createVersionError(code, details) {
606
649
  return new VersionError(fullMessage, code);
607
650
  }
608
651
 
609
- // src/utils/packageMatching.ts
610
- function matchesPackageTarget(packageName, target) {
611
- if (packageName === target) {
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) {
612
706
  return true;
613
707
  }
614
- if (target.endsWith("/*")) {
615
- const scope = target.slice(0, -2);
616
- if (scope.startsWith("@")) {
617
- return packageName.startsWith(`${scope}/`);
618
- }
708
+ if (pattern.startsWith("@") && pattern.endsWith("/*") && !pattern.includes("**")) {
709
+ const scope = pattern.slice(0, -2);
619
710
  return packageName.startsWith(`${scope}/`);
620
711
  }
621
- if (target === "*") {
622
- return true;
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;
623
725
  }
624
- return false;
625
- }
626
- function shouldMatchPackageTargets(packageName, targets) {
627
- return targets.some((target) => matchesPackageTarget(packageName, target));
628
- }
629
- function shouldProcessPackage(packageName, skip = []) {
630
- return !skip.includes(packageName);
631
726
  }
632
727
 
633
728
  // src/core/versionStrategies.ts
729
+ import { execSync as execSync5 } from "child_process";
634
730
  import fs9 from "fs";
635
- 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
+ }
636
809
 
637
810
  // src/git/commands.ts
638
811
  import { cwd as cwd2 } from "process";
@@ -658,11 +831,11 @@ var execAsync = (command, options) => {
658
831
  var execSync3 = (command, args) => nativeExecSync(command, { maxBuffer: 1024 * 1024 * 10, ...args });
659
832
 
660
833
  // src/git/repository.ts
661
- import { existsSync, statSync } from "fs";
662
- import { join } from "path";
834
+ import { existsSync as existsSync2, statSync } from "fs";
835
+ import { join as join2 } from "path";
663
836
  function isGitRepository(directory) {
664
- const gitDir = join(directory, ".git");
665
- if (!existsSync(gitDir)) {
837
+ const gitDir = join2(directory, ".git");
838
+ if (!existsSync2(gitDir)) {
666
839
  return false;
667
840
  }
668
841
  const stats = statSync(gitDir);
@@ -1020,21 +1193,21 @@ async function getLatestTagForPackage(packageName, versionPrefix, options) {
1020
1193
  }
1021
1194
 
1022
1195
  // src/package/packageManagement.ts
1023
- import fs4 from "fs";
1024
- import path3 from "path";
1196
+ import fs5 from "fs";
1197
+ import path5 from "path";
1025
1198
 
1026
1199
  // src/cargo/cargoHandler.ts
1027
- import fs3 from "fs";
1028
- import path2 from "path";
1200
+ import fs4 from "fs";
1201
+ import path4 from "path";
1029
1202
  import * as TOML from "smol-toml";
1030
1203
  function getCargoInfo(cargoPath) {
1031
1204
  var _a;
1032
- if (!fs3.existsSync(cargoPath)) {
1205
+ if (!fs4.existsSync(cargoPath)) {
1033
1206
  log(`Cargo.toml file not found at: ${cargoPath}`, "error");
1034
1207
  throw new Error(`Cargo.toml file not found at: ${cargoPath}`);
1035
1208
  }
1036
1209
  try {
1037
- const fileContent = fs3.readFileSync(cargoPath, "utf8");
1210
+ const fileContent = fs4.readFileSync(cargoPath, "utf8");
1038
1211
  const cargo = TOML.parse(fileContent);
1039
1212
  if (!((_a = cargo.package) == null ? void 0 : _a.name)) {
1040
1213
  log(`Package name not found in: ${cargoPath}`, "error");
@@ -1044,7 +1217,7 @@ function getCargoInfo(cargoPath) {
1044
1217
  name: cargo.package.name,
1045
1218
  version: cargo.package.version || "0.0.0",
1046
1219
  path: cargoPath,
1047
- dir: path2.dirname(cargoPath),
1220
+ dir: path4.dirname(cargoPath),
1048
1221
  content: cargo
1049
1222
  };
1050
1223
  } catch (error) {
@@ -1057,12 +1230,12 @@ function getCargoInfo(cargoPath) {
1057
1230
  }
1058
1231
  }
1059
1232
  function isCargoToml(filePath) {
1060
- return path2.basename(filePath) === "Cargo.toml";
1233
+ return path4.basename(filePath) === "Cargo.toml";
1061
1234
  }
1062
1235
  function updateCargoVersion(cargoPath, version) {
1063
1236
  var _a;
1064
1237
  try {
1065
- const originalContent = fs3.readFileSync(cargoPath, "utf8");
1238
+ const originalContent = fs4.readFileSync(cargoPath, "utf8");
1066
1239
  const cargo = TOML.parse(originalContent);
1067
1240
  const packageName = (_a = cargo.package) == null ? void 0 : _a.name;
1068
1241
  if (!packageName) {
@@ -1074,7 +1247,7 @@ function updateCargoVersion(cargoPath, version) {
1074
1247
  cargo.package.version = version;
1075
1248
  }
1076
1249
  const updatedContent = TOML.stringify(cargo);
1077
- fs3.writeFileSync(cargoPath, updatedContent);
1250
+ fs4.writeFileSync(cargoPath, updatedContent);
1078
1251
  addPackageUpdate(packageName, version, cargoPath);
1079
1252
  log(`Updated Cargo.toml at ${cargoPath} to version ${version}`, "success");
1080
1253
  } catch (error) {
@@ -1093,11 +1266,11 @@ function updatePackageVersion(packagePath, version) {
1093
1266
  return;
1094
1267
  }
1095
1268
  try {
1096
- const packageContent = fs4.readFileSync(packagePath, "utf8");
1269
+ const packageContent = fs5.readFileSync(packagePath, "utf8");
1097
1270
  const packageJson = JSON.parse(packageContent);
1098
1271
  const packageName = packageJson.name;
1099
1272
  packageJson.version = version;
1100
- fs4.writeFileSync(packagePath, `${JSON.stringify(packageJson, null, 2)}
1273
+ fs5.writeFileSync(packagePath, `${JSON.stringify(packageJson, null, 2)}
1101
1274
  `);
1102
1275
  addPackageUpdate(packageName, version, packagePath);
1103
1276
  log(`Updated package.json at ${packagePath} to version ${version}`, "success");
@@ -1113,334 +1286,9 @@ function updatePackageVersion(packagePath, version) {
1113
1286
  // src/package/packageProcessor.ts
1114
1287
  import { execSync as execSync4 } from "child_process";
1115
1288
  import * as fs8 from "fs";
1116
- import path6 from "path";
1289
+ import path7 from "path";
1117
1290
  import { exit } from "process";
1118
1291
 
1119
- // src/changelog/changelogManager.ts
1120
- import * as fs5 from "fs";
1121
- import * as path4 from "path";
1122
- function createChangelog(_packagePath, packageName) {
1123
- return {
1124
- projectName: packageName,
1125
- unreleased: [],
1126
- versions: []
1127
- };
1128
- }
1129
- function parseChangelog(filePath) {
1130
- try {
1131
- if (!fs5.existsSync(filePath)) {
1132
- return null;
1133
- }
1134
- fs5.readFileSync(filePath, "utf8");
1135
- log(`Parsed changelog at ${filePath}`, "info");
1136
- return {
1137
- projectName: path4.basename(path4.dirname(filePath)),
1138
- unreleased: [],
1139
- versions: []
1140
- };
1141
- } catch (error) {
1142
- log(
1143
- `Error parsing changelog: ${error instanceof Error ? error.message : String(error)}`,
1144
- "error"
1145
- );
1146
- return null;
1147
- }
1148
- }
1149
- function generateLinks(changelog, repoUrl) {
1150
- var _a, _b;
1151
- if (!repoUrl || changelog.versions.length === 0) {
1152
- return "";
1153
- }
1154
- let links = "\n";
1155
- if (changelog.unreleased.length > 0) {
1156
- const latestVersion = ((_a = changelog.versions[0]) == null ? void 0 : _a.version) || "";
1157
- links += `[unreleased]: ${repoUrl}/compare/v${latestVersion}...HEAD
1158
- `;
1159
- }
1160
- for (let i = 0; i < changelog.versions.length; i++) {
1161
- const currentVersion = changelog.versions[i].version;
1162
- const previousVersion = (_b = changelog.versions[i + 1]) == null ? void 0 : _b.version;
1163
- if (previousVersion) {
1164
- links += `[${currentVersion}]: ${repoUrl}/compare/v${previousVersion}...v${currentVersion}
1165
- `;
1166
- } else if (i === changelog.versions.length - 1) {
1167
- links += `[${currentVersion}]: ${repoUrl}/releases/tag/v${currentVersion}
1168
- `;
1169
- }
1170
- }
1171
- return links;
1172
- }
1173
- function generateAngularChangelogContent(changelog, repoUrl) {
1174
- let content = "# Changelog\n\n";
1175
- if (changelog.unreleased.length > 0) {
1176
- content += "## [Unreleased]\n\n";
1177
- const groupedByType = groupEntriesByAngularType(changelog.unreleased);
1178
- for (const [type, entries] of Object.entries(groupedByType)) {
1179
- content += `### ${formatAngularType(type)}
1180
-
1181
- `;
1182
- const groupedByScope = groupEntriesByScope2(entries);
1183
- for (const [scope, scopeEntries] of Object.entries(groupedByScope)) {
1184
- if (scope !== "undefined" && scope !== "") {
1185
- content += `* **${scope}:**
1186
- `;
1187
- for (const entry of scopeEntries) {
1188
- content += formatAngularEntry(entry, false);
1189
- }
1190
- content += "\n";
1191
- } else {
1192
- for (const entry of scopeEntries) {
1193
- content += formatAngularEntry(entry, true);
1194
- }
1195
- }
1196
- }
1197
- content += "\n";
1198
- }
1199
- const breakingChanges = changelog.unreleased.filter(
1200
- (entry) => entry.description.includes("**BREAKING**")
1201
- );
1202
- if (breakingChanges.length > 0) {
1203
- content += "### BREAKING CHANGES\n\n";
1204
- for (const entry of breakingChanges) {
1205
- const description = entry.description.replace("**BREAKING** ", "");
1206
- content += `* ${entry.scope ? `**${entry.scope}:** ` : ""}${description}`;
1207
- if (entry.issueIds && entry.issueIds.length > 0) {
1208
- content += ` (${entry.issueIds.join(", ")})`;
1209
- }
1210
- content += "\n";
1211
- }
1212
- content += "\n";
1213
- }
1214
- }
1215
- for (const version of changelog.versions) {
1216
- content += `## [${version.version}] - ${version.date}
1217
-
1218
- `;
1219
- const groupedByType = groupEntriesByAngularType(version.entries);
1220
- for (const [type, entries] of Object.entries(groupedByType)) {
1221
- content += `### ${formatAngularType(type)}
1222
-
1223
- `;
1224
- const groupedByScope = groupEntriesByScope2(entries);
1225
- for (const [scope, scopeEntries] of Object.entries(groupedByScope)) {
1226
- if (scope !== "undefined" && scope !== "") {
1227
- content += `* **${scope}:**
1228
- `;
1229
- for (const entry of scopeEntries) {
1230
- content += formatAngularEntry(entry, false);
1231
- }
1232
- content += "\n";
1233
- } else {
1234
- for (const entry of scopeEntries) {
1235
- content += formatAngularEntry(entry, true);
1236
- }
1237
- }
1238
- }
1239
- content += "\n";
1240
- }
1241
- const breakingChanges = version.entries.filter(
1242
- (entry) => entry.description.includes("**BREAKING**")
1243
- );
1244
- if (breakingChanges.length > 0) {
1245
- content += "### BREAKING CHANGES\n\n";
1246
- for (const entry of breakingChanges) {
1247
- const description = entry.description.replace("**BREAKING** ", "");
1248
- content += `* ${entry.scope ? `**${entry.scope}:** ` : ""}${description}`;
1249
- if (entry.issueIds && entry.issueIds.length > 0) {
1250
- content += ` (${entry.issueIds.join(", ")})`;
1251
- }
1252
- content += "\n";
1253
- }
1254
- content += "\n";
1255
- }
1256
- }
1257
- content += generateLinks(changelog, repoUrl);
1258
- return content;
1259
- }
1260
- function groupEntriesByAngularType(entries) {
1261
- const result = {};
1262
- for (const entry of entries) {
1263
- const type = entry.originalType || mapToAngularType(entry.type);
1264
- if (!result[type]) {
1265
- result[type] = [];
1266
- }
1267
- result[type].push(entry);
1268
- }
1269
- return result;
1270
- }
1271
- function mapToAngularType(type) {
1272
- switch (type) {
1273
- case "added":
1274
- return "feat";
1275
- case "fixed":
1276
- return "fix";
1277
- case "changed":
1278
- return "perf";
1279
- case "deprecated":
1280
- case "removed":
1281
- case "security":
1282
- return type;
1283
- default:
1284
- return type;
1285
- }
1286
- }
1287
- function formatAngularType(type) {
1288
- switch (type) {
1289
- case "feat":
1290
- return "Features";
1291
- case "fix":
1292
- return "Bug Fixes";
1293
- case "perf":
1294
- return "Performance Improvements";
1295
- case "security":
1296
- return "Security";
1297
- case "deprecated":
1298
- return "Deprecated";
1299
- case "removed":
1300
- return "Removed";
1301
- default:
1302
- return capitalizeFirstLetter(type);
1303
- }
1304
- }
1305
- function groupEntriesByScope2(entries) {
1306
- const result = {};
1307
- for (const entry of entries) {
1308
- const scope = entry.scope || "";
1309
- if (!result[scope]) {
1310
- result[scope] = [];
1311
- }
1312
- result[scope].push(entry);
1313
- }
1314
- return result;
1315
- }
1316
- function formatAngularEntry(entry, includeScope) {
1317
- let result = " * ";
1318
- if (includeScope && entry.scope) {
1319
- result += `**${entry.scope}:** `;
1320
- }
1321
- let description = entry.description;
1322
- if (!includeScope && entry.scope && description.startsWith(`**${entry.scope}**: `)) {
1323
- description = description.substring(`**${entry.scope}**: `.length);
1324
- }
1325
- if (description.startsWith("**BREAKING** ")) {
1326
- description = description.substring("**BREAKING** ".length);
1327
- }
1328
- result += description;
1329
- if (entry.issueIds && entry.issueIds.length > 0) {
1330
- result += ` (${entry.issueIds.join(", ")})`;
1331
- }
1332
- result += "\n";
1333
- return result;
1334
- }
1335
- function generateChangelogContent(changelog, repoUrl, format = "keep-a-changelog") {
1336
- if (format === "angular") {
1337
- return generateAngularChangelogContent(changelog, repoUrl);
1338
- }
1339
- let content = "# Changelog\n\n";
1340
- content += `All notable changes to ${changelog.projectName} will be documented in this file.
1341
-
1342
- `;
1343
- content += "The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),\n";
1344
- content += "and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n\n";
1345
- if (changelog.unreleased.length > 0) {
1346
- content += "## [Unreleased]\n\n";
1347
- const grouped = changelog.unreleased.reduce(
1348
- (acc, entry) => {
1349
- if (!acc[entry.type]) {
1350
- acc[entry.type] = [];
1351
- }
1352
- acc[entry.type].push(entry);
1353
- return acc;
1354
- },
1355
- {}
1356
- );
1357
- for (const [type, entries] of Object.entries(grouped)) {
1358
- content += `### ${capitalizeFirstLetter(type)}
1359
-
1360
- `;
1361
- for (const entry of entries) {
1362
- let entryText = `- ${entry.description}`;
1363
- if (entry.issueIds && entry.issueIds.length > 0) {
1364
- entryText += ` (${entry.issueIds.join(", ")})`;
1365
- }
1366
- content += `${entryText}.
1367
- `;
1368
- }
1369
- content += "\n";
1370
- }
1371
- }
1372
- for (const version of changelog.versions) {
1373
- content += `## [${version.version}] - ${version.date}
1374
-
1375
- `;
1376
- const grouped = version.entries.reduce(
1377
- (acc, entry) => {
1378
- if (!acc[entry.type]) {
1379
- acc[entry.type] = [];
1380
- }
1381
- acc[entry.type].push(entry);
1382
- return acc;
1383
- },
1384
- {}
1385
- );
1386
- for (const [type, entries] of Object.entries(grouped)) {
1387
- content += `### ${capitalizeFirstLetter(type)}
1388
-
1389
- `;
1390
- for (const entry of entries) {
1391
- let entryText = `- ${entry.description}`;
1392
- if (entry.issueIds && entry.issueIds.length > 0) {
1393
- entryText += ` (${entry.issueIds.join(", ")})`;
1394
- }
1395
- content += `${entryText}.
1396
- `;
1397
- }
1398
- content += "\n";
1399
- }
1400
- }
1401
- content += generateLinks(changelog, repoUrl);
1402
- return content;
1403
- }
1404
- function updateChangelog(packagePath, packageName, version, entries, repoUrl, format = "keep-a-changelog") {
1405
- try {
1406
- const changelogPath = path4.join(packagePath, "CHANGELOG.md");
1407
- let changelog;
1408
- if (fs5.existsSync(changelogPath)) {
1409
- const existingChangelog = parseChangelog(changelogPath);
1410
- if (existingChangelog) {
1411
- changelog = existingChangelog;
1412
- } else {
1413
- changelog = createChangelog(packagePath, packageName);
1414
- }
1415
- } else {
1416
- changelog = createChangelog(packagePath, packageName);
1417
- }
1418
- if (version) {
1419
- const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
1420
- const newVersion = {
1421
- version,
1422
- date: today,
1423
- entries: [...changelog.unreleased, ...entries]
1424
- };
1425
- changelog.unreleased = [];
1426
- changelog.versions.unshift(newVersion);
1427
- } else {
1428
- changelog.unreleased = [...changelog.unreleased, ...entries];
1429
- }
1430
- const content = generateChangelogContent(changelog, repoUrl, format);
1431
- fs5.writeFileSync(changelogPath, content);
1432
- log(`Updated changelog at ${changelogPath}`, "success");
1433
- } catch (error) {
1434
- log(
1435
- `Error updating changelog: ${error instanceof Error ? error.message : String(error)}`,
1436
- "error"
1437
- );
1438
- }
1439
- }
1440
- function capitalizeFirstLetter(input) {
1441
- return input.charAt(0).toUpperCase() + input.slice(1);
1442
- }
1443
-
1444
1292
  // src/core/versionCalculator.ts
1445
1293
  import { cwd as cwd3 } from "process";
1446
1294
  import { Bumper } from "conventional-recommended-bump";
@@ -1448,10 +1296,10 @@ import semver3 from "semver";
1448
1296
 
1449
1297
  // src/utils/manifestHelpers.ts
1450
1298
  import fs6 from "fs";
1451
- import path5 from "path";
1299
+ import path6 from "path";
1452
1300
  function getVersionFromManifests(packageDir) {
1453
- const packageJsonPath = path5.join(packageDir, "package.json");
1454
- const cargoTomlPath = path5.join(packageDir, "Cargo.toml");
1301
+ const packageJsonPath = path6.join(packageDir, "package.json");
1302
+ const cargoTomlPath = path6.join(packageDir, "Cargo.toml");
1455
1303
  if (fs6.existsSync(packageJsonPath)) {
1456
1304
  try {
1457
1305
  const packageJson = JSON.parse(fs6.readFileSync(packageJsonPath, "utf-8"));
@@ -1496,8 +1344,8 @@ function getVersionFromManifests(packageDir) {
1496
1344
  };
1497
1345
  }
1498
1346
  function throwIfNoManifestsFound(packageDir) {
1499
- const packageJsonPath = path5.join(packageDir, "package.json");
1500
- const cargoTomlPath = path5.join(packageDir, "Cargo.toml");
1347
+ const packageJsonPath = path6.join(packageDir, "package.json");
1348
+ const cargoTomlPath = path6.join(packageDir, "Cargo.toml");
1501
1349
  throw new Error(
1502
1350
  `Neither package.json nor Cargo.toml found at ${packageDir}. Checked paths: ${packageJsonPath}, ${cargoTomlPath}. Cannot determine version.`
1503
1351
  );
@@ -1774,6 +1622,42 @@ function calculateNextVersion(version, manifestType, name, releaseType, prerelea
1774
1622
  return result || initialVersion;
1775
1623
  }
1776
1624
 
1625
+ // src/utils/packageMatching.ts
1626
+ import micromatch2 from "micromatch";
1627
+ function matchesPackageTarget(packageName, target) {
1628
+ if (packageName === target) {
1629
+ return true;
1630
+ }
1631
+ if (target.startsWith("@") && target.endsWith("/*") && !target.includes("**")) {
1632
+ const scope = target.slice(0, -2);
1633
+ return packageName.startsWith(`${scope}/`);
1634
+ }
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
+ );
1648
+ return false;
1649
+ }
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) {
1656
+ return true;
1657
+ }
1658
+ return !shouldMatchPackageTargets(packageName, skip);
1659
+ }
1660
+
1777
1661
  // src/package/packageProcessor.ts
1778
1662
  var PackageProcessor = class {
1779
1663
  skip;
@@ -1884,22 +1768,20 @@ var PackageProcessor = class {
1884
1768
  if (this.fullConfig.updateChangelog !== false) {
1885
1769
  let changelogEntries = [];
1886
1770
  try {
1887
- let revisionRange = latestTag;
1771
+ let revisionRange;
1888
1772
  if (latestTag) {
1889
1773
  try {
1890
1774
  execSync4(`git rev-parse --verify "${latestTag}"`, {
1891
1775
  cwd: pkgPath,
1892
1776
  stdio: "ignore"
1893
1777
  });
1778
+ revisionRange = `${latestTag}..HEAD`;
1894
1779
  } catch {
1895
- log(
1896
- `Tag ${latestTag} doesn't exist, using recent commits from HEAD for changelog`,
1897
- "debug"
1898
- );
1899
- revisionRange = "HEAD~10..HEAD";
1780
+ log(`Tag ${latestTag} doesn't exist, using all commits for changelog`, "debug");
1781
+ revisionRange = "HEAD";
1900
1782
  }
1901
1783
  } else {
1902
- revisionRange = "HEAD~10..HEAD";
1784
+ revisionRange = "HEAD";
1903
1785
  }
1904
1786
  changelogEntries = extractChangelogEntriesFromCommits(pkgPath, revisionRange);
1905
1787
  if (changelogEntries.length === 0) {
@@ -1924,7 +1806,7 @@ var PackageProcessor = class {
1924
1806
  }
1925
1807
  let repoUrl;
1926
1808
  try {
1927
- const packageJsonPath2 = path6.join(pkgPath, "package.json");
1809
+ const packageJsonPath2 = path7.join(pkgPath, "package.json");
1928
1810
  if (fs8.existsSync(packageJsonPath2)) {
1929
1811
  const packageJson = JSON.parse(fs8.readFileSync(packageJsonPath2, "utf8"));
1930
1812
  if (packageJson.repository) {
@@ -1953,7 +1835,7 @@ var PackageProcessor = class {
1953
1835
  this.fullConfig.changelogFormat
1954
1836
  );
1955
1837
  }
1956
- const packageJsonPath = path6.join(pkgPath, "package.json");
1838
+ const packageJsonPath = path7.join(pkgPath, "package.json");
1957
1839
  if (fs8.existsSync(packageJsonPath)) {
1958
1840
  updatePackageVersion(packageJsonPath, nextVersion);
1959
1841
  }
@@ -1962,13 +1844,13 @@ var PackageProcessor = class {
1962
1844
  const cargoPaths = (_b = this.fullConfig.cargo) == null ? void 0 : _b.paths;
1963
1845
  if (cargoPaths && cargoPaths.length > 0) {
1964
1846
  for (const cargoPath of cargoPaths) {
1965
- const resolvedCargoPath = path6.resolve(pkgPath, cargoPath, "Cargo.toml");
1847
+ const resolvedCargoPath = path7.resolve(pkgPath, cargoPath, "Cargo.toml");
1966
1848
  if (fs8.existsSync(resolvedCargoPath)) {
1967
1849
  updatePackageVersion(resolvedCargoPath, nextVersion);
1968
1850
  }
1969
1851
  }
1970
1852
  } else {
1971
- const cargoTomlPath = path6.join(pkgPath, "Cargo.toml");
1853
+ const cargoTomlPath = path7.join(pkgPath, "Cargo.toml");
1972
1854
  if (fs8.existsSync(cargoTomlPath)) {
1973
1855
  updatePackageVersion(cargoTomlPath, nextVersion);
1974
1856
  }
@@ -2006,7 +1888,7 @@ var PackageProcessor = class {
2006
1888
  }
2007
1889
  const filesToCommit = [];
2008
1890
  for (const info of updatedPackagesInfo) {
2009
- const packageJsonPath = path6.join(info.path, "package.json");
1891
+ const packageJsonPath = path7.join(info.path, "package.json");
2010
1892
  if (fs8.existsSync(packageJsonPath)) {
2011
1893
  filesToCommit.push(packageJsonPath);
2012
1894
  }
@@ -2015,13 +1897,13 @@ var PackageProcessor = class {
2015
1897
  const cargoPaths = (_d = this.fullConfig.cargo) == null ? void 0 : _d.paths;
2016
1898
  if (cargoPaths && cargoPaths.length > 0) {
2017
1899
  for (const cargoPath of cargoPaths) {
2018
- const resolvedCargoPath = path6.resolve(info.path, cargoPath, "Cargo.toml");
1900
+ const resolvedCargoPath = path7.resolve(info.path, cargoPath, "Cargo.toml");
2019
1901
  if (fs8.existsSync(resolvedCargoPath)) {
2020
1902
  filesToCommit.push(resolvedCargoPath);
2021
1903
  }
2022
1904
  }
2023
1905
  } else {
2024
- const cargoTomlPath = path6.join(info.path, "Cargo.toml");
1906
+ const cargoTomlPath = path7.join(info.path, "Cargo.toml");
2025
1907
  if (fs8.existsSync(cargoTomlPath)) {
2026
1908
  filesToCommit.push(cargoTomlPath);
2027
1909
  }
@@ -2118,7 +2000,8 @@ function createSyncedStrategy(config) {
2118
2000
  type: config.type
2119
2001
  });
2120
2002
  if (!nextVersion) {
2121
- log("No version change needed", "info");
2003
+ const msg = mainPkgName ? `No version change needed for ${mainPkgName}` : "No version change needed";
2004
+ log(msg, "info");
2122
2005
  return;
2123
2006
  }
2124
2007
  const files = [];
@@ -2126,7 +2009,7 @@ function createSyncedStrategy(config) {
2126
2009
  const processedPaths = /* @__PURE__ */ new Set();
2127
2010
  try {
2128
2011
  if (packages.root) {
2129
- const rootPkgPath = path7.join(packages.root, "package.json");
2012
+ const rootPkgPath = path8.join(packages.root, "package.json");
2130
2013
  if (fs9.existsSync(rootPkgPath)) {
2131
2014
  updatePackageVersion(rootPkgPath, nextVersion);
2132
2015
  files.push(rootPkgPath);
@@ -2144,7 +2027,7 @@ function createSyncedStrategy(config) {
2144
2027
  if (!shouldProcessPackage2(pkg, config)) {
2145
2028
  continue;
2146
2029
  }
2147
- const packageJsonPath = path7.join(pkg.dir, "package.json");
2030
+ const packageJsonPath = path8.join(pkg.dir, "package.json");
2148
2031
  if (processedPaths.has(packageJsonPath)) {
2149
2032
  continue;
2150
2033
  }
@@ -2160,7 +2043,7 @@ function createSyncedStrategy(config) {
2160
2043
  return;
2161
2044
  }
2162
2045
  let tagPackageName = null;
2163
- let commitPackageName = void 0;
2046
+ let commitPackageName;
2164
2047
  if (config.packageSpecificTags && packages.packages.length === 1) {
2165
2048
  tagPackageName = packages.packages[0].packageJson.name;
2166
2049
  commitPackageName = packages.packages[0].packageJson.name;
@@ -2194,7 +2077,6 @@ function createSingleStrategy(config) {
2194
2077
  return async (packages) => {
2195
2078
  try {
2196
2079
  const {
2197
- packages: configPackages,
2198
2080
  mainPackage,
2199
2081
  versionPrefix,
2200
2082
  tagTemplate,
@@ -2205,12 +2087,12 @@ function createSingleStrategy(config) {
2205
2087
  let packageName;
2206
2088
  if (mainPackage) {
2207
2089
  packageName = mainPackage;
2208
- } else if (configPackages && configPackages.length === 1) {
2209
- packageName = configPackages[0];
2090
+ } else if (packages.packages.length === 1) {
2091
+ packageName = packages.packages[0].packageJson.name;
2210
2092
  } else {
2211
2093
  throw createVersionError(
2212
2094
  "INVALID_CONFIG" /* INVALID_CONFIG */,
2213
- "Single mode requires either mainPackage or exactly one package in the packages array"
2095
+ "Single mode requires either mainPackage or exactly one resolved package"
2214
2096
  );
2215
2097
  }
2216
2098
  const pkg = packages.packages.find((p) => p.packageJson.name === packageName);
@@ -2228,50 +2110,114 @@ function createSingleStrategy(config) {
2228
2110
  latestTagResult = globalTagResult || "";
2229
2111
  }
2230
2112
  const latestTag = latestTagResult;
2231
- let nextVersion = void 0;
2232
- try {
2233
- nextVersion = await calculateVersion(config, {
2234
- latestTag,
2235
- versionPrefix: formattedPrefix,
2236
- path: pkgPath,
2237
- name: packageName,
2238
- type: config.type
2239
- });
2240
- } catch (error) {
2241
- const errorMessage = error instanceof Error ? error.message : String(error);
2242
- throw createVersionError("VERSION_CALCULATION_ERROR" /* VERSION_CALCULATION_ERROR */, errorMessage);
2243
- }
2244
- 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) {
2245
2125
  log(`No version change needed for ${packageName}`, "info");
2246
2126
  return;
2247
2127
  }
2248
- 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");
2249
2199
  updatePackageVersion(packageJsonPath, nextVersion);
2250
2200
  log(`Updated package ${packageName} to version ${nextVersion}`, "success");
2251
- const nextTag = formatTag(
2201
+ const tagName = formatTag(
2252
2202
  nextVersion,
2253
2203
  formattedPrefix,
2254
2204
  packageName,
2255
2205
  tagTemplate,
2256
2206
  config.packageSpecificTags
2257
2207
  );
2258
- const formattedCommitMessage = formatCommitMessage(commitMessage, nextVersion, packageName);
2259
- await createGitCommitAndTag(
2260
- [packageJsonPath],
2261
- nextTag,
2262
- formattedCommitMessage,
2263
- skipHooks,
2264
- dryRun
2265
- );
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
+ }
2266
2215
  } catch (error) {
2267
2216
  if (error instanceof VersionError || error instanceof GitError) {
2268
- log(
2269
- `Single Package Strategy failed: ${error.message} (${error.code || "UNKNOWN"})`,
2270
- "error"
2271
- );
2217
+ log(`Single Strategy failed: ${error.message} (${error.code || "UNKNOWN"})`, "error");
2272
2218
  } else {
2273
2219
  const errorMessage = error instanceof Error ? error.message : String(error);
2274
- log(`Single Package Strategy failed: ${errorMessage}`, "error");
2220
+ log(`Single Strategy failed: ${errorMessage}`, "error");
2275
2221
  }
2276
2222
  throw error;
2277
2223
  }
@@ -2327,13 +2273,9 @@ function createAsyncStrategy(config) {
2327
2273
  };
2328
2274
  }
2329
2275
  function createStrategy(config) {
2330
- var _a;
2331
2276
  if (config.synced) {
2332
2277
  return createSyncedStrategy(config);
2333
2278
  }
2334
- if (config.mainPackage || ((_a = config.packages) == null ? void 0 : _a.length) === 1) {
2335
- return createSingleStrategy(config);
2336
- }
2337
2279
  return createAsyncStrategy(config);
2338
2280
  }
2339
2281
  function createStrategyMap(config) {
@@ -2385,8 +2327,10 @@ var VersionEngine = class {
2385
2327
  }
2386
2328
  if (this.config.packages && this.config.packages.length > 0) {
2387
2329
  const originalCount = pkgsResult.packages.length;
2388
- const filteredPackages = pkgsResult.packages.filter(
2389
- (pkg) => shouldMatchPackageTargets(pkg.packageJson.name, this.config.packages)
2330
+ const filteredPackages = filterPackagesByConfig(
2331
+ pkgsResult.packages,
2332
+ this.config.packages,
2333
+ pkgsResult.root
2390
2334
  );
2391
2335
  pkgsResult.packages = filteredPackages;
2392
2336
  log(
@@ -2396,11 +2340,6 @@ var VersionEngine = class {
2396
2340
  if (filteredPackages.length === 0) {
2397
2341
  log("Warning: No packages matched the specified patterns in config.packages", "warning");
2398
2342
  }
2399
- } else {
2400
- log(
2401
- `Processing all ${pkgsResult.packages.length} workspace packages (no packages filter specified)`,
2402
- "info"
2403
- );
2404
2343
  }
2405
2344
  this.workspaceCache = pkgsResult;
2406
2345
  return pkgsResult;
@@ -2413,11 +2352,11 @@ var VersionEngine = class {
2413
2352
  }
2414
2353
  /**
2415
2354
  * Run the current strategy
2355
+ * @param packages Workspace packages to process
2416
2356
  * @param targets Optional package targets to process (only used by async strategy)
2417
2357
  */
2418
- async run(targets = []) {
2358
+ async run(packages, targets = []) {
2419
2359
  try {
2420
- const packages = await this.getWorkspacePackages();
2421
2360
  return this.currentStrategy(packages, targets);
2422
2361
  } catch (error) {
2423
2362
  if (error instanceof VersionError || error instanceof GitError) {
@@ -2454,8 +2393,8 @@ var VersionEngine = class {
2454
2393
  // src/index.ts
2455
2394
  function getPackageVersion() {
2456
2395
  try {
2457
- const packageJsonPath = path8.resolve(
2458
- path8.dirname(import.meta.url.replace("file:", "")),
2396
+ const packageJsonPath = path9.resolve(
2397
+ path9.dirname(import.meta.url.replace("file:", "")),
2459
2398
  "../package.json"
2460
2399
  );
2461
2400
  const packageJsonContent = fs10.readFileSync(packageJsonPath, "utf-8");
@@ -2492,24 +2431,31 @@ async function run() {
2492
2431
  config.prereleaseIdentifier = options.prerelease === true ? "next" : options.prerelease;
2493
2432
  const cliTargets = options.target ? options.target.split(",").map((t) => t.trim()) : [];
2494
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");
2495
2439
  if (config.synced) {
2496
2440
  log("Using synced versioning strategy.", "info");
2497
2441
  engine.setStrategy("synced");
2498
- await engine.run();
2499
- } else if (config.packages && config.packages.length === 1) {
2442
+ await engine.run(pkgsResult);
2443
+ } else if (resolvedCount === 1) {
2500
2444
  log("Using single package versioning strategy.", "info");
2501
2445
  if (cliTargets.length > 0) {
2502
2446
  log("--target flag is ignored for single package strategy.", "warning");
2503
2447
  }
2504
2448
  engine.setStrategy("single");
2505
- await engine.run();
2449
+ await engine.run(pkgsResult);
2450
+ } else if (resolvedCount === 0) {
2451
+ throw new Error("No packages found in workspace");
2506
2452
  } else {
2507
2453
  log("Using async versioning strategy.", "info");
2508
2454
  if (cliTargets.length > 0) {
2509
2455
  log(`Targeting specific packages: ${cliTargets.join(", ")}`, "info");
2510
2456
  }
2511
2457
  engine.setStrategy("async");
2512
- await engine.run(cliTargets);
2458
+ await engine.run(pkgsResult, cliTargets);
2513
2459
  }
2514
2460
  log("Versioning process completed.", "success");
2515
2461
  printJsonOutput();
@@ -2528,38 +2474,43 @@ async function run() {
2528
2474
  process.exit(1);
2529
2475
  }
2530
2476
  });
2531
- 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(
2532
2478
  "-f, --format <format>",
2533
2479
  "Changelog format (keep-a-changelog|angular)",
2534
2480
  "keep-a-changelog"
2535
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) => {
2536
- try {
2537
- log("Regenerating changelog from git history...", "info");
2538
- if (options.format !== "keep-a-changelog" && options.format !== "angular") {
2539
- throw new Error(
2540
- '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
2541
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);
2542
2511
  }
2543
- const regenerateOptions = {
2544
- format: options.format,
2545
- since: options.since,
2546
- output: options.output,
2547
- dryRun: options.dryRun,
2548
- projectDir: options.projectDir,
2549
- repoUrl: options.repoUrl
2550
- };
2551
- const content = await regenerateChangelog(regenerateOptions);
2552
- await writeChangelog(
2553
- content,
2554
- path8.resolve(options.projectDir, options.output),
2555
- options.dryRun
2556
- );
2557
- if (!options.dryRun) {
2558
- log(`Changelog successfully regenerated at ${options.output}`, "success");
2559
- }
2560
- } catch (error) {
2561
- log(error instanceof Error ? error.message : String(error), "error");
2562
- process.exit(1);
2512
+ } else {
2513
+ (_a = program.commands.find((cmd) => cmd.name() === "changelog")) == null ? void 0 : _a.help();
2563
2514
  }
2564
2515
  });
2565
2516
  program.parse(process.argv);