-
Notifications
You must be signed in to change notification settings - Fork 3
/
env_path.py
56 lines (44 loc) · 1.61 KB
/
env_path.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
"""TcEx Framework Module"""
# standard library
import os
import re
from collections.abc import Generator
from pathlib import Path
from typing import Any
# pylint: disable=duplicate-bases
class _EnvPath(type(Path()), Path): # type: ignore
"""A stub of Path with additional attribute."""
# store for the original value passed to EnvPath
original_value: str | None = None
class EnvPath(Path):
"""EnvPath custom pydantic model type."""
@classmethod
def __modify_schema__(cls, field_schema: dict[str, Any]):
"""."""
field_schema.update(format='file-path')
@classmethod
def __get_validators__(cls) -> Generator:
"""."""
yield cls.validate
@classmethod
def validate(cls, value: Path | str) -> Path | str:
"""Replace any environment variables in the tcex.json file."""
if isinstance(value, Path):
return value
string = str(value)
for m in re.finditer(r'\${(env|envs|local|remote):(.*?)}', string):
try:
full_match = m.group(0)
env_type = m.group(1)
env_key = m.group(2)
if env_type != 'env':
raise ValueError(f'Invalid environment type found ({env_type})')
env_value = os.getenv(env_key)
if env_value is not None:
string = string.replace(full_match, env_value)
except IndexError:
return string
# convert value to Path and return original value
p = _EnvPath(os.path.expanduser(string))
p.original_value = value
return p