76 lines
2.1 KiB
TypeScript
76 lines
2.1 KiB
TypeScript
import fs from "node:fs";
|
|
import path from "node:path";
|
|
|
|
const formatCommit = (value?: string | null) => {
|
|
if (!value) return null;
|
|
const trimmed = value.trim();
|
|
if (!trimmed) return null;
|
|
return trimmed.length > 7 ? trimmed.slice(0, 7) : trimmed;
|
|
};
|
|
|
|
const resolveGitHead = (startDir: string) => {
|
|
let current = startDir;
|
|
for (let i = 0; i < 12; i += 1) {
|
|
const gitPath = path.join(current, ".git");
|
|
try {
|
|
const stat = fs.statSync(gitPath);
|
|
if (stat.isDirectory()) {
|
|
return path.join(gitPath, "HEAD");
|
|
}
|
|
if (stat.isFile()) {
|
|
const raw = fs.readFileSync(gitPath, "utf-8");
|
|
const match = raw.match(/gitdir:\s*(.+)/i);
|
|
if (match?.[1]) {
|
|
const resolved = path.resolve(current, match[1].trim());
|
|
return path.join(resolved, "HEAD");
|
|
}
|
|
}
|
|
} catch {
|
|
// ignore missing .git at this level
|
|
}
|
|
const parent = path.dirname(current);
|
|
if (parent === current) break;
|
|
current = parent;
|
|
}
|
|
return null;
|
|
};
|
|
|
|
let cachedCommit: string | null | undefined;
|
|
|
|
export const resolveCommitHash = (
|
|
options: { cwd?: string; env?: NodeJS.ProcessEnv } = {},
|
|
) => {
|
|
if (cachedCommit !== undefined) return cachedCommit;
|
|
const env = options.env ?? process.env;
|
|
const envCommit = env.GIT_COMMIT?.trim() || env.GIT_SHA?.trim();
|
|
const normalized = formatCommit(envCommit);
|
|
if (normalized) {
|
|
cachedCommit = normalized;
|
|
return cachedCommit;
|
|
}
|
|
try {
|
|
const headPath = resolveGitHead(options.cwd ?? process.cwd());
|
|
if (!headPath) {
|
|
cachedCommit = null;
|
|
return cachedCommit;
|
|
}
|
|
const head = fs.readFileSync(headPath, "utf-8").trim();
|
|
if (!head) {
|
|
cachedCommit = null;
|
|
return cachedCommit;
|
|
}
|
|
if (head.startsWith("ref:")) {
|
|
const ref = head.replace(/^ref:\s*/i, "").trim();
|
|
const refPath = path.resolve(path.dirname(headPath), ref);
|
|
const refHash = fs.readFileSync(refPath, "utf-8").trim();
|
|
cachedCommit = formatCommit(refHash);
|
|
return cachedCommit;
|
|
}
|
|
cachedCommit = formatCommit(head);
|
|
return cachedCommit;
|
|
} catch {
|
|
cachedCommit = null;
|
|
return cachedCommit;
|
|
}
|
|
};
|