refactor(packages): rename rules-core to rules-engine
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
import { existsSync, statSync } from "node:fs";
|
||||
import { dirname, join } from "node:path";
|
||||
import { PROJECT_MARKERS } from "./constants";
|
||||
|
||||
const projectRootCache = new Map<string, string | null>();
|
||||
|
||||
export function clearProjectRootCache(): void {
|
||||
projectRootCache.clear();
|
||||
}
|
||||
|
||||
export function findProjectRoot(startPath: string): string | null {
|
||||
const cached = projectRootCache.get(startPath);
|
||||
if (cached !== undefined) return cached;
|
||||
const startDir = resolveStartDir(startPath);
|
||||
const cachedStartDir = projectRootCache.get(startDir);
|
||||
if (cachedStartDir !== undefined) {
|
||||
projectRootCache.set(startPath, cachedStartDir);
|
||||
return cachedStartDir;
|
||||
}
|
||||
|
||||
const visited: string[] = [];
|
||||
let current = startDir;
|
||||
let resolved: string | null = null;
|
||||
while (true) {
|
||||
const cachedAncestor = projectRootCache.get(current);
|
||||
if (cachedAncestor !== undefined) {
|
||||
resolved = cachedAncestor;
|
||||
break;
|
||||
}
|
||||
visited.push(current);
|
||||
if (hasProjectMarker(current)) {
|
||||
resolved = current;
|
||||
break;
|
||||
}
|
||||
const parent = dirname(current);
|
||||
if (parent === current) break;
|
||||
current = parent;
|
||||
}
|
||||
|
||||
for (const directory of visited) projectRootCache.set(directory, resolved);
|
||||
projectRootCache.set(startPath, resolved);
|
||||
return resolved;
|
||||
}
|
||||
|
||||
function resolveStartDir(startPath: string): string {
|
||||
try {
|
||||
return statSync(startPath).isDirectory() ? startPath : dirname(startPath);
|
||||
} catch {
|
||||
return dirname(startPath);
|
||||
}
|
||||
}
|
||||
|
||||
function hasProjectMarker(directory: string): boolean {
|
||||
return PROJECT_MARKERS.some((marker) => existsSync(join(directory, marker)));
|
||||
}
|
||||
Reference in New Issue
Block a user