@codluv/versionguard 0.7.0 → 0.8.0

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.
@@ -1592,6 +1592,89 @@ function checkHardcodedVersions(expectedVersion, config, ignorePatterns, cwd = p
1592
1592
  }
1593
1593
  return mismatches;
1594
1594
  }
1595
+ const BINARY_EXTENSIONS = /* @__PURE__ */ new Set([
1596
+ ".png",
1597
+ ".jpg",
1598
+ ".jpeg",
1599
+ ".gif",
1600
+ ".ico",
1601
+ ".svg",
1602
+ ".woff",
1603
+ ".woff2",
1604
+ ".ttf",
1605
+ ".eot",
1606
+ ".otf",
1607
+ ".zip",
1608
+ ".tar",
1609
+ ".gz",
1610
+ ".bz2",
1611
+ ".7z",
1612
+ ".pdf",
1613
+ ".exe",
1614
+ ".dll",
1615
+ ".so",
1616
+ ".dylib",
1617
+ ".wasm",
1618
+ ".mp3",
1619
+ ".mp4",
1620
+ ".webm",
1621
+ ".webp",
1622
+ ".avif"
1623
+ ]);
1624
+ function scanRepoForVersions(expectedVersion, scanConfig, ignorePatterns, cwd = process.cwd()) {
1625
+ const files = [
1626
+ ...new Set(
1627
+ globSync("**/*", {
1628
+ cwd,
1629
+ absolute: true,
1630
+ dot: true,
1631
+ ignore: [
1632
+ ...ignorePatterns,
1633
+ // Always skip changelogs (handled by changelog validation) and lockfiles
1634
+ "CHANGELOG.md",
1635
+ "*.lock",
1636
+ "package-lock.json",
1637
+ "yarn.lock",
1638
+ "pnpm-lock.yaml",
1639
+ // Skip VG's own config
1640
+ ".versionguard.yml",
1641
+ ".versionguard.yaml"
1642
+ ]
1643
+ })
1644
+ )
1645
+ ].sort();
1646
+ const allowedFiles = new Set(
1647
+ scanConfig.allowlist.flatMap((entry) => resolveFiles([entry.file], cwd, []))
1648
+ );
1649
+ const mismatches = [];
1650
+ for (const filePath of files) {
1651
+ if (BINARY_EXTENSIONS.has(path.extname(filePath).toLowerCase())) continue;
1652
+ if (allowedFiles.has(filePath)) continue;
1653
+ let content;
1654
+ try {
1655
+ content = fs.readFileSync(filePath, "utf-8");
1656
+ } catch {
1657
+ continue;
1658
+ }
1659
+ if (content.slice(0, 8192).includes("\0")) continue;
1660
+ for (const patternStr of scanConfig.patterns) {
1661
+ const regex = new RegExp(patternStr, "gm");
1662
+ let match = regex.exec(content);
1663
+ while (match) {
1664
+ const found = match[1] ?? match[0] ?? "";
1665
+ if (found && found !== expectedVersion && found !== "Unreleased") {
1666
+ mismatches.push({
1667
+ file: path.relative(cwd, filePath),
1668
+ line: getLineNumber(content, match.index),
1669
+ found
1670
+ });
1671
+ }
1672
+ match = regex.exec(content);
1673
+ }
1674
+ }
1675
+ }
1676
+ return mismatches;
1677
+ }
1595
1678
  const DEFAULT_SEMVER_CONFIG = {
1596
1679
  allowVPrefix: false,
1597
1680
  allowBuildMetadata: true,
@@ -1811,6 +1894,18 @@ const DEFAULT_CONFIG = {
1811
1894
  enforceStructure: false,
1812
1895
  sections: ["Added", "Changed", "Deprecated", "Removed", "Fixed", "Security"]
1813
1896
  },
1897
+ scan: {
1898
+ enabled: false,
1899
+ patterns: [
1900
+ // version = "1.2.3" or version: "1.2.3" in code/config
1901
+ `(?:version\\s*[:=]\\s*["'])([\\d]+\\.[\\d]+\\.[\\d]+(?:-[\\w.]+)?)["']`,
1902
+ // Docker FROM image:1.2.3
1903
+ "(?:FROM\\s+\\S+:)(\\d+\\.\\d+\\.\\d+(?:-[\\w.]+)?)",
1904
+ // GitHub Actions uses: action@v1.2.3
1905
+ "(?:uses:\\s+\\S+@v?)(\\d+\\.\\d+\\.\\d+(?:-[\\w.]+)?)"
1906
+ ],
1907
+ allowlist: []
1908
+ },
1814
1909
  git: {
1815
1910
  hooks: {
1816
1911
  "pre-commit": true,
@@ -2829,6 +2924,14 @@ function validate(config, cwd = process.cwd()) {
2829
2924
  );
2830
2925
  }
2831
2926
  }
2927
+ if (config.scan?.enabled) {
2928
+ const scanFindings = scanRepoForVersions(version, config.scan, config.ignore, cwd);
2929
+ for (const finding of scanFindings) {
2930
+ errors.push(
2931
+ `Stale version in ${finding.file}:${finding.line} - found "${finding.found}" but expected "${version}"`
2932
+ );
2933
+ }
2934
+ }
2832
2935
  let changelogValid = true;
2833
2936
  if (config.changelog.enabled) {
2834
2937
  const changelogPath = path.join(cwd, config.changelog.file);
@@ -2924,7 +3027,7 @@ function isWorktreeClean(cwd) {
2924
3027
  }
2925
3028
  }
2926
3029
  export {
2927
- validateVersion as $,
3030
+ validateTagForPush as $,
2928
3031
  checkHardcodedVersions as A,
2929
3032
  checkHookIntegrity as B,
2930
3033
  checkHooksPathOverride as C,
@@ -2943,16 +3046,17 @@ export {
2943
3046
  initConfig as P,
2944
3047
  resolveVersionSource as Q,
2945
3048
  RegexVersionSource as R,
2946
- semver as S,
3049
+ scanRepoForVersions as S,
2947
3050
  TomlVersionSource as T,
2948
- suggestTagMessage as U,
3051
+ semver as U,
2949
3052
  VersionFileSource as V,
2950
- sync as W,
2951
- syncVersion as X,
3053
+ suggestTagMessage as W,
3054
+ sync as X,
2952
3055
  YamlVersionSource as Y,
2953
- validateChangelog as Z,
2954
- validateTagForPush as _,
3056
+ syncVersion as Z,
3057
+ validateChangelog as _,
2955
3058
  installHooks as a,
3059
+ validateVersion as a0,
2956
3060
  getPackageVersion as b,
2957
3061
  createCkmEngine as c,
2958
3062
  getVersionFeedback as d,
@@ -2979,4 +3083,4 @@ export {
2979
3083
  canBump as y,
2980
3084
  checkEnforceHooksPolicy as z
2981
3085
  };
2982
- //# sourceMappingURL=index-DWiw8Nps.js.map
3086
+ //# sourceMappingURL=index-Cipg9sxE.js.map