Implement infospace scaffold and service baseline
This commit is contained in:
parent
df6238c7e0
commit
9883a99f78
43 changed files with 35986 additions and 28 deletions
134
src/info_tech_canon/cli.py
Normal file
134
src/info_tech_canon/cli.py
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import sys
|
||||
from collections.abc import Callable
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from .api import serve
|
||||
from .service import (
|
||||
CanonServiceError,
|
||||
artifact_graph,
|
||||
inspect_canon,
|
||||
list_artifacts,
|
||||
list_models,
|
||||
list_standards,
|
||||
profile_inspect,
|
||||
validate_canon,
|
||||
)
|
||||
|
||||
|
||||
Command = Callable[[argparse.Namespace], dict[str, Any]]
|
||||
|
||||
|
||||
def build_parser() -> argparse.ArgumentParser:
|
||||
parser = argparse.ArgumentParser(prog="info-tech-canon")
|
||||
parser.add_argument(
|
||||
"--root",
|
||||
default="",
|
||||
help="Infospace root. Defaults to ./infospace from the repository root.",
|
||||
)
|
||||
sub = parser.add_subparsers(dest="command", required=True)
|
||||
|
||||
inspect = sub.add_parser("inspect", help="Inspect the canon infospace")
|
||||
inspect.set_defaults(handler=_inspect)
|
||||
|
||||
artifacts = sub.add_parser("artifacts", help="List canon artifacts")
|
||||
artifacts.add_argument("--kind", default="")
|
||||
artifacts.set_defaults(handler=_artifacts)
|
||||
|
||||
models = sub.add_parser("models", help="List canon model artifacts")
|
||||
models.set_defaults(handler=_models)
|
||||
|
||||
standards = sub.add_parser("standards", help="List canon standard artifacts")
|
||||
standards.set_defaults(handler=_standards)
|
||||
|
||||
validate = sub.add_parser("validate", help="Validate the canon infospace")
|
||||
validate.set_defaults(handler=_validate)
|
||||
|
||||
graph = sub.add_parser("graph", help="Export the canon artifact graph")
|
||||
graph.add_argument("--format", choices=["json", "mermaid"], default="json")
|
||||
graph.set_defaults(handler=_graph)
|
||||
|
||||
profile = sub.add_parser("profile", help="Inspect canon profiles")
|
||||
profile_sub = profile.add_subparsers(dest="profile_command", required=True)
|
||||
profile_inspect_cmd = profile_sub.add_parser("inspect", help="Inspect a profile")
|
||||
profile_inspect_cmd.add_argument("profile")
|
||||
profile_inspect_cmd.set_defaults(handler=_profile_inspect)
|
||||
|
||||
api = sub.add_parser("api", help="Run the read-only local API")
|
||||
api.add_argument("--host", default="127.0.0.1")
|
||||
api.add_argument("--port", type=int, default=8765)
|
||||
api.set_defaults(handler=_api)
|
||||
|
||||
return parser
|
||||
|
||||
|
||||
def main(argv: list[str] | None = None) -> int:
|
||||
parser = build_parser()
|
||||
args = parser.parse_args(argv)
|
||||
handler: Command = args.handler
|
||||
try:
|
||||
result = handler(args)
|
||||
except CanonServiceError as exc:
|
||||
_print_json(exc.to_dict())
|
||||
return 2
|
||||
except Exception as exc:
|
||||
_print_json(
|
||||
{
|
||||
"ok": False,
|
||||
"error": {
|
||||
"code": "unhandled_error",
|
||||
"message": str(exc),
|
||||
"details": {},
|
||||
},
|
||||
}
|
||||
)
|
||||
return 1
|
||||
if result:
|
||||
_print_json(result)
|
||||
return 0 if result.get("ok", False) else 1
|
||||
|
||||
|
||||
def _root(args: argparse.Namespace) -> Path | None:
|
||||
return Path(args.root) if args.root else None
|
||||
|
||||
|
||||
def _inspect(args: argparse.Namespace) -> dict[str, Any]:
|
||||
return inspect_canon(_root(args))
|
||||
|
||||
|
||||
def _artifacts(args: argparse.Namespace) -> dict[str, Any]:
|
||||
return list_artifacts(_root(args), kind=args.kind or None)
|
||||
|
||||
|
||||
def _models(args: argparse.Namespace) -> dict[str, Any]:
|
||||
return list_models(_root(args))
|
||||
|
||||
|
||||
def _standards(args: argparse.Namespace) -> dict[str, Any]:
|
||||
return list_standards(_root(args))
|
||||
|
||||
|
||||
def _validate(args: argparse.Namespace) -> dict[str, Any]:
|
||||
return validate_canon(_root(args))
|
||||
|
||||
|
||||
def _graph(args: argparse.Namespace) -> dict[str, Any]:
|
||||
return artifact_graph(_root(args), output_format=args.format)
|
||||
|
||||
|
||||
def _profile_inspect(args: argparse.Namespace) -> dict[str, Any]:
|
||||
return profile_inspect(args.profile, _root(args))
|
||||
|
||||
|
||||
def _api(args: argparse.Namespace) -> dict[str, Any]:
|
||||
serve(host=args.host, port=args.port, root=_root(args))
|
||||
return {}
|
||||
|
||||
|
||||
def _print_json(data: dict[str, Any]) -> None:
|
||||
json.dump(data, sys.stdout, indent=2, sort_keys=True)
|
||||
sys.stdout.write("\n")
|
||||
Loading…
Add table
Add a link
Reference in a new issue