chore: add code formatting config and pre-commit hooks (#450)
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
const fs = require("fs-extra");
|
||||
const path = require("node:path");
|
||||
const fs = require('fs-extra');
|
||||
const path = require('node:path');
|
||||
|
||||
// Deno/Node compatibility: explicitly import process
|
||||
const process = require("node:process");
|
||||
const { execFile } = require("node:child_process");
|
||||
const { promisify } = require("node:util");
|
||||
const process = require('node:process');
|
||||
const { execFile } = require('node:child_process');
|
||||
const { promisify } = require('node:util');
|
||||
const execFileAsync = promisify(execFile);
|
||||
|
||||
// Simple memoization across calls (keyed by realpath of startDir)
|
||||
@@ -18,7 +18,7 @@ async function _tryRun(cmd, args, cwd, timeoutMs = 500) {
|
||||
windowsHide: true,
|
||||
maxBuffer: 1024 * 1024,
|
||||
});
|
||||
const out = String(stdout || "").trim();
|
||||
const out = String(stdout || '').trim();
|
||||
return out || null;
|
||||
} catch {
|
||||
return null;
|
||||
@@ -27,15 +27,17 @@ async function _tryRun(cmd, args, cwd, timeoutMs = 500) {
|
||||
|
||||
async function _detectVcsTopLevel(startDir) {
|
||||
// Run common VCS root queries in parallel; ignore failures
|
||||
const gitP = _tryRun("git", ["rev-parse", "--show-toplevel"], startDir);
|
||||
const hgP = _tryRun("hg", ["root"], startDir);
|
||||
const gitP = _tryRun('git', ['rev-parse', '--show-toplevel'], startDir);
|
||||
const hgP = _tryRun('hg', ['root'], startDir);
|
||||
const svnP = (async () => {
|
||||
const show = await _tryRun("svn", ["info", "--show-item", "wc-root"], startDir);
|
||||
const show = await _tryRun('svn', ['info', '--show-item', 'wc-root'], startDir);
|
||||
if (show) return show;
|
||||
const info = await _tryRun("svn", ["info"], startDir);
|
||||
const info = await _tryRun('svn', ['info'], startDir);
|
||||
if (info) {
|
||||
const line = info.split(/\r?\n/).find((l) => l.toLowerCase().startsWith("working copy root path:"));
|
||||
if (line) return line.split(":").slice(1).join(":").trim();
|
||||
const line = info
|
||||
.split(/\r?\n/)
|
||||
.find((l) => l.toLowerCase().startsWith('working copy root path:'));
|
||||
if (line) return line.split(':').slice(1).join(':').trim();
|
||||
}
|
||||
return null;
|
||||
})();
|
||||
@@ -71,90 +73,92 @@ async function findProjectRoot(startDir) {
|
||||
const checks = [];
|
||||
|
||||
const add = (rel, weight) => {
|
||||
const makePath = (d) => Array.isArray(rel) ? path.join(d, ...rel) : path.join(d, rel);
|
||||
const makePath = (d) => (Array.isArray(rel) ? path.join(d, ...rel) : path.join(d, rel));
|
||||
checks.push({ makePath, weight });
|
||||
};
|
||||
|
||||
// Highest priority: explicit sentinel markers
|
||||
add(".project-root", 110);
|
||||
add(".workspace-root", 110);
|
||||
add(".repo-root", 110);
|
||||
add('.project-root', 110);
|
||||
add('.workspace-root', 110);
|
||||
add('.repo-root', 110);
|
||||
|
||||
// Highest priority: VCS roots
|
||||
add(".git", 100);
|
||||
add(".hg", 95);
|
||||
add(".svn", 95);
|
||||
add('.git', 100);
|
||||
add('.hg', 95);
|
||||
add('.svn', 95);
|
||||
|
||||
// Monorepo/workspace indicators
|
||||
add("pnpm-workspace.yaml", 90);
|
||||
add("lerna.json", 90);
|
||||
add("turbo.json", 90);
|
||||
add("nx.json", 90);
|
||||
add("rush.json", 90);
|
||||
add("go.work", 90);
|
||||
add("WORKSPACE", 90);
|
||||
add("WORKSPACE.bazel", 90);
|
||||
add("MODULE.bazel", 90);
|
||||
add("pants.toml", 90);
|
||||
add('pnpm-workspace.yaml', 90);
|
||||
add('lerna.json', 90);
|
||||
add('turbo.json', 90);
|
||||
add('nx.json', 90);
|
||||
add('rush.json', 90);
|
||||
add('go.work', 90);
|
||||
add('WORKSPACE', 90);
|
||||
add('WORKSPACE.bazel', 90);
|
||||
add('MODULE.bazel', 90);
|
||||
add('pants.toml', 90);
|
||||
|
||||
// Lockfiles and package-manager/top-level locks
|
||||
add("yarn.lock", 85);
|
||||
add("pnpm-lock.yaml", 85);
|
||||
add("package-lock.json", 85);
|
||||
add("bun.lockb", 85);
|
||||
add("Cargo.lock", 85);
|
||||
add("composer.lock", 85);
|
||||
add("poetry.lock", 85);
|
||||
add("Pipfile.lock", 85);
|
||||
add("Gemfile.lock", 85);
|
||||
add('yarn.lock', 85);
|
||||
add('pnpm-lock.yaml', 85);
|
||||
add('package-lock.json', 85);
|
||||
add('bun.lockb', 85);
|
||||
add('Cargo.lock', 85);
|
||||
add('composer.lock', 85);
|
||||
add('poetry.lock', 85);
|
||||
add('Pipfile.lock', 85);
|
||||
add('Gemfile.lock', 85);
|
||||
|
||||
// Build-system root indicators
|
||||
add("settings.gradle", 80);
|
||||
add("settings.gradle.kts", 80);
|
||||
add("gradlew", 80);
|
||||
add("pom.xml", 80);
|
||||
add("build.sbt", 80);
|
||||
add(["project", "build.properties"], 80);
|
||||
add('settings.gradle', 80);
|
||||
add('settings.gradle.kts', 80);
|
||||
add('gradlew', 80);
|
||||
add('pom.xml', 80);
|
||||
add('build.sbt', 80);
|
||||
add(['project', 'build.properties'], 80);
|
||||
|
||||
// Language/project config markers
|
||||
add("deno.json", 75);
|
||||
add("deno.jsonc", 75);
|
||||
add("pyproject.toml", 75);
|
||||
add("Pipfile", 75);
|
||||
add("requirements.txt", 75);
|
||||
add("go.mod", 75);
|
||||
add("Cargo.toml", 75);
|
||||
add("composer.json", 75);
|
||||
add("mix.exs", 75);
|
||||
add("Gemfile", 75);
|
||||
add("CMakeLists.txt", 75);
|
||||
add("stack.yaml", 75);
|
||||
add("cabal.project", 75);
|
||||
add("rebar.config", 75);
|
||||
add("pubspec.yaml", 75);
|
||||
add("flake.nix", 75);
|
||||
add("shell.nix", 75);
|
||||
add("default.nix", 75);
|
||||
add(".tool-versions", 75);
|
||||
add("package.json", 74); // generic Node project (lower than lockfiles/workspaces)
|
||||
add('deno.json', 75);
|
||||
add('deno.jsonc', 75);
|
||||
add('pyproject.toml', 75);
|
||||
add('Pipfile', 75);
|
||||
add('requirements.txt', 75);
|
||||
add('go.mod', 75);
|
||||
add('Cargo.toml', 75);
|
||||
add('composer.json', 75);
|
||||
add('mix.exs', 75);
|
||||
add('Gemfile', 75);
|
||||
add('CMakeLists.txt', 75);
|
||||
add('stack.yaml', 75);
|
||||
add('cabal.project', 75);
|
||||
add('rebar.config', 75);
|
||||
add('pubspec.yaml', 75);
|
||||
add('flake.nix', 75);
|
||||
add('shell.nix', 75);
|
||||
add('default.nix', 75);
|
||||
add('.tool-versions', 75);
|
||||
add('package.json', 74); // generic Node project (lower than lockfiles/workspaces)
|
||||
|
||||
// Changesets
|
||||
add([".changeset", "config.json"], 70);
|
||||
add(".changeset", 70);
|
||||
add(['.changeset', 'config.json'], 70);
|
||||
add('.changeset', 70);
|
||||
|
||||
// Custom markers via env (comma-separated names)
|
||||
if (process.env.PROJECT_ROOT_MARKERS) {
|
||||
for (const name of process.env.PROJECT_ROOT_MARKERS.split(",").map((s) => s.trim()).filter(Boolean)) {
|
||||
for (const name of process.env.PROJECT_ROOT_MARKERS.split(',')
|
||||
.map((s) => s.trim())
|
||||
.filter(Boolean)) {
|
||||
add(name, 72);
|
||||
}
|
||||
}
|
||||
|
||||
/** Check for package.json with "workspaces" */
|
||||
const hasWorkspacePackageJson = async (d) => {
|
||||
const pkgPath = path.join(d, "package.json");
|
||||
const pkgPath = path.join(d, 'package.json');
|
||||
if (!(await exists(pkgPath))) return false;
|
||||
try {
|
||||
const raw = await fs.readFile(pkgPath, "utf8");
|
||||
const raw = await fs.readFile(pkgPath, 'utf8');
|
||||
const pkg = JSON.parse(raw);
|
||||
return Boolean(pkg && pkg.workspaces);
|
||||
} catch {
|
||||
@@ -172,9 +176,8 @@ async function findProjectRoot(startDir) {
|
||||
|
||||
while (true) {
|
||||
// Special check: package.json with "workspaces"
|
||||
if (await hasWorkspacePackageJson(dir)) {
|
||||
if (!best || 90 >= best.weight) best = { dir, weight: 90 };
|
||||
}
|
||||
if ((await hasWorkspacePackageJson(dir)) && (!best || 90 >= best.weight))
|
||||
best = { dir, weight: 90 };
|
||||
|
||||
// Evaluate all other checks in parallel
|
||||
const results = await Promise.all(
|
||||
@@ -201,4 +204,3 @@ async function findProjectRoot(startDir) {
|
||||
}
|
||||
|
||||
module.exports = { findProjectRoot };
|
||||
|
||||
|
||||
Reference in New Issue
Block a user