fork-version 4.1.1 → 4.1.7

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.
@@ -2,13 +2,14 @@
2
2
 
3
3
  var zod = require('zod');
4
4
  var child_process = require('child_process');
5
- var semver = require('semver');
5
+ var semver5 = require('semver');
6
6
  var path = require('path');
7
- var glob = require('glob');
7
+ var promises = require('fs/promises');
8
8
  var conventionalChangelogConfigSpec = require('conventional-changelog-config-spec');
9
9
  var fs = require('fs');
10
10
  var JoyCon = require('joycon');
11
11
  var bundleRequire = require('bundle-require');
12
+ var util = require('util');
12
13
  var jsoncParser = require('jsonc-parser');
13
14
  var yaml = require('yaml');
14
15
  var cheerio = require('cheerio/slim');
@@ -34,7 +35,7 @@ function _interopNamespace(e) {
34
35
  return Object.freeze(n);
35
36
  }
36
37
 
37
- var semver__default = /*#__PURE__*/_interopDefault(semver);
38
+ var semver5__default = /*#__PURE__*/_interopDefault(semver5);
38
39
  var conventionalChangelogConfigSpec__default = /*#__PURE__*/_interopDefault(conventionalChangelogConfigSpec);
39
40
  var JoyCon__default = /*#__PURE__*/_interopDefault(JoyCon);
40
41
  var cheerio__namespace = /*#__PURE__*/_interopNamespace(cheerio);
