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 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, str | list[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, str | list[str]], clean: dict[str, list[str]], type: str
53
- ) -> dict[str, 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
- conditions = tuple((k, tuple(wrap_in_list(v))) for k, v in when.items())
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
- if all(
211
- override.when.get(dim) == output.dimensions.get(dim)
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.7
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
- ```console
189
- $ toml-combine {path/to/config.toml}
220
+ [[override]]
221
+ when.environment = ["staging", "dev"]
222
+ when.service = "backend"
223
+ container.env.ENABLE_EXPENSIVE_MONITORING = false
190
224
  ```
191
225
 
192
- Generates all the outputs described by the given TOML config.
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
- ## Lib
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-job-manage": {...},
213
- "production-job-special-command": {...},
214
- "staging-job-manage": {...},
215
- "staging-job-special-command": {...},
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=98iWUnkbzDVGEkw-dXFZEt5G7io5SQzayceuTU2hRvo,7315
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.7.dist-info/METADATA,sha256=vUsTB2Phm6t8GMpu28aPPsIxkSNOb0nBIFnQuKJSj_Y,6401
8
- toml_combine-0.1.7.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
9
- toml_combine-0.1.7.dist-info/entry_points.txt,sha256=dXUQNom54uZt_7ylEG81iNYMamYpaFo9-ItcZJU6Uzc,58
10
- toml_combine-0.1.7.dist-info/RECORD,,
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,,