UNPKG

code-auditor-mcp

Version:

Multi-language code quality auditor with MCP server - Analyze TypeScript, JavaScript, and Go code for SOLID principles, DRY violations, security patterns, and more

155 lines 5.64 kB
/** * Go Configuration Utility * * Handles Go executable detection and configuration for conditional language support. */ import { execFile } from 'child_process'; import { promisify } from 'util'; import fs from 'fs'; import { GoAdapter } from './GoAdapter.js'; const execFileAsync = promisify(execFile); /** * Resolves symlinks to get the real executable path */ function resolveSymlinks(executablePath) { try { const realPath = fs.realpathSync(executablePath); console.error(`[DEBUG] GoConfig: Resolved symlink ${executablePath}${realPath}`); return realPath; } catch (error) { console.error(`[DEBUG] GoConfig: Failed to resolve symlink ${executablePath}:`, error.message); return executablePath; // Return original path if resolution fails } } /** * Uses which/where to find absolute path to Go executable */ async function findAbsoluteGoPath() { const isWindows = process.platform === 'win32'; const checkCommand = isWindows ? 'where' : 'which'; try { console.error(`[DEBUG] GoConfig: Using ${checkCommand} to find absolute Go path...`); const { stdout } = await execFileAsync(checkCommand, ['go'], { timeout: 5000, env: process.env }); // 'which' or 'where' returns the absolute path // 'where' on Windows might return multiple paths, so take the first one const absolutePath = stdout.trim().split('\n')[0].trim(); console.error(`[DEBUG] GoConfig: Found Go via PATH lookup: ${absolutePath}`); return absolutePath; } catch (error) { throw new Error(`Go executable not found via ${checkCommand}: ${error.message}`); } } /** * Detects Go installation and returns configuration with absolute path */ export async function detectGoConfig(customPath) { console.error('[DEBUG] GoConfig: Detecting Go installation...'); // Strategy 1: Try custom path if provided if (customPath) { try { console.error(`[DEBUG] GoConfig: Trying custom Go path: ${customPath}`); const { stdout } = await execFileAsync(customPath, ['version'], { timeout: 5000, env: process.env }); const version = stdout.trim(); console.error(`[DEBUG] GoConfig: Found Go at custom path ${customPath}: ${version}`); return { enabled: true, executablePath: customPath, // Use the custom path as-is version: version }; } catch (error) { console.error(`[DEBUG] GoConfig: Custom path failed: ${error.message}`); // Continue to fallback strategy } } // Strategy 2: Use which/where to find absolute path try { const absolutePath = await findAbsoluteGoPath(); // Resolve symlinks to get the real binary path const realPath = resolveSymlinks(absolutePath); // Verify the resolved path works const { stdout } = await execFileAsync(realPath, ['version'], { timeout: 5000, env: process.env }); const version = stdout.trim(); console.error(`[DEBUG] GoConfig: Verified Go at ${realPath}: ${version}`); return { enabled: true, executablePath: realPath, // Return the REAL path (symlinks resolved) version: version }; } catch (error) { console.error(`[DEBUG] GoConfig: PATH-based detection failed: ${error.message}`); } // Strategy 3: Try common absolute paths as fallback const commonPaths = [ '/usr/local/bin/go', '/opt/homebrew/bin/go', '/usr/bin/go' ]; for (const goPath of commonPaths) { try { console.error(`[DEBUG] GoConfig: Trying fallback path: ${goPath}`); const { stdout } = await execFileAsync(goPath, ['version'], { timeout: 5000, env: process.env }); const version = stdout.trim(); console.error(`[DEBUG] GoConfig: Found Go at fallback ${goPath}: ${version}`); return { enabled: true, executablePath: goPath, version: version }; } catch (error) { console.error(`[DEBUG] GoConfig: Fallback path ${goPath} failed: ${error.message}`); continue; } } const errorMsg = `Go executable not found. Tried custom path, PATH lookup, and common locations.`; console.error(`[DEBUG] GoConfig: ${errorMsg}`); return { enabled: false, error: errorMsg }; } /** * Creates a GoAdapter if Go is available, null otherwise */ export async function createGoAdapter(customPath) { const config = await detectGoConfig(customPath); if (!config.enabled || !config.executablePath) { console.error('[DEBUG] GoConfig: Go support disabled - no valid Go executable found'); return null; } console.error(`[DEBUG] GoConfig: Creating GoAdapter with path: ${config.executablePath}`); return new GoAdapter(config.executablePath); } /** * Environment variable names for Go configuration */ export const GO_CONFIG_ENV = { EXECUTABLE_PATH: 'CODE_AUDITOR_GO_PATH', DISABLE: 'CODE_AUDITOR_DISABLE_GO' }; /** * Gets Go configuration from environment variables */ export function getGoConfigFromEnv() { return { customPath: process.env[GO_CONFIG_ENV.EXECUTABLE_PATH], disabled: process.env[GO_CONFIG_ENV.DISABLE] === 'true' }; } //# sourceMappingURL=GoConfig.js.map