#!/usr/bin/env python3 from __future__ import annotations import argparse import os import sys import glob from jsonschema import ValidationError from app.core.parser import read_markdown, validate_required_frontmatter, normalize_frontmatter from app.core.note_payload import make_note_payload from app.core.validate_note import validate_note_payload def iter_md_files(root: str, include: str, exclude: list[str]) -> list[str]: # include z.B. "**/*.md" all_files = glob.glob(os.path.join(root, include), recursive=True) def is_excluded(p: str) -> bool: p_norm = p.replace("\\", "/") return any(x in p_norm for x in exclude) return [p for p in all_files if p.lower().endswith(".md") and not is_excluded(p)] def main(): ap = argparse.ArgumentParser() ap.add_argument("--vault", required=True, help="Pfad zum Obsidian Vault") ap.add_argument("--include", default="**/*.md") ap.add_argument("--exclude", nargs="*", default=["/.obsidian/", "/_imported/"]) args = ap.parse_args() root = os.path.abspath(args.vault) files = iter_md_files(root, args.include, args.exclude) if not files: print("Keine Markdown-Dateien gefunden.", file=sys.stderr) sys.exit(2) ok, failed = 0, 0 for path in files: try: parsed = read_markdown(path) fm = normalize_frontmatter(parsed.frontmatter) validate_required_frontmatter(fm) # Note-Payload gemäß note.schema.json validieren payload = make_note_payload(parsed, vault_root=root) validate_note_payload(payload) ok += 1 except (ValidationError, ValueError) as e: failed += 1 print(f"❌ {os.path.relpath(path, root)} :: {e}", file=sys.stderr) print(f"✅ Valid: {ok} | ❌ Invalid: {failed}") if failed: sys.exit(1) if __name__ == "__main__": main()