tools: one data record per command - -h, index and CONTRACT.md render from cli_contract (#121)
Files changed: - AGENTS.md - CHANGES.md - VERSION - instructions/dev/doc-pull-through.md - instructions/dev/stack-close/SKILL.md - tools/CONTRACT.md - tools/README.md - tools/chemenu/cli.py - tools/chemenu/cli_contract.py - tools/chemenu/commands/cite_cmd.py - tools/chemenu/commands/dist_cmd.py - tools/chemenu/commands/docs_verify.py - tools/chemenu/commands/doctor.py - tools/chemenu/commands/eval_cmd.py - tools/chemenu/commands/git_publish.py - tools/chemenu/commands/index_build.py - tools/chemenu/commands/instructions_cmd.py - tools/chemenu/commands/links_cmd.py - tools/chemenu/commands/lint.py - tools/chemenu/commands/log_append.py - tools/chemenu/commands/migrate_cmd.py - tools/chemenu/commands/new_page.py - tools/chemenu/commands/page_ops.py - tools/chemenu/commands/provenance_cmd.py - tools/chemenu/commands/raw_cmd.py - tools/chemenu/commands/review_cmd.py - tools/chemenu/commands/run_budget.py - tools/chemenu/commands/search.py - tools/chemenu/commands/task_cmd.py - tools/chemenu/commands/touch.py - tools/chemenu/commands/types_cmd.py - tools/chemenu/commands/upload_cmd.py - tools/chemenu/commands/upstream_cmd.py - tools/chemenu/commands/version_cmd.py - tools/chemenu/commands/work_cmd.py - tools/chemenu/commands/xref.py - tools/chemenu/tests/test_cli_contract.py - tools/chemenu/tests/test_docs_verify.py - tools/chemenu/tests/test_run_budget.py
This commit is contained in:
1 parent
919e733e21
commit
26e1018766
39 files changed
+5203
-702
No files matched your search
@@ -13,7 +13,7 @@ from typing import Optional
|
||||
|
||||
import typer
|
||||
|
||||
from chemenu import config
|
||||
from chemenu import cli_contract, config
|
||||
from chemenu.commands._util import fail, rel_path, success
|
||||
from chemenu.provenance import (
|
||||
broken_raw_refs,
|
||||
@@ -49,6 +49,21 @@ def _normalize_raw_path(raw: str) -> str:
|
||||
|
||||
|
||||
@app.command("coverage")
|
||||
@cli_contract.record(cli_contract.CommandRecord(
|
||||
path="sources coverage",
|
||||
summary="List raw files with no source page, broken `raw_files:` references, and legacy "
|
||||
"directory/URL-only source pages.",
|
||||
synopsis=(cli_contract.Variant(usage="sources coverage [--json]"),),
|
||||
properties=cli_contract.Properties(
|
||||
effect=cli_contract.Effect.READ,
|
||||
idempotent=cli_contract.Idempotent.YES,
|
||||
atomic="Read-only",
|
||||
budget=cli_contract.Budget.COUNTED,
|
||||
),
|
||||
notes="List raw files with no source page, broken `raw_files:` references, and legacy "
|
||||
"directory/URL-only source pages. Never fails. Safe to retry freely.",
|
||||
failures=(),
|
||||
))
|
||||
def coverage(json_out: bool = typer.Option(False, "--json", help="Print raw findings as JSON")):
|
||||
"""Report raw files with no source page, broken raw_files: references, and
|
||||
source pages still using a legacy directory/URL-only `source:` field."""
|
||||
@@ -74,6 +89,26 @@ def coverage(json_out: bool = typer.Option(False, "--json", help="Print raw find
|
||||
|
||||
|
||||
@app.command("trace")
|
||||
@cli_contract.record(cli_contract.CommandRecord(
|
||||
path="sources trace",
|
||||
summary="Trace provenance in either direction: raw file, or page.",
|
||||
synopsis=(cli_contract.Variant(usage='sources trace --raw <path> | --page "<Title>"'),),
|
||||
properties=cli_contract.Properties(
|
||||
effect=cli_contract.Effect.READ,
|
||||
idempotent=cli_contract.Idempotent.YES,
|
||||
atomic="Read-only",
|
||||
budget=cli_contract.Budget.COUNTED,
|
||||
),
|
||||
notes="Trace provenance in either direction: raw file -> source page(s) -> citing pages, or "
|
||||
"page -> its sources -> their raw files",
|
||||
failures=(cli_contract.Failure(
|
||||
label="",
|
||||
exit_1="Neither or both of `--raw`/`--page` given, `--raw` names a file no source page "
|
||||
"covers (reported as a plain finding plus exit 1, not the usual `ERROR`-prefixed "
|
||||
"rejection), or `--page` names an unknown page",
|
||||
retry="Fix the argument and retry",
|
||||
),),
|
||||
))
|
||||
def trace(
|
||||
raw: Optional[str] = typer.Option(None, "--raw", help="Raw file path to trace forward from"),
|
||||
page: Optional[str] = typer.Option(None, "--page", help="Wiki page title to trace backward from"),
|
||||
@@ -170,9 +205,28 @@ def build_provenance_index(kb_dir: Path, raw_dir: Path) -> str:
|
||||
|
||||
|
||||
@app.command("rebuild-index")
|
||||
@cli_contract.record(cli_contract.CommandRecord(
|
||||
path="sources rebuild-index",
|
||||
summary="Regenerate the `kb/provenance.md` reverse index.",
|
||||
synopsis=(cli_contract.Variant(usage="sources rebuild-index [--dry-run]"),),
|
||||
properties=cli_contract.Properties(
|
||||
effect=cli_contract.Effect.WRITE,
|
||||
idempotent=cli_contract.Idempotent.YES,
|
||||
atomic="Yes - the single provenance file is regenerated from scratch",
|
||||
budget=cli_contract.Budget.COUNTED,
|
||||
),
|
||||
notes="Regenerate the `kb/provenance.md` reverse index (raw file -> source page -> citing "
|
||||
"pages)",
|
||||
failures=(cli_contract.Failure(
|
||||
label="",
|
||||
exit_1="Rare I/O error only",
|
||||
retry="Safe to retry freely",
|
||||
),),
|
||||
))
|
||||
def rebuild_index(
|
||||
dry_run: bool = typer.Option(False, "--dry-run", help="Print the result instead of writing kb/provenance.md"),
|
||||
):
|
||||
"""Regenerate the `kb/provenance.md` reverse index."""
|
||||
content = build_provenance_index(config.KB_DIR, config.RAW_DIR)
|
||||
provenance_file = config.KB_DIR / "provenance.md"
|
||||
if dry_run:
|
||||
|
||||
Reference in new issue
Block a user