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.
@@ -1,12 +1,13 @@
1
1
  import { z } from 'zod';
2
2
  import { execFile } from 'child_process';
3
- import semver from 'semver';
4
- import { resolve, parse } from 'path';
5
- import { glob } from 'glob';
3
+ import semver5 from 'semver';
4
+ import { resolve, join, isAbsolute, parse, basename } from 'path';
5
+ import { glob } from 'fs/promises';
6
6
  import conventionalChangelogConfigSpec from 'conventional-changelog-config-spec';
7
7
  import { writeFileSync, readFileSync, lstatSync } from 'fs';
8
8
  import JoyCon from 'joycon';
9
9
  import { bundleRequire } from 'bundle-require';
10
+ import { styleText } from 'util';
10
11
  import { modify, applyEdits, parse as parse$1 } from 'jsonc-parser';
11
12
  import { parse as parse$2, parseDocument } from 'yaml';
12
13
  import * as cheerio from 'cheerio/slim';
@@ -79,12 +80,13 @@ var ForkConfigSchema = z.object({
79
80
  * - `main` - Bumps the version, update files, generate changelog, commit, and tag.
80
81
  * - `inspect-version` - Prints the current version and exits.
81
82
  * - `inspect-tag` - Prints the current git tag and exits.
83
+ * - `inspect` - Prints the current version and git tag and exits.
82
84
  * - `validate-config` - Validates the configuration and exits.
83
85
  *
84
86
  * @default "main"
85
87
  */
86
- command: z.literal(["main", "inspect-version", "inspect-tag", "validate-config"]).describe(
87
- "The command to run. Can be one of: main, inspect-version, inspect-tag, validate-config. Defaults to main."
88
+ command: z.literal(["main", "inspect", "inspect-version", "inspect-tag", "validate-config"]).describe(
89
+ "The command to run. Can be one of: main, inspect, inspect-version, inspect-tag, validate-config. Defaults to main."
88
90
  ),
89
91
  /**
90
92
  * If set, Fork-Version will print the current version and exit.
@@ -247,6 +249,11 @@ var ForkConfigSchema = z.object({
247
249
  * @default false
248
250
  */
249
251
  verify: z.boolean().describe("If true, git will run user defined git hooks before committing."),
252
+ /**
253
+ * Output result as JSON.
254
+ * @default false
255
+ */
256
+ asJson: z.boolean().describe("Output the result as JSON."),
250
257
  // Skip Steps
251
258
  //
252
259
  /**
@@ -289,8 +296,11 @@ function escapeRegex(input) {
289
296
 
290
297
  // src/services/git.ts
291
298
  var Git = class {
299
+ #path;
300
+ #dryRun;
292
301
  constructor(config) {
293
- this.config = config;
302
+ this.#path = config.path;
303
+ this.#dryRun = config.dryRun ?? false;
294
304
  this.add = this.add.bind(this);
295
305
  this.commit = this.commit.bind(this);
296
306
  this.tag = this.tag.bind(this);
@@ -300,8 +310,6 @@ var Git = class {
300
310
  this.getRemoteUrl = this.getRemoteUrl.bind(this);
301
311
  this.getTags = this.getTags.bind(this);
302
312
  this.getMostRecentTag = this.getMostRecentTag.bind(this);
303
- this.getCleanedTags = this.getCleanedTags.bind(this);
304
- this.getHighestSemverVersionFromTags = this.getHighestSemverVersionFromTags.bind(this);
305
313
  this.getCommits = this.getCommits.bind(this);
306
314
  }
307
315
  async #execGit(command, args) {
@@ -310,7 +318,7 @@ var Git = class {
310
318
  "git",
311
319
  [command, ...args],
312
320
  {
313
- cwd: this.config.path,
321
+ cwd: this.#path,
314
322
  maxBuffer: Infinity
315
323
  },
316
324
  (error, stdout, stderr) => {
@@ -334,7 +342,7 @@ var Git = class {
334
342
  * ```
335
343
  */
336
344
  async add(...args) {
337
- if (this.config.dryRun) {
345
+ if (this.#dryRun) {
338
346
  return "";
339
347
  }
340
348
  return this.#execGit("add", args.filter(Boolean));
@@ -350,7 +358,7 @@ var Git = class {
350
358
  * ```
351
359
  */
352
360
  async commit(...args) {
353
- if (this.config.dryRun) {
361
+ if (this.#dryRun) {
354
362
  return "";
355
363
  }
356
364
  return this.#execGit("commit", args.filter(Boolean));
@@ -366,7 +374,7 @@ var Git = class {
366
374
  * ```
367
375
  */
368
376
  async tag(...args) {
369
- if (this.config.dryRun) {
377
+ if (this.#dryRun) {
370
378
  return "";
371
379
  }
372
380
  return this.#execGit("tag", args.filter(Boolean));
@@ -475,18 +483,18 @@ var Git = class {
475
483
  if (tagPrefix) {
476
484
  if (tag.startsWith(tagPrefix)) {
477
485
  const tagWithoutPrefix = tag.replace(new RegExp(`^${escapedTagPrefix}`), "");
478
- if (semver.valid(tagWithoutPrefix)) {
486
+ if (semver5.valid(tagWithoutPrefix)) {
479
487
  tags.push(tag);
480
488
  }
481
489
  }
482
- } else if (/^\d/.test(tag) && semver.valid(tag)) {
490
+ } else if (/^\d/.test(tag) && semver5.valid(tag)) {
483
491
  tags.push(tag);
484
492
  }
485
493
  }
486
494
  return tags;
487
495
  }
488
496
  /**
489
- * Returns the latest git tag based on commit date
497
+ * Returns the most recent tag from the commit history, or `undefined` if no valid semver tags are found
490
498
  *
491
499
  * @example
492
500
  * ```ts
@@ -497,40 +505,6 @@ var Git = class {
497
505
  const tags = await this.getTags(tagPrefix);
498
506
  return tags[0] || void 0;
499
507
  }
500
- /**
501
- * Get cleaned semver tags, with any tag prefix's removed
502
- *
503
- * @example
504
- * ```ts
505
- * await git.getCleanedTags("v"); // ["1.2.3", "1.2.2", "1.2.1"]
506
- * ```
507
- */
508
- async getCleanedTags(tagPrefix) {
509
- const tags = await this.getTags(tagPrefix);
510
- const escapedTagPrefix = tagPrefix ? escapeRegex(tagPrefix) : void 0;
511
- const cleanedTags = [];
512
- for (const tag of tags) {
513
- const tagWithoutPrefix = tag.replace(new RegExp(`^${escapedTagPrefix}`), "");
514
- const cleanedTag = semver.clean(tagWithoutPrefix);
515
- if (cleanedTag) {
516
- cleanedTags.push(cleanedTag);
517
- }
518
- }
519
- return cleanedTags;
520
- }
521
- /**
522
- * Get the highest semver version from git tags. This will return the highest
523
- * semver version found for the given tag prefix, regardless of the commit date.
524
- *
525
- * @example
526
- * ```ts
527
- * await git.getHighestSemverVersionFromTags("v"); // "1.2.3"
528
- * ```
529
- */
530
- async getHighestSemverVersionFromTags(tagPrefix) {
531
- const cleanedTags = await this.getCleanedTags(tagPrefix);
532
- return cleanedTags.sort(semver.rcompare)[0] || void 0;
533
- }
534
508
  /**
535
509
  * Get commit history in a parsable format
536
510
  *
@@ -685,6 +659,7 @@ All notable changes to this project will be documented in this file. See [fork-v
685
659
  gitTagFallback: true,
686
660
  sign: false,
687
661
  verify: false,
662
+ asJson: false,
688
663
  // Skip Steps
689
664
  skipBump: false,
690
665
  skipChangelog: false,
@@ -694,11 +669,8 @@ All notable changes to this project will be documented in this file. See [fork-v
694
669
  };
695
670
 
696
671
  // src/config/detect-git-host.ts
697
- async function detectGitHost(cwd) {
698
- const remoteUrl = await new Git({
699
- path: cwd,
700
- dryRun: false
701
- }).getRemoteUrl();
672
+ async function detectGitHost(path) {
673
+ const remoteUrl = await new Git({ path }).getRemoteUrl();
702
674
  if (remoteUrl.startsWith("https://") && remoteUrl.includes("@dev.azure.com/")) {
703
675
  const match = /^https:\/\/(?<atorganisation>.*?)@dev.azure.com\/(?<organisation>.*?)\/(?<project>.*?)\/_git\/(?<repository>.*?)(?:\.git)?$/.exec(
704
676
  remoteUrl
@@ -797,13 +769,19 @@ async function getUserConfig(cliArguments) {
797
769
  ...configFile,
798
770
  ...cliArguments.flags
799
771
  };
800
- let globResults = [];
772
+ const globResults = [];
801
773
  if (mergedConfig.glob) {
802
- globResults = await glob(mergedConfig.glob, {
774
+ const IGNORE_LIST = /* @__PURE__ */ new Set(["node_modules", ".git"]);
775
+ const entries = glob(mergedConfig.glob, {
803
776
  cwd,
804
- ignore: ["node_modules/**"],
805
- nodir: true
777
+ withFileTypes: true,
778
+ exclude: (entry) => IGNORE_LIST.has(entry.name)
806
779
  });
780
+ for await (const entry of entries) {
781
+ if (entry.isFile()) {
782
+ globResults.push(join(entry.parentPath, entry.name));
783
+ }
784
+ }
807
785
  }
808
786
  const files = mergeFiles(configFile?.files, cliArguments.flags.files, globResults);
809
787
  const detectedGitHost = await detectGitHost(cwd);
@@ -835,36 +813,44 @@ async function getUserConfig(cliArguments) {
835
813
  changelogPresetConfig
836
814
  };
837
815
  }
838
-
839
- // src/services/logger.ts
840
816
  var Logger = class {
817
+ #silent;
818
+ #debug;
841
819
  constructor(config) {
842
- this.config = config;
820
+ this.#silent = config.silent ?? false;
821
+ this.#debug = config.debug ?? false;
843
822
  this.log = this.log.bind(this);
844
823
  this.warn = this.warn.bind(this);
845
824
  this.error = this.error.bind(this);
846
825
  this.debug = this.debug.bind(this);
847
- this.disableLogs = this.config.silent;
826
+ this.skipping = this.skipping.bind(this);
848
827
  }
849
- disableLogs = false;
850
- log(...messages) {
851
- if (!this.disableLogs) {
852
- console.log(...messages);
828
+ log(message) {
829
+ if (!this.#silent) {
830
+ console.log(message);
853
831
  }
854
832
  }
855
- warn(...messages) {
856
- if (!this.disableLogs) {
857
- console.warn(...messages);
833
+ warn(message) {
834
+ if (!this.#silent) {
835
+ console.warn(styleText("yellowBright", message));
858
836
  }
859
837
  }
860
- error(...messages) {
861
- if (!this.disableLogs) {
862
- console.error(...messages);
838
+ error(message) {
839
+ if (!this.#silent) {
840
+ console.error(styleText("redBright", message));
863
841
  }
864
842
  }
865
- debug(...messages) {
866
- if (this.config.debug && !this.disableLogs) {
867
- console.debug(...messages);
843
+ debug(message, ...optionalParams) {
844
+ if (!this.#silent && this.#debug) {
845
+ console.debug(styleText("cyanBright", message));
846
+ if (optionalParams.length > 0) {
847
+ console.debug(...optionalParams);
848
+ }
849
+ }
850
+ }
851
+ skipping(message) {
852
+ if (!this.#silent) {
853
+ console.log(styleText("magenta", message));
868
854
  }
869
855
  }
870
856
  };
@@ -875,15 +861,13 @@ function fileExists(filePath) {
875
861
  return false;
876
862
  }
877
863
  }
878
-
879
- // src/files/json-package.ts
880
864
  var JSONPackage = class {
881
- constructor(config, logger) {
882
- this.config = config;
883
- this.logger = logger;
865
+ #logger;
866
+ constructor(logger) {
867
+ this.#logger = logger;
884
868
  }
885
869
  /** Options for parsing JSON and JSONC files. */
886
- PARSE_OPTIONS = {
870
+ #jsoncOptions = {
887
871
  allowEmptyContent: false,
888
872
  allowTrailingComma: true,
889
873
  disallowComments: false
@@ -895,42 +879,32 @@ var JSONPackage = class {
895
879
  * @param newString string to set the value to
896
880
  * @returns the JSON or JSONC string with the value set
897
881
  */
898
- setStringInJsonc(jsonc, jsonPath, newString) {
882
+ #setStringInJsonc(jsonc, jsonPath, newString) {
899
883
  const edits = modify(jsonc, jsonPath, newString, {});
900
884
  return applyEdits(jsonc, edits);
901
885
  }
902
- read(fileName) {
903
- const filePath = resolve(this.config.path, fileName);
904
- if (fileExists(filePath)) {
905
- const fileContents = readFileSync(filePath, "utf8");
906
- const parseErrors = [];
907
- const parsedJson = parse$1(fileContents, parseErrors, this.PARSE_OPTIONS);
908
- if (parseErrors.length) {
909
- this.logger.warn(`[File Manager] Unable to parse JSON: ${fileName}`, parseErrors);
910
- return void 0;
911
- }
912
- if (parsedJson?.version) {
913
- return {
914
- name: fileName,
915
- path: filePath,
916
- version: parsedJson.version,
917
- isPrivate: typeof parsedJson?.private === "boolean" ? parsedJson.private : true
918
- };
919
- }
920
- this.logger.warn(`[File Manager] Unable to determine json version: ${fileName}`);
886
+ read(filePath) {
887
+ const fileName = basename(filePath);
888
+ const fileContents = readFileSync(filePath, "utf8");
889
+ const parseErrors = [];
890
+ const parsedJson = parse$1(fileContents, parseErrors, this.#jsoncOptions);
891
+ if (parsedJson?.version && parseErrors.length === 0) {
892
+ return {
893
+ name: fileName,
894
+ path: filePath,
895
+ version: parsedJson.version,
896
+ isPrivate: typeof parsedJson?.private === "boolean" ? parsedJson.private : true
897
+ };
921
898
  }
899
+ this.#logger.warn(`[File Manager] Unable to determine json version: ${fileName}`);
922
900
  }
923
901
  write(fileState, newVersion) {
924
902
  let fileContents = readFileSync(fileState.path, "utf8");
925
903
  const parseErrors = [];
926
- const parsedJson = parse$1(fileContents, parseErrors, this.PARSE_OPTIONS);
927
- if (parseErrors.length) {
928
- this.logger.warn(`[File Manager] Unable to parse JSON: ${fileState.path}`, parseErrors);
929
- return;
930
- }
931
- fileContents = this.setStringInJsonc(fileContents, ["version"], newVersion);
904
+ const parsedJson = parse$1(fileContents, parseErrors, this.#jsoncOptions);
905
+ fileContents = this.#setStringInJsonc(fileContents, ["version"], newVersion);
932
906
  if (parsedJson?.packages?.[""]) {
933
- fileContents = this.setStringInJsonc(fileContents, ["packages", "", "version"], newVersion);
907
+ fileContents = this.#setStringInJsonc(fileContents, ["packages", "", "version"], newVersion);
934
908
  }
935
909
  writeFileSync(fileState.path, fileContents, "utf8");
936
910
  }
@@ -939,16 +913,16 @@ var JSONPackage = class {
939
913
  }
940
914
  };
941
915
  var YAMLPackage = class {
942
- constructor(config, logger) {
943
- this.config = config;
944
- this.logger = logger;
916
+ #logger;
917
+ constructor(logger) {
918
+ this.#logger = logger;
945
919
  }
946
920
  /**
947
921
  * If the version is returned with a "+" symbol in the value then the version might be from a
948
922
  * flutter `pubspec.yaml` file, if so we want to retain the input builderNumber by splitting it
949
923
  * and joining it again later.
950
924
  */
951
- handleBuildNumber(fileVersion) {
925
+ #handleBuildNumber(fileVersion) {
952
926
  const [version, builderNumber] = fileVersion.split("+");
953
927
  if (/^\d+$/.test(builderNumber)) {
954
928
  return {
@@ -960,22 +934,20 @@ var YAMLPackage = class {
960
934
  version: fileVersion
961
935
  };
962
936
  }
963
- read(fileName) {
964
- const filePath = resolve(this.config.path, fileName);
965
- if (fileExists(filePath)) {
966
- const fileContents = readFileSync(filePath, "utf-8");
967
- const fileVersion = parse$2(fileContents)?.version;
968
- if (fileVersion) {
969
- const parsedVersion = this.handleBuildNumber(fileVersion);
970
- return {
971
- name: fileName,
972
- path: filePath,
973
- version: parsedVersion.version || "",
974
- builderNumber: parsedVersion.builderNumber ?? void 0
975
- };
976
- }
937
+ read(filePath) {
938
+ const fileName = basename(filePath);
939
+ const fileContents = readFileSync(filePath, "utf-8");
940
+ const fileVersion = parse$2(fileContents)?.version;
941
+ if (fileVersion) {
942
+ const parsedVersion = this.#handleBuildNumber(fileVersion);
943
+ return {
944
+ name: fileName,
945
+ path: filePath,
946
+ version: parsedVersion.version || "",
947
+ builderNumber: parsedVersion.builderNumber ?? void 0
948
+ };
977
949
  }
978
- this.logger.warn(`[File Manager] Unable to determine yaml version: ${fileName}`);
950
+ this.#logger.warn(`[File Manager] Unable to determine yaml version: ${fileName}`);
979
951
  }
980
952
  write(fileState, newVersion) {
981
953
  const fileContents = readFileSync(fileState.path, "utf8");
@@ -992,21 +964,21 @@ var YAMLPackage = class {
992
964
  }
993
965
  };
994
966
  var PlainText = class {
995
- constructor(config, logger) {
996
- this.config = config;
997
- this.logger = logger;
967
+ #logger;
968
+ constructor(logger) {
969
+ this.#logger = logger;
998
970
  }
999
- read(fileName) {
1000
- const filePath = resolve(this.config.path, fileName);
1001
- if (fileExists(filePath)) {
1002
- const fileContents = readFileSync(filePath, "utf8");
971
+ read(filePath) {
972
+ const fileName = basename(filePath);
973
+ const fileContents = readFileSync(filePath, "utf8").trim();
974
+ if (fileContents) {
1003
975
  return {
1004
976
  name: fileName,
1005
977
  path: filePath,
1006
- version: fileContents || ""
978
+ version: fileContents
1007
979
  };
1008
980
  }
1009
- this.logger.warn(`[File Manager] Unable to determine plain text version: ${fileName}`);
981
+ this.#logger.warn(`[File Manager] Unable to determine plain text version: ${fileName}`);
1010
982
  }
1011
983
  write(fileState, newVersion) {
1012
984
  writeFileSync(fileState.path, newVersion, "utf8");
@@ -1016,35 +988,31 @@ var PlainText = class {
1016
988
  }
1017
989
  };
1018
990
  var MSBuildProject = class {
1019
- constructor(config, logger) {
1020
- this.config = config;
1021
- this.logger = logger;
1022
- }
1023
- read(fileName) {
1024
- const filePath = resolve(this.config.path, fileName);
1025
- if (fileExists(filePath)) {
1026
- const fileContents = readFileSync(filePath, "utf8");
1027
- const $ = cheerio.load(fileContents, {
1028
- xmlMode: true,
1029
- xml: { decodeEntities: false }
1030
- });
1031
- const version = $("Project > PropertyGroup > Version").text();
1032
- if (version) {
1033
- return {
1034
- name: fileName,
1035
- path: filePath,
1036
- version
1037
- };
1038
- }
1039
- this.logger.warn(`[File Manager] Unable to determine ms-build version: ${fileName}`);
991
+ #logger;
992
+ constructor(logger) {
993
+ this.#logger = logger;
994
+ }
995
+ #cheerioOptions = {
996
+ xmlMode: true,
997
+ xml: { decodeEntities: false }
998
+ };
999
+ read(filePath) {
1000
+ const fileName = basename(filePath);
1001
+ const fileContents = readFileSync(filePath, "utf8");
1002
+ const $ = cheerio.load(fileContents, this.#cheerioOptions);
1003
+ const version = $("Project > PropertyGroup > Version").text();
1004
+ if (version) {
1005
+ return {
1006
+ name: fileName,
1007
+ path: filePath,
1008
+ version
1009
+ };
1040
1010
  }
1011
+ this.#logger.warn(`[File Manager] Unable to determine ms-build version: ${fileName}`);
1041
1012
  }
1042
1013
  write(fileState, newVersion) {
1043
1014
  const fileContents = readFileSync(fileState.path, "utf8");
1044
- const $ = cheerio.load(fileContents, {
1045
- xmlMode: true,
1046
- xml: { decodeEntities: false }
1047
- });
1015
+ const $ = cheerio.load(fileContents, this.#cheerioOptions);
1048
1016
  $("Project > PropertyGroup > Version").text(newVersion);
1049
1017
  const updatedContent = $.xml().replaceAll('"/>', '" />');
1050
1018
  writeFileSync(fileState.path, updatedContent, "utf8");
@@ -1056,40 +1024,38 @@ var MSBuildProject = class {
1056
1024
  }
1057
1025
  };
1058
1026
  var ARMBicep = class {
1059
- constructor(config, logger) {
1060
- this.config = config;
1061
- this.logger = logger;
1027
+ #logger;
1028
+ constructor(logger) {
1029
+ this.#logger = logger;
1062
1030
  }
1063
1031
  /** https://regex101.com/r/Lriphb/2 */
1064
- metadataRegex = /(metadata contentVersion *= *['"])(?<version>[^'"]+)(['"])/;
1032
+ #metadataRegex = /(metadata contentVersion *= *['"])(?<version>[^'"]+)(['"])/;
1065
1033
  /** https://regex101.com/r/iKCTF9/1 */
1066
- varRegex = /(var contentVersion(?: string)? *= *['"])(?<version>[^'"]+)(['"])/;
1067
- read(fileName) {
1068
- const filePath = resolve(this.config.path, fileName);
1069
- if (fileExists(filePath)) {
1070
- const fileContents = readFileSync(filePath, "utf8");
1071
- const metadataMatch = this.metadataRegex.exec(fileContents);
1072
- const varMatch = this.varRegex.exec(fileContents);
1073
- if (metadataMatch?.groups?.version && varMatch?.groups?.version) {
1074
- return {
1075
- name: fileName,
1076
- path: filePath,
1077
- version: metadataMatch.groups.version
1078
- };
1079
- }
1080
- if (!metadataMatch) {
1081
- this.logger.warn(
1082
- `[File Manager] Missing 'metadata contentVersion' in bicep file: ${fileName}`
1083
- );
1084
- }
1085
- if (!varMatch) {
1086
- this.logger.warn(`[File Manager] Missing 'var contentVersion' in bicep file: ${fileName}`);
1087
- }
1034
+ #varRegex = /(var contentVersion(?: string)? *= *['"])(?<version>[^'"]+)(['"])/;
1035
+ read(filePath) {
1036
+ const fileName = basename(filePath);
1037
+ const fileContents = readFileSync(filePath, "utf8");
1038
+ const metadataMatch = this.#metadataRegex.exec(fileContents);
1039
+ const varMatch = this.#varRegex.exec(fileContents);
1040
+ if (metadataMatch?.groups?.version && varMatch?.groups?.version) {
1041
+ return {
1042
+ name: fileName,
1043
+ path: filePath,
1044
+ version: metadataMatch.groups.version
1045
+ };
1046
+ }
1047
+ if (!metadataMatch) {
1048
+ this.#logger.warn(
1049
+ `[File Manager] Missing 'metadata contentVersion' in bicep file: ${fileName}`
1050
+ );
1051
+ }
1052
+ if (!varMatch) {
1053
+ this.#logger.warn(`[File Manager] Missing 'var contentVersion' in bicep file: ${fileName}`);
1088
1054
  }
1089
1055
  }
1090
1056
  write(fileState, newVersion) {
1091
1057
  const fileContents = readFileSync(fileState.path, "utf8");
1092
- const updatedContent = fileContents.replace(this.metadataRegex, `$1${newVersion}$3`).replace(this.varRegex, `$1${newVersion}$3`);
1058
+ const updatedContent = fileContents.replace(this.#metadataRegex, `$1${newVersion}$3`).replace(this.#varRegex, `$1${newVersion}$3`);
1093
1059
  writeFileSync(fileState.path, updatedContent, "utf8");
1094
1060
  }
1095
1061
  isSupportedFile(fileName) {
@@ -1097,35 +1063,31 @@ var ARMBicep = class {
1097
1063
  }
1098
1064
  };
1099
1065
  var InstallShieldISM = class {
1100
- constructor(config, logger) {
1101
- this.config = config;
1102
- this.logger = logger;
1103
- }
1104
- read(fileName) {
1105
- const filePath = resolve(this.config.path, fileName);
1106
- if (fileExists(filePath)) {
1107
- const fileContents = readFileSync(filePath, "utf8");
1108
- const $ = cheerio.load(fileContents, {
1109
- xmlMode: true,
1110
- xml: { decodeEntities: false }
1111
- });
1112
- const version = $('msi > table[name="Property"] > row > td:contains("ProductVersion")').next().text().trim();
1113
- if (version) {
1114
- return {
1115
- name: fileName,
1116
- path: filePath,
1117
- version
1118
- };
1119
- }
1120
- this.logger.warn(`[File Manager] Unable to determine InstallShield ISM version: ${fileName}`);
1066
+ #logger;
1067
+ constructor(logger) {
1068
+ this.#logger = logger;
1069
+ }
1070
+ #cheerioOptions = {
1071
+ xmlMode: true,
1072
+ xml: { decodeEntities: false }
1073
+ };
1074
+ read(filePath) {
1075
+ const fileName = basename(filePath);
1076
+ const fileContents = readFileSync(filePath, "utf8");
1077
+ const $ = cheerio.load(fileContents, this.#cheerioOptions);
1078
+ const version = $('msi > table[name="Property"] > row > td:contains("ProductVersion")').next().text().trim();
1079
+ if (version) {
1080
+ return {
1081
+ name: fileName,
1082
+ path: filePath,
1083
+ version
1084
+ };
1121
1085
  }
1086
+ this.#logger.warn(`[File Manager] Unable to determine InstallShield ISM version: ${fileName}`);
1122
1087
  }
1123
1088
  write(fileState, newVersion) {
1124
1089
  const fileContents = readFileSync(fileState.path, "utf8");
1125
- const $ = cheerio.load(fileContents, {
1126
- xmlMode: true,
1127
- xml: { decodeEntities: false }
1128
- });
1090
+ const $ = cheerio.load(fileContents, this.#cheerioOptions);
1129
1091
  const versionCell = $(
1130
1092
  'msi > table[name="Property"] > row > td:contains("ProductVersion")'
1131
1093
  ).next();
@@ -1142,22 +1104,21 @@ var InstallShieldISM = class {
1142
1104
 
1143
1105
  // src/files/file-manager.ts
1144
1106
  var FileManager = class {
1107
+ #config;
1108
+ #logger;
1109
+ #fileManagers = [];
1145
1110
  constructor(config, logger) {
1146
- this.config = config;
1147
- this.logger = logger;
1148
- this.JSONPackage = new JSONPackage(config, logger);
1149
- this.YAMLPackage = new YAMLPackage(config, logger);
1150
- this.PlainText = new PlainText(config, logger);
1151
- this.MSBuildProject = new MSBuildProject(config, logger);
1152
- this.ARMBicep = new ARMBicep(config, logger);
1153
- this.InstallShieldISM = new InstallShieldISM(config, logger);
1154
- }
1155
- JSONPackage;
1156
- YAMLPackage;
1157
- PlainText;
1158
- MSBuildProject;
1159
- ARMBicep;
1160
- InstallShieldISM;
1111
+ this.#config = config;
1112
+ this.#logger = logger;
1113
+ this.#fileManagers = [
1114
+ new JSONPackage(logger),
1115
+ new YAMLPackage(logger),
1116
+ new PlainText(logger),
1117
+ new MSBuildProject(logger),
1118
+ new ARMBicep(logger),
1119
+ new InstallShieldISM(logger)
1120
+ ];
1121
+ }
1161
1122
  /**
1162
1123
  * Get the state from the given file name.
1163
1124
  *
@@ -1171,27 +1132,16 @@ var FileManager = class {
1171
1132
  * { "name": "package.json", "path": "/path/to/package.json", "version": "1.2.3", "isPrivate": true }
1172
1133
  * ```
1173
1134
  */
1174
- read(fileName) {
1175
- const _fileName = fileName.toLowerCase();
1176
- if (this.JSONPackage.isSupportedFile(_fileName)) {
1177
- return this.JSONPackage.read(fileName);
1178
- }
1179
- if (this.YAMLPackage.isSupportedFile(_fileName)) {
1180
- return this.YAMLPackage.read(fileName);
1181
- }
1182
- if (this.PlainText.isSupportedFile(_fileName)) {
1183
- return this.PlainText.read(fileName);
1184
- }
1185
- if (this.MSBuildProject.isSupportedFile(_fileName)) {
1186
- return this.MSBuildProject.read(fileName);
1187
- }
1188
- if (this.ARMBicep.isSupportedFile(_fileName)) {
1189
- return this.ARMBicep.read(fileName);
1190
- }
1191
- if (this.InstallShieldISM.isSupportedFile(_fileName)) {
1192
- return this.InstallShieldISM.read(fileName);
1135
+ read(pathOrName) {
1136
+ const _fileName = pathOrName.toLowerCase();
1137
+ const filePath = isAbsolute(pathOrName) ? pathOrName : resolve(this.#config.path, pathOrName);
1138
+ if (!fileExists(filePath)) return;
1139
+ for (const fileManager of this.#fileManagers) {
1140
+ if (fileManager.isSupportedFile(_fileName)) {
1141
+ return fileManager.read(filePath);
1142
+ }
1193
1143
  }
1194
- this.logger.error(`[File Manager] Unsupported file: ${fileName}`);
1144
+ this.#logger.error(`[File Manager] Unsupported file: ${pathOrName}`);
1195
1145
  }
1196
1146
  /**
1197
1147
  * Write the new version to the given file.
@@ -1205,29 +1155,16 @@ var FileManager = class {
1205
1155
  * ```
1206
1156
  */
1207
1157
  write(fileState, newVersion) {
1208
- if (this.config.dryRun) {
1158
+ if (this.#config.dryRun) {
1209
1159
  return;
1210
1160
  }
1211
1161
  const _fileName = fileState.name.toLowerCase();
1212
- if (this.JSONPackage.isSupportedFile(_fileName)) {
1213
- return this.JSONPackage.write(fileState, newVersion);
1214
- }
1215
- if (this.YAMLPackage.isSupportedFile(_fileName)) {
1216
- return this.YAMLPackage.write(fileState, newVersion);
1217
- }
1218
- if (this.PlainText.isSupportedFile(_fileName)) {
1219
- return this.PlainText.write(fileState, newVersion);
1220
- }
1221
- if (this.MSBuildProject.isSupportedFile(_fileName)) {
1222
- return this.MSBuildProject.write(fileState, newVersion);
1223
- }
1224
- if (this.ARMBicep.isSupportedFile(_fileName)) {
1225
- return this.ARMBicep.write(fileState, newVersion);
1226
- }
1227
- if (this.InstallShieldISM.isSupportedFile(_fileName)) {
1228
- return this.InstallShieldISM.write(fileState, newVersion);
1162
+ for (const fileManager of this.#fileManagers) {
1163
+ if (fileManager.isSupportedFile(_fileName)) {
1164
+ return fileManager.write(fileState, newVersion);
1165
+ }
1229
1166
  }
1230
- this.logger.error(`[File Manager] Unsupported file: ${fileState.path}`);
1167
+ this.#logger.error(`[File Manager] Unsupported file: ${fileState.path}`);
1231
1168
  }
1232
1169
  };
1233
1170
 
@@ -1240,66 +1177,6 @@ ${JSON.stringify(config, null, 2)}
1240
1177
  \u2705 Configuration is valid.
1241
1178
  `);
1242
1179
  }
1243
- async function getCurrentVersion(config, logger, git, fileManager, filesToUpdate) {
1244
- const files = [];
1245
- const versions = /* @__PURE__ */ new Set();
1246
- for (const file of filesToUpdate) {
1247
- if (await git.isIgnored(file)) {
1248
- logger.debug(`[Git Ignored] ${file}`);
1249
- continue;
1250
- }
1251
- const fileState = fileManager.read(file);
1252
- if (fileState) {
1253
- files.push(fileState);
1254
- if (!config.currentVersion) {
1255
- versions.add(fileState.version);
1256
- }
1257
- }
1258
- }
1259
- if (config.currentVersion) {
1260
- versions.add(config.currentVersion);
1261
- }
1262
- if (versions.size === 0 && config.gitTagFallback) {
1263
- const version = await git.getHighestSemverVersionFromTags(config.tagPrefix);
1264
- if (version) {
1265
- logger.warn(`Using latest git tag as fallback`);
1266
- versions.add(version);
1267
- }
1268
- }
1269
- if (versions.size === 0) {
1270
- throw new Error("Unable to find current version");
1271
- } else if (versions.size > 1) {
1272
- if (!config.allowMultipleVersions) {
1273
- throw new Error("Found multiple versions");
1274
- }
1275
- logger.warn(
1276
- `Found multiple versions (${Array.from(versions).join(", ")}), using the higher semver version`
1277
- );
1278
- }
1279
- const currentVersion = semver.rsort(Array.from(versions))[0];
1280
- logger.log(`Current version: ${currentVersion}`);
1281
- return {
1282
- files,
1283
- version: currentVersion
1284
- };
1285
- }
1286
-
1287
- // src/commands/inspect-version.ts
1288
- async function inspectVersion(config, logger, fileManager, git) {
1289
- let foundVersion = "";
1290
- try {
1291
- const currentVersion = await getCurrentVersion(config, logger, git, fileManager, config.files);
1292
- if (currentVersion) foundVersion = currentVersion.version;
1293
- } catch {
1294
- }
1295
- console.log(foundVersion);
1296
- }
1297
-
1298
- // src/commands/inspect-tag.ts
1299
- async function inspectTag(config, git) {
1300
- const tag = await git.getMostRecentTag(config.tagPrefix);
1301
- console.log(tag ?? "");
1302
- }
1303
1180
 
1304
1181
  // src/utils/trim-string-array.ts
1305
1182
  function trimStringArray(array) {
@@ -1763,6 +1640,12 @@ function filterRevertedCommits(parsedCommits) {
1763
1640
  }
1764
1641
  return commitsWithoutReverts;
1765
1642
  }
1643
+ function cleanTag(tag, tagPrefix) {
1644
+ if (!tag) return void 0;
1645
+ const escapedTagPrefix = tagPrefix ? escapeRegex(tagPrefix) : void 0;
1646
+ const tagWithoutPrefix = escapedTagPrefix ? tag.replace(new RegExp(`^${escapedTagPrefix}`), "") : tag;
1647
+ return semver5.clean(tagWithoutPrefix) ?? void 0;
1648
+ }
1766
1649
 
1767
1650
  // src/process/get-commits.ts
1768
1651
  async function getCommitsSinceTag(config, logger, git) {
@@ -1773,7 +1656,6 @@ async function getCommitsSinceTag(config, logger, git) {
1773
1656
  logger.warn("No previous tag found, using all commits");
1774
1657
  }
1775
1658
  const foundCommits = await git.getCommits(latestTag, "HEAD");
1776
- logger.debug(`Found ${foundCommits.length} commits since last tag (${latestTag ?? "none"})`);
1777
1659
  const commits = foundCommits.reduce((acc, commit) => {
1778
1660
  const parsed = commitParser.parse(commit);
1779
1661
  if (parsed) {
@@ -1781,19 +1663,136 @@ async function getCommitsSinceTag(config, logger, git) {
1781
1663
  }
1782
1664
  return acc;
1783
1665
  }, []);
1784
- logger.debug(`Parsed ${commits.length} commits after applying commit parser`);
1785
1666
  const filteredCommits = filterRevertedCommits(commits);
1786
- logger.debug(`Filtered to ${filteredCommits.length} commits after removing reverts`);
1667
+ logger.debug(
1668
+ `Found ${foundCommits.length} commits since tag: ${latestTag ?? "none"} (${commits.length} parsed, ${filteredCommits.length} after filtering reverts)`
1669
+ );
1787
1670
  return {
1788
1671
  latestTag,
1672
+ latestTagVersion: cleanTag(latestTag, config.tagPrefix),
1789
1673
  commits: filteredCommits
1790
1674
  };
1791
1675
  }
1676
+ async function getCurrentVersion(config, logger, git, fileManager, filesToUpdate, latestTagVersion) {
1677
+ const files = [];
1678
+ const versions = /* @__PURE__ */ new Set();
1679
+ for (const file of filesToUpdate) {
1680
+ if (await git.isIgnored(file)) {
1681
+ logger.debug(`[Git Ignored] ${file}`);
1682
+ continue;
1683
+ }
1684
+ const fileState = fileManager.read(file);
1685
+ if (fileState) {
1686
+ files.push(fileState);
1687
+ if (!config.currentVersion) {
1688
+ versions.add(fileState.version);
1689
+ }
1690
+ }
1691
+ }
1692
+ if (config.currentVersion) {
1693
+ versions.add(config.currentVersion);
1694
+ }
1695
+ if (versions.size === 0 && config.gitTagFallback && latestTagVersion) {
1696
+ logger.warn(`Using latest git tag as fallback`);
1697
+ versions.add(latestTagVersion);
1698
+ }
1699
+ if (versions.size === 0) {
1700
+ throw new Error("Unable to find current version");
1701
+ } else if (versions.size > 1) {
1702
+ if (!config.allowMultipleVersions) {
1703
+ throw new Error("Found multiple versions");
1704
+ }
1705
+ logger.warn(
1706
+ `Found multiple versions (${Array.from(versions).join(", ")}), using the higher semver version`
1707
+ );
1708
+ }
1709
+ const currentVersion = semver5.rsort(Array.from(versions))[0];
1710
+ logger.log(`Current version: ${currentVersion}`);
1711
+ return {
1712
+ files,
1713
+ version: currentVersion
1714
+ };
1715
+ }
1716
+ async function inspect(config, logger, fileManager, git) {
1717
+ let latestTag = "";
1718
+ let latestVersion = "";
1719
+ try {
1720
+ const commits = await getCommitsSinceTag(config, logger, git);
1721
+ if (commits.latestTag) {
1722
+ latestTag = commits.latestTag;
1723
+ latestVersion = commits.latestTagVersion ?? "";
1724
+ }
1725
+ const currentVersion = await getCurrentVersion(
1726
+ config,
1727
+ logger,
1728
+ git,
1729
+ fileManager,
1730
+ config.files,
1731
+ latestVersion
1732
+ );
1733
+ if (currentVersion.version) {
1734
+ latestVersion = currentVersion.version;
1735
+ }
1736
+ } catch {
1737
+ }
1738
+ if (!latestVersion && !latestTag) {
1739
+ console.error(
1740
+ styleText(
1741
+ "yellowBright",
1742
+ "No version found. Make sure you have at least one tag in your repository."
1743
+ )
1744
+ );
1745
+ process.exit(1);
1746
+ return;
1747
+ }
1748
+ switch (config.command) {
1749
+ case "inspect-version": {
1750
+ console.log(
1751
+ config.asJson ? JSON.stringify(
1752
+ {
1753
+ version: latestVersion
1754
+ },
1755
+ null,
1756
+ 2
1757
+ ) : latestVersion
1758
+ );
1759
+ return;
1760
+ }
1761
+ case "inspect-tag": {
1762
+ console.log(
1763
+ config.asJson ? JSON.stringify(
1764
+ {
1765
+ tag: latestTag
1766
+ },
1767
+ null,
1768
+ 2
1769
+ ) : latestTag
1770
+ );
1771
+ return;
1772
+ }
1773
+ default: {
1774
+ console.log(
1775
+ config.asJson ? JSON.stringify(
1776
+ {
1777
+ version: latestVersion,
1778
+ tag: latestTag
1779
+ },
1780
+ null,
1781
+ 2
1782
+ ) : `
1783
+ Version: ${latestVersion}
1784
+ Tag: ${latestTag}
1785
+ `.trim()
1786
+ );
1787
+ return;
1788
+ }
1789
+ }
1790
+ }
1792
1791
  function getPriority(type) {
1793
1792
  return ["patch", "minor", "major"].indexOf(type ?? "");
1794
1793
  }
1795
1794
  function getVersionType(version) {
1796
- const parseVersion = semver.parse(version);
1795
+ const parseVersion = semver5.parse(version);
1797
1796
  if (parseVersion?.major) {
1798
1797
  return "major";
1799
1798
  } else if (parseVersion?.minor) {
@@ -1807,7 +1806,7 @@ function getReleaseType(releaseType, currentVersion, preReleaseTag) {
1807
1806
  if (!preReleaseTag) {
1808
1807
  return releaseType;
1809
1808
  }
1810
- const currentVersionsIsPreRelease = Array.isArray(semver.prerelease(currentVersion));
1809
+ const currentVersionsIsPreRelease = Array.isArray(semver5.prerelease(currentVersion));
1811
1810
  if (currentVersionsIsPreRelease) {
1812
1811
  const currentReleaseType = getVersionType(currentVersion);
1813
1812
  if (currentReleaseType === releaseType || getPriority(currentReleaseType) > getPriority(releaseType)) {
@@ -1820,13 +1819,13 @@ function getReleaseType(releaseType, currentVersion, preReleaseTag) {
1820
1819
  // src/process/get-next-version.ts
1821
1820
  async function getNextVersion(config, logger, commits, currentVersion) {
1822
1821
  if (config.skipBump) {
1823
- logger.warn(`Skip bump, using ${currentVersion} as the next version`);
1822
+ logger.skipping(`Skipping bump, using ${currentVersion} as the next version`);
1824
1823
  return {
1825
1824
  version: currentVersion
1826
1825
  };
1827
1826
  }
1828
1827
  if (config.nextVersion) {
1829
- if (!semver.valid(config.nextVersion)) {
1828
+ if (!semver5.valid(config.nextVersion)) {
1830
1829
  throw new Error(`Invalid Version: ${config.nextVersion}`);
1831
1830
  }
1832
1831
  logger.log(`Next version: ${config.nextVersion}`);
@@ -1834,7 +1833,7 @@ async function getNextVersion(config, logger, commits, currentVersion) {
1834
1833
  version: config.nextVersion
1835
1834
  };
1836
1835
  }
1837
- const isPreMajor = semver.lt(currentVersion, "1.0.0");
1836
+ const isPreMajor = semver5.lt(currentVersion, "1.0.0");
1838
1837
  let releaseType = "patch";
1839
1838
  const changes = {
1840
1839
  major: 0,
@@ -1884,7 +1883,7 @@ async function getNextVersion(config, logger, commits, currentVersion) {
1884
1883
  }
1885
1884
  }
1886
1885
  const releaseTypeOrPreRelease = getReleaseType(releaseType, currentVersion, config.preRelease);
1887
- const nextVersion = semver.inc(
1886
+ const nextVersion = semver5.inc(
1888
1887
  currentVersion,
1889
1888
  releaseTypeOrPreRelease,
1890
1889
  typeof config.preRelease === "string" ? config.preRelease : ""
@@ -1946,7 +1945,7 @@ function getNewReleaseContent(config, logger, nextVersion) {
1946
1945
  }
1947
1946
  async function updateChangelog(config, logger, nextVersion) {
1948
1947
  if (config.skipChangelog) {
1949
- logger.warn("Skip changelog update");
1948
+ logger.skipping("Skipping changelog update");
1950
1949
  return;
1951
1950
  }
1952
1951
  if (config.header.search(RELEASE_PATTERN) !== -1) {
@@ -1984,7 +1983,7 @@ function formatCommitMessage(message, version) {
1984
1983
  // src/process/commit.ts
1985
1984
  async function commitChanges(config, logger, git, files, nextVersion) {
1986
1985
  if (config.skipCommit) {
1987
- logger.warn("Skip commit");
1986
+ logger.skipping("Skipping commit");
1988
1987
  return;
1989
1988
  }
1990
1989
  logger.log("Committing changes");
@@ -2016,7 +2015,7 @@ async function commitChanges(config, logger, git, files, nextVersion) {
2016
2015
  // src/process/tag.ts
2017
2016
  async function tagChanges(config, logger, git, nextVersion) {
2018
2017
  if (config.skipTag) {
2019
- logger.warn("Skip tag creation");
2018
+ logger.skipping("Skipping tag creation");
2020
2019
  return;
2021
2020
  }
2022
2021
  const tag = `${config.tagPrefix}${nextVersion}`;
@@ -2036,7 +2035,14 @@ async function main(config, logger, fileManager, git) {
2036
2035
  logger.log(`Running fork-version - ${(/* @__PURE__ */ new Date()).toUTCString()}`);
2037
2036
  logger.warn(config.dryRun ? "[Dry Run] No changes will be written to disk.\n" : "");
2038
2037
  const commits = await getCommitsSinceTag(config, logger, git);
2039
- const current = await getCurrentVersion(config, logger, git, fileManager, config.files);
2038
+ const current = await getCurrentVersion(
2039
+ config,
2040
+ logger,
2041
+ git,
2042
+ fileManager,
2043
+ config.files,
2044
+ commits.latestTagVersion
2045
+ );
2040
2046
  const next = await getNextVersion(config, logger, commits.commits, current.version);
2041
2047
  logger.log("Updating files: ");
2042
2048
  for (const outFile of current.files) {
@@ -2054,6 +2060,6 @@ async function main(config, logger, fileManager, git) {
2054
2060
  };
2055
2061
  }
2056
2062
 
2057
- export { CommitParser, FileManager, ForkConfigSchema, Git, Logger, commitChanges, createParserOptions, filterRevertedCommits, getCommitsSinceTag, getCurrentVersion, getNextVersion, getUserConfig, inspectTag, inspectVersion, main, tagChanges, updateChangelog, validateConfig };
2058
- //# sourceMappingURL=chunk-35VBEKVS.js.map
2059
- //# sourceMappingURL=chunk-35VBEKVS.js.map
2063
+ export { CommitParser, FileManager, ForkConfigSchema, Git, Logger, commitChanges, createParserOptions, filterRevertedCommits, getCommitsSinceTag, getCurrentVersion, getNextVersion, getUserConfig, inspect, main, tagChanges, updateChangelog, validateConfig };
2064
+ //# sourceMappingURL=chunk-5CZU5EA7.js.map
2065
+ //# sourceMappingURL=chunk-5CZU5EA7.js.map