Coverage for src/edwh_restic_plugin/env.py: 13%

60 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-11-10 20:53 +0100

1import warnings 

2from pathlib import Path 

3 

4# the path where the environment variables are going 

5DOTENV = Path(".env") 

6DOTENV.touch(exist_ok=True) 

7 

8_dotenv_settings = {} 

9 

10 

11def read_dotenv(path: Path = DOTENV) -> dict: 

12 """Reads a .env file at the specified path and returns a dictionary of key - value pairs. 

13 

14 If the specified key is not found in the.env file, the function prompts the user to enter a value for the key, 

15 with a default value provided.The key-value pair is then appended to the.env file. 

16 

17 Args: 

18 path(Path): The path to the .env file. 

19 

20 Returns: 

21 dict: A dictionary containing the key - value pairs in the .env file.""" 

22 

23 if existing := _dotenv_settings.get(path): 

24 # 'cache' 

25 return existing 

26 

27 items = {} 

28 with path.open(mode="r") as env_file: 

29 for line in env_file: 

30 # remove comments and redundant whitespace 

31 line = line.split("#", 1)[0].strip() 

32 if not line or "=" not in line: 

33 # just a comment, skip 

34 # or key without value? invalid, prevent crash: 

35 continue 

36 

37 # convert to tuples 

38 k, v = line.split("=", 1) 

39 

40 # clean the tuples and add to dict 

41 items[k.strip()] = v.strip() 

42 

43 _dotenv_settings[path] = items 

44 return items 

45 

46 

47def set_env_value(path: Path, target: str, value: str) -> None: 

48 """ 

49 update/set environment variables in the .env file, keeping comments intact 

50 

51 set_env_value(Path('.env'), 'SCHEMA_VERSION', schemaversion) 

52 

53 Args: 

54 path: pathlib.Path designating the .env file 

55 target: key to write, probably best to use UPPERCASE 

56 value: string value to write, or anything that converts to a string using str() 

57 """ 

58 with path.open(mode="r") as env_file: 

59 # open the .env file and read every line in the inlines 

60 inlines = env_file.read().split("\n") 

61 

62 outlines = [] # lines for output 

63 geschreven = False 

64 for line in inlines: 

65 if line.strip().startswith("#"): 

66 # ignore comments 

67 outlines.append(line) 

68 continue 

69 # remove redundant whitespace 

70 line = line.strip() 

71 if not line: 

72 # remove empty lines 

73 continue 

74 # convert to tuples 

75 key, oldvalue = line.split("=", 1) 

76 # clean the key and value 

77 key = key.strip() 

78 if key == target: 

79 # add the new tuple to the lines 

80 outlines.append(f"{key}={value}") 

81 geschreven = True 

82 else: 

83 # or leave it as it is 

84 outlines.append(line) 

85 if not geschreven: 

86 # if target in .env file 

87 outlines.append(f"{target.strip().upper()}={value.strip()}") 

88 with path.open(mode="w") as env_file: 

89 # write outlines to .env file 

90 env_file.write("\n".join(outlines)) 

91 env_file.write("\n") 

92 

93 

94def check_env( 

95 key: str, 

96 default: str | None, 

97 comment: str, 

98 prefix: str = None, 

99 suffix: str = None, 

100 postfix: str = None, 

101 path: Path = None, 

102): 

103 """ 

104 Test if key is in .env file path, appends prompted or default value if missing. 

105 """ 

106 if postfix: 

107 warnings.warn("`postfix` option passed. Please use `suffix` instead!", category=DeprecationWarning) 

108 

109 suffix = suffix or postfix 

110 

111 env = read_dotenv(path) 

112 if key in env: 

113 return env[key] 

114 

115 # get response value from prompt/input 

116 # if response_value is empty make value default else value is response_value 

117 value = input(f"Enter value for {key} ({comment})\n default=`{default}`: ").strip() or default or "" 

118 if value.startswith("~/") and Path(value).expanduser().exists(): 

119 value = str(Path(value).expanduser()) 

120 if prefix: 

121 value = prefix + value 

122 if suffix: 

123 value += suffix 

124 

125 with path.open(mode="r+") as env_file: 

126 env_file.seek(0, 2) 

127 # write key and value to .env file 

128 env_file.write(f"\n{key.upper()}={value}\n") 

129 

130 # update in memory too: 

131 env[key] = value 

132 return value