cfe925a76c
Files changed: - CHANGES.md - VERSION - instructions/link-taxonomy.md - instructions/migrations/4.0.0-link-taxonomy.md - kb/comparisons/amd-pstate vs acpi-cpufreq.md - kb/concepts/Episodic Memory.md - kb/concepts/Memory Lifecycle.md - kb/concepts/Mesh Sync.md - kb/concepts/Procedural Memory.md - kb/concepts/Reciprocal Rank Fusion.md - kb/concepts/Semantic Memory.md - kb/concepts/Shared vs Private.md - kb/concepts/Split Threshold.md - kb/concepts/Stub Threshold.md - kb/concepts/Supersession.md - kb/concepts/Typed Relationships.md - kb/concepts/Vector Search.md - kb/concepts/Work Coordination.md - kb/concepts/Working Memory.md - kb/entities/technologies/Wine-Staging.md - kb/entities/tools/pascalandy schema.md - kb/index.md - kb/log.md - kb/sources/COLLECTION.md - tools/CONTRACT.md - tools/chemenu/commands/lint.py - tools/chemenu/kb_collections.py - tools/chemenu/lint_core.py - tools/chemenu/tests/test_conventions.py - tools/chemenu/tests/test_lint.py - tools/chemenu/tests/test_type_resolver.py - types/comparison.md - types/comparison.schema.yaml
87 lines
2.9 KiB
Python
87 lines
2.9 KiB
Python
"""`wikitool lint` - the terminal adapter over `chemenu.lint_core`.
|
|
|
|
The checks, the report and the hard-error rule live in `chemenu/lint_core.py`,
|
|
which imports no CLI machinery. This module owns only what a terminal needs:
|
|
the flags, where the report file lands, and the exit code.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
from pathlib import Path
|
|
from typing import Optional
|
|
|
|
import typer
|
|
|
|
from chemenu import config
|
|
from chemenu.commands._util import rel_path, success
|
|
from chemenu.lint_core import (
|
|
HARD_ERROR_KEYS,
|
|
MIGRATION_GATED_KEYS,
|
|
MOST_LINKED_COUNT,
|
|
QUOTE_LIMIT,
|
|
count_quote_blocks,
|
|
default_report_path,
|
|
hard_error_keys,
|
|
has_hard_errors,
|
|
render_markdown,
|
|
render_summary,
|
|
run_lint,
|
|
)
|
|
|
|
# Re-exported: `from chemenu.commands.lint import run_lint` still resolves, and
|
|
# so does every other name the tests and sibling commands already import.
|
|
__all__ = [
|
|
"HARD_ERROR_KEYS",
|
|
"MIGRATION_GATED_KEYS",
|
|
"MOST_LINKED_COUNT",
|
|
"QUOTE_LIMIT",
|
|
"count_quote_blocks",
|
|
"default_report_path",
|
|
"hard_error_keys",
|
|
"has_hard_errors",
|
|
"render_markdown",
|
|
"render_summary",
|
|
"run_lint",
|
|
"lint_command",
|
|
]
|
|
|
|
|
|
def lint_command(
|
|
json_out: bool = typer.Option(False, "--json", help="Print the raw findings as JSON and write no report"),
|
|
markdown_out: Optional[Path] = typer.Option(None, "--markdown", help="Write the markdown report here instead of the default reports/Lint Report <date>.md"),
|
|
full: bool = typer.Option(False, "--full", help="Print the whole report instead of only the sections with findings"),
|
|
fail_on_error: bool = typer.Option(False, "--fail-on-error", help="Exit non-zero if hard errors were found"),
|
|
):
|
|
"""Run structural lint checks against kb/.
|
|
|
|
Unless `--json` is given, the full report is always written to a file and
|
|
its path is printed. That path is the point: a lint report is long, and an
|
|
agent that only saw it on stdout had no way back to the part it scrolled
|
|
past except by running lint again - two budget slots for one look at the
|
|
corpus.
|
|
"""
|
|
report = run_lint(config.KB_DIR)
|
|
|
|
if json_out:
|
|
typer.echo(json.dumps(report, indent=2))
|
|
if fail_on_error and has_hard_errors(report):
|
|
raise typer.Exit(code=1)
|
|
return
|
|
|
|
typer.echo(render_markdown(report) if full else render_summary(report))
|
|
|
|
target = markdown_out or default_report_path(report)
|
|
frontmatter = (
|
|
"---\n"
|
|
"type: types/lint-report.md\n"
|
|
f"created: {report['generated']}\n"
|
|
f"summary: Structural lint report - {report['page_count']} pages scanned\n"
|
|
"---\n\n"
|
|
)
|
|
target.parent.mkdir(parents=True, exist_ok=True)
|
|
target.write_text(frontmatter + render_markdown(report) + "\n", encoding="utf-8")
|
|
success(f"Full report written to {rel_path(target)}")
|
|
|
|
if fail_on_error and has_hard_errors(report):
|
|
raise typer.Exit(code=1)
|