Coverage for src/tomcli/cli/get.py: 95%
40 statements
« prev ^ index » next coverage.py v7.2.3, created at 2023-04-13 04:07 +0300
« prev ^ index » next coverage.py v7.2.3, created at 2023-04-13 04:07 +0300
1# Copyright (C) 2023 Maxwell G <maxwell@gtmx.me>
2#
3# SPDX-License-Identifier: MIT
5from __future__ import annotations
7import sys
8from collections.abc import Iterable, Mapping, MutableMapping
9from contextlib import contextmanager
10from typing import Any, BinaryIO, Optional
12from typer import Argument, Exit, Typer
14from tomcli.toml import Reader, Writer, dump, load
16app = Typer()
19def get_part(data: MutableMapping[str, Any], selector: str, /) -> Any:
20 if selector == ".":
21 return data
23 cur = data
24 parts = selector.split(".")
25 idx = 0
26 try:
27 for idx, part in enumerate(parts): # noqa: B007
28 cur = cur[part]
29 except (IndexError, KeyError):
30 up_to = ".".join(parts[: idx + 1])
31 msg = f"Invalid selector {selector!r}: could not find {up_to!r}"
32 raise Exit(msg) from None
33 return cur
36@contextmanager
37def _std_cm(path: str, dash_stream: str, mode: str) -> Iterable[BinaryIO]:
38 if str(path) == "-":
39 yield dash_stream
40 else:
41 with open(path, mode) as fp:
42 yield fp
45@app.command()
46def get(
47 path: str = Argument(...),
48 selector: str = Argument("."),
49 reader: Optional[Reader] = None,
50 writer: Optional[Writer] = None,
51):
52 allow_fallback_r = bool(reader)
53 allow_fallback_w = bool(writer)
54 reader = reader or Reader.TOMLKIT
55 writer = writer or Writer.TOMLKIT
56 with _std_cm(path, sys.stdin.buffer, "rb") as fp:
57 data = load(fp, reader, allow_fallback_r)
58 selected = get_part(data, selector)
59 if isinstance(selected, Mapping):
60 dump(selected, sys.stdout.buffer, writer, allow_fallback_w)
61 else:
62 print(selected)