screw-up 1.31.0 → 1.33.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.
- package/dist/index.cjs +604 -179
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +4 -4
- package/dist/main.cjs +620 -195
- package/dist/main.cjs.map +1 -1
- package/dist/main.mjs +6 -6
- package/dist/{metadata-file-BWd04LhD.js → metadata-file-Case8fsm.js} +603 -177
- package/dist/metadata-file-Case8fsm.js.map +1 -0
- package/dist/{packageMetadata-BsMXJpMH.js → packageMetadata-4rUlIBjt.js} +6 -6
- package/dist/{packageMetadata-BsMXJpMH.js.map → packageMetadata-4rUlIBjt.js.map} +1 -1
- package/dist/{packageMetadata-BDGBM3Fx.cjs → packageMetadata-CaaD3Ehh.cjs} +3 -3
- package/dist/{packageMetadata-ip0rBTwa.cjs → packageMetadata-k_QXJ2PH.cjs} +5 -5
- package/dist/{packageMetadata-ip0rBTwa.cjs.map → packageMetadata-k_QXJ2PH.cjs.map} +1 -1
- package/dist/src/analyzer.d.ts +2 -2
- package/dist/src/analyzer.d.ts.map +1 -1
- package/dist/src/cli-internal.d.ts +2 -2
- package/dist/src/cli.d.ts +2 -2
- package/dist/src/declaration-import-fix.d.ts +2 -2
- package/dist/src/default-import-fix.d.ts +2 -2
- package/dist/src/fast-tags.d.ts +2 -2
- package/dist/src/fast-tags.d.ts.map +1 -1
- package/dist/src/generated/packageMetadata.d.ts +4 -4
- package/dist/src/git-operations.d.ts +2 -2
- package/dist/src/git-operations.d.ts.map +1 -1
- package/dist/src/git-ref-utils.d.ts +46 -4
- package/dist/src/git-ref-utils.d.ts.map +1 -1
- package/dist/src/index.d.ts +2 -2
- package/dist/src/internal.d.ts +2 -2
- package/dist/src/main.d.ts +2 -2
- package/dist/src/metadata-file.d.ts +2 -2
- package/dist/src/text-edits.d.ts +2 -2
- package/dist/src/types.d.ts +2 -2
- package/dist/src/vite-plugin.d.ts +2 -2
- package/package.json +8 -8
- package/dist/metadata-file-BWd04LhD.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* name: screw-up
|
|
3
|
-
* version: 1.
|
|
3
|
+
* version: 1.33.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:
|
|
8
|
+
* git.commit.hash: be56ff1901b5073e1b0238a28b80d0c4f3c1e894
|
|
9
9
|
*/
|
|
10
10
|
//#region \0rolldown/runtime.js
|
|
11
11
|
var __create = Object.create;
|
|
@@ -31,13 +31,14 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
31
31
|
}) : target, mod));
|
|
32
32
|
//#endregion
|
|
33
33
|
let fs_promises = require("fs/promises");
|
|
34
|
-
fs_promises = __toESM(fs_promises);
|
|
34
|
+
fs_promises = __toESM(fs_promises, 1);
|
|
35
35
|
let fs = require("fs");
|
|
36
36
|
let path = require("path");
|
|
37
37
|
require("glob");
|
|
38
38
|
let isomorphic_git = require("isomorphic-git");
|
|
39
|
-
isomorphic_git = __toESM(isomorphic_git);
|
|
39
|
+
isomorphic_git = __toESM(isomorphic_git, 1);
|
|
40
40
|
let crypto$1 = require("crypto");
|
|
41
|
+
let zlib = require("zlib");
|
|
41
42
|
//#region node_modules/async-primitives/dist/index.mjs
|
|
42
43
|
/*!
|
|
43
44
|
* name: async-primitives
|
|
@@ -222,8 +223,8 @@ createLogicalContext(Symbol("[root]"));
|
|
|
222
223
|
//#endregion
|
|
223
224
|
//#region src/generated/packageMetadata.ts
|
|
224
225
|
var name = "screw-up";
|
|
225
|
-
var version = "1.
|
|
226
|
-
var git_commit_hash = "
|
|
226
|
+
var version = "1.33.0";
|
|
227
|
+
var git_commit_hash = "be56ff1901b5073e1b0238a28b80d0c4f3c1e894";
|
|
227
228
|
//#endregion
|
|
228
229
|
//#region node_modules/json5/dist/index.js
|
|
229
230
|
var require_dist = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
@@ -1686,10 +1687,10 @@ var require_dayjs_min = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
1686
1687
|
//#region src/internal.ts
|
|
1687
1688
|
var import_dist = /* @__PURE__ */ __toESM(require_dist(), 1);
|
|
1688
1689
|
var import_dayjs_min = /* @__PURE__ */ __toESM(require_dayjs_min(), 1);
|
|
1689
|
-
var JSON5 = __resolveDefaultExport$
|
|
1690
|
-
var dayjs$1 = __resolveDefaultExport$
|
|
1690
|
+
var JSON5 = __resolveDefaultExport$2(import_dist.default, false);
|
|
1691
|
+
var dayjs$1 = __resolveDefaultExport$2(import_dayjs_min.default, false);
|
|
1691
1692
|
globalThis.__screwUpIsInCJS_db7919f73ec9 = true;
|
|
1692
|
-
function __resolveDefaultExport$
|
|
1693
|
+
function __resolveDefaultExport$2(module, isESM) {
|
|
1693
1694
|
const __isInCJS = typeof globalThis !== "undefined" && globalThis.__screwUpIsInCJS_db7919f73ec9 === true;
|
|
1694
1695
|
const maybe = module;
|
|
1695
1696
|
const hasDefault = !!(maybe && typeof maybe === "object" && "default" in maybe);
|
|
@@ -1851,57 +1852,405 @@ var resolvePackageMetadata = async (projectRoot, fetchGitMetadata, alwaysOverrid
|
|
|
1851
1852
|
};
|
|
1852
1853
|
//#endregion
|
|
1853
1854
|
//#region src/git-ref-utils.ts
|
|
1854
|
-
var
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
return value;
|
|
1865
|
-
};
|
|
1866
|
-
const resolvedDefault = hasDefault ? unwrapNamespaceDefault(maybe.default) : void 0;
|
|
1867
|
-
if (__isInCJS) return hasDefault ? resolvedDefault !== null && resolvedDefault !== void 0 ? resolvedDefault : module : module;
|
|
1868
|
-
if (isESM) {
|
|
1869
|
-
if (hasDefault) return resolvedDefault;
|
|
1870
|
-
throw new Error("Default export not found.");
|
|
1871
|
-
}
|
|
1872
|
-
return hasDefault ? resolvedDefault !== null && resolvedDefault !== void 0 ? resolvedDefault : module : module;
|
|
1873
|
-
}
|
|
1855
|
+
var PACK_TRAILER_SIZE = 20;
|
|
1856
|
+
var LOOSE_TAG_RESOLUTION_CONCURRENCY = 4;
|
|
1857
|
+
var PACKED_OBJECT_TYPE_BY_CODE = new Map([
|
|
1858
|
+
[1, "commit"],
|
|
1859
|
+
[2, "tree"],
|
|
1860
|
+
[3, "blob"],
|
|
1861
|
+
[4, "tag"],
|
|
1862
|
+
[6, "ofs-delta"],
|
|
1863
|
+
[7, "ref-delta"]
|
|
1864
|
+
]);
|
|
1874
1865
|
/**
|
|
1875
|
-
* Resolve
|
|
1866
|
+
* Resolve Git directory paths for repositories, worktrees, and submodules.
|
|
1876
1867
|
* @param repoPath - Repository path
|
|
1877
|
-
* @returns The resolved Git directory
|
|
1868
|
+
* @returns The resolved Git directory paths
|
|
1878
1869
|
*/
|
|
1879
|
-
var
|
|
1870
|
+
var resolveGitDirectoryPaths = async (repoPath) => {
|
|
1880
1871
|
const gitDir = (0, path.join)(repoPath, ".git");
|
|
1881
1872
|
const gitStat = await (0, fs_promises.stat)(gitDir).catch(() => null);
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1873
|
+
const resolvedGitDir = !(gitStat === null || gitStat === void 0 ? void 0 : gitStat.isFile()) ? gitDir : await (async () => {
|
|
1874
|
+
const match = (await (0, fs_promises.readFile)(gitDir, "utf-8")).match(/^gitdir:\s*(.+)$/m);
|
|
1875
|
+
if (!match) return gitDir;
|
|
1876
|
+
return (0, path.isAbsolute)(match[1]) ? match[1] : (0, path.join)(repoPath, match[1]);
|
|
1877
|
+
})();
|
|
1878
|
+
return {
|
|
1879
|
+
gitDir: resolvedGitDir,
|
|
1880
|
+
commonGitDir: await (0, fs_promises.readFile)((0, path.join)(resolvedGitDir, "commondir"), "utf-8").then((content) => {
|
|
1881
|
+
const commondir = content.trim();
|
|
1882
|
+
if (!commondir) return resolvedGitDir;
|
|
1883
|
+
return (0, path.isAbsolute)(commondir) ? commondir : (0, path.join)(resolvedGitDir, commondir);
|
|
1884
|
+
}).catch((error) => {
|
|
1885
|
+
if ((error === null || error === void 0 ? void 0 : error.code) !== "ENOENT") throw error;
|
|
1886
|
+
return resolvedGitDir;
|
|
1887
|
+
})
|
|
1888
|
+
};
|
|
1886
1889
|
};
|
|
1887
1890
|
/**
|
|
1888
|
-
* Resolve
|
|
1889
|
-
* Lightweight tags are returned unchanged.
|
|
1891
|
+
* Resolve the worktree-specific Git directory.
|
|
1890
1892
|
* @param repoPath - Repository path
|
|
1891
|
-
* @
|
|
1892
|
-
* @returns Commit hash this tag points to
|
|
1893
|
+
* @returns The resolved worktree-specific Git directory path
|
|
1893
1894
|
*/
|
|
1894
|
-
var
|
|
1895
|
+
var getActualGitDir = async (repoPath) => {
|
|
1896
|
+
return (await resolveGitDirectoryPaths(repoPath)).gitDir;
|
|
1897
|
+
};
|
|
1898
|
+
/**
|
|
1899
|
+
* Resolve the common Git directory used for refs and objects.
|
|
1900
|
+
* @param repoPath - Repository path
|
|
1901
|
+
* @returns The resolved common Git directory path
|
|
1902
|
+
*/
|
|
1903
|
+
var getCommonGitDir = async (repoPath) => {
|
|
1904
|
+
return (await resolveGitDirectoryPaths(repoPath)).commonGitDir;
|
|
1905
|
+
};
|
|
1906
|
+
var readFixedRange = async (fileHandle, offset, length) => {
|
|
1907
|
+
const buffer = Buffer.alloc(length);
|
|
1908
|
+
const { bytesRead } = await fileHandle.read(buffer, 0, length, offset);
|
|
1909
|
+
if (bytesRead !== length) throw new Error(`Unexpected EOF while reading pack entry at offset ${offset} (expected ${length}, got ${bytesRead})`);
|
|
1910
|
+
return buffer;
|
|
1911
|
+
};
|
|
1912
|
+
var readLooseObject = async (gitDir, oid) => {
|
|
1895
1913
|
try {
|
|
1896
|
-
|
|
1897
|
-
const
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1914
|
+
const wrapped = (0, zlib.inflateSync)(await (0, fs_promises.readFile)((0, path.join)(gitDir, "objects", oid.slice(0, 2), oid.slice(2))));
|
|
1915
|
+
const headerEnd = wrapped.indexOf(0);
|
|
1916
|
+
if (headerEnd < 0) throw new Error(`Invalid loose object header: ${oid}`);
|
|
1917
|
+
const header = wrapped.subarray(0, headerEnd).toString("utf-8");
|
|
1918
|
+
const match = header.match(/^(commit|tree|blob|tag) (\d+)$/);
|
|
1919
|
+
if (!match) throw new Error(`Unsupported loose object header: ${header}`);
|
|
1920
|
+
const content = wrapped.subarray(headerEnd + 1);
|
|
1921
|
+
const expectedSize = Number(match[2]);
|
|
1922
|
+
if (content.length !== expectedSize) throw new Error(`Loose object size mismatch: ${oid} (expected ${expectedSize}, got ${content.length})`);
|
|
1923
|
+
return {
|
|
1924
|
+
oid,
|
|
1925
|
+
type: match[1],
|
|
1926
|
+
content
|
|
1927
|
+
};
|
|
1928
|
+
} catch (error) {
|
|
1929
|
+
if (error.code === "ENOENT") return null;
|
|
1930
|
+
throw error;
|
|
1931
|
+
}
|
|
1932
|
+
};
|
|
1933
|
+
var readLargePackOffset = (idxBuffer, largeOffsetsStart, largeOffsetIndex) => {
|
|
1934
|
+
const offset = Number(idxBuffer.readBigUInt64BE(largeOffsetsStart + largeOffsetIndex * 8));
|
|
1935
|
+
if (!Number.isSafeInteger(offset)) throw new Error(`Pack offset exceeds safe integer range: ${offset}`);
|
|
1936
|
+
return offset;
|
|
1937
|
+
};
|
|
1938
|
+
var loadPackIndex = async (idxPath) => {
|
|
1939
|
+
const packPath = idxPath.replace(/\.idx$/, ".pack");
|
|
1940
|
+
const [idxBuffer, packStat, fileHandle] = await Promise.all([
|
|
1941
|
+
(0, fs_promises.readFile)(idxPath),
|
|
1942
|
+
(0, fs_promises.stat)(packPath),
|
|
1943
|
+
(0, fs_promises.open)(packPath, "r")
|
|
1944
|
+
]);
|
|
1945
|
+
if (idxBuffer.readUInt32BE(0) !== 4285812579) throw new Error(`Unsupported pack index signature: ${idxPath}`);
|
|
1946
|
+
if (idxBuffer.readUInt32BE(4) !== 2) throw new Error(`Unsupported pack index version: ${idxPath}`);
|
|
1947
|
+
const objectCount = idxBuffer.readUInt32BE(1028);
|
|
1948
|
+
const oidStart = 1032;
|
|
1949
|
+
const offsetStart = oidStart + objectCount * 20 + objectCount * 4;
|
|
1950
|
+
const largeOffsetStart = offsetStart + objectCount * 4;
|
|
1951
|
+
const objectByOid = /* @__PURE__ */ new Map();
|
|
1952
|
+
const objectByOffset = /* @__PURE__ */ new Map();
|
|
1953
|
+
const sortedObjects = [];
|
|
1954
|
+
const packIndex = {
|
|
1955
|
+
fileHandle,
|
|
1956
|
+
objectByOid,
|
|
1957
|
+
objectByOffset
|
|
1958
|
+
};
|
|
1959
|
+
for (let index = 0; index < objectCount; index++) {
|
|
1960
|
+
const oidOffset = oidStart + index * 20;
|
|
1961
|
+
const oid = idxBuffer.subarray(oidOffset, oidOffset + 20).toString("hex");
|
|
1962
|
+
const rawOffset = idxBuffer.readUInt32BE(offsetStart + index * 4);
|
|
1963
|
+
const offset = (rawOffset & 2147483648) === 0 ? rawOffset : readLargePackOffset(idxBuffer, largeOffsetStart, rawOffset & 2147483647);
|
|
1964
|
+
sortedObjects.push({
|
|
1965
|
+
oid,
|
|
1966
|
+
offset
|
|
1967
|
+
});
|
|
1968
|
+
}
|
|
1969
|
+
sortedObjects.sort((left, right) => left.offset - right.offset);
|
|
1970
|
+
const packEndOffset = packStat.size - PACK_TRAILER_SIZE;
|
|
1971
|
+
for (let index = 0; index < sortedObjects.length; index++) {
|
|
1972
|
+
var _sortedObjects$offset, _sortedObjects;
|
|
1973
|
+
const currentObject = sortedObjects[index];
|
|
1974
|
+
const nextOffset = (_sortedObjects$offset = (_sortedObjects = sortedObjects[index + 1]) === null || _sortedObjects === void 0 ? void 0 : _sortedObjects.offset) !== null && _sortedObjects$offset !== void 0 ? _sortedObjects$offset : packEndOffset;
|
|
1975
|
+
const location = {
|
|
1976
|
+
oid: currentObject.oid,
|
|
1977
|
+
offset: currentObject.offset,
|
|
1978
|
+
nextOffset,
|
|
1979
|
+
packIndex
|
|
1980
|
+
};
|
|
1981
|
+
objectByOid.set(currentObject.oid, location);
|
|
1982
|
+
objectByOffset.set(currentObject.offset, location);
|
|
1983
|
+
}
|
|
1984
|
+
return packIndex;
|
|
1985
|
+
};
|
|
1986
|
+
var loadPackStore = async (gitDir) => {
|
|
1987
|
+
try {
|
|
1988
|
+
const packDir = (0, path.join)(gitDir, "objects", "pack");
|
|
1989
|
+
const idxPaths = (await (0, fs_promises.readdir)(packDir)).filter((entryName) => entryName.endsWith(".idx")).map((entryName) => (0, path.join)(packDir, entryName));
|
|
1990
|
+
const packs = await Promise.all(idxPaths.map(loadPackIndex));
|
|
1991
|
+
const objectByOid = /* @__PURE__ */ new Map();
|
|
1992
|
+
for (const pack of packs) for (const [oid, location] of pack.objectByOid.entries()) objectByOid.set(oid, location);
|
|
1993
|
+
return {
|
|
1994
|
+
packs,
|
|
1995
|
+
objectByOid
|
|
1996
|
+
};
|
|
1997
|
+
} catch (error) {
|
|
1998
|
+
if (error.code === "ENOENT") return {
|
|
1999
|
+
packs: [],
|
|
2000
|
+
objectByOid: /* @__PURE__ */ new Map()
|
|
2001
|
+
};
|
|
2002
|
+
throw error;
|
|
2003
|
+
}
|
|
2004
|
+
};
|
|
2005
|
+
var decodeOfsDeltaDistance = (buffer, startOffset) => {
|
|
2006
|
+
let cursor = startOffset;
|
|
2007
|
+
let byte = buffer[cursor++];
|
|
2008
|
+
let distance = byte & 127;
|
|
2009
|
+
while (byte & 128) {
|
|
2010
|
+
byte = buffer[cursor++];
|
|
2011
|
+
distance = distance + 1 << 7 | byte & 127;
|
|
2012
|
+
}
|
|
2013
|
+
return {
|
|
2014
|
+
distance,
|
|
2015
|
+
nextOffset: cursor
|
|
2016
|
+
};
|
|
2017
|
+
};
|
|
2018
|
+
var parsePackedEntryHeader = (entryBuffer, objectOffset) => {
|
|
2019
|
+
let cursor = 0;
|
|
2020
|
+
let byte = entryBuffer[cursor++];
|
|
2021
|
+
const packedType = PACKED_OBJECT_TYPE_BY_CODE.get(byte >> 4 & 7);
|
|
2022
|
+
if (!packedType) throw new Error(`Unsupported packed object type at offset ${objectOffset}`);
|
|
2023
|
+
let declaredSize = byte & 15;
|
|
2024
|
+
let shift = 4;
|
|
2025
|
+
while (byte & 128) {
|
|
2026
|
+
byte = entryBuffer[cursor++];
|
|
2027
|
+
declaredSize |= (byte & 127) << shift;
|
|
2028
|
+
shift += 7;
|
|
2029
|
+
}
|
|
2030
|
+
let baseOffset;
|
|
2031
|
+
let baseOid;
|
|
2032
|
+
if (packedType === "ofs-delta") {
|
|
2033
|
+
const decoded = decodeOfsDeltaDistance(entryBuffer, cursor);
|
|
2034
|
+
cursor = decoded.nextOffset;
|
|
2035
|
+
baseOffset = objectOffset - decoded.distance;
|
|
2036
|
+
} else if (packedType === "ref-delta") {
|
|
2037
|
+
baseOid = entryBuffer.subarray(cursor, cursor + 20).toString("hex");
|
|
2038
|
+
cursor += 20;
|
|
2039
|
+
}
|
|
2040
|
+
return {
|
|
2041
|
+
packedType,
|
|
2042
|
+
declaredSize,
|
|
2043
|
+
headerLength: cursor,
|
|
2044
|
+
baseOffset,
|
|
2045
|
+
baseOid
|
|
2046
|
+
};
|
|
2047
|
+
};
|
|
2048
|
+
var readDeltaSize = (buffer, startOffset) => {
|
|
2049
|
+
let cursor = startOffset;
|
|
2050
|
+
let size = 0;
|
|
2051
|
+
let shift = 0;
|
|
2052
|
+
while (cursor < buffer.length) {
|
|
2053
|
+
const byte = buffer[cursor++];
|
|
2054
|
+
size |= (byte & 127) << shift;
|
|
2055
|
+
if ((byte & 128) === 0) return {
|
|
2056
|
+
size,
|
|
2057
|
+
nextOffset: cursor
|
|
2058
|
+
};
|
|
2059
|
+
shift += 7;
|
|
2060
|
+
}
|
|
2061
|
+
throw new Error("Invalid git delta size encoding");
|
|
2062
|
+
};
|
|
2063
|
+
var applyGitDelta = (baseContent, deltaContent) => {
|
|
2064
|
+
const baseSizeInfo = readDeltaSize(deltaContent, 0);
|
|
2065
|
+
if (baseSizeInfo.size !== baseContent.length) throw new Error(`Git delta base size mismatch: expected ${baseSizeInfo.size}, got ${baseContent.length}`);
|
|
2066
|
+
const targetSizeInfo = readDeltaSize(deltaContent, baseSizeInfo.nextOffset);
|
|
2067
|
+
const result = Buffer.alloc(targetSizeInfo.size);
|
|
2068
|
+
let deltaOffset = targetSizeInfo.nextOffset;
|
|
2069
|
+
let resultOffset = 0;
|
|
2070
|
+
while (deltaOffset < deltaContent.length) {
|
|
2071
|
+
const opcode = deltaContent[deltaOffset++];
|
|
2072
|
+
if ((opcode & 128) !== 0) {
|
|
2073
|
+
let copyOffset = 0;
|
|
2074
|
+
let copySize = 0;
|
|
2075
|
+
if (opcode & 1) copyOffset |= deltaContent[deltaOffset++];
|
|
2076
|
+
if (opcode & 2) copyOffset |= deltaContent[deltaOffset++] << 8;
|
|
2077
|
+
if (opcode & 4) copyOffset |= deltaContent[deltaOffset++] << 16;
|
|
2078
|
+
if (opcode & 8) copyOffset |= deltaContent[deltaOffset++] << 24;
|
|
2079
|
+
if (opcode & 16) copySize |= deltaContent[deltaOffset++];
|
|
2080
|
+
if (opcode & 32) copySize |= deltaContent[deltaOffset++] << 8;
|
|
2081
|
+
if (opcode & 64) copySize |= deltaContent[deltaOffset++] << 16;
|
|
2082
|
+
if (copySize === 0) copySize = 65536;
|
|
2083
|
+
baseContent.copy(result, resultOffset, copyOffset, copyOffset + copySize);
|
|
2084
|
+
resultOffset += copySize;
|
|
2085
|
+
continue;
|
|
2086
|
+
}
|
|
2087
|
+
if (opcode === 0) throw new Error("Invalid git delta opcode");
|
|
2088
|
+
deltaContent.copy(result, resultOffset, deltaOffset, deltaOffset + opcode);
|
|
2089
|
+
deltaOffset += opcode;
|
|
2090
|
+
resultOffset += opcode;
|
|
2091
|
+
}
|
|
2092
|
+
if (resultOffset !== result.length) throw new Error(`Git delta size mismatch: expected ${result.length}, got ${resultOffset}`);
|
|
2093
|
+
return result;
|
|
2094
|
+
};
|
|
2095
|
+
var inflatePackedObject = (compressedContent) => Buffer.from((0, zlib.inflateSync)(compressedContent));
|
|
2096
|
+
var parseTagTargetOid = (tagContent) => {
|
|
2097
|
+
const firstLineEnd = tagContent.indexOf(10);
|
|
2098
|
+
const firstLine = firstLineEnd >= 0 ? tagContent.subarray(0, firstLineEnd).toString("utf-8") : tagContent.toString("utf-8");
|
|
2099
|
+
const match = firstLine.match(/^object ([0-9a-f]{40})$/);
|
|
2100
|
+
if (!match) throw new Error(`Invalid annotated tag payload: ${firstLine}`);
|
|
2101
|
+
return match[1];
|
|
2102
|
+
};
|
|
2103
|
+
var parseTreeEntries = (treeContent) => {
|
|
2104
|
+
const entries = [];
|
|
2105
|
+
let offset = 0;
|
|
2106
|
+
while (offset < treeContent.length) {
|
|
2107
|
+
const modeEnd = treeContent.indexOf(32, offset);
|
|
2108
|
+
if (modeEnd < 0) throw new Error("Invalid tree entry mode");
|
|
2109
|
+
const nameEnd = treeContent.indexOf(0, modeEnd + 1);
|
|
2110
|
+
if (nameEnd < 0 || nameEnd + 21 > treeContent.length) throw new Error("Invalid tree entry name");
|
|
2111
|
+
entries.push({
|
|
2112
|
+
mode: treeContent.subarray(offset, modeEnd).toString("utf-8"),
|
|
2113
|
+
name: treeContent.subarray(modeEnd + 1, nameEnd).toString("utf-8"),
|
|
2114
|
+
oid: treeContent.subarray(nameEnd + 1, nameEnd + 21).toString("hex")
|
|
2115
|
+
});
|
|
2116
|
+
offset = nameEnd + 21;
|
|
2117
|
+
}
|
|
2118
|
+
return entries;
|
|
2119
|
+
};
|
|
2120
|
+
var createGitObjectResolver = async (repoPath) => {
|
|
2121
|
+
const commonGitDir = await getCommonGitDir(repoPath);
|
|
2122
|
+
const resolvedObjects = /* @__PURE__ */ new Map();
|
|
2123
|
+
let packStorePromise;
|
|
2124
|
+
const getPackStore = async () => {
|
|
2125
|
+
if (!packStorePromise) packStorePromise = loadPackStore(commonGitDir);
|
|
2126
|
+
return packStorePromise;
|
|
2127
|
+
};
|
|
2128
|
+
const readPackedObject = async (location) => {
|
|
2129
|
+
var _location$packIndex$o, _location$packIndex$o2, _header$baseOid;
|
|
2130
|
+
const entryLength = location.nextOffset - location.offset;
|
|
2131
|
+
const entryBuffer = await readFixedRange(location.packIndex.fileHandle, location.offset, entryLength);
|
|
2132
|
+
const header = parsePackedEntryHeader(entryBuffer, location.offset);
|
|
2133
|
+
const compressedContent = entryBuffer.subarray(header.headerLength);
|
|
2134
|
+
if (header.packedType === "commit" || header.packedType === "tree" || header.packedType === "blob" || header.packedType === "tag") {
|
|
2135
|
+
const content = inflatePackedObject(compressedContent);
|
|
2136
|
+
if (content.length !== header.declaredSize) throw new Error(`Packed object size mismatch: ${location.oid} (expected ${header.declaredSize}, got ${content.length})`);
|
|
2137
|
+
return {
|
|
2138
|
+
oid: location.oid,
|
|
2139
|
+
type: header.packedType,
|
|
2140
|
+
content
|
|
2141
|
+
};
|
|
2142
|
+
}
|
|
2143
|
+
const deltaContent = inflatePackedObject(compressedContent);
|
|
2144
|
+
if (deltaContent.length !== header.declaredSize) throw new Error(`Packed delta size mismatch: ${location.oid} (expected ${header.declaredSize}, got ${deltaContent.length})`);
|
|
2145
|
+
const baseObject = header.packedType === "ofs-delta" ? await readObject((_location$packIndex$o = (_location$packIndex$o2 = location.packIndex.objectByOffset.get(header.baseOffset)) === null || _location$packIndex$o2 === void 0 ? void 0 : _location$packIndex$o2.oid) !== null && _location$packIndex$o !== void 0 ? _location$packIndex$o : (() => {
|
|
2146
|
+
throw new Error(`Missing ofs-delta base object at offset ${header.baseOffset}`);
|
|
2147
|
+
})()) : await readObject((_header$baseOid = header.baseOid) !== null && _header$baseOid !== void 0 ? _header$baseOid : (() => {
|
|
2148
|
+
throw new Error("Missing ref-delta base object id");
|
|
2149
|
+
})());
|
|
2150
|
+
const content = applyGitDelta(baseObject.content, deltaContent);
|
|
2151
|
+
return {
|
|
2152
|
+
oid: location.oid,
|
|
2153
|
+
type: baseObject.type,
|
|
2154
|
+
content
|
|
2155
|
+
};
|
|
2156
|
+
};
|
|
2157
|
+
const readObject = async (oid) => {
|
|
2158
|
+
const cachedObject = resolvedObjects.get(oid);
|
|
2159
|
+
if (cachedObject) return cachedObject;
|
|
2160
|
+
const objectPromise = (async () => {
|
|
2161
|
+
const looseObject = await readLooseObject(commonGitDir, oid);
|
|
2162
|
+
if (looseObject) return looseObject;
|
|
2163
|
+
const location = (await getPackStore()).objectByOid.get(oid);
|
|
2164
|
+
if (!location) throw new Error(`Git object not found: ${oid}`);
|
|
2165
|
+
return readPackedObject(location);
|
|
2166
|
+
})();
|
|
2167
|
+
resolvedObjects.set(oid, objectPromise);
|
|
2168
|
+
try {
|
|
2169
|
+
return await objectPromise;
|
|
2170
|
+
} catch (error) {
|
|
2171
|
+
resolvedObjects.delete(oid);
|
|
2172
|
+
throw error;
|
|
2173
|
+
}
|
|
2174
|
+
};
|
|
2175
|
+
return {
|
|
2176
|
+
close: async () => {
|
|
2177
|
+
if (!packStorePromise) return;
|
|
2178
|
+
const packStore = await packStorePromise;
|
|
2179
|
+
await Promise.allSettled(packStore.packs.map(async (pack) => {
|
|
2180
|
+
await pack.fileHandle.close();
|
|
2181
|
+
}));
|
|
2182
|
+
},
|
|
2183
|
+
readObject,
|
|
2184
|
+
resolveTagOidToCommit: async (tagOid) => {
|
|
2185
|
+
let currentOid = tagOid;
|
|
2186
|
+
const visitedOids = /* @__PURE__ */ new Set();
|
|
2187
|
+
while (true) {
|
|
2188
|
+
if (visitedOids.has(currentOid)) throw new Error(`Detected cyclic tag reference: ${currentOid}`);
|
|
2189
|
+
visitedOids.add(currentOid);
|
|
2190
|
+
const object = await readObject(currentOid);
|
|
2191
|
+
if (object.type !== "tag") return currentOid;
|
|
2192
|
+
currentOid = parseTagTargetOid(object.content);
|
|
2193
|
+
}
|
|
2194
|
+
}
|
|
2195
|
+
};
|
|
2196
|
+
};
|
|
2197
|
+
var runWithConcurrency = async (values, concurrency, worker) => {
|
|
2198
|
+
let nextIndex = 0;
|
|
2199
|
+
const runWorker = async () => {
|
|
2200
|
+
while (nextIndex < values.length) {
|
|
2201
|
+
const currentIndex = nextIndex;
|
|
2202
|
+
nextIndex += 1;
|
|
2203
|
+
await worker(values[currentIndex]);
|
|
2204
|
+
}
|
|
2205
|
+
};
|
|
2206
|
+
await Promise.all(Array.from({ length: Math.min(concurrency, Math.max(values.length, 1)) }, () => runWorker()));
|
|
2207
|
+
};
|
|
2208
|
+
/**
|
|
2209
|
+
* Resolve multiple tag object OIDs to their peeled commit OIDs.
|
|
2210
|
+
* @param repoPath - Repository path
|
|
2211
|
+
* @param tagOids - Tag or commit OIDs
|
|
2212
|
+
* @returns Map of tag object OID to peeled commit OID
|
|
2213
|
+
*/
|
|
2214
|
+
var resolveTagOidsToCommits = async (repoPath, tagOids) => {
|
|
2215
|
+
const resolver = await createGitObjectResolver(repoPath);
|
|
2216
|
+
const result = /* @__PURE__ */ new Map();
|
|
2217
|
+
const uniqueTagOids = Array.from(new Set(tagOids));
|
|
2218
|
+
try {
|
|
2219
|
+
await runWithConcurrency(uniqueTagOids, LOOSE_TAG_RESOLUTION_CONCURRENCY, async (tagOid) => {
|
|
2220
|
+
result.set(tagOid, await resolver.resolveTagOidToCommit(tagOid));
|
|
1901
2221
|
});
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
2222
|
+
} finally {
|
|
2223
|
+
await resolver.close();
|
|
2224
|
+
}
|
|
2225
|
+
return result;
|
|
2226
|
+
};
|
|
2227
|
+
var collectTreeFiles = async (resolver, treeOid, prefix, files) => {
|
|
2228
|
+
const treeObject = await resolver.readObject(treeOid);
|
|
2229
|
+
if (treeObject.type !== "tree") throw new Error(`Expected tree object: ${treeOid}`);
|
|
2230
|
+
for (const entry of parseTreeEntries(treeObject.content)) {
|
|
2231
|
+
const path$7 = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
2232
|
+
if (entry.mode === "40000") {
|
|
2233
|
+
await collectTreeFiles(resolver, entry.oid, path$7, files);
|
|
2234
|
+
continue;
|
|
2235
|
+
}
|
|
2236
|
+
if (entry.mode !== "160000") files.set(path$7, entry.oid);
|
|
2237
|
+
}
|
|
2238
|
+
};
|
|
2239
|
+
/**
|
|
2240
|
+
* Collect all tracked file blob OIDs under the specified tree.
|
|
2241
|
+
* @param repoPath - Repository path
|
|
2242
|
+
* @param treeOid - Tree object OID
|
|
2243
|
+
* @returns Map of repository-relative file path to blob OID
|
|
2244
|
+
*/
|
|
2245
|
+
var listTreeFiles = async (repoPath, treeOid) => {
|
|
2246
|
+
const resolver = await createGitObjectResolver(repoPath);
|
|
2247
|
+
const files = /* @__PURE__ */ new Map();
|
|
2248
|
+
try {
|
|
2249
|
+
await collectTreeFiles(resolver, treeOid, "", files);
|
|
2250
|
+
} finally {
|
|
2251
|
+
await resolver.close();
|
|
2252
|
+
}
|
|
2253
|
+
return files;
|
|
1905
2254
|
};
|
|
1906
2255
|
//#endregion
|
|
1907
2256
|
//#region src/fast-tags.ts
|
|
@@ -1954,8 +2303,8 @@ var readLooseTags = async (refsTagsPath) => {
|
|
|
1954
2303
|
* @returns Array of all tag names
|
|
1955
2304
|
*/
|
|
1956
2305
|
var listTagsFast = async (repoPath) => {
|
|
1957
|
-
const
|
|
1958
|
-
const [packedTags, looseTags] = await Promise.all([parsePackedRefs((0, path.join)(
|
|
2306
|
+
const commonGitDir = await getCommonGitDir(repoPath);
|
|
2307
|
+
const [packedTags, looseTags] = await Promise.all([parsePackedRefs((0, path.join)(commonGitDir, "packed-refs")), readLooseTags((0, path.join)(commonGitDir, "refs", "tags"))]);
|
|
1959
2308
|
const allTags = new Set([...packedTags, ...looseTags]);
|
|
1960
2309
|
return Array.from(allTags).sort();
|
|
1961
2310
|
};
|
|
@@ -1968,11 +2317,11 @@ var listTagsFast = async (repoPath) => {
|
|
|
1968
2317
|
var resolveTagsBatchWithCommit = async (repoPath, tagNames, logger) => {
|
|
1969
2318
|
const startTime = Date.now();
|
|
1970
2319
|
const result = /* @__PURE__ */ new Map();
|
|
1971
|
-
const
|
|
2320
|
+
const commonGitDir = await getCommonGitDir(repoPath);
|
|
1972
2321
|
const tagSet = new Set(tagNames);
|
|
1973
2322
|
const packedRefsStart = Date.now();
|
|
1974
2323
|
try {
|
|
1975
|
-
const lines = (await (0, fs_promises.readFile)((0, path.join)(
|
|
2324
|
+
const lines = (await (0, fs_promises.readFile)((0, path.join)(commonGitDir, "packed-refs"), "utf-8")).split("\n");
|
|
1976
2325
|
for (let i = 0; i < lines.length; i++) {
|
|
1977
2326
|
const line = lines[i];
|
|
1978
2327
|
if (line.startsWith("#") || !line.trim()) continue;
|
|
@@ -1995,19 +2344,28 @@ var resolveTagsBatchWithCommit = async (repoPath, tagNames, logger) => {
|
|
|
1995
2344
|
const remainingTags = tagNames.filter((tag) => !result.has(tag));
|
|
1996
2345
|
if (remainingTags.length > 0) {
|
|
1997
2346
|
const looseRefsStart = Date.now();
|
|
1998
|
-
await Promise.all(remainingTags.map(async (tagName) => {
|
|
1999
|
-
const looseRefPath = (0, path.join)(
|
|
2347
|
+
const looseTagEntries = (await Promise.all(remainingTags.map(async (tagName) => {
|
|
2348
|
+
const looseRefPath = (0, path.join)(commonGitDir, "refs", "tags", tagName);
|
|
2000
2349
|
try {
|
|
2001
|
-
|
|
2002
|
-
|
|
2350
|
+
return {
|
|
2351
|
+
tagName,
|
|
2352
|
+
oid: (await (0, fs_promises.readFile)(looseRefPath, "utf-8")).trim()
|
|
2353
|
+
};
|
|
2354
|
+
} catch (error) {
|
|
2355
|
+
if (error.code !== "ENOENT") throw error;
|
|
2356
|
+
return;
|
|
2357
|
+
}
|
|
2358
|
+
}))).filter((entry) => entry !== void 0);
|
|
2359
|
+
if (looseTagEntries.length > 0) {
|
|
2360
|
+
const commitOids = await resolveTagOidsToCommits(repoPath, looseTagEntries.map((entry) => entry.oid));
|
|
2361
|
+
for (const { tagName, oid } of looseTagEntries) {
|
|
2362
|
+
var _commitOids$get;
|
|
2003
2363
|
result.set(tagName, {
|
|
2004
2364
|
oid,
|
|
2005
|
-
commitOid
|
|
2365
|
+
commitOid: (_commitOids$get = commitOids.get(oid)) !== null && _commitOids$get !== void 0 ? _commitOids$get : oid
|
|
2006
2366
|
});
|
|
2007
|
-
} catch (error) {
|
|
2008
|
-
if (error.code !== "ENOENT") throw error;
|
|
2009
2367
|
}
|
|
2010
|
-
}
|
|
2368
|
+
}
|
|
2011
2369
|
logger.debug(`[fast-tags] read loose refs: ${Date.now() - looseRefsStart}ms`);
|
|
2012
2370
|
}
|
|
2013
2371
|
const totalTime = Date.now() - startTime;
|
|
@@ -2203,16 +2561,26 @@ var formatVersion = (version) => {
|
|
|
2203
2561
|
return result;
|
|
2204
2562
|
};
|
|
2205
2563
|
/**
|
|
2206
|
-
*
|
|
2564
|
+
* Build a Git read context that can operate correctly inside worktrees.
|
|
2207
2565
|
* @param repositoryPath - Local Git repository directory
|
|
2566
|
+
* @returns The resolved Git read context
|
|
2567
|
+
*/
|
|
2568
|
+
var createGitReadContext = async (repositoryPath) => ({
|
|
2569
|
+
dir: repositoryPath,
|
|
2570
|
+
gitdir: await getCommonGitDir(repositoryPath)
|
|
2571
|
+
});
|
|
2572
|
+
/**
|
|
2573
|
+
* Get a commit by hash
|
|
2574
|
+
* @param context - Git read context
|
|
2208
2575
|
* @param hash - The hash of the commit
|
|
2209
2576
|
* @returns The commit or undefined if the commit is not found
|
|
2210
2577
|
*/
|
|
2211
|
-
var getCommit = async (
|
|
2578
|
+
var getCommit = async (context, hash) => {
|
|
2212
2579
|
try {
|
|
2213
2580
|
const commit = await isomorphic_git.readCommit({
|
|
2214
2581
|
fs: fs_promises.default,
|
|
2215
|
-
dir:
|
|
2582
|
+
dir: context.dir,
|
|
2583
|
+
gitdir: context.gitdir,
|
|
2216
2584
|
oid: hash
|
|
2217
2585
|
});
|
|
2218
2586
|
return {
|
|
@@ -2220,7 +2588,8 @@ var getCommit = async (repositoryPath, hash) => {
|
|
|
2220
2588
|
shortHash: commit.oid.substring(0, 7),
|
|
2221
2589
|
date: (/* @__PURE__ */ new Date(commit.commit.author.timestamp * 1e3)).toISOString(),
|
|
2222
2590
|
message: commit.commit.message.trim(),
|
|
2223
|
-
parents: commit.commit.parent || []
|
|
2591
|
+
parents: commit.commit.parent || [],
|
|
2592
|
+
tree: commit.commit.tree
|
|
2224
2593
|
};
|
|
2225
2594
|
} catch (_unused) {
|
|
2226
2595
|
return;
|
|
@@ -2228,19 +2597,20 @@ var getCommit = async (repositoryPath, hash) => {
|
|
|
2228
2597
|
};
|
|
2229
2598
|
/**
|
|
2230
2599
|
* Get the current commit
|
|
2231
|
-
* @param
|
|
2600
|
+
* @param context - Git read context
|
|
2232
2601
|
* @returns The current commit or undefined if the current commit is not found
|
|
2233
2602
|
*/
|
|
2234
|
-
var getCurrentCommit = async (
|
|
2603
|
+
var getCurrentCommit = async (context) => {
|
|
2235
2604
|
try {
|
|
2236
2605
|
const currentOid = await isomorphic_git.resolveRef({
|
|
2237
2606
|
fs: fs_promises.default,
|
|
2238
|
-
dir:
|
|
2607
|
+
dir: context.dir,
|
|
2239
2608
|
ref: "HEAD"
|
|
2240
2609
|
});
|
|
2241
2610
|
const commit = await isomorphic_git.readCommit({
|
|
2242
2611
|
fs: fs_promises.default,
|
|
2243
|
-
dir:
|
|
2612
|
+
dir: context.dir,
|
|
2613
|
+
gitdir: context.gitdir,
|
|
2244
2614
|
oid: currentOid
|
|
2245
2615
|
});
|
|
2246
2616
|
return {
|
|
@@ -2248,7 +2618,8 @@ var getCurrentCommit = async (repositoryPath) => {
|
|
|
2248
2618
|
shortHash: commit.oid.substring(0, 7),
|
|
2249
2619
|
date: (/* @__PURE__ */ new Date(commit.commit.author.timestamp * 1e3)).toISOString(),
|
|
2250
2620
|
message: commit.commit.message.trim(),
|
|
2251
|
-
parents: commit.commit.parent || []
|
|
2621
|
+
parents: commit.commit.parent || [],
|
|
2622
|
+
tree: commit.commit.tree
|
|
2252
2623
|
};
|
|
2253
2624
|
} catch (_unused2) {
|
|
2254
2625
|
return;
|
|
@@ -2265,21 +2636,23 @@ var getRelatedTagsFromMap = (commitToTags, commitHash) => {
|
|
|
2265
2636
|
};
|
|
2266
2637
|
/**
|
|
2267
2638
|
* Get the commit related branch name.
|
|
2268
|
-
* @param
|
|
2639
|
+
* @param context - Git read context
|
|
2269
2640
|
* @param commitHash - The hash of the commit
|
|
2270
2641
|
* @returns The commit related branch name or undefined if not found
|
|
2271
2642
|
*/
|
|
2272
|
-
var getRelatedBranches = async (
|
|
2643
|
+
var getRelatedBranches = async (context, commitHash) => {
|
|
2273
2644
|
try {
|
|
2274
2645
|
const branches = await isomorphic_git.listBranches({
|
|
2275
2646
|
fs: fs_promises.default,
|
|
2276
|
-
dir:
|
|
2647
|
+
dir: context.dir,
|
|
2648
|
+
gitdir: context.gitdir
|
|
2277
2649
|
});
|
|
2278
2650
|
const relatedBranches = [];
|
|
2279
2651
|
for (const branch of branches) try {
|
|
2280
2652
|
if (await isomorphic_git.resolveRef({
|
|
2281
2653
|
fs: fs_promises.default,
|
|
2282
|
-
dir:
|
|
2654
|
+
dir: context.dir,
|
|
2655
|
+
gitdir: context.gitdir,
|
|
2283
2656
|
ref: branch
|
|
2284
2657
|
}) === commitHash) relatedBranches.push(branch);
|
|
2285
2658
|
} catch (_unused3) {}
|
|
@@ -2288,94 +2661,133 @@ var getRelatedBranches = async (repositoryPath, commitHash) => {
|
|
|
2288
2661
|
return [];
|
|
2289
2662
|
}
|
|
2290
2663
|
};
|
|
2291
|
-
|
|
2292
|
-
* Check if the repository has modified files (following RelaxVersioner logic).
|
|
2293
|
-
* Checks for staged files, unstaged files, and untracked files (respecting .gitignore).
|
|
2294
|
-
* @param repositoryPath - Local Git repository directory
|
|
2295
|
-
* @returns Modified files
|
|
2296
|
-
*/
|
|
2297
|
-
var isModifiedFile = ([, head, workdir, stage]) => {
|
|
2298
|
-
return workdir === 2 || stage === 2 || stage === 3 || head === 1 && workdir === 0 || head === 0 && workdir === 1;
|
|
2299
|
-
};
|
|
2300
|
-
var getStatusRow = async (filepath, entries) => {
|
|
2301
|
-
const [head, workdir, stage] = entries;
|
|
2302
|
-
const [headType, workdirType, stageType] = await Promise.all([
|
|
2303
|
-
head ? head.type() : void 0,
|
|
2304
|
-
workdir ? workdir.type() : void 0,
|
|
2305
|
-
stage ? stage.type() : void 0
|
|
2306
|
-
]);
|
|
2307
|
-
const isBlob = [
|
|
2308
|
-
headType,
|
|
2309
|
-
workdirType,
|
|
2310
|
-
stageType
|
|
2311
|
-
].includes("blob");
|
|
2312
|
-
if ((headType === "tree" || headType === "special") && !isBlob) return;
|
|
2313
|
-
if (headType === "commit") return;
|
|
2314
|
-
if ((workdirType === "tree" || workdirType === "special") && !isBlob) return;
|
|
2315
|
-
if (stageType === "commit") return;
|
|
2316
|
-
if ((stageType === "tree" || stageType === "special") && !isBlob) return;
|
|
2317
|
-
const headOid = headType === "blob" ? await head.oid() : void 0;
|
|
2318
|
-
const stageOid = stageType === "blob" ? await stage.oid() : void 0;
|
|
2319
|
-
let workdirOid;
|
|
2320
|
-
if (headType !== "blob" && workdirType === "blob" && stageType !== "blob") workdirOid = "42";
|
|
2321
|
-
else if (workdirType === "blob") workdirOid = await workdir.oid();
|
|
2322
|
-
const entry = [
|
|
2323
|
-
void 0,
|
|
2324
|
-
headOid,
|
|
2325
|
-
workdirOid,
|
|
2326
|
-
stageOid
|
|
2327
|
-
];
|
|
2328
|
-
const statusValues = entry.map((value) => entry.indexOf(value));
|
|
2329
|
-
return [
|
|
2330
|
-
filepath,
|
|
2331
|
-
statusValues[1],
|
|
2332
|
-
statusValues[2],
|
|
2333
|
-
statusValues[3]
|
|
2334
|
-
];
|
|
2335
|
-
};
|
|
2336
|
-
var reduceModifiedFiles = async (parent, children) => {
|
|
2337
|
-
const modifiedFiles = parent ? [parent] : [];
|
|
2338
|
-
for (const child of children) modifiedFiles.push(...child);
|
|
2339
|
-
return modifiedFiles;
|
|
2340
|
-
};
|
|
2341
|
-
var iterateSequentially = async (walk, children) => {
|
|
2342
|
-
const results = [];
|
|
2343
|
-
for (const child of children) results.push(await walk(child));
|
|
2344
|
-
return results;
|
|
2345
|
-
};
|
|
2346
|
-
var getModifiedFiles = async (repositoryPath) => {
|
|
2664
|
+
var parseGitIndex = async (gitDir) => {
|
|
2347
2665
|
try {
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2666
|
+
const buffer = await fs_promises.default.readFile((0, path.join)(gitDir, "index"));
|
|
2667
|
+
if (buffer.subarray(0, 4).toString("ascii") !== "DIRC") throw new Error("Unsupported git index signature");
|
|
2668
|
+
const version = buffer.readUInt32BE(4);
|
|
2669
|
+
if (version !== 2 && version !== 3) throw new Error(`Unsupported git index version: ${version}`);
|
|
2670
|
+
const entryCount = buffer.readUInt32BE(8);
|
|
2671
|
+
let offset = 12;
|
|
2672
|
+
const entries = /* @__PURE__ */ new Map();
|
|
2673
|
+
for (let index = 0; index < entryCount; index++) {
|
|
2674
|
+
const entryStart = offset;
|
|
2675
|
+
const size = buffer.readUInt32BE(entryStart + 36);
|
|
2676
|
+
const oid = buffer.subarray(entryStart + 40, entryStart + 60).toString("hex");
|
|
2677
|
+
const flags = buffer.readUInt16BE(entryStart + 60);
|
|
2678
|
+
const stage = flags >> 12 & 3;
|
|
2679
|
+
offset = entryStart + 62;
|
|
2680
|
+
if (version >= 3 && (flags & 16384) !== 0) offset += 2;
|
|
2681
|
+
const pathEnd = buffer.indexOf(0, offset);
|
|
2682
|
+
if (pathEnd < 0) throw new Error("Invalid git index path entry");
|
|
2683
|
+
const path$3 = buffer.subarray(offset, pathEnd).toString("utf-8");
|
|
2684
|
+
offset = pathEnd + 1;
|
|
2685
|
+
while ((offset - entryStart) % 8 !== 0) offset += 1;
|
|
2686
|
+
entries.set(path$3, {
|
|
2687
|
+
path: path$3,
|
|
2688
|
+
oid,
|
|
2689
|
+
size,
|
|
2690
|
+
stage
|
|
2691
|
+
});
|
|
2692
|
+
}
|
|
2693
|
+
return entries;
|
|
2694
|
+
} catch (error) {
|
|
2695
|
+
if (error.code === "ENOENT") return /* @__PURE__ */ new Map();
|
|
2696
|
+
throw error;
|
|
2697
|
+
}
|
|
2698
|
+
};
|
|
2699
|
+
var listTrackedDirectories = (indexEntries) => {
|
|
2700
|
+
const directories = new Set([""]);
|
|
2701
|
+
for (const path$4 of indexEntries.keys()) {
|
|
2702
|
+
const segments = path$4.split("/");
|
|
2703
|
+
let currentPath = "";
|
|
2704
|
+
for (let index = 0; index < segments.length - 1; index++) {
|
|
2705
|
+
currentPath = currentPath ? `${currentPath}/${segments[index]}` : segments[index];
|
|
2706
|
+
directories.add(currentPath);
|
|
2707
|
+
}
|
|
2708
|
+
}
|
|
2709
|
+
return directories;
|
|
2710
|
+
};
|
|
2711
|
+
var listWorkingDirectoryFiles = async (repositoryPath, trackedDirectories, relativePath = "") => {
|
|
2712
|
+
const directoryPath = relativePath ? (0, path.join)(repositoryPath, relativePath) : repositoryPath;
|
|
2713
|
+
const entries = await fs_promises.default.readdir(directoryPath, { withFileTypes: true });
|
|
2714
|
+
const files = [];
|
|
2715
|
+
for (const entry of entries) {
|
|
2716
|
+
if (entry.name === ".git") continue;
|
|
2717
|
+
const entryPath = relativePath ? `${relativePath}/${entry.name}` : entry.name;
|
|
2718
|
+
if (entry.isDirectory()) {
|
|
2719
|
+
if (!trackedDirectories.has(entryPath)) {
|
|
2720
|
+
if (await isomorphic_git.isIgnored({
|
|
2721
|
+
fs: fs_promises.default,
|
|
2722
|
+
dir: repositoryPath,
|
|
2723
|
+
filepath: entryPath
|
|
2724
|
+
})) continue;
|
|
2725
|
+
}
|
|
2726
|
+
files.push(...await listWorkingDirectoryFiles(repositoryPath, trackedDirectories, entryPath));
|
|
2727
|
+
continue;
|
|
2728
|
+
}
|
|
2729
|
+
if (entry.isFile() || entry.isSymbolicLink()) files.push(entryPath);
|
|
2730
|
+
}
|
|
2731
|
+
return files;
|
|
2732
|
+
};
|
|
2733
|
+
var calculateBlobOid = async (filePath) => {
|
|
2734
|
+
const content = await fs_promises.default.readFile(filePath);
|
|
2735
|
+
return (0, crypto$1.createHash)("sha1").update(`blob ${content.length}\0`).update(content).digest("hex");
|
|
2736
|
+
};
|
|
2737
|
+
var getModifiedFiles = async (repositoryPath, headTreeOid) => {
|
|
2738
|
+
try {
|
|
2739
|
+
const gitDir = await getActualGitDir(repositoryPath);
|
|
2740
|
+
const [headFiles, indexEntries] = await Promise.all([listTreeFiles(repositoryPath, headTreeOid), parseGitIndex(gitDir)]);
|
|
2741
|
+
const workdirFiles = await listWorkingDirectoryFiles(repositoryPath, listTrackedDirectories(indexEntries));
|
|
2742
|
+
const modifiedFiles = /* @__PURE__ */ new Map();
|
|
2743
|
+
const rememberModifiedFile = (path$5, reason) => {
|
|
2744
|
+
if (!modifiedFiles.has(path$5)) modifiedFiles.set(path$5, {
|
|
2745
|
+
path: path$5,
|
|
2746
|
+
reason
|
|
2747
|
+
});
|
|
2748
|
+
};
|
|
2749
|
+
for (const [path$6, headOid] of headFiles.entries()) {
|
|
2750
|
+
const indexEntry = indexEntries.get(path$6);
|
|
2751
|
+
if (!indexEntry) rememberModifiedFile(path$6, "staged");
|
|
2752
|
+
else if (indexEntry.stage !== 0 || indexEntry.oid !== headOid) rememberModifiedFile(path$6, "staged");
|
|
2753
|
+
}
|
|
2754
|
+
for (const indexEntry of indexEntries.values()) {
|
|
2755
|
+
if (!headFiles.has(indexEntry.path)) rememberModifiedFile(indexEntry.path, "staged");
|
|
2756
|
+
const absolutePath = (0, path.join)(repositoryPath, indexEntry.path);
|
|
2757
|
+
try {
|
|
2758
|
+
const stats = await fs_promises.default.lstat(absolutePath);
|
|
2759
|
+
if (!stats.isFile() && !stats.isSymbolicLink()) {
|
|
2760
|
+
rememberModifiedFile(indexEntry.path, "worktree");
|
|
2761
|
+
continue;
|
|
2364
2762
|
}
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2763
|
+
if (indexEntry.stage !== 0) {
|
|
2764
|
+
rememberModifiedFile(indexEntry.path, "staged");
|
|
2765
|
+
continue;
|
|
2766
|
+
}
|
|
2767
|
+
if (indexEntry.size !== stats.size || await calculateBlobOid(absolutePath) !== indexEntry.oid) rememberModifiedFile(indexEntry.path, "worktree");
|
|
2768
|
+
} catch (error) {
|
|
2769
|
+
if (error.code === "ENOENT") {
|
|
2770
|
+
rememberModifiedFile(indexEntry.path, "worktree");
|
|
2771
|
+
continue;
|
|
2772
|
+
}
|
|
2773
|
+
throw error;
|
|
2774
|
+
}
|
|
2775
|
+
}
|
|
2776
|
+
const trackedPaths = new Set(indexEntries.keys());
|
|
2777
|
+
for (const filepath of workdirFiles) {
|
|
2778
|
+
if (trackedPaths.has(filepath)) continue;
|
|
2779
|
+
if (!await isomorphic_git.isIgnored({
|
|
2780
|
+
fs: fs_promises.default,
|
|
2781
|
+
dir: repositoryPath,
|
|
2782
|
+
filepath
|
|
2783
|
+
})) rememberModifiedFile(filepath, "untracked");
|
|
2784
|
+
}
|
|
2785
|
+
return Array.from(modifiedFiles.values());
|
|
2372
2786
|
} catch (_unused5) {
|
|
2373
2787
|
return [];
|
|
2374
2788
|
}
|
|
2375
2789
|
};
|
|
2376
|
-
var formatModifiedFile = (modifiedFile) => {
|
|
2377
|
-
return `'${modifiedFile[0]}':${modifiedFile[1]}:${modifiedFile[2]}:${modifiedFile[3]}`;
|
|
2378
|
-
};
|
|
2790
|
+
var formatModifiedFile = (modifiedFile) => `'${modifiedFile.path}':${modifiedFile.reason}`;
|
|
2379
2791
|
/**
|
|
2380
2792
|
* Lookup version label recursively core analyzer
|
|
2381
2793
|
* @param cwd - The directory to check
|
|
@@ -2384,7 +2796,7 @@ var formatModifiedFile = (modifiedFile) => {
|
|
|
2384
2796
|
* @param commitToTags - Map of commit hash to tags for performance
|
|
2385
2797
|
* @returns The version or undefined if no version is found
|
|
2386
2798
|
*/
|
|
2387
|
-
var lookupVersionLabelRecursive = async (
|
|
2799
|
+
var lookupVersionLabelRecursive = async (context, commit, reachedCommits, commitToTags) => {
|
|
2388
2800
|
const scheduledStack = [];
|
|
2389
2801
|
let version = {
|
|
2390
2802
|
major: 0,
|
|
@@ -2408,10 +2820,11 @@ var lookupVersionLabelRecursive = async (cwd, commit, reachedCommits, commitToTa
|
|
|
2408
2820
|
try {
|
|
2409
2821
|
const parentHashes = (await isomorphic_git.readCommit({
|
|
2410
2822
|
fs: fs_promises.default,
|
|
2411
|
-
dir:
|
|
2823
|
+
dir: context.dir,
|
|
2824
|
+
gitdir: context.gitdir,
|
|
2412
2825
|
oid: currentCommit.hash
|
|
2413
2826
|
})).commit.parent || [];
|
|
2414
|
-
parentCommits = (await Promise.all(parentHashes.map((parentHash) => getCommit(
|
|
2827
|
+
parentCommits = (await Promise.all(parentHashes.map((parentHash) => getCommit(context, parentHash)))).filter((ci) => ci !== void 0);
|
|
2415
2828
|
} catch (_unused6) {}
|
|
2416
2829
|
if (parentCommits.length === 0) {
|
|
2417
2830
|
reachedCommits.set(currentCommit.hash, version);
|
|
@@ -2426,7 +2839,7 @@ var lookupVersionLabelRecursive = async (cwd, commit, reachedCommits, commitToTa
|
|
|
2426
2839
|
while (scheduledStack.length >= 1) {
|
|
2427
2840
|
const { commit: scheduledCommit, parents } = scheduledStack.pop();
|
|
2428
2841
|
if (parents.length >= 2) for (let index = 1; index < parents.length; index++) {
|
|
2429
|
-
const alternateParentVersion = await lookupVersionLabelRecursive(
|
|
2842
|
+
const alternateParentVersion = await lookupVersionLabelRecursive(context, parents[index], reachedCommits, commitToTags);
|
|
2430
2843
|
if (alternateParentVersion && compareVersions(alternateParentVersion, version) < 0) version = alternateParentVersion;
|
|
2431
2844
|
}
|
|
2432
2845
|
version = incrementLastVersionComponent(version);
|
|
@@ -2454,12 +2867,31 @@ var getGitMetadata = async (repositoryPath, checkWorkingDirectoryStatus, logger)
|
|
|
2454
2867
|
logger.debug(`[screw-up] Total getGitMetadata: ${Date.now() - startTime}ms`);
|
|
2455
2868
|
return metadata;
|
|
2456
2869
|
}
|
|
2870
|
+
let gitContext;
|
|
2457
2871
|
try {
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2872
|
+
gitContext = await createGitReadContext(gitRootPath);
|
|
2873
|
+
} catch (error) {
|
|
2874
|
+
logger.warn(`Failed to resolve git metadata context: ${error}`);
|
|
2875
|
+
logger.debug(`[screw-up] Total getGitMetadata: ${Date.now() - startTime}ms`);
|
|
2876
|
+
return metadata;
|
|
2877
|
+
}
|
|
2878
|
+
const currentCommit = await getCurrentCommit(gitContext);
|
|
2879
|
+
if (!currentCommit) {
|
|
2880
|
+
logger.debug(`[screw-up] Total getGitMetadata: ${Date.now() - startTime}ms`);
|
|
2881
|
+
return metadata;
|
|
2882
|
+
}
|
|
2883
|
+
const gitMetadata = {
|
|
2884
|
+
tags: [],
|
|
2885
|
+
branches: [],
|
|
2886
|
+
commit: {
|
|
2887
|
+
hash: currentCommit.hash,
|
|
2888
|
+
shortHash: currentCommit.shortHash,
|
|
2889
|
+
date: dayjs(currentCommit.date).format("YYYY-MM-DDTHH:mm:ssZ"),
|
|
2890
|
+
message: currentCommit.message
|
|
2462
2891
|
}
|
|
2892
|
+
};
|
|
2893
|
+
metadata.git = gitMetadata;
|
|
2894
|
+
try {
|
|
2463
2895
|
const buildStart = Date.now();
|
|
2464
2896
|
const commitToTags = await buildCompleteTagCache(gitRootPath, (tagName) => {
|
|
2465
2897
|
const version = parseVersion(tagName);
|
|
@@ -2467,15 +2899,10 @@ var getGitMetadata = async (repositoryPath, checkWorkingDirectoryStatus, logger)
|
|
|
2467
2899
|
}, logger);
|
|
2468
2900
|
logger.debug(`[screw-up] buildCompleteTagCache: ${Date.now() - buildStart}ms`);
|
|
2469
2901
|
logger.debug(`Built tag map with ${commitToTags.size} commits`);
|
|
2470
|
-
let version = await lookupVersionLabelRecursive(
|
|
2471
|
-
const gitMetadata = {
|
|
2472
|
-
tags: [],
|
|
2473
|
-
branches: []
|
|
2474
|
-
};
|
|
2475
|
-
metadata.git = gitMetadata;
|
|
2902
|
+
let version = await lookupVersionLabelRecursive(gitContext, currentCommit, /* @__PURE__ */ new Map(), commitToTags);
|
|
2476
2903
|
if (version) {
|
|
2477
2904
|
if (checkWorkingDirectoryStatus) {
|
|
2478
|
-
const modifiedFiles = await getModifiedFiles(gitRootPath);
|
|
2905
|
+
const modifiedFiles = await getModifiedFiles(gitRootPath, currentCommit.tree);
|
|
2479
2906
|
if (modifiedFiles.length >= 1) {
|
|
2480
2907
|
const newVersion = incrementLastVersionComponent(version);
|
|
2481
2908
|
logger.debug(`Increased git version by detected modified items: ${formatVersion(version)} ---> ${formatVersion(newVersion)}, Files=[${modifiedFiles.map(formatModifiedFile).join(", ")}]`);
|
|
@@ -2486,16 +2913,14 @@ var getGitMetadata = async (repositoryPath, checkWorkingDirectoryStatus, logger)
|
|
|
2486
2913
|
gitMetadata.version = gitVersion;
|
|
2487
2914
|
metadata.version = gitVersion;
|
|
2488
2915
|
}
|
|
2489
|
-
gitMetadata.commit = {
|
|
2490
|
-
hash: currentCommit.hash,
|
|
2491
|
-
shortHash: currentCommit.shortHash,
|
|
2492
|
-
date: dayjs(currentCommit.date).format("YYYY-MM-DDTHH:mm:ssZ"),
|
|
2493
|
-
message: currentCommit.message
|
|
2494
|
-
};
|
|
2495
2916
|
gitMetadata.tags = getRelatedTagsFromMap(commitToTags, currentCommit.hash).map((tag) => tag.name);
|
|
2496
|
-
gitMetadata.branches = await getRelatedBranches(gitRootPath, currentCommit.hash);
|
|
2497
2917
|
} catch (error) {
|
|
2498
|
-
logger.warn(`Failed to
|
|
2918
|
+
logger.warn(`Failed to resolve git versioning metadata: ${error}`);
|
|
2919
|
+
}
|
|
2920
|
+
try {
|
|
2921
|
+
gitMetadata.branches = await getRelatedBranches(gitContext, currentCommit.hash);
|
|
2922
|
+
} catch (error) {
|
|
2923
|
+
logger.warn(`Failed to resolve git branch metadata: ${error}`);
|
|
2499
2924
|
}
|
|
2500
2925
|
logger.debug(`[screw-up] Total getGitMetadata: ${Date.now() - startTime}ms`);
|
|
2501
2926
|
return metadata;
|