UNPKG

@inox-tools/content-utils

Version:

Utilities to work with content collections on an Astro project from an integration or library.

131 lines (128 loc) 4.03 kB
import { spawnSync } from 'child_process'; import { relative, resolve } from 'path'; import { hooks } from '@inox-tools/modular-station/hooks'; import debugC from 'debug'; // src/runtime/git.ts var debug = debugC("inox-tools:content-utils"); var getDebug = (name) => name === void 0 ? debug : debug.extend(name); // src/runtime/git.ts var projectRoot = process.cwd(); var debug2 = getDebug("git"); function setProjectRoot(path) { projectRoot = path; } function getRepoRoot() { debug2("Retrieving git repo root", { projectRoot }); const result = spawnSync("git", ["rev-parse", "--show-toplevel"], { cwd: projectRoot, encoding: "utf-8" }); if (result.error) { debug2(`Failed to retrieve repo root:`, result.error, result.stderr); debug2("Falling back to contentPath:", projectRoot); return projectRoot; } return result.stdout.trim(); } async function collectGitInfoForContentFiles() { const repoRoot = getRepoRoot(); const args = [ "log", "--format=t:%ct %an <%ae>|%(trailers:key=co-authored-by,valueonly,separator=|)", "--name-status", "--", projectRoot ]; debug2("Retrieving content git log:", args.join(" ")); const gitLog = spawnSync("git", args, { cwd: repoRoot, encoding: "utf-8" }); if (gitLog.error) { debug2("Failed to retrieve content git log:", gitLog.error, gitLog.stderr); return []; } const parsingState = { date: 0, author: { name: "", email: "" }, coAuthors: [] }; const fileInfos = /* @__PURE__ */ new Map(); for (const logLine of gitLog.stdout.split("\n")) { if (logLine.startsWith("t:")) { const firstSpace = logLine.indexOf(" "); parsingState.date = Number.parseInt(logLine.slice(2, firstSpace)) * 1e3; const authors = logLine.slice(firstSpace + 1).replace(/\|$/, "").split("|").map((author) => { const [name, email] = author.split("<"); return { name: name.trim(), email: email.slice(0, -1) }; }); parsingState.author = authors[0]; parsingState.coAuthors = authors.slice(1); continue; } const tabSplit = logLine.lastIndexOf(" "); if (tabSplit === -1) continue; const fileName = relative(projectRoot, resolve(repoRoot, logLine.slice(tabSplit + 1))); const fileInfo = fileInfos.get(fileName); if (fileInfo === void 0) { fileInfos.set(fileName, { earliest: parsingState.date, latest: parsingState.date, authors: [parsingState.author], coAuthors: [...parsingState.coAuthors] }); continue; } fileInfo.earliest = Math.min(fileInfo.earliest, parsingState.date); fileInfo.latest = Math.max(fileInfo.latest, parsingState.date); } debug2("Invoking @it/content:git:listed hook", { trackedFiles: Array.from(fileInfos.keys()) }); await hooks.run("@it/content:git:listed", (logger) => [ { logger, trackedFiles: Array.from(fileInfos.keys()), ignoreFiles: (ignore) => { for (const file of ignore) { fileInfos.delete(file); } } } ]); const result = []; for (const [file, rawFileInfo] of fileInfos.entries()) { const fileInfo = { earliest: new Date(rawFileInfo.earliest), latest: new Date(rawFileInfo.latest), authors: rawFileInfo.authors, coAuthors: rawFileInfo.coAuthors }; let dropped = false; debug2("Invoking @it/content:git:resolved hook", { file, fileInfo }); await hooks.run("@it/content:git:resolved", (logger) => [ { logger, file, fileInfo, drop: () => { dropped = true; } } ]); if (dropped) continue; rawFileInfo.earliest = fileInfo.earliest.valueOf(); rawFileInfo.latest = fileInfo.latest.valueOf(); result.push([file, rawFileInfo]); } return result; } export { collectGitInfoForContentFiles, debug, getDebug, setProjectRoot }; //# sourceMappingURL=chunk-JOKBL6FV.js.map //# sourceMappingURL=chunk-JOKBL6FV.js.map