toml-combine 0.2.0__tar.gz → 0.4.0__tar.gz
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-0.2.0 → toml_combine-0.4.0}/PKG-INFO +3 -20
- {toml_combine-0.2.0 → toml_combine-0.4.0}/README.md +2 -19
- {toml_combine-0.2.0 → toml_combine-0.4.0}/tests/result.json +8 -66
- {toml_combine-0.2.0 → toml_combine-0.4.0}/tests/test_combiner.py +0 -3
- {toml_combine-0.2.0 → toml_combine-0.4.0}/toml_combine/combiner.py +7 -4
- {toml_combine-0.2.0 → toml_combine-0.4.0}/toml_combine/toml.py +1 -1
- {toml_combine-0.2.0 → toml_combine-0.4.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {toml_combine-0.2.0 → toml_combine-0.4.0}/.github/renovate.json5 +0 -0
- {toml_combine-0.2.0 → toml_combine-0.4.0}/.github/workflows/ci.yml +0 -0
- {toml_combine-0.2.0 → toml_combine-0.4.0}/.pre-commit-config.yaml +0 -0
- {toml_combine-0.2.0 → toml_combine-0.4.0}/pyproject.toml +0 -0
- {toml_combine-0.2.0 → toml_combine-0.4.0}/tests/test.toml +0 -0
- {toml_combine-0.2.0 → toml_combine-0.4.0}/tests/test_cli.py +0 -0
- {toml_combine-0.2.0 → toml_combine-0.4.0}/tests/test_lib.py +0 -0
- {toml_combine-0.2.0 → toml_combine-0.4.0}/toml_combine/__init__.py +0 -0
- {toml_combine-0.2.0 → toml_combine-0.4.0}/toml_combine/__main__.py +0 -0
- {toml_combine-0.2.0 → toml_combine-0.4.0}/toml_combine/cli.py +0 -0
- {toml_combine-0.2.0 → toml_combine-0.4.0}/toml_combine/exceptions.py +0 -0
- {toml_combine-0.2.0 → toml_combine-0.4.0}/toml_combine/lib.py +0 -0
- {toml_combine-0.2.0 → toml_combine-0.4.0}/uv.lock +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: toml-combine
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.4.0
|
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
|
@@ -131,8 +131,7 @@ list and use that name as a key. Also, yes, you'll loose ordering.
|
|
131
131
|
When you call the tool either with the CLI or the lib (see both below), you will have to
|
132
132
|
provide a mapping of the desired dimentions. These values will be compared to overrides
|
133
133
|
to apply overrides when relevant. It's ok to omit some dimensions, corresponding
|
134
|
-
overrides won't be selected.
|
135
|
-
dict under the `dimensions` key.
|
134
|
+
overrides won't be selected.
|
136
135
|
|
137
136
|
By default, the output is `toml` though you can switch to `json` with `--format=json`
|
138
137
|
|
@@ -160,7 +159,6 @@ result = toml_combine.combine(config_file=config_file, environment="staging")
|
|
160
159
|
|
161
160
|
print(result)
|
162
161
|
{
|
163
|
-
"dimensions": {"environment": "staging"},
|
164
162
|
"fruits": {"apple": {"color": "red"}, "orange": {"color": "orange"}}
|
165
163
|
}
|
166
164
|
```
|
@@ -203,13 +201,10 @@ container.env.ENABLE_EXPENSIVE_MONITORING = false
|
|
203
201
|
This produces the following configs:
|
204
202
|
|
205
203
|
```console
|
206
|
-
$
|
204
|
+
$ toml-combine example.toml --environment=production --service=frontend
|
207
205
|
registry = "gcr.io/my-project/"
|
208
206
|
service_account = "my-service-account"
|
209
207
|
name = "service-frontend"
|
210
|
-
[dimensions]
|
211
|
-
environment = "production"
|
212
|
-
service = "frontend"
|
213
208
|
|
214
209
|
[container]
|
215
210
|
image_name = "my-image-frontend"
|
@@ -220,9 +215,6 @@ $ toml-combine example.toml --environment=production --service=backend
|
|
220
215
|
registry = "gcr.io/my-project/"
|
221
216
|
service_account = "my-service-account"
|
222
217
|
name = "service-backend"
|
223
|
-
[dimensions]
|
224
|
-
environment = "production"
|
225
|
-
service = "backend"
|
226
218
|
|
227
219
|
[container]
|
228
220
|
image_name = "my-image-backend"
|
@@ -234,9 +226,6 @@ $ toml-combine example.toml --environment=staging --service=frontend
|
|
234
226
|
registry = "gcr.io/my-project/"
|
235
227
|
service_account = "my-service-account"
|
236
228
|
name = "service-frontend"
|
237
|
-
[dimensions]
|
238
|
-
environment = "staging"
|
239
|
-
service = "frontend"
|
240
229
|
|
241
230
|
[container]
|
242
231
|
image_name = "my-image-frontend"
|
@@ -247,9 +236,6 @@ $ toml-combine example.toml --environment=staging --service=backend
|
|
247
236
|
registry = "gcr.io/my-project/"
|
248
237
|
service_account = "my-service-account"
|
249
238
|
name = "service-backend"
|
250
|
-
[dimensions]
|
251
|
-
environment = "staging"
|
252
|
-
service = "backend"
|
253
239
|
|
254
240
|
[container]
|
255
241
|
image_name = "my-image-backend"
|
@@ -264,9 +250,6 @@ $ toml-combine example.toml --environment=dev --service=backend
|
|
264
250
|
registry = "gcr.io/my-project/"
|
265
251
|
service_account = "my-service-account"
|
266
252
|
name = "service-backend"
|
267
|
-
[dimensions]
|
268
|
-
environment = "dev"
|
269
|
-
service = "backend"
|
270
253
|
|
271
254
|
[container]
|
272
255
|
image_name = "my-image-backend"
|
@@ -112,8 +112,7 @@ list and use that name as a key. Also, yes, you'll loose ordering.
|
|
112
112
|
When you call the tool either with the CLI or the lib (see both below), you will have to
|
113
113
|
provide a mapping of the desired dimentions. These values will be compared to overrides
|
114
114
|
to apply overrides when relevant. It's ok to omit some dimensions, corresponding
|
115
|
-
overrides won't be selected.
|
116
|
-
dict under the `dimensions` key.
|
115
|
+
overrides won't be selected.
|
117
116
|
|
118
117
|
By default, the output is `toml` though you can switch to `json` with `--format=json`
|
119
118
|
|
@@ -141,7 +140,6 @@ result = toml_combine.combine(config_file=config_file, environment="staging")
|
|
141
140
|
|
142
141
|
print(result)
|
143
142
|
{
|
144
|
-
"dimensions": {"environment": "staging"},
|
145
143
|
"fruits": {"apple": {"color": "red"}, "orange": {"color": "orange"}}
|
146
144
|
}
|
147
145
|
```
|
@@ -184,13 +182,10 @@ container.env.ENABLE_EXPENSIVE_MONITORING = false
|
|
184
182
|
This produces the following configs:
|
185
183
|
|
186
184
|
```console
|
187
|
-
$
|
185
|
+
$ toml-combine example.toml --environment=production --service=frontend
|
188
186
|
registry = "gcr.io/my-project/"
|
189
187
|
service_account = "my-service-account"
|
190
188
|
name = "service-frontend"
|
191
|
-
[dimensions]
|
192
|
-
environment = "production"
|
193
|
-
service = "frontend"
|
194
189
|
|
195
190
|
[container]
|
196
191
|
image_name = "my-image-frontend"
|
@@ -201,9 +196,6 @@ $ toml-combine example.toml --environment=production --service=backend
|
|
201
196
|
registry = "gcr.io/my-project/"
|
202
197
|
service_account = "my-service-account"
|
203
198
|
name = "service-backend"
|
204
|
-
[dimensions]
|
205
|
-
environment = "production"
|
206
|
-
service = "backend"
|
207
199
|
|
208
200
|
[container]
|
209
201
|
image_name = "my-image-backend"
|
@@ -215,9 +207,6 @@ $ toml-combine example.toml --environment=staging --service=frontend
|
|
215
207
|
registry = "gcr.io/my-project/"
|
216
208
|
service_account = "my-service-account"
|
217
209
|
name = "service-frontend"
|
218
|
-
[dimensions]
|
219
|
-
environment = "staging"
|
220
|
-
service = "frontend"
|
221
210
|
|
222
211
|
[container]
|
223
212
|
image_name = "my-image-frontend"
|
@@ -228,9 +217,6 @@ $ toml-combine example.toml --environment=staging --service=backend
|
|
228
217
|
registry = "gcr.io/my-project/"
|
229
218
|
service_account = "my-service-account"
|
230
219
|
name = "service-backend"
|
231
|
-
[dimensions]
|
232
|
-
environment = "staging"
|
233
|
-
service = "backend"
|
234
220
|
|
235
221
|
[container]
|
236
222
|
image_name = "my-image-backend"
|
@@ -245,9 +231,6 @@ $ toml-combine example.toml --environment=dev --service=backend
|
|
245
231
|
registry = "gcr.io/my-project/"
|
246
232
|
service_account = "my-service-account"
|
247
233
|
name = "service-backend"
|
248
|
-
[dimensions]
|
249
|
-
environment = "dev"
|
250
|
-
service = "backend"
|
251
234
|
|
252
235
|
[container]
|
253
236
|
image_name = "my-image-backend"
|
@@ -9,11 +9,6 @@
|
|
9
9
|
"name": "frontend",
|
10
10
|
"env": { "NEXT_PUBLIC_FOO": "baz" }
|
11
11
|
}
|
12
|
-
},
|
13
|
-
"dimensions": {
|
14
|
-
"environment": "staging",
|
15
|
-
"stack": "next",
|
16
|
-
"type": "service"
|
17
12
|
}
|
18
13
|
},
|
19
14
|
"staging-service-django-api": {
|
@@ -27,13 +22,7 @@
|
|
27
22
|
"env": { "APP_FOO": "qux" }
|
28
23
|
}
|
29
24
|
},
|
30
|
-
"cloudsql_instance": "staging-postgres"
|
31
|
-
"dimensions": {
|
32
|
-
"environment": "staging",
|
33
|
-
"stack": "django",
|
34
|
-
"type": "service",
|
35
|
-
"service": "api"
|
36
|
-
}
|
25
|
+
"cloudsql_instance": "staging-postgres"
|
37
26
|
},
|
38
27
|
"staging-service-django-admin": {
|
39
28
|
"registry": { "region": "us" },
|
@@ -46,13 +35,7 @@
|
|
46
35
|
"env": { "APP_FOO": "qux", "APP_ID": 5678, "APP_ADMIN_ENABLED": true }
|
47
36
|
}
|
48
37
|
},
|
49
|
-
"cloudsql_instance": "staging-postgres"
|
50
|
-
"dimensions": {
|
51
|
-
"environment": "staging",
|
52
|
-
"stack": "django",
|
53
|
-
"type": "service",
|
54
|
-
"service": "admin"
|
55
|
-
}
|
38
|
+
"cloudsql_instance": "staging-postgres"
|
56
39
|
},
|
57
40
|
"staging-job-django-manage": {
|
58
41
|
"registry": { "region": "us" },
|
@@ -65,13 +48,7 @@
|
|
65
48
|
"command": ["./manage.py"]
|
66
49
|
}
|
67
50
|
},
|
68
|
-
"cloudsql_instance": "staging-postgres"
|
69
|
-
"dimensions": {
|
70
|
-
"environment": "staging",
|
71
|
-
"stack": "django",
|
72
|
-
"type": "job",
|
73
|
-
"job": "manage"
|
74
|
-
}
|
51
|
+
"cloudsql_instance": "staging-postgres"
|
75
52
|
},
|
76
53
|
"staging-job-django-special-command": {
|
77
54
|
"registry": { "region": "us" },
|
@@ -86,13 +63,7 @@
|
|
86
63
|
"args": ["special-command"]
|
87
64
|
}
|
88
65
|
},
|
89
|
-
"cloudsql_instance": "staging-postgres"
|
90
|
-
"dimensions": {
|
91
|
-
"environment": "staging",
|
92
|
-
"stack": "django",
|
93
|
-
"type": "job",
|
94
|
-
"job": "special-command"
|
95
|
-
}
|
66
|
+
"cloudsql_instance": "staging-postgres"
|
96
67
|
},
|
97
68
|
"production-service-next": {
|
98
69
|
"registry": { "region": "us" },
|
@@ -104,11 +75,6 @@
|
|
104
75
|
"service": { "min_scale": 1 }
|
105
76
|
},
|
106
77
|
"telemetry": { "enabled": true }
|
107
|
-
},
|
108
|
-
"dimensions": {
|
109
|
-
"environment": "production",
|
110
|
-
"stack": "next",
|
111
|
-
"type": "service"
|
112
78
|
}
|
113
79
|
},
|
114
80
|
"production-service-django-api": {
|
@@ -122,13 +88,7 @@
|
|
122
88
|
"env": { "APP_FOO": "bar" }
|
123
89
|
}
|
124
90
|
},
|
125
|
-
"cloudsql_instance": "production-postgres"
|
126
|
-
"dimensions": {
|
127
|
-
"environment": "production",
|
128
|
-
"stack": "django",
|
129
|
-
"type": "service",
|
130
|
-
"service": "api"
|
131
|
-
}
|
91
|
+
"cloudsql_instance": "production-postgres"
|
132
92
|
},
|
133
93
|
"production-service-django-admin": {
|
134
94
|
"registry": { "region": "us" },
|
@@ -141,13 +101,7 @@
|
|
141
101
|
"env": { "APP_FOO": "bar", "APP_ADMIN_ENABLED": true, "APP_ID": 1234 }
|
142
102
|
}
|
143
103
|
},
|
144
|
-
"cloudsql_instance": "production-postgres"
|
145
|
-
"dimensions": {
|
146
|
-
"environment": "production",
|
147
|
-
"stack": "django",
|
148
|
-
"type": "service",
|
149
|
-
"service": "admin"
|
150
|
-
}
|
104
|
+
"cloudsql_instance": "production-postgres"
|
151
105
|
},
|
152
106
|
"production-job-django-manage": {
|
153
107
|
"registry": { "region": "us" },
|
@@ -160,13 +114,7 @@
|
|
160
114
|
"command": ["./manage.py"]
|
161
115
|
}
|
162
116
|
},
|
163
|
-
"cloudsql_instance": "production-postgres"
|
164
|
-
"dimensions": {
|
165
|
-
"environment": "production",
|
166
|
-
"stack": "django",
|
167
|
-
"type": "job",
|
168
|
-
"job": "manage"
|
169
|
-
}
|
117
|
+
"cloudsql_instance": "production-postgres"
|
170
118
|
},
|
171
119
|
"production-job-django-special-command": {
|
172
120
|
"registry": { "region": "us" },
|
@@ -181,12 +129,6 @@
|
|
181
129
|
"args": ["special-command"]
|
182
130
|
}
|
183
131
|
},
|
184
|
-
"cloudsql_instance": "production-postgres"
|
185
|
-
"dimensions": {
|
186
|
-
"environment": "production",
|
187
|
-
"stack": "django",
|
188
|
-
"type": "job",
|
189
|
-
"job": "special-command"
|
190
|
-
}
|
132
|
+
"cloudsql_instance": "production-postgres"
|
191
133
|
}
|
192
134
|
}
|
@@ -75,7 +75,6 @@ def test_merge_configs__dicts_error():
|
|
75
75
|
"c": 3,
|
76
76
|
"d": {"e": {"h": {"i": {"j": 4}}}},
|
77
77
|
"g": 6,
|
78
|
-
"dimensions": {"env": "dev"},
|
79
78
|
},
|
80
79
|
id="no_matches",
|
81
80
|
),
|
@@ -87,7 +86,6 @@ def test_merge_configs__dicts_error():
|
|
87
86
|
"c": 30,
|
88
87
|
"d": {"e": {"h": {"i": {"j": 40}}}},
|
89
88
|
"g": 60,
|
90
|
-
"dimensions": {"env": "prod"},
|
91
89
|
},
|
92
90
|
id="single_match",
|
93
91
|
),
|
@@ -100,7 +98,6 @@ def test_merge_configs__dicts_error():
|
|
100
98
|
"d": {"e": {"h": {"i": {"j": 400}}}},
|
101
99
|
"f": 500,
|
102
100
|
"g": 6,
|
103
|
-
"dimensions": {"env": "staging"},
|
104
101
|
},
|
105
102
|
id="dont_override_if_match_is_more_specific",
|
106
103
|
),
|
@@ -4,7 +4,7 @@ import copy
|
|
4
4
|
import dataclasses
|
5
5
|
from collections.abc import Mapping, Sequence
|
6
6
|
from functools import partial
|
7
|
-
from typing import Any
|
7
|
+
from typing import Any, TypeVar
|
8
8
|
|
9
9
|
from . import exceptions
|
10
10
|
|
@@ -89,7 +89,10 @@ def override_sort_key(
|
|
89
89
|
return tuple(result)
|
90
90
|
|
91
91
|
|
92
|
-
|
92
|
+
T = TypeVar("T", dict, list, str, int, float, bool)
|
93
|
+
|
94
|
+
|
95
|
+
def merge_configs(a: T, b: T, /) -> T:
|
93
96
|
"""
|
94
97
|
Recursively merge two configuration dictionaries, with b taking precedence.
|
95
98
|
"""
|
@@ -100,7 +103,7 @@ def merge_configs(a: Any, b: Any, /) -> Any:
|
|
100
103
|
return b
|
101
104
|
|
102
105
|
result = a.copy()
|
103
|
-
for key, b_value in b.items():
|
106
|
+
for key, b_value in b.items(): # type: ignore
|
104
107
|
if a_value := a.get(key):
|
105
108
|
result[key] = merge_configs(a_value, b_value)
|
106
109
|
else:
|
@@ -183,4 +186,4 @@ def generate_for_mapping(
|
|
183
186
|
if mapping_matches_override(mapping=mapping, override=override):
|
184
187
|
result = merge_configs(result, override.config)
|
185
188
|
|
186
|
-
return
|
189
|
+
return result
|
@@ -22,6 +22,6 @@ def dumps(config: dict) -> str:
|
|
22
22
|
# features. The easiest way to turn tomlkit objects into plain dicts and strings
|
23
23
|
# is through a json round-trip.
|
24
24
|
try:
|
25
|
-
return tomlkit.dumps(json.loads(json.dumps(config)))
|
25
|
+
return tomlkit.dumps(json.loads(json.dumps(config)), sort_keys=False)
|
26
26
|
except tomlkit.exceptions.TOMLKitError as e:
|
27
27
|
raise exceptions.TomlEncodeError from e
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|