screw-up 1.5.0 → 1.6.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.
@@ -1,11 +1,11 @@
1
1
  /*!
2
2
  * name: screw-up
3
- * version: 1.5.0
3
+ * version: 1.6.0
4
4
  * description: Simply package metadata inserter on Vite plugin
5
5
  * author: Kouji Matsui (@kekyo@mi.kekyo.net)
6
6
  * license: MIT
7
7
  * repository.url: https://github.com/kekyo/screw-up.git
8
- * git.commit.hash: 72fd5b88656bc400ba3fed500895826208e23217
8
+ * git.commit.hash: 10c04af9c9b127002592d48cbb6ec18cfe5048bb
9
9
  */
10
10
  "use strict";
11
11
  const fs = require("fs");
@@ -13,6 +13,8 @@ const fs$1 = require("fs/promises");
13
13
  const path = require("path");
14
14
  const glob = require("glob");
15
15
  const git = require("isomorphic-git");
16
+ const crypto = require("crypto");
17
+ const os = require("os");
16
18
  function _interopNamespaceDefault(e) {
17
19
  const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
18
20
  if (e) {
@@ -1669,6 +1671,397 @@ function requireDayjs_min() {
1669
1671
  }
1670
1672
  var dayjs_minExports = requireDayjs_min();
1671
1673
  const dayjs = /* @__PURE__ */ getDefaultExportFromCjs(dayjs_minExports);
1674
+ const CLEANUP_DELETE_AGE_MS = 10 * 24 * 60 * 60 * 1e3;
1675
+ const getCachePath = (repoPath) => {
1676
+ const absoluteRepoPath = path.resolve(repoPath);
1677
+ const pathHash = crypto.createHash("sha1").update(absoluteRepoPath).digest("hex");
1678
+ return path.join(
1679
+ os.homedir(),
1680
+ ".cache",
1681
+ "screw-up",
1682
+ "tag-cache",
1683
+ `${pathHash}.json`
1684
+ );
1685
+ };
1686
+ const buildCacheValidation = async (repoPath) => {
1687
+ const tags = await git__namespace.listTags({ fs: fs$1, dir: repoPath });
1688
+ const tagListHash = crypto.createHash("sha256").update(tags.sort().join("\n")).digest("hex");
1689
+ const validation = {
1690
+ tagListHash,
1691
+ tagCount: tags.length
1692
+ };
1693
+ try {
1694
+ const packedRefsPath = path.join(repoPath, ".git", "packed-refs");
1695
+ const stats = await fs$1.stat(packedRefsPath);
1696
+ validation.packedRefsMtime = stats.mtimeMs;
1697
+ } catch (e) {
1698
+ }
1699
+ try {
1700
+ const refsTagsPath = path.join(repoPath, ".git", "refs", "tags");
1701
+ const stats = await fs$1.stat(refsTagsPath);
1702
+ validation.refsTagsMtime = stats.mtimeMs;
1703
+ } catch (e) {
1704
+ }
1705
+ return validation;
1706
+ };
1707
+ const isCacheValid = async (cachedData, repoPath) => {
1708
+ try {
1709
+ const currentTags = await git__namespace.listTags({ fs: fs$1, dir: repoPath });
1710
+ if (currentTags.length !== cachedData.validation.tagCount) {
1711
+ return false;
1712
+ }
1713
+ const tagListHash = crypto.createHash("sha256").update(currentTags.sort().join("\n")).digest("hex");
1714
+ if (cachedData.validation.tagListHash !== tagListHash) {
1715
+ return false;
1716
+ }
1717
+ if (cachedData.validation.packedRefsMtime !== void 0) {
1718
+ try {
1719
+ const packedRefsPath = path.join(repoPath, ".git", "packed-refs");
1720
+ const stats = await fs$1.stat(packedRefsPath);
1721
+ if (stats.mtimeMs > cachedData.timestamp) {
1722
+ return false;
1723
+ }
1724
+ } catch (e) {
1725
+ }
1726
+ }
1727
+ if (cachedData.validation.refsTagsMtime !== void 0) {
1728
+ try {
1729
+ const refsTagsPath = path.join(repoPath, ".git", "refs", "tags");
1730
+ const stats = await fs$1.stat(refsTagsPath);
1731
+ if (stats.mtimeMs > cachedData.timestamp) {
1732
+ return false;
1733
+ }
1734
+ } catch (e) {
1735
+ }
1736
+ }
1737
+ return true;
1738
+ } catch (e) {
1739
+ return false;
1740
+ }
1741
+ };
1742
+ const loadCachedTags = async (repoPath) => {
1743
+ try {
1744
+ const cachePath = getCachePath(repoPath);
1745
+ const data = await fs$1.readFile(cachePath, "utf-8");
1746
+ const cachedData = JSON.parse(data);
1747
+ if (cachedData.version !== "1.0.0") {
1748
+ return null;
1749
+ }
1750
+ return cachedData;
1751
+ } catch (e) {
1752
+ return null;
1753
+ }
1754
+ };
1755
+ const saveCachedTags = async (repoPath, tagCache, validation) => {
1756
+ const cachePath = getCachePath(repoPath);
1757
+ const cacheDir = path.dirname(cachePath);
1758
+ await fs$1.mkdir(cacheDir, { recursive: true });
1759
+ const randomSuffix = crypto.randomBytes(8).toString("hex");
1760
+ const tempPath = cachePath.replace(".json", `_${randomSuffix}.json`);
1761
+ const data = {
1762
+ version: "1.0.0",
1763
+ timestamp: Date.now(),
1764
+ repository: {
1765
+ path: repoPath
1766
+ },
1767
+ validation,
1768
+ tagCache: {
1769
+ commitToTags: Object.fromEntries(tagCache.commitToTags)
1770
+ }
1771
+ };
1772
+ try {
1773
+ await fs$1.writeFile(tempPath, JSON.stringify(data, null, 2), "utf-8");
1774
+ await fs$1.rename(tempPath, cachePath);
1775
+ } catch (error) {
1776
+ try {
1777
+ await fs$1.unlink(tempPath);
1778
+ } catch (e) {
1779
+ }
1780
+ throw error;
1781
+ }
1782
+ };
1783
+ const reconstructTagCache = (cachedData) => {
1784
+ return {
1785
+ commitToTags: new Map(Object.entries(cachedData.tagCache.commitToTags)),
1786
+ initialized: true
1787
+ };
1788
+ };
1789
+ const cleanupOldCacheFiles = async (currentCachePath, currentTimestamp) => {
1790
+ let deletedCount = 0;
1791
+ try {
1792
+ const cacheDir = path.dirname(currentCachePath);
1793
+ const currentFileName = path.basename(currentCachePath);
1794
+ const files = await fs$1.readdir(cacheDir);
1795
+ await Promise.all(
1796
+ files.map(async (fileName) => {
1797
+ if (!fileName.endsWith(".json") || fileName === currentFileName) {
1798
+ return;
1799
+ }
1800
+ const filePath = path.join(cacheDir, fileName);
1801
+ try {
1802
+ const stats = await fs$1.stat(filePath);
1803
+ const fileAge = currentTimestamp - stats.mtimeMs;
1804
+ if (fileAge > CLEANUP_DELETE_AGE_MS) {
1805
+ await fs$1.unlink(filePath);
1806
+ deletedCount++;
1807
+ }
1808
+ } catch (e) {
1809
+ }
1810
+ })
1811
+ );
1812
+ } catch (e) {
1813
+ }
1814
+ return deletedCount;
1815
+ };
1816
+ const calculateTagDiff = (cachedTags, currentTagList) => {
1817
+ const cachedTagNames = /* @__PURE__ */ new Set();
1818
+ for (const tags of cachedTags.values()) {
1819
+ for (const tag of tags) {
1820
+ cachedTagNames.add(tag.name);
1821
+ }
1822
+ }
1823
+ const currentSet = new Set(currentTagList);
1824
+ const added = [];
1825
+ const unchanged = [];
1826
+ for (const tagName of currentTagList) {
1827
+ if (cachedTagNames.has(tagName)) {
1828
+ unchanged.push(tagName);
1829
+ } else {
1830
+ added.push(tagName);
1831
+ }
1832
+ }
1833
+ const deleted = [];
1834
+ for (const tagName of cachedTagNames) {
1835
+ if (!currentSet.has(tagName)) {
1836
+ deleted.push(tagName);
1837
+ }
1838
+ }
1839
+ return { added, deleted, unchanged };
1840
+ };
1841
+ const removeTagsFromCache = (cache, tagNames) => {
1842
+ const tagNamesToRemove = new Set(tagNames);
1843
+ const newCache = /* @__PURE__ */ new Map();
1844
+ for (const [commitHash, tags] of cache.entries()) {
1845
+ const filteredTags = tags.filter((tag) => !tagNamesToRemove.has(tag.name));
1846
+ if (filteredTags.length > 0) {
1847
+ newCache.set(commitHash, filteredTags);
1848
+ }
1849
+ }
1850
+ return newCache;
1851
+ };
1852
+ const addTagsToCache = (cache, newTags) => {
1853
+ const newCache = new Map(cache);
1854
+ for (const tag of newTags) {
1855
+ const existing = newCache.get(tag.hash) || [];
1856
+ const updated = [...existing, tag];
1857
+ updated.sort((a, b) => a.name.localeCompare(b.name));
1858
+ newCache.set(tag.hash, updated);
1859
+ }
1860
+ return newCache;
1861
+ };
1862
+ const updateTagsInCache = (cache, tagNames, updatedTags) => {
1863
+ let newCache = removeTagsFromCache(cache, tagNames);
1864
+ newCache = addTagsToCache(newCache, updatedTags);
1865
+ return newCache;
1866
+ };
1867
+ const resolveTagToCommit = async (repoPath, tagOid) => {
1868
+ var _a;
1869
+ try {
1870
+ const tagObject = await git__namespace.readTag({
1871
+ fs: fs$1,
1872
+ dir: repoPath,
1873
+ oid: tagOid
1874
+ });
1875
+ if ((_a = tagObject == null ? void 0 : tagObject.tag) == null ? void 0 : _a.object) {
1876
+ return tagObject.tag.object;
1877
+ }
1878
+ } catch (e) {
1879
+ }
1880
+ return tagOid;
1881
+ };
1882
+ const getTagsInfo = async (repoPath, tagNames, parseVersion2) => {
1883
+ const result = [];
1884
+ await Promise.all(
1885
+ tagNames.map(async (tagName) => {
1886
+ try {
1887
+ const oid = await git__namespace.resolveRef({
1888
+ fs: fs$1,
1889
+ dir: repoPath,
1890
+ ref: `refs/tags/${tagName}`
1891
+ });
1892
+ const commitHash = await resolveTagToCommit(repoPath, oid);
1893
+ const version2 = parseVersion2(tagName);
1894
+ result.push({
1895
+ name: tagName,
1896
+ hash: commitHash,
1897
+ version: version2
1898
+ });
1899
+ } catch (error) {
1900
+ console.warn(`Failed to get info for tag ${tagName}:`, error);
1901
+ }
1902
+ })
1903
+ );
1904
+ return result;
1905
+ };
1906
+ const buildCompleteTagCache = async (repoPath, parseVersion2) => {
1907
+ const cache = /* @__PURE__ */ new Map();
1908
+ const tags = await git__namespace.listTags({ fs: fs$1, dir: repoPath });
1909
+ await Promise.all(
1910
+ tags.map(async (tagName) => {
1911
+ const oid = await git__namespace.resolveRef({
1912
+ fs: fs$1,
1913
+ dir: repoPath,
1914
+ ref: `refs/tags/${tagName}`
1915
+ });
1916
+ const commitHash = await resolveTagToCommit(repoPath, oid);
1917
+ const version2 = parseVersion2(tagName);
1918
+ const tagInfo = {
1919
+ name: tagName,
1920
+ hash: commitHash,
1921
+ version: version2
1922
+ };
1923
+ if (!cache.has(commitHash)) {
1924
+ cache.set(commitHash, []);
1925
+ }
1926
+ cache.get(commitHash).push(tagInfo);
1927
+ })
1928
+ );
1929
+ for (const tags2 of cache.values()) {
1930
+ tags2.sort((a, b) => a.name.localeCompare(b.name));
1931
+ }
1932
+ return cache;
1933
+ };
1934
+ const hasTagMoved = async (repoPath, tagName, cachedCommit) => {
1935
+ try {
1936
+ const oid = await git__namespace.resolveRef({
1937
+ fs: fs$1,
1938
+ dir: repoPath,
1939
+ ref: `refs/tags/${tagName}`
1940
+ });
1941
+ const currentCommit = await resolveTagToCommit(repoPath, oid);
1942
+ return currentCommit !== cachedCommit;
1943
+ } catch (e) {
1944
+ return true;
1945
+ }
1946
+ };
1947
+ const findModifiedTags = async (repoPath, tagNames, cache) => {
1948
+ const modified = [];
1949
+ await Promise.all(
1950
+ tagNames.map(async (tagName) => {
1951
+ let cachedCommit;
1952
+ for (const [commit, tags] of cache.entries()) {
1953
+ const tag = tags.find((t) => t.name === tagName);
1954
+ if (tag) {
1955
+ cachedCommit = commit;
1956
+ break;
1957
+ }
1958
+ }
1959
+ if (cachedCommit) {
1960
+ const moved = await hasTagMoved(repoPath, tagName, cachedCommit);
1961
+ if (moved) {
1962
+ modified.push(tagName);
1963
+ }
1964
+ }
1965
+ })
1966
+ );
1967
+ return modified;
1968
+ };
1969
+ const loadOrBuildTagCache = async (repoPath, parseVersion2, logger) => {
1970
+ const startTime = Date.now();
1971
+ const cachedData = await loadCachedTags(repoPath);
1972
+ const currentTags = await git__namespace.listTags({ fs: fs$1, dir: repoPath });
1973
+ if (cachedData && await isCacheValid(cachedData, repoPath)) {
1974
+ logger.debug(`Cache valid, performing differential update...`);
1975
+ const cache = reconstructTagCache(cachedData);
1976
+ const stats = await performDifferentialUpdate(
1977
+ repoPath,
1978
+ cache.commitToTags,
1979
+ currentTags,
1980
+ parseVersion2,
1981
+ logger
1982
+ );
1983
+ const validation = await buildCacheValidation(repoPath);
1984
+ await saveCachedTags(repoPath, cache, validation);
1985
+ if (cachedData && Date.now() - cachedData.timestamp > 24 * 60 * 60 * 1e3) {
1986
+ try {
1987
+ const cachePath = getCachePath(repoPath);
1988
+ const deletedCount = await cleanupOldCacheFiles(cachePath, Date.now());
1989
+ if (deletedCount > 0) {
1990
+ logger.debug(`Cleaned up ${deletedCount} old cache files`);
1991
+ }
1992
+ } catch (e) {
1993
+ }
1994
+ }
1995
+ return {
1996
+ cache,
1997
+ stats: {
1998
+ ...stats,
1999
+ updateTime: Date.now() - startTime,
2000
+ fullRebuild: false
2001
+ }
2002
+ };
2003
+ } else {
2004
+ logger.debug(`Cache invalid or missing, building from scratch...`);
2005
+ const commitToTags = await buildCompleteTagCache(repoPath, parseVersion2);
2006
+ const cache = {
2007
+ commitToTags,
2008
+ initialized: true
2009
+ };
2010
+ const validation = await buildCacheValidation(repoPath);
2011
+ await saveCachedTags(repoPath, cache, validation);
2012
+ return {
2013
+ cache,
2014
+ stats: {
2015
+ added: currentTags.length,
2016
+ deleted: 0,
2017
+ modified: 0,
2018
+ unchanged: 0,
2019
+ totalTags: currentTags.length,
2020
+ updateTime: Date.now() - startTime,
2021
+ fullRebuild: true
2022
+ }
2023
+ };
2024
+ }
2025
+ };
2026
+ async function performDifferentialUpdate(repoPath, cache, currentTags, parseVersion2, logger) {
2027
+ const diff = calculateTagDiff(cache, currentTags);
2028
+ logger.debug(
2029
+ `Tag diff: +${diff.added.length} -${diff.deleted.length} =${diff.unchanged.length}`
2030
+ );
2031
+ const modified = await findModifiedTags(repoPath, diff.unchanged, cache);
2032
+ logger.debug(`Found ${modified.length} modified tags`);
2033
+ if (diff.deleted.length > 0) {
2034
+ const newCache = removeTagsFromCache(cache, diff.deleted);
2035
+ cache.clear();
2036
+ for (const [k, v] of newCache) {
2037
+ cache.set(k, v);
2038
+ }
2039
+ }
2040
+ if (diff.added.length > 0) {
2041
+ const newTags = await getTagsInfo(repoPath, diff.added, parseVersion2);
2042
+ const newCache = addTagsToCache(cache, newTags);
2043
+ cache.clear();
2044
+ for (const [k, v] of newCache) {
2045
+ cache.set(k, v);
2046
+ }
2047
+ }
2048
+ if (modified.length > 0) {
2049
+ const updatedTags = await getTagsInfo(repoPath, modified, parseVersion2);
2050
+ const newCache = updateTagsInCache(cache, modified, updatedTags);
2051
+ cache.clear();
2052
+ for (const [k, v] of newCache) {
2053
+ cache.set(k, v);
2054
+ }
2055
+ }
2056
+ const unchangedCount = diff.unchanged.length - modified.length;
2057
+ return {
2058
+ added: diff.added.length,
2059
+ deleted: diff.deleted.length,
2060
+ modified: modified.length,
2061
+ unchanged: unchangedCount,
2062
+ totalTags: currentTags.length
2063
+ };
2064
+ }
1672
2065
  const parseVersionComponent = (value) => {
1673
2066
  const num = parseInt(value, 10);
1674
2067
  return num < 0 || num > 65535 ? void 0 : num;
@@ -1794,67 +2187,6 @@ const getCurrentCommit = async (repositoryPath) => {
1794
2187
  return void 0;
1795
2188
  }
1796
2189
  };
1797
- const buildTagCache = async (repositoryPath) => {
1798
- const cache = {
1799
- commitToTags: /* @__PURE__ */ new Map(),
1800
- initialized: true
1801
- };
1802
- try {
1803
- const tags = await git__namespace.listTags({ fs: fs__namespace, dir: repositoryPath });
1804
- await Promise.all(
1805
- tags.map(async (tagName) => {
1806
- try {
1807
- const tagOid = await git__namespace.resolveRef({
1808
- fs: fs__namespace,
1809
- dir: repositoryPath,
1810
- ref: `refs/tags/${tagName}`
1811
- });
1812
- const version2 = parseVersion(tagName);
1813
- const tagInfo = {
1814
- name: tagName,
1815
- hash: tagOid,
1816
- // This will be updated for annotated tags
1817
- version: version2 && isValidVersion(version2) ? version2 : void 0
1818
- };
1819
- if (!cache.commitToTags.has(tagOid)) {
1820
- cache.commitToTags.set(tagOid, []);
1821
- }
1822
- cache.commitToTags.get(tagOid).push({ ...tagInfo, hash: tagOid });
1823
- try {
1824
- const tagObject = await git__namespace.readTag({
1825
- fs: fs__namespace,
1826
- dir: repositoryPath,
1827
- oid: tagOid
1828
- });
1829
- if (tagObject && tagObject.tag.object) {
1830
- const commitOid = tagObject.tag.object;
1831
- const lightweightTags = cache.commitToTags.get(tagOid);
1832
- if (lightweightTags) {
1833
- const index = lightweightTags.findIndex(
1834
- (t) => t.name === tagName
1835
- );
1836
- if (index >= 0) {
1837
- lightweightTags.splice(index, 1);
1838
- if (lightweightTags.length === 0) {
1839
- cache.commitToTags.delete(tagOid);
1840
- }
1841
- }
1842
- }
1843
- if (!cache.commitToTags.has(commitOid)) {
1844
- cache.commitToTags.set(commitOid, []);
1845
- }
1846
- cache.commitToTags.get(commitOid).push({ ...tagInfo, hash: commitOid });
1847
- }
1848
- } catch (e) {
1849
- }
1850
- } catch (e) {
1851
- }
1852
- })
1853
- );
1854
- } catch (e) {
1855
- }
1856
- return cache;
1857
- };
1858
2190
  const getRelatedTagsFromCache = (cache, commitHash) => {
1859
2191
  if (!cache.initialized) {
1860
2192
  return [];
@@ -2019,10 +2351,23 @@ const getGitMetadata = async (repositoryPath, checkWorkingDirectoryStatus, logge
2019
2351
  if (!currentCommit) {
2020
2352
  return metadata;
2021
2353
  }
2022
- const tagCache = await buildTagCache(gitRootPath);
2023
- logger.debug(
2024
- `Built tag cache with ${tagCache.commitToTags.size} commit entries`
2354
+ const { cache: tagCache, stats } = await loadOrBuildTagCache(
2355
+ gitRootPath,
2356
+ (tagName) => {
2357
+ const version22 = parseVersion(tagName);
2358
+ return version22 && isValidVersion(version22) ? version22 : void 0;
2359
+ },
2360
+ logger
2025
2361
  );
2362
+ if (stats.fullRebuild) {
2363
+ logger.debug(
2364
+ `Built new tag cache: ${stats.totalTags} tags in ${stats.updateTime}ms`
2365
+ );
2366
+ } else {
2367
+ logger.debug(
2368
+ `Updated cache differentially: +${stats.added} -${stats.deleted} ~${stats.modified} =${stats.unchanged} (${stats.updateTime}ms)`
2369
+ );
2370
+ }
2026
2371
  const reachedCommits = /* @__PURE__ */ new Map();
2027
2372
  let version2 = await lookupVersionLabelRecursive(
2028
2373
  gitRootPath,
@@ -2079,11 +2424,11 @@ const getFetchGitMetadata = (targetDir, checkWorkingDirectoryStatus, logger) =>
2079
2424
  };
2080
2425
  };
2081
2426
  const name = "screw-up";
2082
- const version = "1.5.0";
2427
+ const version = "1.6.0";
2083
2428
  const author = "Kouji Matsui (@kekyo@mi.kekyo.net)";
2084
2429
  const license = "MIT";
2085
2430
  const repository_url = "https://github.com/kekyo/screw-up.git";
2086
- const git_commit_hash = "72fd5b88656bc400ba3fed500895826208e23217";
2431
+ const git_commit_hash = "10c04af9c9b127002592d48cbb6ec18cfe5048bb";
2087
2432
  const packageMetadata = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2088
2433
  __proto__: null,
2089
2434
  author,
@@ -2104,4 +2449,4 @@ exports.replacePeerDependenciesWildcards = replacePeerDependenciesWildcards;
2104
2449
  exports.resolvePackageMetadata = resolvePackageMetadata;
2105
2450
  exports.resolveRawPackageJsonObject = resolveRawPackageJsonObject;
2106
2451
  exports.version = version;
2107
- //# sourceMappingURL=packageMetadata-CbqTWPYD.cjs.map
2452
+ //# sourceMappingURL=packageMetadata-CCW9p12u.cjs.map