Files
opencli/src/validate.ts
T

56 lines
2.4 KiB
TypeScript

/** Validate CLI definitions. */
import * as fs from 'node:fs';
import * as path from 'node:path';
import yaml from 'js-yaml';
export function validateClisWithTarget(dirs: string[], target?: string): any {
const results: any[] = [];
let errors = 0; let warnings = 0; let files = 0;
for (const dir of dirs) {
if (!fs.existsSync(dir)) continue;
for (const site of fs.readdirSync(dir)) {
if (target && site !== target && !target.startsWith(site + '/')) continue;
const siteDir = path.join(dir, site);
if (!fs.statSync(siteDir).isDirectory()) continue;
for (const file of fs.readdirSync(siteDir)) {
if (!file.endsWith('.yaml') && !file.endsWith('.yml')) continue;
if (target && target.includes('/') && !target.endsWith(file.replace(/\.(yaml|yml)$/, ''))) continue;
files++;
const filePath = path.join(siteDir, file);
const r = validateYamlFile(filePath);
results.push(r);
errors += r.errors.length;
warnings += r.warnings.length;
}
}
}
return { ok: errors === 0, results, errors, warnings, files };
}
function validateYamlFile(filePath: string): any {
const errors: string[] = []; const warnings: string[] = [];
try {
const raw = fs.readFileSync(filePath, 'utf-8');
const def = yaml.load(raw) as any;
if (!def || typeof def !== 'object') { errors.push('Not a valid YAML object'); return { path: filePath, errors, warnings }; }
if (!def.site) errors.push('Missing "site"');
if (!def.name) errors.push('Missing "name"');
if (def.pipeline && !Array.isArray(def.pipeline)) errors.push('"pipeline" must be an array');
if (def.columns && !Array.isArray(def.columns)) errors.push('"columns" must be an array');
if (def.args && typeof def.args !== 'object') errors.push('"args" must be an object');
} catch (e: any) { errors.push(`YAML parse error: ${e.message}`); }
return { path: filePath, errors, warnings };
}
export function renderValidationReport(report: any): string {
const lines = [`opencli validate: ${report.ok ? 'PASS' : 'FAIL'}`, `Checked ${report.results.length} CLI(s) in ${report.files} file(s)`, `Errors: ${report.errors} Warnings: ${report.warnings}`];
for (const r of report.results) {
if (r.errors.length > 0 || r.warnings.length > 0) {
lines.push(`\n${r.path}:`);
for (const e of r.errors) lines.push(` ❌ ${e}`);
for (const w of r.warnings) lines.push(` ⚠️ ${w}`);
}
}
return lines.join('\n');
}