feat(cli): 'tht session set-schema-linking' (file/stdin, validated)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
"""L1: `tht session set-schema-linking` — stdin/file JSON → validate → write."""
|
||||
import json
|
||||
|
||||
from typer.testing import CliRunner
|
||||
|
||||
from tht.cli.session_cmd import session_app
|
||||
from tht.config import DatabaseConfig
|
||||
from tht.session.store import create_session
|
||||
|
||||
|
||||
def _db():
|
||||
return DatabaseConfig(database="testdb", user="u", password="p", **{"schema": "public"}) # noqa: S106
|
||||
|
||||
|
||||
def _patch_cfg(monkeypatch, tmp_path):
|
||||
from tht.cli import session_cmd
|
||||
|
||||
class FakePaths:
|
||||
sessions = tmp_path
|
||||
|
||||
class FakeCfg:
|
||||
paths = FakePaths()
|
||||
database = _db()
|
||||
|
||||
monkeypatch.setattr(session_cmd, "_load_config_or_exit", lambda _: FakeCfg())
|
||||
|
||||
|
||||
_VALID = json.dumps({
|
||||
"question": "q",
|
||||
"candidates": [{"kind": "table", "name": "fact_x", "decision": "promoted"}],
|
||||
})
|
||||
|
||||
|
||||
def test_cli_stdin_writes(tmp_path, monkeypatch):
|
||||
m = create_session("q", _db(), tmp_path)
|
||||
_patch_cfg(monkeypatch, tmp_path)
|
||||
res = CliRunner().invoke(session_app, ["set-schema-linking", m.id, "--file", "-"], input=_VALID)
|
||||
assert res.exit_code == 0, res.output
|
||||
assert (tmp_path / m.id / "schema_linking.json").exists()
|
||||
|
||||
|
||||
def test_cli_file_writes(tmp_path, monkeypatch):
|
||||
m = create_session("q", _db(), tmp_path)
|
||||
p = tmp_path / "sl.json"
|
||||
p.write_text(_VALID)
|
||||
_patch_cfg(monkeypatch, tmp_path)
|
||||
res = CliRunner().invoke(session_app, ["set-schema-linking", m.id, "--file", str(p)])
|
||||
assert res.exit_code == 0, res.output
|
||||
assert (tmp_path / m.id / "schema_linking.json").exists()
|
||||
|
||||
|
||||
def test_cli_invalid_json_exit5(tmp_path, monkeypatch):
|
||||
m = create_session("q", _db(), tmp_path)
|
||||
_patch_cfg(monkeypatch, tmp_path)
|
||||
res = CliRunner().invoke(session_app, ["set-schema-linking", m.id, "--file", "-"], input="{not json")
|
||||
assert res.exit_code == 5
|
||||
assert not (tmp_path / m.id / "schema_linking.json").exists()
|
||||
|
||||
|
||||
def test_cli_invalid_model_exit5(tmp_path, monkeypatch):
|
||||
m = create_session("q", _db(), tmp_path)
|
||||
_patch_cfg(monkeypatch, tmp_path)
|
||||
res = CliRunner().invoke(
|
||||
session_app, ["set-schema-linking", m.id, "--file", "-"], input='{"question":"q","bogus":1}'
|
||||
)
|
||||
assert res.exit_code == 5
|
||||
assert not (tmp_path / m.id / "schema_linking.json").exists()
|
||||
@@ -110,6 +110,37 @@ def set_question_cmd(
|
||||
typer.secho(f"OK: question.md aggiornato ({path}).", fg=typer.colors.GREEN)
|
||||
|
||||
|
||||
@session_app.command("set-schema-linking")
|
||||
def set_schema_linking_cmd(
|
||||
session_id: str = typer.Argument(...),
|
||||
file: str = typer.Option(
|
||||
..., "--file", "-f",
|
||||
help="Path al JSON dello schema-linking, oppure '-' per leggere da stdin."),
|
||||
config: Path = CONFIG_OPT,
|
||||
) -> None:
|
||||
"""Valida (modello SchemaLinking) e scrive schema_linking.json deterministicamente."""
|
||||
import sys
|
||||
|
||||
from pydantic import ValidationError
|
||||
|
||||
from tht.session.store import set_schema_linking
|
||||
|
||||
cfg = _load_config_or_exit(config)
|
||||
load_session_or_exit(cfg, session_id)
|
||||
raw = sys.stdin.read() if file == "-" else Path(file).read_text()
|
||||
try:
|
||||
data = json.loads(raw)
|
||||
except json.JSONDecodeError as e:
|
||||
typer.secho(f"ERRORE: JSON non valido: {e}", fg=typer.colors.RED, err=True)
|
||||
raise typer.Exit(code=5)
|
||||
try:
|
||||
path = set_schema_linking(session_id, data, cfg.paths.sessions)
|
||||
except ValidationError as e:
|
||||
typer.secho(f"ERRORE: schema_linking non valido:\n{e}", fg=typer.colors.RED, err=True)
|
||||
raise typer.Exit(code=5)
|
||||
typer.secho(f"OK: schema_linking.json aggiornato ({path}).", fg=typer.colors.GREEN)
|
||||
|
||||
|
||||
@session_app.command("show")
|
||||
def show_cmd(
|
||||
session_id: str = typer.Argument(...),
|
||||
|
||||
Reference in New Issue
Block a user