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.
This commit is contained in:
Jonghyeok Park
2026-03-11 09:55:56 +09:00
parent 0a3afbe38f
commit 67841042d6
2 changed files with 33 additions and 52 deletions

View File

@@ -67,7 +67,7 @@ function maybeRunQualityGate(filePath) {
const strict = String(process.env.ECC_QUALITY_GATE_STRICT || '').toLowerCase() === 'true'; const strict = String(process.env.ECC_QUALITY_GATE_STRICT || '').toLowerCase() === 'true';
if (['.ts', '.tsx', '.js', '.jsx', '.json', '.md'].includes(ext)) { 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); const formatter = detectFormatter(projectRoot);
if (formatter === 'biome') { if (formatter === 'biome') {

View File

@@ -16,14 +16,11 @@ const projectRootCache = new Map();
const formatterCache = new Map(); const formatterCache = new Map();
const binCache = 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 const BIOME_CONFIGS = ['biome.json', 'biome.jsonc'];
// repos without package.json are still detected correctly).
const PROJECT_ROOT_MARKERS = [ const PRETTIER_CONFIGS = [
'package.json',
'biome.json',
'biome.jsonc',
'.prettierrc', '.prettierrc',
'.prettierrc.json', '.prettierrc.json',
'.prettierrc.js', '.prettierrc.js',
@@ -37,6 +34,19 @@ const PROJECT_ROOT_MARKERS = [
'prettier.config.mjs' '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 * Walk up from `startDir` until a directory containing a known project
* root marker (package.json or formatter config) is found. * root marker (package.json or formatter config) is found.
@@ -73,8 +83,7 @@ function findProjectRoot(startDir) {
function detectFormatter(projectRoot) { function detectFormatter(projectRoot) {
if (formatterCache.has(projectRoot)) return formatterCache.get(projectRoot); if (formatterCache.has(projectRoot)) return formatterCache.get(projectRoot);
const biomeConfigs = ['biome.json', 'biome.jsonc']; for (const cfg of BIOME_CONFIGS) {
for (const cfg of biomeConfigs) {
if (fs.existsSync(path.join(projectRoot, cfg))) { if (fs.existsSync(path.join(projectRoot, cfg))) {
formatterCache.set(projectRoot, 'biome'); formatterCache.set(projectRoot, 'biome');
return 'biome'; return 'biome';
@@ -95,20 +104,7 @@ function detectFormatter(projectRoot) {
// Malformed package.json — continue to file-based detection // Malformed package.json — continue to file-based detection
} }
const prettierConfigs = [ for (const cfg of PRETTIER_CONFIGS) {
'.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) {
if (fs.existsSync(path.join(projectRoot, cfg))) { if (fs.existsSync(path.join(projectRoot, cfg))) {
formatterCache.set(projectRoot, 'prettier'); formatterCache.set(projectRoot, 'prettier');
return 'prettier'; return 'prettier';
@@ -126,9 +122,6 @@ function detectFormatter(projectRoot) {
* @param {string} projectRoot - Absolute path to the project root * @param {string} projectRoot - Absolute path to the project root
* @returns {{ bin: string, prefix: string[] }} * @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) { function getRunnerFromPackageManager(projectRoot) {
const isWin = process.platform === 'win32'; const isWin = process.platform === 'win32';
const { getPackageManager } = require('./package-manager'); const { getPackageManager } = require('./package-manager');
@@ -154,37 +147,25 @@ function resolveFormatterBin(projectRoot, formatter) {
const cacheKey = `${projectRoot}:${formatter}`; const cacheKey = `${projectRoot}:${formatter}`;
if (binCache.has(cacheKey)) return binCache.get(cacheKey); 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 isWin = process.platform === 'win32';
const localBin = path.join(projectRoot, 'node_modules', '.bin', isWin ? `${pkg.binName}.cmd` : pkg.binName);
if (formatter === 'biome') { if (fs.existsSync(localBin)) {
const localBin = path.join(projectRoot, 'node_modules', '.bin', isWin ? 'biome.cmd' : 'biome'); const result = { bin: localBin, prefix: [] };
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'] };
binCache.set(cacheKey, result); binCache.set(cacheKey, result);
return result; return result;
} }
if (formatter === 'prettier') { const runner = getRunnerFromPackageManager(projectRoot);
const localBin = path.join(projectRoot, 'node_modules', '.bin', isWin ? 'prettier.cmd' : 'prettier'); const result = { bin: runner.bin, prefix: [...runner.prefix, pkg.pkgName] };
if (fs.existsSync(localBin)) { binCache.set(cacheKey, result);
const result = { bin: localBin, prefix: [] }; return result;
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;
} }
/** /**