Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions historian/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,23 @@ def build_parser() -> argparse.ArgumentParser:
)
config_subparsers.add_parser("path", help="Print the path Historian loads config from.")

parser.add_argument("--json", action="store_true", dest="as_json")
parser.add_argument(
"--json",
action="store_true",
dest="as_json",
help="Output compact minified JSON (machine-readable) instead of indented JSON.",
)
return parser


_compact_json = False


def _print(payload: Any) -> None:
print(json.dumps(to_jsonable(payload), indent=2, sort_keys=True))
if _compact_json:
print(json.dumps(to_jsonable(payload), separators=(",", ":"), sort_keys=True))
else:
print(json.dumps(to_jsonable(payload), indent=2, sort_keys=True))


def _write_private_token(path: Path, token: str) -> None:
Expand Down Expand Up @@ -146,8 +157,10 @@ def _try_client(settings: Settings, token: str) -> HistorianClient:


def main(argv: Sequence[str] | None = None) -> int:
global _compact_json
parser = build_parser()
args = parser.parse_args(argv)
_compact_json = args.as_json
try:
if args.command == "serve":
import uvicorn
Expand Down
22 changes: 22 additions & 0 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,28 @@ def test_init_cli_token_becomes_default_credential(config_path, tmp_path, capsys
assert listed["status"] == "ok"


def test_default_output_is_indented(config_path, tmp_path, capsys) -> None:
"""Without --json, output is pretty-printed with indentation."""
assert main(["--config", str(config_path), "app", "list"]) == 0
out = capsys.readouterr().out
# Indented output contains newlines and leading spaces.
assert "\n" in out
assert ' "' in out
# Still valid JSON.
assert json.loads(out)["status"] == "ok"


def test_json_flag_produces_compact_output(config_path, tmp_path, capsys) -> None:
"""With --json, output is single-line minified JSON."""
assert main(["--json", "--config", str(config_path), "app", "list"]) == 0
out = capsys.readouterr().out.rstrip("\n")
# Compact output is a single line with no extra whitespace.
assert "\n" not in out
assert " " not in out
# Still valid JSON.
assert json.loads(out)["status"] == "ok"


def _template_text() -> str:
return files("historian").joinpath("config.example.json").read_text(encoding="utf-8")

Expand Down
Loading