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

1# Copyright (C) 2023 Maxwell G <maxwell@gtmx.me> 

2# 

3# SPDX-License-Identifier: MIT 

4 

5from __future__ import annotations 

6 

7import sys 

8from collections.abc import Iterable, Mapping, MutableMapping 

9from contextlib import contextmanager 

10from typing import Any, BinaryIO, Optional 

11 

12from typer import Argument, Exit, Typer 

13 

14from tomcli.toml import Reader, Writer, dump, load 

15 

16app = Typer() 

17 

18 

19def get_part(data: MutableMapping[str, Any], selector: str, /) -> Any: 

20 if selector == ".": 

21 return data 

22 

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 

34 

35 

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 

43 

44 

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)