From 67841042d67706bf1e1700b3f165c44b991c60e9 Mon Sep 17 00:00:00 2001 From: Jonghyeok Park Date: Wed, 11 Mar 2026 09:55:56 +0900 Subject: [PATCH] refactor: deduplicate config lists and unify resolveFormatterBin branches Extract BIOME_CONFIGS and PRETTIER_CONFIGS as shared constants to eliminate duplication between PROJECT_ROOT_MARKERS and detectFormatter(). Unify the biome/prettier branches in resolveFormatterBin() via a FORMATTER_PACKAGES map. Remove redundant path.resolve() in quality-gate.js. --- scripts/hooks/quality-gate.js | 2 +- scripts/lib/resolve-formatter.js | 83 ++++++++++++-------------------- 2 files changed, 33 insertions(+), 52 deletions(-) diff --git a/scripts/hooks/quality-gate.js b/scripts/hooks/quality-gate.js index 19f35195..37373b87 100755 --- a/scripts/hooks/quality-gate.js +++ b/scripts/hooks/quality-gate.js @@ -67,7 +67,7 @@ function maybeRunQualityGate(filePath) { const strict = String(process.env.ECC_QUALITY_GATE_STRICT || '').toLowerCase() === 'true'; if (['.ts', '.tsx', '.js', '.jsx', '.json', '.md'].includes(ext)) { - const projectRoot = findProjectRoot(path.dirname(path.resolve(filePath))); + const projectRoot = findProjectRoot(path.dirname(filePath)); const formatter = detectFormatter(projectRoot); if (formatter === 'biome') { diff --git a/scripts/lib/resolve-formatter.js b/scripts/lib/resolve-formatter.js index 22d04819..a118752f 100644 --- a/scripts/lib/resolve-formatter.js +++ b/scripts/lib/resolve-formatter.js @@ -16,14 +16,11 @@ const projectRootCache = new Map(); const formatterCache = new Map(); const binCache = new Map(); -// ── Public helpers ────────────────────────────────────────────────── +// ── Config file lists (single source of truth) ───────────────────── -// Markers that indicate a project root (formatter configs included so -// repos without package.json are still detected correctly). -const PROJECT_ROOT_MARKERS = [ - 'package.json', - 'biome.json', - 'biome.jsonc', +const BIOME_CONFIGS = ['biome.json', 'biome.jsonc']; + +const PRETTIER_CONFIGS = [ '.prettierrc', '.prettierrc.json', '.prettierrc.js', @@ -37,6 +34,19 @@ const PROJECT_ROOT_MARKERS = [ 'prettier.config.mjs' ]; +const PROJECT_ROOT_MARKERS = ['package.json', ...BIOME_CONFIGS, ...PRETTIER_CONFIGS]; + +// ── Windows .cmd shim mapping ─────────────────────────────────────── +const WIN_CMD_SHIMS = { npx: 'npx.cmd', pnpm: 'pnpm.cmd', yarn: 'yarn.cmd', bunx: 'bunx.cmd' }; + +// ── Formatter → package name mapping ──────────────────────────────── +const FORMATTER_PACKAGES = { + biome: { binName: 'biome', pkgName: '@biomejs/biome' }, + prettier: { binName: 'prettier', pkgName: 'prettier' } +}; + +// ── Public helpers ────────────────────────────────────────────────── + /** * Walk up from `startDir` until a directory containing a known project * root marker (package.json or formatter config) is found. @@ -73,8 +83,7 @@ function findProjectRoot(startDir) { function detectFormatter(projectRoot) { if (formatterCache.has(projectRoot)) return formatterCache.get(projectRoot); - const biomeConfigs = ['biome.json', 'biome.jsonc']; - for (const cfg of biomeConfigs) { + for (const cfg of BIOME_CONFIGS) { if (fs.existsSync(path.join(projectRoot, cfg))) { formatterCache.set(projectRoot, 'biome'); return 'biome'; @@ -95,20 +104,7 @@ function detectFormatter(projectRoot) { // Malformed package.json — continue to file-based detection } - const prettierConfigs = [ - '.prettierrc', - '.prettierrc.json', - '.prettierrc.js', - '.prettierrc.cjs', - '.prettierrc.mjs', - '.prettierrc.yml', - '.prettierrc.yaml', - '.prettierrc.toml', - 'prettier.config.js', - 'prettier.config.cjs', - 'prettier.config.mjs' - ]; - for (const cfg of prettierConfigs) { + for (const cfg of PRETTIER_CONFIGS) { if (fs.existsSync(path.join(projectRoot, cfg))) { formatterCache.set(projectRoot, 'prettier'); return 'prettier'; @@ -126,9 +122,6 @@ function detectFormatter(projectRoot) { * @param {string} projectRoot - Absolute path to the project root * @returns {{ bin: string, prefix: string[] }} */ -// Windows .cmd shim mapping for cross-platform safety -const WIN_CMD_SHIMS = { npx: 'npx.cmd', pnpm: 'pnpm.cmd', yarn: 'yarn.cmd', bunx: 'bunx.cmd' }; - function getRunnerFromPackageManager(projectRoot) { const isWin = process.platform === 'win32'; const { getPackageManager } = require('./package-manager'); @@ -154,37 +147,25 @@ function resolveFormatterBin(projectRoot, formatter) { const cacheKey = `${projectRoot}:${formatter}`; if (binCache.has(cacheKey)) return binCache.get(cacheKey); + const pkg = FORMATTER_PACKAGES[formatter]; + if (!pkg) { + binCache.set(cacheKey, null); + return null; + } + const isWin = process.platform === 'win32'; + const localBin = path.join(projectRoot, 'node_modules', '.bin', isWin ? `${pkg.binName}.cmd` : pkg.binName); - if (formatter === 'biome') { - const localBin = path.join(projectRoot, 'node_modules', '.bin', isWin ? 'biome.cmd' : 'biome'); - if (fs.existsSync(localBin)) { - const result = { bin: localBin, prefix: [] }; - binCache.set(cacheKey, result); - return result; - } - const runner = getRunnerFromPackageManager(projectRoot); - const result = { bin: runner.bin, prefix: [...runner.prefix, '@biomejs/biome'] }; + if (fs.existsSync(localBin)) { + const result = { bin: localBin, prefix: [] }; binCache.set(cacheKey, result); return result; } - if (formatter === 'prettier') { - const localBin = path.join(projectRoot, 'node_modules', '.bin', isWin ? 'prettier.cmd' : 'prettier'); - if (fs.existsSync(localBin)) { - const result = { bin: localBin, prefix: [] }; - binCache.set(cacheKey, result); - return result; - } - const runner = getRunnerFromPackageManager(projectRoot); - const result = { bin: runner.bin, prefix: [...runner.prefix, 'prettier'] }; - binCache.set(cacheKey, result); - return result; - } - - // Unknown formatter — return null so callers can handle gracefully - binCache.set(cacheKey, null); - return null; + const runner = getRunnerFromPackageManager(projectRoot); + const result = { bin: runner.bin, prefix: [...runner.prefix, pkg.pkgName] }; + binCache.set(cacheKey, result); + return result; } /**