toml-combine 1.0.0__py3-none-any.whl → 1.0.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- toml_combine/cli.py +2 -2
- toml_combine/combiner.py +13 -1
- toml_combine/exceptions.py +1 -1
- {toml_combine-1.0.0.dist-info → toml_combine-1.0.2.dist-info}/METADATA +54 -15
- toml_combine-1.0.2.dist-info/RECORD +12 -0
- toml_combine-1.0.0.dist-info/RECORD +0 -12
- {toml_combine-1.0.0.dist-info → toml_combine-1.0.2.dist-info}/WHEEL +0 -0
- {toml_combine-1.0.0.dist-info → toml_combine-1.0.2.dist-info}/entry_points.txt +0 -0
- {toml_combine-1.0.0.dist-info → toml_combine-1.0.2.dist-info}/licenses/LICENSE +0 -0
toml_combine/cli.py
CHANGED
@@ -70,7 +70,7 @@ def cli(argv) -> int:
|
|
70
70
|
try:
|
71
71
|
config = combiner.build_config(dict_config)
|
72
72
|
except exceptions.TomlCombineError as exc:
|
73
|
-
print(exc, file=sys.stderr)
|
73
|
+
print(f"Error: {exc}", file=sys.stderr)
|
74
74
|
return 1
|
75
75
|
|
76
76
|
# Parse all arguments
|
@@ -86,7 +86,7 @@ def cli(argv) -> int:
|
|
86
86
|
try:
|
87
87
|
result = lib.combine(config=dict_config, **mapping)
|
88
88
|
except exceptions.TomlCombineError as exc:
|
89
|
-
print(exc, file=sys.stderr)
|
89
|
+
print(f"Error: {exc}", file=sys.stderr)
|
90
90
|
return 1
|
91
91
|
|
92
92
|
if args.format == "toml":
|
toml_combine/combiner.py
CHANGED
@@ -21,6 +21,7 @@ class Override:
|
|
21
21
|
class Config:
|
22
22
|
dimensions: Mapping[str, list[str]]
|
23
23
|
default: Mapping[str, Any]
|
24
|
+
# List of overrides, in order of increasing specificity
|
24
25
|
overrides: Sequence[Override]
|
25
26
|
|
26
27
|
|
@@ -30,6 +31,7 @@ def clean_dimensions_dict(
|
|
30
31
|
"""
|
31
32
|
Recreate a dictionary of dimension values with the same order as the
|
32
33
|
dimensions list.
|
34
|
+
Also check that the values are valid.
|
33
35
|
"""
|
34
36
|
result = {}
|
35
37
|
if invalid_dimensions := set(to_sort) - set(clean):
|
@@ -63,7 +65,7 @@ T = TypeVar("T", dict, list, str, int, float, bool)
|
|
63
65
|
|
64
66
|
def merge_configs(a: T, b: T, /) -> T:
|
65
67
|
"""
|
66
|
-
Recursively merge two configuration dictionaries, with b taking precedence.
|
68
|
+
Recursively merge two configuration dictionaries a and b, with b taking precedence.
|
67
69
|
"""
|
68
70
|
if isinstance(a, dict) != isinstance(b, dict):
|
69
71
|
raise ValueError(f"Cannot merge {type(a)} with {type(b)}")
|
@@ -116,6 +118,9 @@ def are_conditions_compatible(
|
|
116
118
|
|
117
119
|
|
118
120
|
def build_config(config: dict[str, Any]) -> Config:
|
121
|
+
"""
|
122
|
+
Build a finalized Config object from the given configuration dictionary.
|
123
|
+
"""
|
119
124
|
config = copy.deepcopy(config)
|
120
125
|
# Parse dimensions
|
121
126
|
dimensions = config.pop("dimensions")
|
@@ -165,6 +170,13 @@ def generate_for_mapping(
|
|
165
170
|
config: Config,
|
166
171
|
mapping: Mapping[str, str],
|
167
172
|
) -> Mapping[str, Any]:
|
173
|
+
"""
|
174
|
+
Generate a configuration based on the provided mapping of dimension values.
|
175
|
+
The mapping should contain only the dimensions defined in the config.
|
176
|
+
If a dimension is not defined in the mapping, the default value for that
|
177
|
+
dimension will be used.
|
178
|
+
"""
|
179
|
+
|
168
180
|
result = copy.deepcopy(config.default)
|
169
181
|
keys_to_conditions: dict[tuple[str, ...], list[Mapping[str, list[str]]]] = {}
|
170
182
|
# Apply each matching override
|
toml_combine/exceptions.py
CHANGED
@@ -20,7 +20,7 @@ class TomlEncodeError(TomlCombineError):
|
|
20
20
|
|
21
21
|
|
22
22
|
class IncompatibleOverrides(TomlCombineError):
|
23
|
-
"""
|
23
|
+
"""Incompatible overrides `{id}` and `{other_override}`: When they're both applicable, overrides defining a common overridden key ({key}) must be a subset of one another"""
|
24
24
|
|
25
25
|
|
26
26
|
class DimensionNotFound(TomlCombineError):
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: toml-combine
|
3
|
-
Version: 1.0.
|
3
|
+
Version: 1.0.2
|
4
4
|
Summary: A tool for combining complex configurations in TOML format.
|
5
5
|
Author-email: Joachim Jablon <ewjoachim@gmail.com>
|
6
6
|
License-Expression: MIT
|
@@ -68,24 +68,63 @@ The common configuration to start from, before we start overlaying overrides on
|
|
68
68
|
|
69
69
|
### Overrides
|
70
70
|
|
71
|
-
|
72
|
-
"<
|
71
|
+
Each override defines a set of condition where it applies (`when.<dimension> =
|
72
|
+
"<dimension_value>"`) and a set of overridden key/values.
|
73
73
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
74
|
+
```toml
|
75
|
+
[[override]]
|
76
|
+
# Conditions
|
77
|
+
when.environment = "staging"
|
78
|
+
when.region = "us"
|
79
|
+
|
80
|
+
# Overridden keys / values
|
81
|
+
service_account = "my-us-staging-service-account"
|
82
|
+
```
|
83
|
+
|
84
|
+
If two overrides are both applicable in the same run of `toml-combine`, they will be
|
85
|
+
checked for _compatibility_ with one another, and an error if they're not compatible.
|
86
|
+
|
87
|
+
Compatibility rules:
|
88
|
+
|
89
|
+
- If the two overrides don't share any overridden key, then they're always compatible.
|
90
|
+
- If the conditions of an override are a subset of the condition of the other one,
|
91
|
+
they're compatible. Also, in that case, the overridden values of the more specific one
|
92
|
+
**will have precedence**.
|
93
|
+
- If they both define a dimension that the other one doesn't, they're incompatible.
|
94
|
+
|
95
|
+
Example of incompatible overrides: neither is a subset of the other one and they both
|
96
|
+
define a value for `foo`:
|
97
|
+
|
98
|
+
```toml
|
99
|
+
[dimensions]
|
100
|
+
environment = ["staging"]
|
101
|
+
region = ["eu"]
|
102
|
+
|
103
|
+
[[override]]
|
104
|
+
when.environment = "staging"
|
105
|
+
foo = "bar"
|
82
106
|
|
83
|
-
|
84
|
-
|
107
|
+
[[override]]
|
108
|
+
when.region = "eu"
|
109
|
+
foo = "baz"
|
110
|
+
```
|
111
|
+
|
112
|
+
```console
|
113
|
+
$ toml-combine config.toml --environment=staging --region=eu
|
114
|
+
Error: Incompatible overrides `{'region': ['eu']}` and `{'environment': ['staging']}`:
|
115
|
+
When they're both applicable, overrides defining a common overridden key (foo) must be
|
116
|
+
a subset of one another
|
117
|
+
```
|
85
118
|
|
86
119
|
> [!Note]
|
87
|
-
>
|
88
|
-
>
|
120
|
+
> Instead of defining a single value for the override dimensions, you can define a list.
|
121
|
+
> This is a shortcut to duplicating the override with each individual value:
|
122
|
+
>
|
123
|
+
> ```
|
124
|
+
> [[override]]
|
125
|
+
> when.environment = ["staging", "prod"]
|
126
|
+
> service_account = "my-service-account"
|
127
|
+
> ```
|
89
128
|
|
90
129
|
### The configuration itself
|
91
130
|
|
@@ -0,0 +1,12 @@
|
|
1
|
+
toml_combine/__init__.py,sha256=TDkOwwEM-nS6hOh79u9Qae6g2Q6VfANpPpnKGfSgu80,84
|
2
|
+
toml_combine/__main__.py,sha256=hmF8N8xX6UEApzbKTVZ-4E1HU5-rjgUkdXNLO-mF6vo,100
|
3
|
+
toml_combine/cli.py,sha256=1eeh6sdKLsn5klRSc7E1rcBhN5Cf1O1Za5-Ule9FRVU,2867
|
4
|
+
toml_combine/combiner.py,sha256=fjsZ4WAKl7uO8BE8lYirJgo_1uj1t2o24rJA_FT1NFM,6147
|
5
|
+
toml_combine/exceptions.py,sha256=KrZpSdaI_ssYKw9LMsc3PAqNXEP-q6sT9scpgpXOo8o,1094
|
6
|
+
toml_combine/lib.py,sha256=jh6OG57JefpGa-WE-mLSIK6KjyJ0-1yGBynr_kiVTww,1634
|
7
|
+
toml_combine/toml.py,sha256=iBV8xj0qWcvGp2AZaML8FCT3i2X9DL7iA6jd-wcP5Bc,814
|
8
|
+
toml_combine-1.0.2.dist-info/METADATA,sha256=HUlO98eoZxeR0ZkvbmkB5VjZfcEmRkr1ZoP4p9RqvMU,9122
|
9
|
+
toml_combine-1.0.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
10
|
+
toml_combine-1.0.2.dist-info/entry_points.txt,sha256=dXUQNom54uZt_7ylEG81iNYMamYpaFo9-ItcZJU6Uzc,58
|
11
|
+
toml_combine-1.0.2.dist-info/licenses/LICENSE,sha256=tA7wpipzIPGl7xL5xzMMg0RhhXz9CKOa-ZnlYzgiTKg,1059
|
12
|
+
toml_combine-1.0.2.dist-info/RECORD,,
|
@@ -1,12 +0,0 @@
|
|
1
|
-
toml_combine/__init__.py,sha256=TDkOwwEM-nS6hOh79u9Qae6g2Q6VfANpPpnKGfSgu80,84
|
2
|
-
toml_combine/__main__.py,sha256=hmF8N8xX6UEApzbKTVZ-4E1HU5-rjgUkdXNLO-mF6vo,100
|
3
|
-
toml_combine/cli.py,sha256=hG03eDKz7xU-ydJIa1kDuu6WlFzNS3GTMJ6zals9M9c,2843
|
4
|
-
toml_combine/combiner.py,sha256=HG7KV3EGwmcHOMruhp7sMkH-uXqWKpsO7_BvhNQ2KQY,5668
|
5
|
-
toml_combine/exceptions.py,sha256=cRAZhxg3OHgzp5hJzyxNGG_jvGUm8gG8XzndQXBhvo8,1116
|
6
|
-
toml_combine/lib.py,sha256=jh6OG57JefpGa-WE-mLSIK6KjyJ0-1yGBynr_kiVTww,1634
|
7
|
-
toml_combine/toml.py,sha256=iBV8xj0qWcvGp2AZaML8FCT3i2X9DL7iA6jd-wcP5Bc,814
|
8
|
-
toml_combine-1.0.0.dist-info/METADATA,sha256=JxCXUhIW1v3MyM1ut0ZXbE6B6IuiXj4bf0YpwvlxGCw,8466
|
9
|
-
toml_combine-1.0.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
10
|
-
toml_combine-1.0.0.dist-info/entry_points.txt,sha256=dXUQNom54uZt_7ylEG81iNYMamYpaFo9-ItcZJU6Uzc,58
|
11
|
-
toml_combine-1.0.0.dist-info/licenses/LICENSE,sha256=tA7wpipzIPGl7xL5xzMMg0RhhXz9CKOa-ZnlYzgiTKg,1059
|
12
|
-
toml_combine-1.0.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|