/** * validate-bundle command * Validate an entity bundle directory (catalog + schema + examples + tests + docs + behaviour facets) * Generated from SpecVerse specification */ import { Command } from 'commander'; import { existsSync, statSync } from 'fs'; import { resolve } from 'path'; interface CommandOptions { json?: boolean; } /** * Exit codes: // 0: All facets pass // 1: One or more facets failed */ /** * Register the validate-bundle command on the program. */ export function registerValidateBundleCommand(program: Command): void { program .command('validate-bundle ') .description('Validate an entity bundle directory (catalog + schema + examples + tests + docs + behaviour facets)') .option('--json', 'Emit the BundleReport as JSON', false) .action(async (path: string, options: CommandOptions) => { try { const target = resolve(path); if (!existsSync(target)) { console.error('Path not found:', target); process.exit(1); } if (!statSync(target).isDirectory()) { console.error('Expected a bundle directory, got a file:', target); process.exit(1); } const { validateBundle } = await import('@specverse/engines/bundles'); const report = await validateBundle(target); if (options.json) { console.log(JSON.stringify(report, null, 2)); if (report.totals.fail > 0) process.exit(1); return; } const statusSymbol = (s: 'pass' | 'fail' | 'skip'): string => { if (s === 'pass') return '✓'; if (s === 'fail') return '✗'; return '–'; }; console.log('Bundle: ' + report.bundle + ' (' + report.path + ')'); console.log(''); for (const facet of report.facets) { const facetLine = ' ' + statusSymbol(facet.status) + ' ' + facet.facet.padEnd(10) + facet.status + ' (' + facet.duration + 'ms)'; console.log(facetLine); for (const issue of facet.issues) { const loc = issue.location ? ' [' + issue.location + ']' : ''; console.log(' - ' + issue.severity + ': ' + issue.message + loc); } } console.log(''); console.log('Totals: ' + report.totals.pass + ' pass, ' + report.totals.fail + ' fail, ' + report.totals.skip + ' skip (' + report.duration + 'ms)'); if (report.totals.fail > 0) process.exit(1); } catch (error: any) { console.error('Error:', error.message); process.exit(1); } }); }