2026-10-18 01:03:33 +00:00
|
|
|
import * as vscode from 'vscode';
|
|
|
|
|
import { LinterRule } from './LinterRule';
|
|
|
|
|
import { LinterContext } from '../LinterContext';
|
|
|
|
|
|
|
|
|
|
export class MetadataRule implements LinterRule {
|
|
|
|
|
public checkLine(line: string, rawLine: string, lineIdx: number, ctx: LinterContext, lines: string[]): void {
|
|
|
|
|
if (line.startsWith('metadata') && ctx.inBlock === 'none') {
|
|
|
|
|
ctx.inModuleMetadata = true;
|
|
|
|
|
ctx.hasModuleMetadata = true;
|
|
|
|
|
ctx.moduleMetadataBlockLine = lineIdx;
|
|
|
|
|
ctx.foundModuleMetadata.clear();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ctx.inModuleMetadata) {
|
|
|
|
|
const config = vscode.workspace.getConfiguration('tpl');
|
|
|
|
|
|
|
|
|
|
// Felder erfassen
|
2026-10-18 01:27:52 +00:00
|
|
|
if (line.match(/^origin\b/)) {ctx.foundModuleMetadata.add('origin');}
|
|
|
|
|
if (line.match(/^author\b/)) {ctx.foundModuleMetadata.add('author');}
|
|
|
|
|
if (line.match(/^products\b/)) {ctx.foundModuleMetadata.add('products');}
|
|
|
|
|
if (line.match(/^publishers\b/)) {ctx.foundModuleMetadata.add('publishers');}
|
2026-10-18 01:03:33 +00:00
|
|
|
|
|
|
|
|
// Tree-Path Sonderprüfung
|
|
|
|
|
if (line.match(/^tree_path\b/)) {
|
|
|
|
|
ctx.foundModuleMetadata.add('tree_path');
|
|
|
|
|
if (config.get<boolean>('metadata.require.treePath', true)) {
|
|
|
|
|
this.checkTreePath(line, rawLine, lineIdx, ctx, config);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Block-Ende: Pflichtfelder abgleichen
|
|
|
|
|
if (line.startsWith('end metadata')) {
|
|
|
|
|
ctx.inModuleMetadata = false;
|
|
|
|
|
this.checkRequiredFields(ctx, config);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private checkTreePath(line: string, rawLine: string, lineIdx: number, ctx: LinterContext, config: vscode.WorkspaceConfiguration) {
|
|
|
|
|
const minLevels = config.get<number>('metadata.treePath.minLevels', 3);
|
|
|
|
|
const staticNodes = config.get<string[]>('metadata.treePath.staticNodes', ['Grafing']);
|
|
|
|
|
|
|
|
|
|
// Extrahiert die Strings aus tree_path := 'A', 'B';
|
|
|
|
|
const match = line.match(/tree_path\s*:=\s*(.*);/);
|
|
|
|
|
if (match) {
|
|
|
|
|
const paths = match[1].split(',').map(s => s.trim().replace(/^['"]|['"]$/g, ''));
|
|
|
|
|
|
|
|
|
|
if (paths.length < minLevels) {
|
|
|
|
|
ctx.addDiag(lineIdx, 0, rawLine.length, `Der tree_path muss mindestens ${minLevels} Ebenen haben!`, vscode.DiagnosticSeverity.Error);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < staticNodes.length; i++) {
|
|
|
|
|
if (paths[i] !== staticNodes[i]) {
|
|
|
|
|
ctx.addDiag(lineIdx, 0, rawLine.length, `Die tree_path Ebene ${i + 1} muss zwingend '${staticNodes[i]}' lauten!`, vscode.DiagnosticSeverity.Error);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private checkRequiredFields(ctx: LinterContext, config: vscode.WorkspaceConfiguration) {
|
|
|
|
|
const requiredFields: string[] = [];
|
2026-10-18 01:27:52 +00:00
|
|
|
if (config.get<boolean>('metadata.require.origin', true)) {requiredFields.push('origin');}
|
|
|
|
|
if (config.get<boolean>('metadata.require.author', true)) {requiredFields.push('author');}
|
|
|
|
|
if (config.get<boolean>('metadata.require.products', true)) {requiredFields.push('products');}
|
|
|
|
|
if (config.get<boolean>('metadata.require.publishers', true)) {requiredFields.push('publishers');}
|
|
|
|
|
if (config.get<boolean>('metadata.require.treePath', true)) {requiredFields.push('tree_path');}
|
2026-10-18 01:03:33 +00:00
|
|
|
|
|
|
|
|
const missing = requiredFields.filter(f => !ctx.foundModuleMetadata.has(f));
|
|
|
|
|
|
|
|
|
|
if (missing.length > 0 && ctx.moduleMetadataBlockLine !== -1) {
|
|
|
|
|
const diag = ctx.addDiag(ctx.moduleMetadataBlockLine, 0, 8, `Fehlende Pflicht-Metadaten (Modul-Ebene): ${missing.join(', ')}`, vscode.DiagnosticSeverity.Error);
|
|
|
|
|
diag.code = 'missing_module_metadata';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public checkEnd(lines: string[], ctx: LinterContext): void {
|
|
|
|
|
// empty
|
|
|
|
|
}
|
|
|
|
|
}
|