import { BaseFormatter } from '../classes.baseformatter.js'; import type { IPlannedChange } from '../interfaces.format.js'; import * as plugins from '../mod.plugins.js'; import * as paths from '../../paths.js'; import { logger } from '../../gitzone.logging.js'; const INCOMPATIBLE_LICENSES: string[] = ['AGPL', 'GPL', 'SSPL']; export class LicenseFormatter extends BaseFormatter { get name(): string { return 'license'; } async analyze(): Promise { // License formatter only checks for incompatible licenses // It does not modify any files, so return empty array // The actual check happens in execute() for reporting purposes return []; } async execute(changes: IPlannedChange[]): Promise { const startTime = this.stats.moduleStartTime(this.name); this.stats.startModule(this.name); try { // Check if node_modules exists const nodeModulesPath = plugins.path.join(paths.cwd, 'node_modules'); const nodeModulesExists = await plugins.smartfs .directory(nodeModulesPath) .exists(); if (!nodeModulesExists) { logger.log('warn', 'No node_modules found. Skipping license check'); return; } // Run license check const licenseChecker = await plugins.smartlegal.createLicenseChecker(); const licenseCheckResult = await licenseChecker.excludeLicenseWithinPath( paths.cwd, INCOMPATIBLE_LICENSES, ); if (licenseCheckResult.failingModules.length === 0) { logger.log('info', 'License check passed - no incompatible licenses found'); } else { logger.log('error', 'License check failed - incompatible licenses found:'); for (const failedModule of licenseCheckResult.failingModules) { console.log( ` ${failedModule.name} has license ${failedModule.license}`, ); } } } finally { this.stats.endModule(this.name, startTime); } } async applyChange(change: IPlannedChange): Promise { // No file changes for license formatter } }