feat: 配置加载模块
This commit is contained in:
66
src/core/config.ts
Normal file
66
src/core/config.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
import { existsSync } from "node:fs";
|
||||
import { readFile } from "node:fs/promises";
|
||||
import { join, dirname } from "node:path";
|
||||
import { parse as parseYaml } from "yaml";
|
||||
import { defaultConfig } from "../defaults/config.ts";
|
||||
import type { RuneConfig } from "../types.ts";
|
||||
import { RUNE_DIR, CONFIG_FILE, CHANGES_DIR, ARCHIVE_DIR } from "../types.ts";
|
||||
|
||||
export function findProjectRoot(
|
||||
startDir: string = process.cwd(),
|
||||
): string | null {
|
||||
let dir = startDir;
|
||||
while (true) {
|
||||
if (existsSync(join(dir, RUNE_DIR))) {
|
||||
return dir;
|
||||
}
|
||||
const parent = dirname(dir);
|
||||
if (parent === dir) return null;
|
||||
dir = parent;
|
||||
}
|
||||
}
|
||||
|
||||
export async function loadConfig(projectRoot: string): Promise<RuneConfig> {
|
||||
const configPath = join(projectRoot, RUNE_DIR, CONFIG_FILE);
|
||||
try {
|
||||
const content = await readFile(configPath, "utf-8");
|
||||
const userConfig = parseYaml(content) as Partial<RuneConfig> | null;
|
||||
if (!userConfig?.stages) {
|
||||
return structuredClone(defaultConfig);
|
||||
}
|
||||
return mergeConfig(userConfig);
|
||||
} catch {
|
||||
return structuredClone(defaultConfig);
|
||||
}
|
||||
}
|
||||
|
||||
function mergeConfig(userConfig: Partial<RuneConfig>): RuneConfig {
|
||||
const result: RuneConfig = { stages: {} };
|
||||
const stageKeys = ["discuss", "plan", "build", "archive"] as const;
|
||||
|
||||
for (const stage of stageKeys) {
|
||||
if (userConfig.stages?.[stage]) {
|
||||
result.stages[stage] = userConfig.stages[stage]!;
|
||||
} else if (defaultConfig.stages[stage]) {
|
||||
result.stages[stage] = structuredClone(defaultConfig.stages[stage]!);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
export function getRuneDir(projectRoot: string): string {
|
||||
return join(projectRoot, RUNE_DIR);
|
||||
}
|
||||
|
||||
export function getChangesDir(projectRoot: string): string {
|
||||
return join(projectRoot, RUNE_DIR, CHANGES_DIR);
|
||||
}
|
||||
|
||||
export function getArchiveDir(projectRoot: string): string {
|
||||
return join(projectRoot, RUNE_DIR, ARCHIVE_DIR);
|
||||
}
|
||||
|
||||
export function getChangeDir(projectRoot: string, changeName: string): string {
|
||||
return join(projectRoot, RUNE_DIR, CHANGES_DIR, changeName);
|
||||
}
|
||||
Reference in New Issue
Block a user