UNPKG

sfcoe-ailabs

Version:

AI-powered code review tool with static analysis integration for comprehensive code quality assessment.

88 lines (87 loc) 3.3 kB
import path from 'node:path'; import fs from 'fs'; import { Logger } from '../../utils/observability.js'; import { COMMAND_DEFAULTS } from '../../utils/constants.js'; import SCATProvider from './scatProvider.js'; export default class SFCodeAnalyzer extends SCATProvider { /** * Creates a new Salesforce Code Analyzer instance * * @param scanDirectory - The directory to scan for Salesforce code * @param configFile - Optional configuration file path for the analyzer */ constructor(scanDirectory, configFile) { const sarifFileName = path.join(scanDirectory, COMMAND_DEFAULTS.DEFAULT_SARIF_FILE_NAME); super(scanDirectory, configFile ?? '', sarifFileName); } /** * Runs the Salesforce Code Analyzer on the specified directory * * @param scanDirectory - Optional override for the scan directory * @returns Promise that resolves to the SARIF analysis results */ async run(scanDirectory) { const directoryToScan = scanDirectory ?? this.getScanDirectory(); const { execa: execaModule } = await import('execa'); // Create log directory if it doesn't exist await this.ensureLogDirectoryExists(); // Build v5.x command arguments const args = [ 'code-analyzer', 'run', '--workspace', directoryToScan, '--target', directoryToScan, '--output-file', this.getSarifFileName(), '--rule-selector', 'all', ]; // Add config file if provided if (this.getConfigFile()) { args.push('--config-file', this.getConfigFile()); } Logger.debug(`Running SF code analyzer command for Salesforce files: \n sf ${args.join(' ')}`); try { await execaModule('sf', args, { cwd: directoryToScan, stdio: 'inherit', }); } catch (error) { Logger.error('Code Analyzer execution failed:', error); throw error; } return this.getSarifFile(); } /** * Ensures the log directory exists. * Creates the directory if it doesn't exist. * * @returns Promise that resolves when directory is ensured to exist */ async ensureLogDirectoryExists() { try { const configFile = this.getConfigFile(); let logDir; if (configFile) { // Get the directory containing the config file const configDir = path.dirname(configFile); // The log folder is 'code-analyzer-logs' relative to the config file directory logDir = path.join(configDir, COMMAND_DEFAULTS.SF_CODE_ANALYZER_LOGS_FOLDER); } else { // Default to creating the log directory in the scan directory logDir = path.join(this.getScanDirectory(), COMMAND_DEFAULTS.SF_CODE_ANALYZER_LOGS_FOLDER); } // Create the directory if it doesn't exist if (!fs.existsSync(logDir)) { fs.mkdirSync(logDir); } } catch (error) { Logger.warn('Warning: Could not create log directory:', error); } } }