Coverage for volexport/cli_utils.py: 79%

65 statements  

« prev     ^ index     » next       coverage.py v7.10.7, created at 2025-09-28 12:48 +0000

1import click 

2import json 

3import yaml 

4import pprint 

5import functools 

6from decimal import Decimal 

7from typing import Optional 

8from logging import getLogger 

9 

10_log = getLogger(__name__) 

11 

12 

13def set_verbose(verbose: Optional[bool]): 

14 from logging import basicConfig 

15 

16 fmt = "%(asctime)s %(levelname)s %(name)s %(message)s" 

17 level = "INFO" 

18 if verbose: 

19 level = "DEBUG" 

20 elif verbose is not None: 

21 level = "WARNING" 

22 basicConfig(level=level, format=fmt) 

23 

24 

25def verbose_option(func): 

26 """set log level: 

27 

28 - --verbose -> DEBUG 

29 - --quiet -> WARNING 

30 - (no option) -> INFO 

31 """ 

32 

33 @functools.wraps(func) 

34 def wrap(verbose, *args, **kwargs): 

35 set_verbose(verbose) 

36 return func(*args, **kwargs) 

37 

38 return click.option("--verbose/--quiet", default=None, help="log level")(wrap) 

39 

40 

41def output_format(func): 

42 """set output format: 

43 

44 - --format json -> JSON 

45 - --format pjson -> indented JSON 

46 - --format yaml -> YAML 

47 - --format pprint -> python pprint.pprint() 

48 """ 

49 

50 @click.option("--format", type=click.Choice(["json", "pjson", "yaml", "pprint"]), default="json", show_default=True) 

51 @functools.wraps(func) 

52 def wrap(format, *args, **kwargs): 

53 res = func(*args, **kwargs) 

54 if format == "json": 

55 click.echo(json.dumps(res, ensure_ascii=False)) 

56 elif format == "pjson": 

57 click.echo(json.dumps(res, indent=2, ensure_ascii=False)) 

58 elif format == "yaml": 

59 click.echo(yaml.dump(res, allow_unicode=True, encoding="utf-8")) 

60 elif format == "pprint": 60 ↛ 63line 60 didn't jump to line 63 because the condition on line 60 was always true

61 click.echo(pprint.pformat(res)) 

62 else: 

63 raise NotImplementedError(f"unknown format: {format}") 

64 

65 return wrap 

66 

67 

68class SizeType(click.ParamType): 

69 """size parameter 

70 

71 - xxxS (sector) -> x512 

72 - xxxK (kilo) -> x1024 

73 - xxxM (mega) -> x1024x1024 

74 - xxxG (giga) -> x1024x1024x1024 

75 - xxxT (tera) -> x1024x1024x1024x1024 

76 - xxxP (peta) -> x1024x1024x1024x1024x1024 

77 - xxxE (exa) -> x1024x1024x1024x1024x1024x1024 

78 """ 

79 

80 name = "size" 

81 

82 def convert(self, value: str, param, ctx): 

83 factor = Decimal(1) 

84 if value.endswith("S"): 84 ↛ 85line 84 didn't jump to line 85 because the condition on line 84 was never true

85 factor = Decimal(512) # sector 

86 value = value.removesuffix("S") 

87 if value.endswith("K"): 87 ↛ 88line 87 didn't jump to line 88 because the condition on line 87 was never true

88 factor = factor * Decimal(1024) 

89 value = value.removesuffix("K") 

90 elif value.endswith("M"): 

91 factor = factor * Decimal(1024**2) 

92 value = value.removesuffix("M") 

93 elif value.endswith("G"): 

94 factor = factor * Decimal(1024**3) 

95 value = value.removesuffix("G") 

96 elif value.endswith("T"): 96 ↛ 99line 96 didn't jump to line 99 because the condition on line 96 was always true

97 factor = factor * Decimal(1024**4) 

98 value = value.removesuffix("T") 

99 elif value.endswith("P"): 

100 factor = factor * Decimal(1024**5) 

101 value = value.removesuffix("P") 

102 elif value.endswith("E"): 

103 factor = factor * Decimal(1024**6) 

104 value = value.removesuffix("E") 

105 return int(Decimal(value) * factor)