Coverage for /home/runner/work/coxbuild/coxbuild/src/coxbuild/configuration.py: 0%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1import os
2from pathlib import Path
3from typing import Any
6class Configuration:
7 """Build configuration, entry key is case-insensitive."""
9 def __init__(self, name: str = "", data: dict[str, Any] | None = None) -> None:
10 """
11 Create configuration.
13 name: section name
14 data: data source
15 """
16 self.name = name
17 self.data: dict[str, Any] = data if data is not None else {}
18 self.cache: dict[str, Configuration] = {}
19 if not self.name:
20 self.loadenv()
22 def copy(self) -> "Configuration":
23 """Copy configuration."""
24 return Configuration(self.name, self.data.copy())
26 def _getid(self, attr: str) -> str:
27 return (self.name + ":" + attr if self.name else attr).lower()
29 def __iter__(self):
30 pre = ""
31 if self.name:
32 pre = f"{self.name}:"
33 return (key for key in self.data if key.startswith(pre))
35 def get(self, key: str) -> Any | None:
36 id = self._getid(key)
37 return self.data.get(id)
39 def __getitem__(self, key: str) -> Any:
40 id = self._getid(key)
41 return self.data[id]
43 def __setitem__(self, key: str, value: Any) -> None:
44 id = self._getid(key)
45 self.data[id] = value
47 def __delitem__(self, key: str) -> None:
48 id = self._getid(key)
49 del self.data[id]
51 def section(self, name: str):
52 """
53 Get sub-section.
55 name: sub-section name
56 """
57 if name not in self.cache:
58 self.cache[name] = Configuration(self._getid(name), self.data)
59 return self.cache[name]
61 def env(self):
62 """Get environ section."""
63 return self.section("env")
65 def envbuild(self):
66 """Get environ:coxbuild section."""
67 return self.env().section("coxbuild")
69 def loadenv(self):
70 """Load environ section from os."""
71 env = self.env()
72 for key in os.environ:
73 env[key] = os.getenv(key)
76class ConfigurationAccessor:
77 """Configuration accessor."""
79 __configname__ = ""
81 def __init__(self, config: Configuration) -> None:
82 self.rootConfig = config
83 if self.__configname__:
84 self.config = config.section(self.__configname__)
85 self.fallback = config.envbuild().section(self.__configname__)
86 else:
87 self.config = config
88 self.fallback = config.envbuild()
90 def get(self, key: str) -> Any:
91 """Get configuration value (or fallback)."""
92 return self.config.get(key) or self.fallback.get(key)
94 def getPath(self, key: str) -> Path | None:
95 """Get configuration value (or fallback) as Path."""
96 value: Path | None | str = self.get(key)
97 if isinstance(value, str):
98 value = Path(value)
99 return value