toml-combine 0.1.7__py3-none-any.whl → 0.1.9__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/combiner.py +26 -10
- {toml_combine-0.1.7.dist-info → toml_combine-0.1.9.dist-info}/METADATA +116 -30
- {toml_combine-0.1.7.dist-info → toml_combine-0.1.9.dist-info}/RECORD +5 -5
- {toml_combine-0.1.7.dist-info → toml_combine-0.1.9.dist-info}/WHEEL +0 -0
- {toml_combine-0.1.7.dist-info → toml_combine-0.1.9.dist-info}/entry_points.txt +0 -0
toml_combine/combiner.py
CHANGED
@@ -5,7 +5,7 @@ import dataclasses
|
|
5
5
|
import itertools
|
6
6
|
from collections.abc import Mapping, Sequence
|
7
7
|
from functools import partial
|
8
|
-
from typing import Any
|
8
|
+
from typing import Any, TypeVar, Union
|
9
9
|
|
10
10
|
from . import exceptions
|
11
11
|
|
@@ -24,7 +24,7 @@ class Output:
|
|
24
24
|
|
25
25
|
@dataclasses.dataclass()
|
26
26
|
class Override:
|
27
|
-
when: Mapping[str,
|
27
|
+
when: Mapping[str, list[str]]
|
28
28
|
config: Mapping[str, Any]
|
29
29
|
|
30
30
|
def __str__(self) -> str:
|
@@ -48,9 +48,12 @@ def wrap_in_list(value: str | list[str]) -> list[str]:
|
|
48
48
|
return value
|
49
49
|
|
50
50
|
|
51
|
+
T = TypeVar("T", bound=Union[str, list[str]])
|
52
|
+
|
53
|
+
|
51
54
|
def clean_dimensions_dict(
|
52
|
-
to_sort: Mapping[str,
|
53
|
-
) -> dict[str,
|
55
|
+
to_sort: Mapping[str, T], clean: dict[str, list[str]], type: str
|
56
|
+
) -> dict[str, T]:
|
54
57
|
"""
|
55
58
|
Recreate a dictionary of dimension values with the same order as the
|
56
59
|
dimensions list.
|
@@ -148,7 +151,9 @@ def build_config(config: dict[str, Any]) -> Config:
|
|
148
151
|
except KeyError:
|
149
152
|
raise exceptions.MissingOverrideCondition(id=override)
|
150
153
|
|
151
|
-
|
154
|
+
when = {k: wrap_in_list(v) for k, v in when.items()}
|
155
|
+
|
156
|
+
conditions = tuple((k, tuple(v)) for k, v in when.items())
|
152
157
|
if conditions in seen_conditions:
|
153
158
|
raise exceptions.DuplicateError(type="override", id=when)
|
154
159
|
|
@@ -176,7 +181,6 @@ def build_config(config: dict[str, Any]) -> Config:
|
|
176
181
|
output[key] = wrap_in_list(output[key])
|
177
182
|
|
178
183
|
for cartesian_product in itertools.product(*output.values()):
|
179
|
-
# Create a dictionary with the same keys as when
|
180
184
|
single_output = dict(zip(output.keys(), cartesian_product))
|
181
185
|
|
182
186
|
conditions = tuple(single_output.items())
|
@@ -200,6 +204,20 @@ def build_config(config: dict[str, Any]) -> Config:
|
|
200
204
|
)
|
201
205
|
|
202
206
|
|
207
|
+
def output_matches_override(output: Output, override: Override) -> bool:
|
208
|
+
"""
|
209
|
+
Check if the values in the override match the output dimensions.
|
210
|
+
"""
|
211
|
+
for dim, values in override.when.items():
|
212
|
+
if dim not in output.dimensions:
|
213
|
+
return False
|
214
|
+
|
215
|
+
if output.dimensions[dim] not in values:
|
216
|
+
return False
|
217
|
+
|
218
|
+
return True
|
219
|
+
|
220
|
+
|
203
221
|
def generate_output(
|
204
222
|
default: Mapping[str, Any], overrides: Sequence[Override], output: Output
|
205
223
|
) -> dict[str, Any]:
|
@@ -207,10 +225,8 @@ def generate_output(
|
|
207
225
|
# Apply each matching override
|
208
226
|
for override in overrides:
|
209
227
|
# Check if all dimension values in the override match
|
210
|
-
|
211
|
-
|
212
|
-
for dim in override.when.keys()
|
213
|
-
):
|
228
|
+
|
229
|
+
if output_matches_override(output=output, override=override):
|
214
230
|
result = merge_configs(result, override.config)
|
215
231
|
|
216
232
|
return {"dimensions": output.dimensions, **result}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: toml-combine
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.9
|
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
|
@@ -146,6 +146,41 @@ This example is simple because `name` is a natural choice for the key. In some c
|
|
146
146
|
the choice is less natural, but you can always decide to name the elements of your
|
147
147
|
list and use that name as a key. Also, yes, you'll loose ordering.
|
148
148
|
|
149
|
+
### CLI
|
150
|
+
|
151
|
+
```console
|
152
|
+
$ toml-combine {path/to/config.toml}
|
153
|
+
```
|
154
|
+
|
155
|
+
Generates all the outputs described by the given TOML config.
|
156
|
+
|
157
|
+
Note that you can restrict generation to some dimension values by passing
|
158
|
+
`--{dimension}={value}`
|
159
|
+
|
160
|
+
## Lib
|
161
|
+
|
162
|
+
```python
|
163
|
+
import toml_combine
|
164
|
+
|
165
|
+
|
166
|
+
result = toml_combine.combine(
|
167
|
+
config_file=config_file,
|
168
|
+
environment=["production", "staging"],
|
169
|
+
type="job",
|
170
|
+
job=["manage", "special-command"],
|
171
|
+
)
|
172
|
+
|
173
|
+
print(result)
|
174
|
+
{
|
175
|
+
"production-job-manage": {...},
|
176
|
+
"production-job-special-command": {...},
|
177
|
+
"staging-job-manage": {...},
|
178
|
+
"staging-job-special-command": {...},
|
179
|
+
}
|
180
|
+
```
|
181
|
+
|
182
|
+
You can pass either `config` (TOML string or dict) or `config_file` (`pathlib.Path` or string path) to `combine()`. Additional `kwargs` restrict the output.
|
183
|
+
|
149
184
|
### A bigger example
|
150
185
|
|
151
186
|
```toml
|
@@ -181,39 +216,90 @@ container.port = 8080
|
|
181
216
|
name = "service-dev"
|
182
217
|
when.environment = "dev"
|
183
218
|
container.env.DEBUG = true
|
184
|
-
```
|
185
|
-
|
186
|
-
### CLI
|
187
219
|
|
188
|
-
|
189
|
-
|
220
|
+
[[override]]
|
221
|
+
when.environment = ["staging", "dev"]
|
222
|
+
when.service = "backend"
|
223
|
+
container.env.ENABLE_EXPENSIVE_MONITORING = false
|
190
224
|
```
|
191
225
|
|
192
|
-
|
193
|
-
|
194
|
-
Note that you can restrict generation to some dimension values by passing
|
195
|
-
`--{dimension}={value}`
|
226
|
+
This produces the following configs:
|
196
227
|
|
197
|
-
|
198
|
-
|
199
|
-
```python
|
200
|
-
import toml_combine
|
201
|
-
|
202
|
-
|
203
|
-
result = toml_combine.combine(
|
204
|
-
config_file=config_file,
|
205
|
-
environment=["production", "staging"],
|
206
|
-
type="job",
|
207
|
-
job=["manage", "special-command"],
|
208
|
-
)
|
209
|
-
|
210
|
-
print(result)
|
228
|
+
```json
|
211
229
|
{
|
212
|
-
"production-
|
213
|
-
|
214
|
-
|
215
|
-
|
230
|
+
"production-frontend-eu": {
|
231
|
+
"dimensions": {
|
232
|
+
"environment": "production",
|
233
|
+
"service": "frontend",
|
234
|
+
"region": "eu"
|
235
|
+
},
|
236
|
+
"registry": "gcr.io/my-project/",
|
237
|
+
"service_account": "my-service-account",
|
238
|
+
"name": "service-frontend",
|
239
|
+
"container": {
|
240
|
+
"image_name": "my-image-frontend"
|
241
|
+
}
|
242
|
+
},
|
243
|
+
"production-backend-eu": {
|
244
|
+
"dimensions": {
|
245
|
+
"environment": "production",
|
246
|
+
"service": "backend",
|
247
|
+
"region": "eu"
|
248
|
+
},
|
249
|
+
"registry": "gcr.io/my-project/",
|
250
|
+
"service_account": "my-service-account",
|
251
|
+
"name": "service-backend",
|
252
|
+
"container": {
|
253
|
+
"image_name": "my-image-backend",
|
254
|
+
"port": 8080
|
255
|
+
}
|
256
|
+
},
|
257
|
+
"staging-frontend-eu": {
|
258
|
+
"dimensions": {
|
259
|
+
"environment": "staging",
|
260
|
+
"service": "frontend",
|
261
|
+
"region": "eu"
|
262
|
+
},
|
263
|
+
"registry": "gcr.io/my-project/",
|
264
|
+
"service_account": "my-service-account",
|
265
|
+
"name": "service-frontend",
|
266
|
+
"container": {
|
267
|
+
"image_name": "my-image-frontend"
|
268
|
+
}
|
269
|
+
},
|
270
|
+
"staging-backend-eu": {
|
271
|
+
"dimensions": {
|
272
|
+
"environment": "staging",
|
273
|
+
"service": "backend",
|
274
|
+
"region": "eu"
|
275
|
+
},
|
276
|
+
"registry": "gcr.io/my-project/",
|
277
|
+
"service_account": "my-service-account",
|
278
|
+
"name": "service-backend",
|
279
|
+
"container": {
|
280
|
+
"image_name": "my-image-backend",
|
281
|
+
"port": 8080,
|
282
|
+
"env": {
|
283
|
+
"ENABLE_EXPENSIVE_MONITORING": false
|
284
|
+
}
|
285
|
+
}
|
286
|
+
},
|
287
|
+
"dev-backend": {
|
288
|
+
"dimensions": {
|
289
|
+
"environment": "dev",
|
290
|
+
"service": "backend"
|
291
|
+
},
|
292
|
+
"registry": "gcr.io/my-project/",
|
293
|
+
"service_account": "my-service-account",
|
294
|
+
"name": "service-backend",
|
295
|
+
"container": {
|
296
|
+
"env": {
|
297
|
+
"DEBUG": true,
|
298
|
+
"ENABLE_EXPENSIVE_MONITORING": false
|
299
|
+
},
|
300
|
+
"image_name": "my-image-backend",
|
301
|
+
"port": 8080
|
302
|
+
}
|
303
|
+
}
|
216
304
|
}
|
217
305
|
```
|
218
|
-
|
219
|
-
You can pass either `config` (TOML string or dict) or `config_file` (`pathlib.Path` or string path) to `combine()`. Additional `kwargs` restrict the output.
|
@@ -1,10 +1,10 @@
|
|
1
1
|
toml_combine/__init__.py,sha256=l7i0GkM9k7cc__wj1yqK5XjpB3IJ0jqFU63tqKMuYlY,1625
|
2
2
|
toml_combine/__main__.py,sha256=hmF8N8xX6UEApzbKTVZ-4E1HU5-rjgUkdXNLO-mF6vo,100
|
3
3
|
toml_combine/cli.py,sha256=MZrAEP4wt6f9Qn0TEXIjeLoQMlvQulFpkMciwU8GRO4,2328
|
4
|
-
toml_combine/combiner.py,sha256=
|
4
|
+
toml_combine/combiner.py,sha256=_sSOCVBlv8ljAdMd6BEthS6rxiCnt-VV9rMEPSK_Cvk,7643
|
5
5
|
toml_combine/exceptions.py,sha256=SepRFDxeWQEbD88jhF5g7laZSSULthho83BpW8u9RWs,897
|
6
6
|
toml_combine/toml.py,sha256=_vCINvfJeS3gWid35Pmm3Yz4xyJ8LpKJRHL0axSU8nk,384
|
7
|
-
toml_combine-0.1.
|
8
|
-
toml_combine-0.1.
|
9
|
-
toml_combine-0.1.
|
10
|
-
toml_combine-0.1.
|
7
|
+
toml_combine-0.1.9.dist-info/METADATA,sha256=ti8e_ng-_KdRPCAJybModogRhP4guqH8UilQTeXQHAk,8375
|
8
|
+
toml_combine-0.1.9.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
9
|
+
toml_combine-0.1.9.dist-info/entry_points.txt,sha256=dXUQNom54uZt_7ylEG81iNYMamYpaFo9-ItcZJU6Uzc,58
|
10
|
+
toml_combine-0.1.9.dist-info/RECORD,,
|
File without changes
|
File without changes
|