Spaces:
Configuration error
Configuration error
File size: 3,933 Bytes
3a65265 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
import fs from "node:fs";
import path from "node:path";
import { spawnSync } from "node:child_process";
import { fileURLToPath } from "node:url";
const OXFMT_EXTENSIONS = new Set([
".cjs",
".js",
".json",
".jsonc",
".jsx",
".mjs",
".ts",
".tsx",
]);
function getRepoRoot() {
const here = path.dirname(fileURLToPath(import.meta.url));
return path.resolve(here, "..");
}
function runGitCommand(args, options = {}) {
return spawnSync("git", args, {
cwd: options.cwd,
encoding: "utf-8",
stdio: options.stdio ?? "pipe",
});
}
function splitNullDelimited(value) {
if (!value) return [];
const text = String(value);
return text.split("\0").filter(Boolean);
}
function normalizeGitPath(filePath) {
return filePath.replace(/\\/g, "/");
}
function filterOxfmtTargets(paths) {
return paths
.map(normalizeGitPath)
.filter((filePath) =>
(filePath.startsWith("src/") || filePath.startsWith("test/")) &&
OXFMT_EXTENSIONS.has(path.posix.extname(filePath)),
);
}
function findPartiallyStagedFiles(stagedFiles, unstagedFiles) {
const unstaged = new Set(unstagedFiles.map(normalizeGitPath));
return stagedFiles.filter((filePath) => unstaged.has(normalizeGitPath(filePath)));
}
function filterOutPartialTargets(targets, partialTargets) {
if (partialTargets.length === 0) return targets;
const partial = new Set(partialTargets.map(normalizeGitPath));
return targets.filter((filePath) => !partial.has(normalizeGitPath(filePath)));
}
function resolveOxfmtCommand(repoRoot) {
const binName = process.platform === "win32" ? "oxfmt.cmd" : "oxfmt";
const local = path.join(repoRoot, "node_modules", ".bin", binName);
if (fs.existsSync(local)) {
return { command: local, args: [] };
}
const result = spawnSync("oxfmt", ["--version"], { stdio: "ignore" });
if (result.status === 0) {
return { command: "oxfmt", args: [] };
}
return null;
}
function getGitPaths(args, repoRoot) {
const result = runGitCommand(args, { cwd: repoRoot });
if (result.status !== 0) return [];
return splitNullDelimited(result.stdout ?? "");
}
function formatFiles(repoRoot, oxfmt, files) {
const result = spawnSync(oxfmt.command, ["--write", ...oxfmt.args, ...files], {
cwd: repoRoot,
stdio: "inherit",
});
return result.status === 0;
}
function stageFiles(repoRoot, files) {
if (files.length === 0) return true;
const result = runGitCommand(["add", "--", ...files], { cwd: repoRoot, stdio: "inherit" });
return result.status === 0;
}
function main() {
const repoRoot = getRepoRoot();
const staged = getGitPaths([
"diff",
"--cached",
"--name-only",
"-z",
"--diff-filter=ACMR",
], repoRoot);
const targets = filterOxfmtTargets(staged);
if (targets.length === 0) return;
const unstaged = getGitPaths(["diff", "--name-only", "-z"], repoRoot);
const partial = findPartiallyStagedFiles(targets, unstaged);
if (partial.length > 0) {
process.stderr.write("[pre-commit] Skipping partially staged files:\n");
for (const filePath of partial) {
process.stderr.write(`- ${filePath}\n`);
}
process.stderr.write("Stage full files to format them automatically.\n");
}
const filteredTargets = filterOutPartialTargets(targets, partial);
if (filteredTargets.length === 0) return;
const oxfmt = resolveOxfmtCommand(repoRoot);
if (!oxfmt) {
process.stderr.write("[pre-commit] oxfmt not found; skipping format.\n");
return;
}
if (!formatFiles(repoRoot, oxfmt, filteredTargets)) {
process.exitCode = 1;
return;
}
if (!stageFiles(repoRoot, filteredTargets)) {
process.exitCode = 1;
}
}
export {
filterOxfmtTargets,
filterOutPartialTargets,
findPartiallyStagedFiles,
getRepoRoot,
normalizeGitPath,
resolveOxfmtCommand,
splitNullDelimited,
};
if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
main();
}
|