@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
JavaScript
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