@@ -107,12 +108,13 @@ var ForkConfigSchema = zod.z.object({
107
108
  * - `main` - Bumps the version, update files, generate changelog, commit, and tag.
108
109
  * - `inspect-version` - Prints the current version and exits.
109
110
  * - `inspect-tag` - Prints the current git tag and exits.
111
+ * - `inspect` - Prints the current version and git tag and exits.
110
112
  * - `validate-config` - Validates the configuration and exits.
111
113
  *
112
114
  * @default "main"
113
115
  */
114
- command: zod.z.literal(["main", "inspect-version", "inspect-tag", "validate-config"]).describe(
115
- "The command to run. Can be one of: main, inspect-version, inspect-tag, validate-config. Defaults to main."
116
+ command: zod.z.literal(["main", "inspect", "inspect-version", "inspect-tag", "validate-config"]).describe(
117
+ "The command to run. Can be one of: main, inspect, inspect-version, inspect-tag, validate-config. Defaults to main."
116
118
  ),
117
119
  /**
118
120
  * If set, Fork-Version will print the current version and exit.
@@ -275,6 +277,11 @@ var ForkConfigSchema = zod.z.object({
275
277
  * @default false
276
278
  */
277
279
  verify: zod.z.boolean().describe("If true, git will run user defined git hooks before committing."),
280
+ /**
281
+ * Output result as JSON.
282
+ * @default false
283
+ */
284
+ asJson: zod.z.boolean().describe("Output the result as JSON."),
278
285
  // Skip Steps
279
286
  //
280
287
  /**
@@ -317,8 +324,11 @@ function escapeRegex(input) {
317
324
 
318
325
  // src/services/git.ts
319
326
  var Git = class {
327
+ #path;
328
+ #dryRun;
320
329
  constructor(config) {
321
- this.config = config;
330
+ this.#path = config.path;
331
+ this.#dryRun = config.dryRun ?? false;
322
332
  this.add = this.add.bind(this);
323
333
  this.commit = this.commit.bind(this);
324
334
  this.tag = this.tag.bind(this);
@@ -328,8 +338,6 @@ var Git = class {
328
338
  this.getRemoteUrl = this.getRemoteUrl.bind(this);
329
339
  this.getTags = this.getTags.bind(this);
330
340
  this.getMostRecentTag = this.getMostRecentTag.bind(this);
331
- this.getCleanedTags = this.getCleanedTags.bind(this);
332
- this.getHighestSemverVersionFromTags = this.getHighestSemverVersionFromTags.bind(this);
333
341
  this.getCommits = this.getCommits.bind(this);
334
342
  }
335
343
  async #execGit(command, args) {
@@ -338,7 +346,7 @@ var Git = class {
338
346
  "git",
339
347
  [command, ...args],
340
348
  {
341
- cwd: this.config.path,
349
+ cwd: this.#path,
342
350
  maxBuffer: Infinity
343
351
  },
344
352
  (error, stdout, stderr) => {
@@ -362,7 +370,7 @@ var Git = class {
362
370
  * ```
363
371
  */
364
372
  async add(...args) {
365
- if (this.config.dryRun) {
373
+ if (this.#dryRun) {
366
374
  return "";
367
375
  }
368
376
  return this.#execGit("add", args.filter(Boolean));
@@ -378,7 +386,7 @@ var Git = class {
378
386
  * ```
379
387
  */
380
388
  async commit(...args) {
381
- if (this.config.dryRun) {
389
+ if (this.#dryRun) {
382
390
  return "";
383
391
  }
384
392
  return this.#execGit("commit", args.filter(Boolean));
@@ -394,7 +402,7 @@ var Git = class {
394
402
  * ```
395
403
  */
396
404
  async tag(...args) {
397
- if (this.config.dryRun) {
405
+ if (this.#dryRun) {
398
406
  return "";
399
407
  }
400
408
  return this.#execGit("tag", args.filter(Boolean));
@@ -503,18 +511,18 @@ var Git = class {
503
511
  if (tagPrefix) {
504
512
  if (tag.startsWith(tagPrefix)) {
505
513
  const tagWithoutPrefix = tag.replace(new RegExp(`^${escapedTagPrefix}`), "");
506
- if (semver__default.default.valid(tagWithoutPrefix)) {
514
+ if (semver5__default.default.valid(tagWithoutPrefix)) {
507
515
  tags.push(tag);
508
516
  }
509
517
  }
510
- } else if (/^\d/.test(tag) && semver__default.default.valid(tag)) {
518
+ } else if (/^\d/.test(tag) && semver5__default.default.valid(tag)) {
511
519
  tags.push(tag);
512
520
  }
513
521
  }
514
522
  return tags;
515
523
  }
516
524
  /**
517
- * Returns the latest git tag based on commit date
525
+ * Returns the most recent tag from the commit history, or `undefined` if no valid semver tags are found
518
526
  *
519
527
  * @example
520
528
  * ```ts
@@ -525,40 +533,6 @@ var Git = class {
525
533
  const tags = await this.getTags(tagPrefix);
526
534
  return tags[0] || void 0;
527
535
  }
528
- /**
529
- * Get cleaned semver tags, with any tag prefix's removed
530
- *
531
- * @example
532
- * ```ts
533
- * await git.getCleanedTags("v"); // ["1.2.3", "1.2.2", "1.2.1"]
534
- * ```
535
- */
536
- async getCleanedTags(tagPrefix) {
537
- const tags = await this.getTags(tagPrefix);
538
- const escapedTagPrefix = tagPrefix ? escapeRegex(tagPrefix) : void 0;
539
- const cleanedTags = [];
540
- for (const tag of tags) {
541
- const tagWithoutPrefix = tag.replace(new RegExp(`^${escapedTagPrefix}`), "");
542
- const cleanedTag = semver__default.default.clean(tagWithoutPrefix);
543
- if (cleanedTag) {
544
- cleanedTags.push(cleanedTag);
545
- }
546
- }
547
- return cleanedTags;
548
- }
549
- /**
550
- * Get the highest semver version from git tags. This will return the highest
551
- * semver version found for the given tag prefix, regardless of the commit date.
552
- *
553
- * @example
554
- * ```ts
555
- * await git.getHighestSemverVersionFromTags("v"); // "1.2.3"
556
- * ```
557
- */
558
- async getHighestSemverVersionFromTags(tagPrefix) {
559
- const cleanedTags = await this.getCleanedTags(tagPrefix);
560
- return cleanedTags.sort(semver__default.default.rcompare)[0] || void 0;
561
- }
562
536
  /**
563
537
  * Get commit history in a parsable format
564
538
  *
@@ -713,6 +687,7 @@ All notable changes to this project will be documented in this file. See [fork-v
713
687
  gitTagFallback: true,
714
688
  sign: false,
715
689
  verify: false,
690
+ asJson: false,
716
691
  // Skip Steps
717
692
  skipBump: false,
718
693
  skipChangelog: false,
@@ -722,11 +697,8 @@ All notable changes to this project will be documented in this file. See [fork-v
722
697
  };
723
698
 
724
699
  // src/config/detect-git-host.ts
725
- async function detectGitHost(cwd) {
726
- const remoteUrl = await new Git({
727
- path: cwd,
728
- dryRun: false
729
- }).getRemoteUrl();
700
+ async function detectGitHost(path) {
701
+ const remoteUrl = await new Git({ path }).getRemoteUrl();
730
702
  if (remoteUrl.startsWith("https://") && remoteUrl.includes("@dev.azure.com/")) {
731
703
  const match = /^https:\/\/(?<atorganisation>.*?)@dev.azure.com\/(?<organisation>.*?)\/(?<project>.*?)\/_git\/(?<repository>.*?)(?:\.git)?$/.exec(
732
704
  remoteUrl
@@ -825,13 +797,19 @@ async function getUserConfig(cliArguments) {
825
797
  ...configFile,
826
798
  ...cliArguments.flags
827
799
  };
828
- let globResults = [];
800
+ const globResults = [];
829
801
  if (mergedConfig.glob) {
830
- globResults = await glob.glob(mergedConfig.glob, {
802
+ const IGNORE_LIST = /* @__PURE__ */ new Set(["node_modules", ".git"]);
803
+ const entries = promises.glob(mergedConfig.glob, {
831
804
  cwd,
832
- ignore: ["node_modules/**"],
833
- nodir: true
805
+ withFileTypes: true,
806
+ exclude: (entry) => IGNORE_LIST.has(entry.name)
834
807
  });
808
+ for await (const entry of entries) {
809
+ if (entry.isFile()) {
810
+ globResults.push(path.join(entry.parentPath, entry.name));
811
+ }
812
+ }
835
813
  }
836
814
  const files = mergeFiles(configFile?.files, cliArguments.flags.files, globResults);
837
815
  const detectedGitHost = await detectGitHost(cwd);
@@ -863,36 +841,44 @@ async function getUserConfig(cliArguments) {
863
841
  changelogPresetConfig
864
842
  };
865
843
  }
866
-
867
- // src/services/logger.ts
868
844
  var Logger = class {
845
+ #silent;
846
+ #debug;
869
847
  constructor(config) {
870
- this.config = config;
848
+ this.#silent = config.silent ?? false;
849
+ this.#debug = config.debug ?? false;
871
850
  this.log = this.log.bind(this);
872
851
  this.warn = this.warn.bind(this);
873
852
  this.error = this.error.bind(this);
874
853
  this.debug = this.debug.bind(this);
875
- this.disableLogs = this.config.silent;
854
+ this.skipping = this.skipping.bind(this);
876
855
  }
877
- disableLogs = false;
878
- log(...messages) {
879
- if (!this.disableLogs) {
880
- console.log(...messages);
856
+ log(message) {
857
+ if (!this.#silent) {
858
+ console.log(message);
881
859
  }
882
860
  }
883
- warn(...messages) {
884
- if (!this.disableLogs) {
885
- console.warn(...messages);
861
+ warn(message) {
862
+ if (!this.#silent) {
863
+ console.warn(util.styleText("yellowBright", message));
886
864
  }
887
865
  }
888
- error(...messages) {
889
- if (!this.disableLogs) {
890
- console.error(...messages);
866
+ error(message) {
867
+ if (!this.#silent) {
868
+ console.error(util.styleText("redBright", message));
891
869
  }
892
870
  }
893
- debug(...messages) {
894
- if (this.config.debug && !this.disableLogs) {
895
- console.debug(...messages);
871
+ debug(message, ...optionalParams) {
872
+ if (!this.#silent && this.#debug) {
873
+ console.debug(util.styleText("cyanBright", message));
874
+ if (optionalParams.length > 0) {
875
+ console.debug(...optionalParams);
876
+ }
877
+ }
878
+ }
879
+ skipping(message) {
880
+ if (!this.#silent) {
881
+ console.log(util.styleText("magenta", message));
896
882
  }
897
883
  }
898
884
  };
@@ -903,15 +889,13 @@ function fileExists(filePath) {
903
889
  return false;
904
890
  }
905
891
  }
906
-
907
- // src/files/json-package.ts
908
892
  var JSONPackage = class {
909
- constructor(config, logger) {
910
- this.config = config;
911
- this.logger = logger;
893
+ #logger;
894
+ constructor(logger) {
895
+ this.#logger = logger;
912
896
  }
913
897
  /** Options for parsing JSON and JSONC files. */
914
- PARSE_OPTIONS = {
898
+ #jsoncOptions = {
915
899
  allowEmptyContent: false,
916
900
  allowTrailingComma: true,
917
901
  disallowComments: false
@@ -923,42 +907,32 @@ var JSONPackage = class {
923
907
  * @param newString string to set the value to
924
908
  * @returns the JSON or JSONC string with the value set
925
909
  */
926
- setStringInJsonc(jsonc, jsonPath, newString) {
910
+ #setStringInJsonc(jsonc, jsonPath, newString) {
927
911
  const edits = jsoncParser.modify(jsonc, jsonPath, newString, {});
928
912
  return jsoncParser.applyEdits(jsonc, edits);
929
913
  }
930
- read(fileName) {
931
- const filePath = path.resolve(this.config.path, fileName);
932
- if (fileExists(filePath)) {
933
- const fileContents = fs.readFileSync(filePath, "utf8");
934
- const parseErrors = [];
935
- const parsedJson = jsoncParser.parse(fileContents, parseErrors, this.PARSE_OPTIONS);
936
- if (parseErrors.length) {
937
- this.logger.warn(`[File Manager] Unable to parse JSON: ${fileName}`, parseErrors);
938
- return void 0;
939
- }
940
- if (parsedJson?.version) {
941
- return {
942
- name: fileName,
943
- path: filePath,
944
- version: parsedJson.version,
945
- isPrivate: typeof parsedJson?.private === "boolean" ? parsedJson.private : true
946
- };
947
- }
948
- this.logger.warn(`[File Manager] Unable to determine json version: ${fileName}`);
914
+ read(filePath) {
915
+ const fileName = path.basename(filePath);
916
+ const fileContents = fs.readFileSync(filePath, "utf8");
917
+ const parseErrors = [];
918
+ const parsedJson = jsoncParser.parse(fileContents, parseErrors, this.#jsoncOptions);
919
+ if (parsedJson?.version && parseErrors.length === 0) {
920
+ return {
921
+ name: fileName,
922
+ path: filePath,
923
+ version: parsedJson.version,
924
+ isPrivate: typeof parsedJson?.private === "boolean" ? parsedJson.private : true
925
+ };
949
926
  }
927
+ this.#logger.warn(`[File Manager] Unable to determine json version: ${fileName}`);
950
928
  }
951
929
  write(fileState, newVersion) {
952
930
  let fileContents = fs.readFileSync(fileState.path, "utf8");
953
931
  const parseErrors = [];
954
- const parsedJson = jsoncParser.parse(fileContents, parseErrors, this.PARSE_OPTIONS);
955
- if (parseErrors.length) {
956
- this.logger.warn(`[File Manager] Unable to parse JSON: ${fileState.path}`, parseErrors);
957
- return;
958
- }
959
- fileContents = this.setStringInJsonc(fileContents, ["version"], newVersion);
932
+ const parsedJson = jsoncParser.parse(fileContents, parseErrors, this.#jsoncOptions);
933
+ fileContents = this.#setStringInJsonc(fileContents, ["version"], newVersion);
960
934
  if (parsedJson?.packages?.[""]) {
961
- fileContents = this.setStringInJsonc(fileContents, ["packages", "", "version"], newVersion);
935
+ fileContents = this.#setStringInJsonc(fileContents, ["packages", "", "version"], newVersion);
962
936
  }
963
937
  fs.writeFileSync(fileState.path, fileContents, "utf8");
964
938
  }
@@ -967,16 +941,16 @@ var JSONPackage = class {
967
941
  }
968
942
  };
969
943
  var YAMLPackage = class {
970
- constructor(config, logger) {
971
- this.config = config;
972
- this.logger = logger;
944
+ #logger;
945
+ constructor(logger) {
946
+ this.#logger = logger;
973
947
  }
974
948
  /**
975
949
  * If the version is returned with a "+" symbol in the value then the version might be from a
976
950
  * flutter `pubspec.yaml` file, if so we want to retain the input builderNumber by splitting it
977
951
  * and joining it again later.
978
952
  */
979
- handleBuildNumber(fileVersion) {
953
+ #handleBuildNumber(fileVersion) {
980
954
  const [version, builderNumber] = fileVersion.split("+");
981
955
  if (/^\d+$/.test(builderNumber)) {
982
956
  return {
@@ -988,22 +962,20 @@ var YAMLPackage = class {
988
962
  version: fileVersion
989
963
  };
990
964
  }
991
- read(fileName) {
992
- const filePath = path.resolve(this.config.path, fileName);
993
- if (fileExists(filePath)) {
994
- const fileContents = fs.readFileSync(filePath, "utf-8");
995
- const fileVersion = yaml.parse(fileContents)?.version;
996
- if (fileVersion) {
997
- const parsedVersion = this.handleBuildNumber(fileVersion);
998
- return {
999
- name: fileName,
1000
- path: filePath,
1001
- version: parsedVersion.version || "",
1002
- builderNumber: parsedVersion.builderNumber ?? void 0
1003
- };
1004
- }
965
+ read(filePath) {
966
+ const fileName = path.basename(filePath);
967
+ const fileContents = fs.readFileSync(filePath, "utf-8");
968
+ const fileVersion = yaml.parse(fileContents)?.version;
969
+ if (fileVersion) {
970
+ const parsedVersion = this.#handleBuildNumber(fileVersion);
971
+ return {
972
+ name: fileName,
973
+ path: filePath,
974
+ version: parsedVersion.version || "",
975
+ builderNumber: parsedVersion.builderNumber ?? void 0
976
+ };
1005
977
  }
1006
- this.logger.warn(`[File Manager] Unable to determine yaml version: ${fileName}`);
978
+ this.#logger.warn(`[File Manager] Unable to determine yaml version: ${fileName}`);
1007
979
  }
1008
980
  write(fileState, newVersion) {
1009
981
  const fileContents = fs.readFileSync(fileState.path, "utf8");
@@ -1020,21 +992,21 @@ var YAMLPackage = class {
1020
992
  }
1021
993
  };
1022
994
  var PlainText = class {
1023
- constructor(config, logger) {
1024
- this.config = config;
1025
- this.logger = logger;
995
+ #logger;
996
+ constructor(logger) {
997
+ this.#logger = logger;
1026
998
  }
1027
- read(fileName) {
1028
- const filePath = path.resolve(this.config.path, fileName);
1029
- if (fileExists(filePath)) {
1030
- const fileContents = fs.readFileSync(filePath, "utf8");
999
+ read(filePath) {
1000
+ const fileName = path.basename(filePath);
1001
+ const fileContents = fs.readFileSync(filePath, "utf8").trim();
1002
+ if (fileContents) {
1031
1003
  return {
1032
1004
  name: fileName,
1033
1005
  path: filePath,
1034
- version: fileContents || ""
1006
+ version: fileContents
1035
1007
  };
1036
1008
  }
1037
- this.logger.warn(`[File Manager] Unable to determine plain text version: ${fileName}`);
1009
+ this.#logger.warn(`[File Manager] Unable to determine plain text version: ${fileName}`);
1038
1010
  }
1039
1011
  write(fileState, newVersion) {
1040
1012
  fs.writeFileSync(fileState.path, newVersion, "utf8");
@@ -1044,35 +1016,31 @@ var PlainText = class {
1044
1016
  }
1045
1017
  };
1046
1018
  var MSBuildProject = class {
1047
- constructor(config, logger) {
1048
- this.config = config;
1049
- this.logger = logger;
1050
- }
1051
- read(fileName) {
1052
- const filePath = path.resolve(this.config.path, fileName);
1053
- if (fileExists(filePath)) {
1054
- const fileContents = fs.readFileSync(filePath, "utf8");
1055
- const $ = cheerio__namespace.load(fileContents, {
1056
- xmlMode: true,
1057
- xml: { decodeEntities: false }
1058
- });
1059
- const version = $("Project > PropertyGroup > Version").text();
1060
- if (version) {
1061
- return {
1062
- name: fileName,
1063
- path: filePath,
1064
- version
1065
- };
1066
- }
1067
- this.logger.warn(`[File Manager] Unable to determine ms-build version: ${fileName}`);
1019
+ #logger;
1020
+ constructor(logger) {
1021
+ this.#logger = logger;
1022
+ }
1023
+ #cheerioOptions = {
1024
+ xmlMode: true,
1025
+ xml: { decodeEntities: false }
1026
+ };
1027
+ read(filePath) {
1028
+ const fileName = path.basename(filePath);
1029
+ const fileContents = fs.readFileSync(filePath, "utf8");
1030
+ const $ = cheerio__namespace.load(fileContents, this.#cheerioOptions);
1031
+ const version = $("Project > PropertyGroup > Version").text();
1032
+ if (version) {
1033
+ return {
1034
+ name: fileName,
1035
+ path: filePath,
1036
+ version
1037
+ };
1068
1038
  }
1039
+ this.#logger.warn(`[File Manager] Unable to determine ms-build version: ${fileName}`);
1069
1040
  }
1070
1041
  write(fileState, newVersion) {
1071
1042
  const fileContents = fs.readFileSync(fileState.path, "utf8");
1072
- const $ = cheerio__namespace.load(fileContents, {
1073
- xmlMode: true,
1074
- xml: { decodeEntities: false }
1075
- });
1043
+ const $ = cheerio__namespace.load(fileContents, this.#cheerioOptions);
1076
1044
  $("Project > PropertyGroup > Version").text(newVersion);
1077
1045
  const updatedContent = $.xml().replaceAll('"/>', '" />');
1078
1046
  fs.writeFileSync(fileState.path, updatedContent, "utf8");
@@ -1084,40 +1052,38 @@ var MSBuildProject = class {
1084
1052
  }
1085
1053
  };
1086
1054
  var ARMBicep = class {
1087
- constructor(config, logger) {
1088
- this.config = config;
1089
- this.logger = logger;
1055
+ #logger;
1056
+ constructor(logger) {
1057
+ this.#logger = logger;
1090
1058
  }
1091
1059
  /** https://regex101.com/r/Lriphb/2 */
1092
- metadataRegex = /(metadata contentVersion *= *['"])(?<version>[^'"]+)(['"])/;
1060
+ #metadataRegex = /(metadata contentVersion *= *['"])(?<version>[^'"]+)(['"])/;
1093
1061
  /** https://regex101.com/r/iKCTF9/1 */
1094
- varRegex = /(var contentVersion(?: string)? *= *['"])(?<version>[^'"]+)(['"])/;
1095
- read(fileName) {
1096
- const filePath = path.resolve(this.config.path, fileName);
1097
- if (fileExists(filePath)) {
1098
- const fileContents = fs.readFileSync(filePath, "utf8");
1099
- const metadataMatch = this.metadataRegex.exec(fileContents);
1100
- const varMatch = this.varRegex.exec(fileContents);
1101
- if (metadataMatch?.groups?.version && varMatch?.groups?.version) {
1102
- return {
1103
- name: fileName,
1104
- path: filePath,
1105
- version: metadataMatch.groups.version
1106
- };
1107
- }
1108
- if (!metadataMatch) {
1109
- this.logger.warn(
1110
- `[File Manager] Missing 'metadata contentVersion' in bicep file: ${fileName}`
1111
- );
1112
- }
1113
- if (!varMatch) {
1114
- this.logger.warn(`[File Manager] Missing 'var contentVersion' in bicep file: ${fileName}`);
1115
- }
1062
+ #varRegex = /(var contentVersion(?: string)? *= *['"])(?<version>[^'"]+)(['"])/;
1063
+ read(filePath) {
1064
+ const fileName = path.basename(filePath);
1065
+ const fileContents = fs.readFileSync(filePath, "utf8");
1066
+ const metadataMatch = this.#metadataRegex.exec(fileContents);
1067
+ const varMatch = this.#varRegex.exec(fileContents);
1068
+ if (metadataMatch?.groups?.version && varMatch?.groups?.version) {
1069
+ return {
1070
+ name: fileName,
1071
+ path: filePath,
1072
+ version: metadataMatch.groups.version
1073
+ };
1074
+ }
1075
+ if (!metadataMatch) {
1076
+ this.#logger.warn(
1077
+ `[File Manager] Missing 'metadata contentVersion' in bicep file: ${fileName}`
1078
+ );
1079
+ }
1080
+ if (!varMatch) {
1081
+ this.#logger.warn(`[File Manager] Missing 'var contentVersion' in bicep file: ${fileName}`);
1116
1082
  }
1117
1083
  }
1118
1084
  write(fileState, newVersion) {
1119
1085
  const fileContents = fs.readFileSync(fileState.path, "utf8");
1120
- const updatedContent = fileContents.replace(this.metadataRegex, `$1${newVersion}$3`).replace(this.varRegex, `$1${newVersion}$3`);
1086
+ const updatedContent = fileContents.replace(this.#metadataRegex, `$1${newVersion}$3`).replace(this.#varRegex, `$1${newVersion}$3`);
1121
1087
  fs.writeFileSync(fileState.path, updatedContent, "utf8");
1122
1088
  }
1123
1089
  isSupportedFile(fileName) {
@@ -1125,35 +1091,31 @@ var ARMBicep = class {
1125
1091
  }
1126
1092
  };
1127
1093
  var InstallShieldISM = class {
1128
- constructor(config, logger) {
1129
- this.config = config;
1130
- this.logger = logger;
1131
- }
1132
- read(fileName) {
1133
- const filePath = path.resolve(this.config.path, fileName);
1134
- if (fileExists(filePath)) {
1135
- const fileContents = fs.readFileSync(filePath, "utf8");
1136
- const $ = cheerio__namespace.load(fileContents, {
1137
- xmlMode: true,
1138
- xml: { decodeEntities: false }
1139
- });
1140
- const version = $('msi > table[name="Property"] > row > td:contains("ProductVersion")').next().text().trim();
1141
- if (version) {
1142
- return {
1143
- name: fileName,
1144
- path: filePath,
1145
- version
1146
- };
1147
- }
1148
- this.logger.warn(`[File Manager] Unable to determine InstallShield ISM version: ${fileName}`);
1094
+ #logger;
1095
+ constructor(logger) {
1096
+ this.#logger = logger;
1097
+ }
1098
+ #cheerioOptions = {
1099
+ xmlMode: true,
1100
+ xml: { decodeEntities: false }
1101
+ };
1102
+ read(filePath) {
1103
+ const fileName = path.basename(filePath);
1104
+ const fileContents = fs.readFileSync(filePath, "utf8");
1105
+ const $ = cheerio__namespace.load(fileContents, this.#cheerioOptions);
1106
+ const version = $('msi > table[name="Property"] > row > td:contains("ProductVersion")').next().text().trim();
1107
+ if (version) {
1108
+ return {
1109
+ name: fileName,
1110
+ path: filePath,
1111
+ version
1112
+ };
1149
1113
  }
1114
+ this.#logger.warn(`[File Manager] Unable to determine InstallShield ISM version: ${fileName}`);
1150
1115
  }
1151
1116
  write(fileState, newVersion) {
1152
1117
  const fileContents = fs.readFileSync(fileState.path, "utf8");
1153
- const $ = cheerio__namespace.load(fileContents, {
1154
- xmlMode: true,
1155
- xml: { decodeEntities: false }
1156
- });
1118
+ const $ = cheerio__namespace.load(fileContents, this.#cheerioOptions);
1157
1119
  const versionCell = $(
1158
1120
  'msi > table[name="Property"] > row > td:contains("ProductVersion")'
1159
1121
  ).next();
@@ -1170,22 +1132,21 @@ var InstallShieldISM = class {
1170
1132
 
1171
1133
  // src/files/file-manager.ts
1172
1134
  var FileManager = class {
1135
+ #config;
1136
+ #logger;
1137
+ #fileManagers = [];
1173
1138
  constructor(config, logger) {
1174
- this.config = config;
1175
- this.logger = logger;
1176
- this.JSONPackage = new JSONPackage(config, logger);
1177
- this.YAMLPackage = new YAMLPackage(config, logger);
1178
- this.PlainText = new PlainText(config, logger);
1179
- this.MSBuildProject = new MSBuildProject(config, logger);
1180
- this.ARMBicep = new ARMBicep(config, logger);
1181
- this.InstallShieldISM = new InstallShieldISM(config, logger);
1182
- }
1183
- JSONPackage;
1184
- YAMLPackage;
1185
- PlainText;
1186
- MSBuildProject;
1187
- ARMBicep;
1188
- InstallShieldISM;
1139
+ this.#config = config;
1140
+ this.#logger = logger;
1141
+ this.#fileManagers = [
1142
+ new JSONPackage(logger),
1143
+ new YAMLPackage(logger),
1144
+ new PlainText(logger),
1145
+ new MSBuildProject(logger),
1146
+ new ARMBicep(logger),
1147
+ new InstallShieldISM(logger)
1148
+ ];
1149
+ }
1189
1150
  /**
1190
1151
  * Get the state from the given file name.
1191
1152
  *
@@ -1199,27 +1160,16 @@ var FileManager = class {
1199
1160
  * { "name": "package.json", "path": "/path/to/package.json", "version": "1.2.3", "isPrivate": true }
1200
1161
  * ```
1201
1162
  */
1202
- read(fileName) {
1203
- const _fileName = fileName.toLowerCase();
1204
- if (this.JSONPackage.isSupportedFile(_fileName)) {
1205
- return this.JSONPackage.read(fileName);
1206
- }
1207
- if (this.YAMLPackage.isSupportedFile(_fileName)) {
1208
- return this.YAMLPackage.read(fileName);
1209
- }
1210
- if (this.PlainText.isSupportedFile(_fileName)) {
1211
- return this.PlainText.read(fileName);
1212
- }
1213
- if (this.MSBuildProject.isSupportedFile(_fileName)) {
1214
- return this.MSBuildProject.read(fileName);
1215
- }
1216
- if (this.ARMBicep.isSupportedFile(_fileName)) {
1217
- return this.ARMBicep.read(fileName);
1218
- }
1219
- if (this.InstallShieldISM.isSupportedFile(_fileName)) {
1220
- return this.InstallShieldISM.read(fileName);
1163
+ read(pathOrName) {
1164
+ const _fileName = pathOrName.toLowerCase();
1165
+ const filePath = path.isAbsolute(pathOrName) ? pathOrName : path.resolve(this.#config.path, pathOrName);
1166
+ if (!fileExists(filePath)) return;
1167
+ for (const fileManager of this.#fileManagers) {
1168
+ if (fileManager.isSupportedFile(_fileName)) {
1169
+ return fileManager.read(filePath);
1170
+ }
1221
1171
  }
1222
- this.logger.error(`[File Manager] Unsupported file: ${fileName}`);
1172
+ this.#logger.error(`[File Manager] Unsupported file: ${pathOrName}`);
1223
1173
  }
1224
1174
  /**
1225
1175
  * Write the new version to the given file.
@@ -1233,29 +1183,16 @@ var FileManager = class {
1233
1183
  * ```
1234
1184
  */
1235
1185
  write(fileState, newVersion) {
1236
- if (this.config.dryRun) {
1186
+ if (this.#config.dryRun) {
1237
1187
  return;
1238
1188
  }
1239
1189
  const _fileName = fileState.name.toLowerCase();
1240
- if (this.JSONPackage.isSupportedFile(_fileName)) {
1241
- return this.JSONPackage.write(fileState, newVersion);
1242
- }
1243
- if (this.YAMLPackage.isSupportedFile(_fileName)) {
1244
- return this.YAMLPackage.write(fileState, newVersion);
1245
- }
1246
- if (this.PlainText.isSupportedFile(_fileName)) {
1247
- return this.PlainText.write(fileState, newVersion);
1248
- }
1249
- if (this.MSBuildProject.isSupportedFile(_fileName)) {
1250
- return this.MSBuildProject.write(fileState, newVersion);
1251
- }
1252
- if (this.ARMBicep.isSupportedFile(_fileName)) {
1253
- return this.ARMBicep.write(fileState, newVersion);
1254
- }
1255
- if (this.InstallShieldISM.isSupportedFile(_fileName)) {
1256
- return this.InstallShieldISM.write(fileState, newVersion);
1190
+ for (const fileManager of this.#fileManagers) {
1191
+ if (fileManager.isSupportedFile(_fileName)) {
1192
+ return fileManager.write(fileState, newVersion);
1193
+ }
1257
1194
  }
1258
- this.logger.error(`[File Manager] Unsupported file: ${fileState.path}`);
1195
+ this.#logger.error(`[File Manager] Unsupported file: ${fileState.path}`);
1259
1196
  }
1260
1197
  };
1261
1198
 
@@ -1268,66 +1205,6 @@ ${JSON.stringify(config, null, 2)}
1268
1205
  \u2705 Configuration is valid.
1269
1206
  `);
1270
1207
  }
1271
- async function getCurrentVersion(config, logger, git, fileManager, filesToUpdate) {
1272
- const files = [];
1273
- const versions = /* @__PURE__ */ new Set();
1274
- for (const file of filesToUpdate) {
1275
- if (await git.isIgnored(file)) {
1276
- logger.debug(`[Git Ignored] ${file}`);
1277
- continue;
1278
- }
1279
- const fileState = fileManager.read(file);
1280
- if (fileState) {
1281
- files.push(fileState);
1282
- if (!config.currentVersion) {
1283
- versions.add(fileState.version);
1284
- }
1285
- }
1286
- }
1287
- if (config.currentVersion) {
1288
- versions.add(config.currentVersion);
1289
- }
1290
- if (versions.size === 0 && config.gitTagFallback) {
1291
- const version = await git.getHighestSemverVersionFromTags(config.tagPrefix);
1292
- if (version) {
1293
- logger.warn(`Using latest git tag as fallback`);
1294
- versions.add(version);
1295
- }
1296
- }
1297
- if (versions.size === 0) {
1298
- throw new Error("Unable to find current version");
1299
- } else if (versions.size > 1) {
1300
- if (!config.allowMultipleVersions) {
1301
- throw new Error("Found multiple versions");
1302
- }
1303
- logger.warn(
1304
- `Found multiple versions (${Array.from(versions).join(", ")}), using the higher semver version`
1305
- );
1306
- }
1307
- const currentVersion = semver__default.default.rsort(Array.from(versions))[0];
1308
- logger.log(`Current version: ${currentVersion}`);
1309
- return {
1310
- files,
1311
- version: currentVersion
1312
- };
1313
- }
1314
-
1315
- // src/commands/inspect-version.ts
1316
- async function inspectVersion(config, logger, fileManager, git) {
1317
- let foundVersion = "";
1318
- try {
1319
- const currentVersion = await getCurrentVersion(config, logger, git, fileManager, config.files);
1320
- if (currentVersion) foundVersion = currentVersion.version;
1321
- } catch {
1322
- }
1323
- console.log(foundVersion);
1324
- }
1325
-
1326
- // src/commands/inspect-tag.ts
1327
- async function inspectTag(config, git) {
1328
- const tag = await git.getMostRecentTag(config.tagPrefix);
1329
- console.log(tag ?? "");
1330
- }
1331
1208
 
1332
1209
  // src/utils/trim-string-array.ts
1333
1210
  function trimStringArray(array) {
@@ -1791,6 +1668,12 @@ function filterRevertedCommits(parsedCommits) {
1791
1668
  }
1792
1669
  return commitsWithoutReverts;
1793
1670
  }
1671
+ function cleanTag(tag, tagPrefix) {
1672
+ if (!tag) return void 0;
1673
+ const escapedTagPrefix = tagPrefix ? escapeRegex(tagPrefix) : void 0;
1674
+ const tagWithoutPrefix = escapedTagPrefix ? tag.replace(new RegExp(`^${escapedTagPrefix}`), "") : tag;
1675
+ return semver5__default.default.clean(tagWithoutPrefix) ?? void 0;
1676
+ }
1794
1677
 
1795
1678
  // src/process/get-commits.ts
1796
1679
  async function getCommitsSinceTag(config, logger, git) {
@@ -1801,7 +1684,6 @@ async function getCommitsSinceTag(config, logger, git) {
1801
1684
  logger.warn("No previous tag found, using all commits");
1802
1685
  }
1803
1686
  const foundCommits = await git.getCommits(latestTag, "HEAD");
1804
- logger.debug(`Found ${foundCommits.length} commits since last tag (${latestTag ?? "none"})`);
1805
1687
  const commits = foundCommits.reduce((acc, commit) => {
1806
1688
  const parsed = commitParser.parse(commit);
1807
1689
  if (parsed) {
@@ -1809,19 +1691,136 @@ async function getCommitsSinceTag(config, logger, git) {
1809
1691
  }
1810
1692
  return acc;
1811
1693
  }, []);
1812
- logger.debug(`Parsed ${commits.length} commits after applying commit parser`);
1813
1694
  const filteredCommits = filterRevertedCommits(commits);
1814
- logger.debug(`Filtered to ${filteredCommits.length} commits after removing reverts`);
1695
+ logger.debug(
1696
+ `Found ${foundCommits.length} commits since tag: ${latestTag ?? "none"} (${commits.length} parsed, ${filteredCommits.length} after filtering reverts)`
1697
+ );
1815
1698
  return {
1816
1699
  latestTag,
1700
+ latestTagVersion: cleanTag(latestTag, config.tagPrefix),
1817
1701
  commits: filteredCommits
1818
1702
  };
1819
1703
  }
1704
+ async function getCurrentVersion(config, logger, git, fileManager, filesToUpdate, latestTagVersion) {
1705
+ const files = [];
1706
+ const versions = /* @__PURE__ */ new Set();
1707
+ for (const file of filesToUpdate) {
1708
+ if (await git.isIgnored(file)) {
1709
+ logger.debug(`[Git Ignored] ${file}`);
1710
+ continue;
1711
+ }
1712
+ const fileState = fileManager.read(file);
1713
+ if (fileState) {
1714
+ files.push(fileState);
1715
+ if (!config.currentVersion) {
1716
+ versions.add(fileState.version);
1717
+ }
1718
+ }
1719
+ }
1720
+ if (config.currentVersion) {
1721
+ versions.add(config.currentVersion);
1722
+ }
1723
+ if (versions.size === 0 && config.gitTagFallback && latestTagVersion) {
1724
+ logger.warn(`Using latest git tag as fallback`);
1725
+ versions.add(latestTagVersion);
1726
+ }
1727
+ if (versions.size === 0) {
1728
+ throw new Error("Unable to find current version");
1729
+ } else if (versions.size > 1) {
1730
+ if (!config.allowMultipleVersions) {
1731
+ throw new Error("Found multiple versions");
1732
+ }
1733
+ logger.warn(
1734
+ `Found multiple versions (${Array.from(versions).join(", ")}), using the higher semver version`
1735
+ );
1736
+ }
1737
+ const currentVersion = semver5__default.default.rsort(Array.from(versions))[0];
1738
+ logger.log(`Current version: ${currentVersion}`);
1739
+ return {
1740
+ files,
1741
+ version: currentVersion
1742
+ };
1743
+ }
1744
+ async function inspect(config, logger, fileManager, git) {
1745
+ let latestTag = "";
1746
+ let latestVersion = "";
1747
+ try {
1748
+ const commits = await getCommitsSinceTag(config, logger, git);
1749
+ if (commits.latestTag) {
1750
+ latestTag = commits.latestTag;
1751
+ latestVersion = commits.latestTagVersion ?? "";
1752
+ }
1753
+ const currentVersion = await getCurrentVersion(
1754
+ config,
1755
+ logger,
1756
+ git,
1757
+ fileManager,
1758
+ config.files,
1759
+ latestVersion
1760
+ );
1761
+ if (currentVersion.version) {
1762
+ latestVersion = currentVersion.version;
1763
+ }
1764
+ } catch {
1765
+ }
1766
+ if (!latestVersion && !latestTag) {
1767
+ console.error(
1768
+ util.styleText(
1769
+ "yellowBright",
1770
+ "No version found. Make sure you have at least one tag in your repository."
1771
+ )
1772
+ );
1773
+ process.exit(1);
1774
+ return;
1775
+ }
1776
+ switch (config.command) {
1777
+ case "inspect-version": {
1778
+ console.log(
1779
+ config.asJson ? JSON.stringify(
1780
+ {
1781
+ version: latestVersion
1782
+ },
1783
+ null,
1784
+ 2
1785
+ ) : latestVersion
1786
+ );
1787
+ return;
1788
+ }
1789
+ case "inspect-tag": {
1790
+ console.log(
1791
+ config.asJson ? JSON.stringify(
1792
+ {
1793
+ tag: latestTag
1794
+ },
1795
+ null,
1796
+ 2
1797
+ ) : latestTag
1798
+ );
1799
+ return;
1800
+ }
1801
+ default: {
1802
+ console.log(
1803
+ config.asJson ? JSON.stringify(
1804
+ {
1805
+ version: latestVersion,
1806
+ tag: latestTag
1807
+ },
1808
+ null,
1809
+ 2
1810
+ ) : `
1811
+ Version: ${latestVersion}
1812
+ Tag: ${latestTag}
1813
+ `.trim()
1814
+ );
1815
+ return;
1816
+ }
1817
+ }
1818
+ }
1820
1819
  function getPriority(type) {
1821
1820
  return ["patch", "minor", "major"].indexOf(type ?? "");
1822
1821
  }
1823
1822
  function getVersionType(version) {
1824
- const parseVersion = semver__default.default.parse(version);
1823
+ const parseVersion = semver5__default.default.parse(version);
1825
1824
  if (parseVersion?.major) {
1826
1825
  return "major";
1827
1826
  } else if (parseVersion?.minor) {
@@ -1835,7 +1834,7 @@ function getReleaseType(releaseType, currentVersion, preReleaseTag) {
1835
1834
  if (!preReleaseTag) {
1836
1835
  return releaseType;
1837
1836
  }
1838
- const currentVersionsIsPreRelease = Array.isArray(semver__default.default.prerelease(currentVersion));
1837
+ const currentVersionsIsPreRelease = Array.isArray(semver5__default.default.prerelease(currentVersion));
1839
1838
  if (currentVersionsIsPreRelease) {
1840
1839
  const currentReleaseType = getVersionType(currentVersion);
1841
1840
  if (currentReleaseType === releaseType || getPriority(currentReleaseType) > getPriority(releaseType)) {
@@ -1848,13 +1847,13 @@ function getReleaseType(releaseType, currentVersion, preReleaseTag) {
1848
1847
  // src/process/get-next-version.ts
1849
1848
  async function getNextVersion(config, logger, commits, currentVersion) {
1850
1849
  if (config.skipBump) {
1851
- logger.warn(`Skip bump, using ${currentVersion} as the next version`);
1850
+ logger.skipping(`Skipping bump, using ${currentVersion} as the next version`);
1852
1851
  return {
1853
1852
  version: currentVersion
1854
1853
  };
1855
1854
  }
1856
1855
  if (config.nextVersion) {
1857
- if (!semver__default.default.valid(config.nextVersion)) {
1856
+ if (!semver5__default.default.valid(config.nextVersion)) {
1858
1857
  throw new Error(`Invalid Version: ${config.nextVersion}`);
1859
1858
  }
1860
1859
  logger.log(`Next version: ${config.nextVersion}`);
@@ -1862,7 +1861,7 @@ async function getNextVersion(config, logger, commits, currentVersion) {
1862
1861
  version: config.nextVersion
1863
1862
  };
1864
1863
  }
1865
- const isPreMajor = semver__default.default.lt(currentVersion, "1.0.0");
1864
+ const isPreMajor = semver5__default.default.lt(currentVersion, "1.0.0");
1866
1865
  let releaseType = "patch";
1867
1866
  const changes = {
1868
1867
  major: 0,
@@ -1912,7 +1911,7 @@ async function getNextVersion(config, logger, commits, currentVersion) {
1912
1911
  }
1913
1912
  }
1914
1913
  const releaseTypeOrPreRelease = getReleaseType(releaseType, currentVersion, config.preRelease);
1915
- const nextVersion = semver__default.default.inc(
1914
+ const nextVersion = semver5__default.default.inc(
1916
1915
  currentVersion,
1917
1916
  releaseTypeOrPreRelease,
1918
1917
  typeof config.preRelease === "string" ? config.preRelease : ""
@@ -1974,7 +1973,7 @@ function getNewReleaseContent(config, logger, nextVersion) {
1974
1973
  }
1975
1974
  async function updateChangelog(config, logger, nextVersion) {
1976
1975
  if (config.skipChangelog) {
1977
- logger.warn("Skip changelog update");
1976
+ logger.skipping("Skipping changelog update");
1978
1977
  return;
1979
1978
  }
1980
1979
  if (config.header.search(RELEASE_PATTERN) !== -1) {
@@ -2012,7 +2011,7 @@ function formatCommitMessage(message, version) {
2012
2011
  // src/process/commit.ts
2013
2012
  async function commitChanges(config, logger, git, files, nextVersion) {
2014
2013
  if (config.skipCommit) {
2015
- logger.warn("Skip commit");
2014
+ logger.skipping("Skipping commit");
2016
2015
  return;
2017
2016
  }
2018
2017
  logger.log("Committing changes");
@@ -2044,7 +2043,7 @@ async function commitChanges(config, logger, git, files, nextVersion) {
2044
2043
  // src/process/tag.ts
2045
2044
  async function tagChanges(config, logger, git, nextVersion) {
2046
2045
  if (config.skipTag) {
2047
- logger.warn("Skip tag creation");
2046
+ logger.skipping("Skipping tag creation");
2048
2047
  return;
2049
2048
  }
2050
2049
  const tag = `${config.tagPrefix}${nextVersion}`;
@@ -2064,7 +2063,14 @@ async function main(config, logger, fileManager, git) {
2064
2063
  logger.log(`Running fork-version - ${(/* @__PURE__ */ new Date()).toUTCString()}`);
2065
2064
  logger.warn(config.dryRun ? "[Dry Run] No changes will be written to disk.\n" : "");
2066
2065
  const commits = await getCommitsSinceTag(config, logger, git);
2067
- const current = await getCurrentVersion(config, logger, git, fileManager, config.files);
2066
+ const current = await getCurrentVersion(
2067
+ config,
2068
+ logger,
2069
+ git,
2070
+ fileManager,
2071
+ config.files,
2072
+ commits.latestTagVersion
2073
+ );
2068
2074
  const next = await getNextVersion(config, logger, commits.commits, current.version);
2069
2075
  logger.log("Updating files: ");
2070
2076
  for (const outFile of current.files) {
@@ -2094,11 +2100,10 @@ exports.getCommitsSinceTag = getCommitsSinceTag;
2094
2100
  exports.getCurrentVersion = getCurrentVersion;
2095
2101
  exports.getNextVersion = getNextVersion;
2096
2102
  exports.getUserConfig = getUserConfig;
2097
- exports.inspectTag = inspectTag;
2098
- exports.inspectVersion = inspectVersion;
2103
+ exports.inspect = inspect;
2099
2104
  exports.main = main;
2100
2105
  exports.tagChanges = tagChanges;
2101
2106
  exports.updateChangelog = updateChangelog;
2102
2107
  exports.validateConfig = validateConfig;
2103
- //# sourceMappingURL=chunk-DZKKCJU5.cjs.map
2104
- //# sourceMappingURL=chunk-DZKKCJU5.cjs.map
2108
+ //# sourceMappingURL=chunk-JYQTKLHN.cjs.map
2109
+ //# sourceMappingURL=chunk-JYQTKLHN.cjs.map