devconfig-gen 1.0.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.
- devconfig_gen-1.0.0/LICENSE +201 -0
- devconfig_gen-1.0.0/PKG-INFO +456 -0
- devconfig_gen-1.0.0/README.md +436 -0
- devconfig_gen-1.0.0/pyproject.toml +33 -0
- devconfig_gen-1.0.0/setup.cfg +4 -0
- devconfig_gen-1.0.0/src/devconfig_gen/__init__.py +90 -0
- devconfig_gen-1.0.0/src/devconfig_gen/cli.py +213 -0
- devconfig_gen-1.0.0/src/devconfig_gen/engine.py +217 -0
- devconfig_gen-1.0.0/src/devconfig_gen/formats.py +708 -0
- devconfig_gen-1.0.0/src/devconfig_gen/interactive.py +377 -0
- devconfig_gen-1.0.0/src/devconfig_gen/models.py +135 -0
- devconfig_gen-1.0.0/src/devconfig_gen/providers/__init__.py +7 -0
- devconfig_gen-1.0.0/src/devconfig_gen/providers/custom.py +92 -0
- devconfig_gen-1.0.0/src/devconfig_gen/providers/env_provider.py +184 -0
- devconfig_gen-1.0.0/src/devconfig_gen/providers/json_provider.py +84 -0
- devconfig_gen-1.0.0/src/devconfig_gen/py.typed +0 -0
- devconfig_gen-1.0.0/src/devconfig_gen/registry.py +38 -0
- devconfig_gen-1.0.0/src/devconfig_gen/validation.py +148 -0
- devconfig_gen-1.0.0/src/devconfig_gen/web_ui.py +2143 -0
- devconfig_gen-1.0.0/src/devconfig_gen.egg-info/PKG-INFO +456 -0
- devconfig_gen-1.0.0/src/devconfig_gen.egg-info/SOURCES.txt +34 -0
- devconfig_gen-1.0.0/src/devconfig_gen.egg-info/dependency_links.txt +1 -0
- devconfig_gen-1.0.0/src/devconfig_gen.egg-info/entry_points.txt +2 -0
- devconfig_gen-1.0.0/src/devconfig_gen.egg-info/requires.txt +8 -0
- devconfig_gen-1.0.0/src/devconfig_gen.egg-info/top_level.txt +1 -0
- devconfig_gen-1.0.0/tests/test_api_parity.py +69 -0
- devconfig_gen-1.0.0/tests/test_cli_e2e.py +282 -0
- devconfig_gen-1.0.0/tests/test_custom_provider.py +79 -0
- devconfig_gen-1.0.0/tests/test_devconfig_core.py +41 -0
- devconfig_gen-1.0.0/tests/test_env_provider.py +91 -0
- devconfig_gen-1.0.0/tests/test_formats.py +180 -0
- devconfig_gen-1.0.0/tests/test_interactive.py +238 -0
- devconfig_gen-1.0.0/tests/test_merge.py +84 -0
- devconfig_gen-1.0.0/tests/test_provider_metadata.py +120 -0
- devconfig_gen-1.0.0/tests/test_validation.py +101 -0
- devconfig_gen-1.0.0/tests/test_web_ui.py +224 -0
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
|
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
10
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
11
|
+
|
|
12
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
13
|
+
the copyright owner that is granting the License.
|
|
14
|
+
|
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
16
|
+
other entities that control, are controlled by, or are under common
|
|
17
|
+
control with that entity. For the purposes of this definition,
|
|
18
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
19
|
+
direction or management of such entity, whether by contract or
|
|
20
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
21
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
22
|
+
|
|
23
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
24
|
+
exercising permissions granted by this License.
|
|
25
|
+
|
|
26
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
27
|
+
including but not limited to software source code, documentation
|
|
28
|
+
source, and configuration files.
|
|
29
|
+
|
|
30
|
+
"Object" form shall mean any form resulting from mechanical
|
|
31
|
+
transformation or translation of a Source form, including but
|
|
32
|
+
not limited to compiled object code, generated documentation,
|
|
33
|
+
and conversions to other media types.
|
|
34
|
+
|
|
35
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
36
|
+
Object form, made available under the License, as indicated by a
|
|
37
|
+
copyright notice that is included in or attached to the work
|
|
38
|
+
(an example is provided in the Appendix below).
|
|
39
|
+
|
|
40
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
41
|
+
form, that is based on (or derived from) the Work and for which the
|
|
42
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
43
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
44
|
+
of this License, Derivative Works shall not include works that remain
|
|
45
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
46
|
+
the Work and Derivative Works thereof.
|
|
47
|
+
|
|
48
|
+
"Contribution" shall mean any work of authorship, including
|
|
49
|
+
the original version of the Work and any modifications or additions
|
|
50
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
51
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
52
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
53
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
54
|
+
means any form of electronic, verbal, or written communication sent
|
|
55
|
+
to the Licensor or its representatives, including but not limited to
|
|
56
|
+
communication on electronic mailing lists, source code control systems,
|
|
57
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
58
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
59
|
+
excluding communication that is conspicuously marked or otherwise
|
|
60
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
61
|
+
|
|
62
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
63
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
64
|
+
subsequently incorporated within the Work.
|
|
65
|
+
|
|
66
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
67
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
68
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
69
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
70
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
71
|
+
Work and such Derivative Works in Source or Object form.
|
|
72
|
+
|
|
73
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
74
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
75
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
76
|
+
(except as stated in this section) patent license to make, have made,
|
|
77
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
78
|
+
where such license applies only to those patent claims licensable
|
|
79
|
+
by such Contributor that are necessarily infringed by their
|
|
80
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
81
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
82
|
+
institute patent litigation against any entity (including a
|
|
83
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
84
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
85
|
+
or contributory patent infringement, then any patent licenses
|
|
86
|
+
granted to You under this License for that Work shall terminate
|
|
87
|
+
as of the date such litigation is filed.
|
|
88
|
+
|
|
89
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
90
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
91
|
+
modifications, and in Source or Object form, provided that You
|
|
92
|
+
meet the following conditions:
|
|
93
|
+
|
|
94
|
+
(a) You must give any other recipients of the Work or
|
|
95
|
+
Derivative Works a copy of this License; and
|
|
96
|
+
|
|
97
|
+
(b) You must cause any modified files to carry prominent notices
|
|
98
|
+
stating that You changed the files; and
|
|
99
|
+
|
|
100
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
101
|
+
that You distribute, all copyright, patent, trademark, and
|
|
102
|
+
attribution notices from the Source form of the Work,
|
|
103
|
+
excluding those notices that do not pertain to any part of
|
|
104
|
+
the Derivative Works; and
|
|
105
|
+
|
|
106
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
107
|
+
distribution, then any Derivative Works that You distribute must
|
|
108
|
+
include a readable copy of the attribution notices contained
|
|
109
|
+
within such NOTICE file, excluding those notices that do not
|
|
110
|
+
pertain to any part of the Derivative Works, in at least one
|
|
111
|
+
of the following places: within a NOTICE text file distributed
|
|
112
|
+
as part of the Derivative Works; within the Source form or
|
|
113
|
+
documentation, if provided along with the Derivative Works; or,
|
|
114
|
+
within a display generated by the Derivative Works, if and
|
|
115
|
+
wherever such third-party notices normally appear. The contents
|
|
116
|
+
of the NOTICE file are for informational purposes only and
|
|
117
|
+
do not modify the License. You may add Your own attribution
|
|
118
|
+
notices within Derivative Works that You distribute, alongside
|
|
119
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
120
|
+
that such additional attribution notices cannot be construed
|
|
121
|
+
as modifying the License.
|
|
122
|
+
|
|
123
|
+
You may add Your own copyright statement to Your modifications and
|
|
124
|
+
may provide additional or different license terms and conditions
|
|
125
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
126
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
127
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
128
|
+
the conditions stated in this License.
|
|
129
|
+
|
|
130
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
131
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
132
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
133
|
+
this License, without any additional terms or conditions.
|
|
134
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
135
|
+
the terms of any separate license agreement you may have executed
|
|
136
|
+
with Licensor regarding such Contributions.
|
|
137
|
+
|
|
138
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
139
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
140
|
+
except as required for reasonable and customary use in describing the
|
|
141
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
142
|
+
|
|
143
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
144
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
145
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
146
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
147
|
+
implied, including, without limitation, any warranties or conditions
|
|
148
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
149
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
150
|
+
appropriateness of using or redistributing the Work and assume any
|
|
151
|
+
risks associated with Your exercise of permissions under this License.
|
|
152
|
+
|
|
153
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
154
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
155
|
+
unless required by applicable law (such as deliberate and grossly
|
|
156
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
157
|
+
liable to You for damages, including any direct, indirect, special,
|
|
158
|
+
incidental, or consequential damages of any character arising as a
|
|
159
|
+
result of this License or out of the use or inability to use the
|
|
160
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
161
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
162
|
+
other commercial damages or losses), even if such Contributor
|
|
163
|
+
has been advised of the possibility of such damages.
|
|
164
|
+
|
|
165
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
166
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
167
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
168
|
+
or other liability obligations and/or rights consistent with this
|
|
169
|
+
License. However, in accepting such obligations, You may act only
|
|
170
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
171
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
172
|
+
defend, and hold each Contributor harmless for any liability
|
|
173
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
174
|
+
of your accepting any such warranty or additional liability.
|
|
175
|
+
|
|
176
|
+
END OF TERMS AND CONDITIONS
|
|
177
|
+
|
|
178
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
179
|
+
|
|
180
|
+
To apply the Apache License to your work, attach the following
|
|
181
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
182
|
+
replaced with your own identifying information. (Don't include
|
|
183
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
184
|
+
comment syntax for the file format. We also recommend that a
|
|
185
|
+
file or class name and description of purpose be included on the
|
|
186
|
+
same "printed page" as the copyright notice for easier
|
|
187
|
+
identification within third-party archives.
|
|
188
|
+
|
|
189
|
+
Copyright 2026 henryliu443
|
|
190
|
+
|
|
191
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
192
|
+
you may not use this file except in compliance with the License.
|
|
193
|
+
You may obtain a copy of the License at
|
|
194
|
+
|
|
195
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
196
|
+
|
|
197
|
+
Unless required by applicable law or agreed to in writing, software
|
|
198
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
199
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
200
|
+
See the License for the specific language governing permissions and
|
|
201
|
+
limitations under the License.
|
|
@@ -0,0 +1,456 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: devconfig-gen
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Provider-based developer configuration generation engine and CLI
|
|
5
|
+
Author-email: henryliu443 <henryliu443@gmail.com>
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
|
+
Keywords: configuration,json,yaml,code-generation,cli
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Operating System :: OS Independent
|
|
10
|
+
Requires-Python: >=3.8
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Provides-Extra: yaml
|
|
14
|
+
Requires-Dist: PyYAML>=5.1; extra == "yaml"
|
|
15
|
+
Provides-Extra: dev
|
|
16
|
+
Requires-Dist: build; extra == "dev"
|
|
17
|
+
Requires-Dist: wheel; extra == "dev"
|
|
18
|
+
Requires-Dist: PyYAML>=5.1; extra == "dev"
|
|
19
|
+
Dynamic: license-file
|
|
20
|
+
|
|
21
|
+
# DevConfig-Gen
|
|
22
|
+
|
|
23
|
+
[](LICENSE)
|
|
24
|
+

|
|
25
|
+

|
|
26
|
+

|
|
27
|
+
|
|
28
|
+
DevConfig-Gen 是一个开发者工具,用于从结构化输入数据和映射关系生成和校验结构化配置。它围绕一个轻量的 Provider 契约构建,使生成流水线独立于任何特定的配置格式或目标系统。多个输入文档可以在生成前进行合并和覆盖。
|
|
29
|
+
|
|
30
|
+
A developer tool for generating and validating structured configuration from structured input data and mappings. Built around a small provider contract so the generation pipeline is independent of any particular configuration format or target system. Multiple input documents can be merged and overridden before generation.
|
|
31
|
+
|
|
32
|
+
内置三个 Provider / Ships with three providers:
|
|
33
|
+
|
|
34
|
+
- `custom` — 无 schema 的通用文档,任意 JSON/YAML 层级可增删清空 / schema-free generic document with arbitrary nesting you can add, remove, or clear;
|
|
35
|
+
- `json` — 无依赖的透传/重新序列化 / dependency-free pass-through/re-serialization;
|
|
36
|
+
- `env` — 将嵌套数据扁平化为 `UPPER_SNAKE_CASE` 的 `.env` 文件 / flattens nested data into an `UPPER_SNAKE_CASE` `.env` file.
|
|
37
|
+
|
|
38
|
+
## 它是什么 / What it is
|
|
39
|
+
|
|
40
|
+
DevConfig-Gen:
|
|
41
|
+
|
|
42
|
+
- 加载结构化文档(JSON 或 YAML)/ loads a structured document (JSON or YAML);
|
|
43
|
+
- 将其规范化为可预测的结构 / normalizes it into a predictable shape;
|
|
44
|
+
- 校验并报告每个问题的精确字段路径 / validates and reports every problem with a precise field path;
|
|
45
|
+
- 通过 Provider 生成结构化配置文档 / generates a structured configuration document through a provider;
|
|
46
|
+
- 将结果写为 JSON 或 YAML / writes the result as JSON or YAML.
|
|
47
|
+
|
|
48
|
+
刻意保持本地化且无副作用 / Deliberately local and side-effect free. 不会访问远程服务、安装包、管理系统状态 / Does not contact remote services, install packages, or manage system state.
|
|
49
|
+
|
|
50
|
+
## 快速开始 / Quick start (3 minutes)
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
pip install devconfig-gen
|
|
54
|
+
devconfig-gen generate \
|
|
55
|
+
--provider custom --input examples/custom.yaml --output-dir generated --format yaml
|
|
56
|
+
devconfig-gen validate --provider custom --input examples/custom.yaml
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
想要引导式流程?运行终端向导或打开本地 Web 工作台 / Prefer a guided flow?
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
devconfig-gen init --provider custom # 终端向导 / terminal wizard
|
|
63
|
+
devconfig-gen ui # Web 工作台 / web studio
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## 安装 / Installation
|
|
67
|
+
|
|
68
|
+
从 PyPI 安装 / Install from PyPI:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
pip install devconfig-gen
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
YAML 支持无需外部依赖 / YAML support works with **no external dependencies**.
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
pip install devconfig-gen[yaml] # 可选:安装 PyYAML / optional: use PyYAML
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
开发模式 / Development (editable):
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
pip install -e ".[yaml]"
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## 命令行 / CLI
|
|
87
|
+
|
|
88
|
+
列出可用 Provider / List available providers:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
devconfig-gen providers
|
|
92
|
+
# custom / env / json
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
生成配置 / Generate configuration:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
devconfig-gen generate \
|
|
99
|
+
--provider custom \
|
|
100
|
+
--input examples/custom.yaml \
|
|
101
|
+
--output-dir generated \
|
|
102
|
+
--format yaml
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
仅校验不写入 / Validate without writing:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
devconfig-gen validate --provider custom --input examples/custom.yaml
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
校验失败时报告字段路径 / Validation failure reports field paths:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
$ devconfig-gen validate --provider env --input broken.yaml
|
|
115
|
+
invalid: variables must not be empty
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
结构化诊断输出 / Structured diagnostics:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
devconfig-gen validate --provider env --input broken.yaml --json
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
查看 Provider Schema / Inspect provider schema:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
devconfig-gen schema --provider custom
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### 交互式终端向导 / Interactive Terminal Wizard
|
|
131
|
+
|
|
132
|
+
适用于无头环境、SSH 会话 / For headless servers, SSH sessions:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
devconfig-gen init --provider custom
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
向导按 `ProviderField.type` 提示每个字段,含默认值、类型校验、选项、边界检查 / Prompts every field by type with defaults, type validation, choices, bounds checking.
|
|
139
|
+
|
|
140
|
+
```text
|
|
141
|
+
========================================================
|
|
142
|
+
DevConfig-Gen Interactive Wizard: 'custom'
|
|
143
|
+
Answer the prompts below. Press Enter to use defaults.
|
|
144
|
+
========================================================
|
|
145
|
+
|
|
146
|
+
--- [1/1] Custom document ---
|
|
147
|
+
自由构建任意嵌套的 JSON/YAML 结构;任意层级都可增删或清空。
|
|
148
|
+
? document (load document file or enter entries):
|
|
149
|
+
Path to JSON/YAML file (or press enter for key=value input): examples/custom.yaml
|
|
150
|
+
[✓] Loaded document from examples/custom.yaml
|
|
151
|
+
|
|
152
|
+
Validating configuration...
|
|
153
|
+
[✓] All validations passed!
|
|
154
|
+
|
|
155
|
+
Select output format (1: YAML [default], 2: JSON): 1
|
|
156
|
+
Writing configuration to '.'...
|
|
157
|
+
[✓] Generated artifact: .../custom.yaml
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Web 可视化工作台 / Configuration Studio WebUI
|
|
161
|
+
|
|
162
|
+
启动本地 Web 工作台 / Launch local web studio:
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
devconfig-gen ui
|
|
166
|
+
devconfig-gen ui --workspace ~/projects/my-app # 绑定项目目录 / bind to project dir
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
浏览器打开 `http://127.0.0.1:8848` / Opens at `http://127.0.0.1:8848`.
|
|
170
|
+
|
|
171
|
+
特性 / Features:
|
|
172
|
+
- 中英双语界面,一键切换,偏好本地保存 / Bilingual UI (中文/English) with one-click toggle and saved preference;
|
|
173
|
+
- Apple 原生排版,亮色/暗色主题 / Apple-native typography, light/dark theme;
|
|
174
|
+
- 分步表单向导,内联校验 / Step-by-step wizard with inline validation;
|
|
175
|
+
- `custom` Provider 递归树编辑器:任意层级增删字段/项、切换类型、逐层清空 / recursive tree editor for the `custom` provider: add/remove fields or items at any depth, switch types, clear per node;
|
|
176
|
+
- `json` Provider 文档上传与内联编辑器(拖拽 `.json`/`.yaml` 反向解析)/ document drop-zone and inline editor for the `json` provider (drag `.json`/`.yaml` to backfill);
|
|
177
|
+
- 顶部「全部清空」一键重置当前 Provider 内容 / header "Clear All" resets the current provider;
|
|
178
|
+
- 双栏实时预览 / Dual-pane live preview;
|
|
179
|
+
- 模板预设、文件上传、草稿保存、磁盘导出 / Template presets, file upload, auto-save, disk export;
|
|
180
|
+
- 输出格式开关(YAML/JSON,XML 及未来格式已预留)/ output format switch (YAML/JSON; XML and future formats reserved);
|
|
181
|
+
- 零外部依赖 / Zero external build dependencies.
|
|
182
|
+
|
|
183
|
+
Provider 的步骤与字段元数据自带 `i18n` 翻译(内置 Provider 已提供中文)/ Provider step and field metadata carry optional `i18n` translations (the built-in providers ship Chinese).
|
|
184
|
+
|
|
185
|
+
仅绑定本地回环 / Binds to loopback only. 磁盘导出沙箱限制在工作空间内 / Disk export sandboxed to workspace root.
|
|
186
|
+
|
|
187
|
+
退出码 / Exit codes: `0` 成功/success, `1` 校验失败/validation failure, `2` 输入错误/input error.
|
|
188
|
+
|
|
189
|
+
### 多源合并与覆盖 / Multi-source input and overrides
|
|
190
|
+
|
|
191
|
+
`--input` 可重复,文档从左到右深度合并 / `--input` may be repeated, deep-merged left to right:
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
devconfig-gen generate \
|
|
195
|
+
--provider custom \
|
|
196
|
+
--input configs/base.yaml \
|
|
197
|
+
--input configs/prod.json \
|
|
198
|
+
--set app.port=9090 \
|
|
199
|
+
--set app.environment=production \
|
|
200
|
+
--output-dir dist --format yaml
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
`--set` 值自动解析 JSON 类型 / `--set` values parsed as JSON when possible (`true`→bool, `42`→int, `null`→null).
|
|
204
|
+
|
|
205
|
+
### 生成任意结构的自定义文档 / Generating an arbitrary custom document
|
|
206
|
+
|
|
207
|
+
`custom` Provider 不限定 schema,任意 JSON/YAML 层级都能生成 / The `custom` provider imposes no schema; any JSON/YAML nesting is generated as-is:
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
devconfig-gen generate --provider custom --input configs/anything.yaml --output-dir dist --format yaml
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
```python
|
|
214
|
+
from devconfig_gen import GenerationRequest, generate
|
|
215
|
+
|
|
216
|
+
result = generate(
|
|
217
|
+
"custom",
|
|
218
|
+
GenerationRequest(
|
|
219
|
+
context={"document": {"app": {"name": "web", "limits": {"cpu": "500m"}}}},
|
|
220
|
+
options={"format": "yaml"},
|
|
221
|
+
),
|
|
222
|
+
)
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
在 Web 工作台中选择 `custom`,它提供两种编辑模式 / In the studio, `custom` offers two editing modes:
|
|
226
|
+
|
|
227
|
+
- **结构模式**:递归树编辑器,任意层级增删字段/项、切换类型(string/number/boolean/object/array/null)、逐层清空 / **Tree mode**: a recursive editor to add/remove fields or items at any depth, switch types, and clear per node;
|
|
228
|
+
- **文本模式**:直接输入 JSON/YAML,支持列表 `[1,2,3,4,5]`、嵌套 `{"1":{"2":{}}}`、YAML 缩进与 `0: [1,2,3,4,5]` 等任意混合 / **Text mode**: type JSON/YAML directly — lists `[1,2,3,4,5]`, nesting `{"1":{"2":{}}}`, YAML indentation, and `0: [1,2,3,4,5]`, freely mixed.
|
|
229
|
+
|
|
230
|
+
顶层可以是映射、列表或标量 / The root may be a mapping, a list, or a scalar.
|
|
231
|
+
|
|
232
|
+
顶部「全部清空」一键重置 / The header "Clear All" resets the current provider.
|
|
233
|
+
|
|
234
|
+
### 生成 .env 文件 / Generating a .env file
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
devconfig-gen generate --provider env --input examples/vars.yaml --output-dir dist
|
|
238
|
+
# generated dist/.env
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
```env
|
|
242
|
+
DATABASE_HOST=localhost
|
|
243
|
+
DATABASE_PORT=5432
|
|
244
|
+
DATABASE_NAME=appdb
|
|
245
|
+
DEBUG=true
|
|
246
|
+
LOG_LEVEL=info
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
## Python API
|
|
250
|
+
|
|
251
|
+
```python
|
|
252
|
+
from devconfig_gen import GenerationRequest, generate, generate_from_file
|
|
253
|
+
|
|
254
|
+
# 内存上下文 / In-memory context
|
|
255
|
+
result = generate(
|
|
256
|
+
"custom",
|
|
257
|
+
GenerationRequest(
|
|
258
|
+
context={"document": {"app": {"name": "checkout-api", "port": 8080}}},
|
|
259
|
+
options={"format": "yaml"},
|
|
260
|
+
),
|
|
261
|
+
)
|
|
262
|
+
artifact = result.artifacts[0]
|
|
263
|
+
print(artifact.name, artifact.media_type) # custom.yaml application/yaml
|
|
264
|
+
|
|
265
|
+
# 文件到文件,与 CLI 相同流水线 / File to file, same pipeline as CLI
|
|
266
|
+
generate_from_file(
|
|
267
|
+
"custom",
|
|
268
|
+
"examples/custom.yaml",
|
|
269
|
+
output_dir="generated",
|
|
270
|
+
output_format="yaml",
|
|
271
|
+
)
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
直接加载和序列化 / Load and serialize directly:
|
|
275
|
+
|
|
276
|
+
```python
|
|
277
|
+
from devconfig_gen import load_file, loads, dumps
|
|
278
|
+
|
|
279
|
+
data = load_file("examples/custom.yaml")
|
|
280
|
+
text = dumps(data, "json")
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
结构化诊断与 Schema 元数据 / Diagnostics and schema metadata:
|
|
284
|
+
|
|
285
|
+
```python
|
|
286
|
+
from devconfig_gen import diagnose_request, describe_provider
|
|
287
|
+
|
|
288
|
+
for d in diagnose_request("env", context={}):
|
|
289
|
+
print(d.field, "->", d.message, f"({d.severity})")
|
|
290
|
+
|
|
291
|
+
for step in describe_provider("custom"):
|
|
292
|
+
print(step.id, step.title, [f.name for f in step.fields])
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
## 示例输入 / Example input
|
|
296
|
+
|
|
297
|
+
`examples/custom.yaml`:
|
|
298
|
+
|
|
299
|
+
```yaml
|
|
300
|
+
app:
|
|
301
|
+
name: checkout-api
|
|
302
|
+
version: "2.4.0"
|
|
303
|
+
port: 8080
|
|
304
|
+
environment: production
|
|
305
|
+
replicas: 3
|
|
306
|
+
labels:
|
|
307
|
+
team: payments
|
|
308
|
+
tier: backend
|
|
309
|
+
health_check:
|
|
310
|
+
path: /healthz
|
|
311
|
+
interval_seconds: 15
|
|
312
|
+
timeout_seconds: 5
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
`examples/custom.json` 是等效 JSON 文档 / is the equivalent JSON document.
|
|
316
|
+
|
|
317
|
+
## JSON/YAML 支持与限制 / Support and limitations
|
|
318
|
+
|
|
319
|
+
JSON 由标准库处理 / JSON handled by standard library. YAML 在安装 PyYAML 时使用,否则用内置解析器 / YAML uses PyYAML when available, otherwise bundled parser.
|
|
320
|
+
|
|
321
|
+
支持 / Supported:
|
|
322
|
+
- 缩进嵌套的映射和序列 / mappings and sequences by indentation;
|
|
323
|
+
- 标量:字符串、整数、浮点、布尔、`null` / scalars: strings, integers, floats, booleans, `null`;
|
|
324
|
+
- 引号字符串和裸字符串 / quoted and plain strings;
|
|
325
|
+
- 流式集合 `[a, b]` `{x: 1}` / flow collections;
|
|
326
|
+
- 注释和空行 / comments and blank lines;
|
|
327
|
+
- 块标量 `|` `>` 及 `-`/`+` 修剪 / block scalars with chomping.
|
|
328
|
+
|
|
329
|
+
不支持 / Not supported:
|
|
330
|
+
- 锚点别名 `&`/`*`、自定义标签 `!tag`、合并键 `<<` / anchors, aliases, tags, merge keys;
|
|
331
|
+
- 多文档 `---` / multiple documents;
|
|
332
|
+
- 块标 scalar 内注释可能丢失 / comments inside block scalars may be dropped.
|
|
333
|
+
|
|
334
|
+
需要完整 YAML 行为请安装 PyYAML / For full YAML, install PyYAML.
|
|
335
|
+
|
|
336
|
+
`env` Provider 渲染纯文本 `.env`(`media_type: text/plain`)/ renders plain-text `.env`.
|
|
337
|
+
|
|
338
|
+
## 架构与数据流 / Architecture and data flow
|
|
339
|
+
|
|
340
|
+
```text
|
|
341
|
+
输入文件 / 上下文 (input file / context)
|
|
342
|
+
|
|
|
343
|
+
v
|
|
344
|
+
formats.load_* JSON/YAML 解析 + 格式检测
|
|
345
|
+
|
|
|
346
|
+
v
|
|
347
|
+
Provider.diagnose 规范化 + 结构化诊断
|
|
348
|
+
|
|
|
349
|
+
v
|
|
350
|
+
Provider.generate 结构化配置文档
|
|
351
|
+
|
|
|
352
|
+
v
|
|
353
|
+
engine.generate 产物序列化 + 可选持久化
|
|
354
|
+
|
|
|
355
|
+
v
|
|
356
|
+
JSON / YAML 输出
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
CLI、Python API、向导、工作台调用相同的 engine 函数 / CLI, API, wizard, and studio all call the same engine functions. CLI 本身不含生成逻辑 / CLI contains no generation logic of its own.
|
|
360
|
+
|
|
361
|
+
核心模块 / Key modules:
|
|
362
|
+
|
|
363
|
+
| 模块 / Module | 职责 / Responsibility |
|
|
364
|
+
| --- | --- |
|
|
365
|
+
| `formats` | JSON/YAML 加载导出、格式检测、媒体类型 |
|
|
366
|
+
| `validation` | 路径感知校验辅助工具 / path-aware validation helpers |
|
|
367
|
+
| `models` | 请求、产物、诊断、字段、步骤、Provider 协议 |
|
|
368
|
+
| `registry` | ProviderRegistry 及内置 Provider |
|
|
369
|
+
| `engine` | 编排、诊断、Schema、持久化 / orchestration, diagnostics, persistence |
|
|
370
|
+
| `providers` | `custom`、`json`、`env` Provider |
|
|
371
|
+
| `interactive` | `init` 终端向导(延迟加载)/ terminal wizard (lazy-loaded) |
|
|
372
|
+
| `web_ui` | `ui` 本地工作台(延迟加载)/ local studio (lazy-loaded) |
|
|
373
|
+
| `cli` | 仅参数解析 / argument parsing only |
|
|
374
|
+
|
|
375
|
+
## 编写自定义 Provider / Writing a custom provider (5 minutes)
|
|
376
|
+
|
|
377
|
+
实现 `ConfigProvider` 协议 / Implement the `ConfigProvider` protocol. 只需 `name`、`validate`、`generate` 必需 / Only `name`, `validate`, `generate` required.
|
|
378
|
+
|
|
379
|
+
```python
|
|
380
|
+
from devconfig_gen import (
|
|
381
|
+
Diagnostic, GeneratedArtifact, GenerationResult,
|
|
382
|
+
ProviderField, ProviderStep, ValidationError,
|
|
383
|
+
)
|
|
384
|
+
|
|
385
|
+
class GreetingProvider:
|
|
386
|
+
name = "greeting"
|
|
387
|
+
steps = (
|
|
388
|
+
ProviderStep(
|
|
389
|
+
id="input",
|
|
390
|
+
title="Greeting input",
|
|
391
|
+
i18n={"zh": {"title": "问候输入", "description": "输入要问候的对象。"}},
|
|
392
|
+
fields=(
|
|
393
|
+
ProviderField(
|
|
394
|
+
"who",
|
|
395
|
+
type="string",
|
|
396
|
+
required=True,
|
|
397
|
+
title="Who",
|
|
398
|
+
description="Who to greet.",
|
|
399
|
+
i18n={"zh": {"title": "对象", "description": "要问候的对象。"}},
|
|
400
|
+
),
|
|
401
|
+
),
|
|
402
|
+
),
|
|
403
|
+
)
|
|
404
|
+
|
|
405
|
+
def describe_schema(self):
|
|
406
|
+
return self.steps
|
|
407
|
+
|
|
408
|
+
def diagnose(self, request):
|
|
409
|
+
if not request.context.get("who"):
|
|
410
|
+
return (Diagnostic("who", "missing required field: 'who'"),)
|
|
411
|
+
return ()
|
|
412
|
+
|
|
413
|
+
def validate(self, request):
|
|
414
|
+
return tuple(item.message for item in self.diagnose(request))
|
|
415
|
+
|
|
416
|
+
def generate(self, request):
|
|
417
|
+
diagnostics = self.diagnose(request)
|
|
418
|
+
if diagnostics:
|
|
419
|
+
raise ValidationError(diagnostics)
|
|
420
|
+
return GenerationResult(
|
|
421
|
+
provider=self.name,
|
|
422
|
+
artifacts=(
|
|
423
|
+
GeneratedArtifact(
|
|
424
|
+
name="greeting.json",
|
|
425
|
+
content={"message": f"hello {request.context['who']}"},
|
|
426
|
+
media_type="application/json",
|
|
427
|
+
),
|
|
428
|
+
),
|
|
429
|
+
)
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
注册并运行 / Register and run:
|
|
433
|
+
|
|
434
|
+
```python
|
|
435
|
+
from devconfig_gen import GenerationRequest, ProviderRegistry, generate
|
|
436
|
+
from devconfig_gen.providers import CustomProvider, JsonProvider
|
|
437
|
+
|
|
438
|
+
registry = ProviderRegistry((CustomProvider(), JsonProvider(), GreetingProvider()))
|
|
439
|
+
result = generate("greeting", GenerationRequest(context={"who": "world"}), registry=registry)
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
`GeneratedArtifact.content` 可以是数据结构或预渲染字符串 / may be a data structure or pre-rendered string.
|
|
443
|
+
|
|
444
|
+
## 开发与测试 / Development and testing
|
|
445
|
+
|
|
446
|
+
```bash
|
|
447
|
+
python -m unittest discover -s tests -v
|
|
448
|
+
# 或无需安装 / or without installing:
|
|
449
|
+
PYTHONPATH=src python3 -m unittest discover -s tests -v
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
测试覆盖格式解析、校验、Provider、多源合并、CLI/API 等价性、向导、WebUI / Covers format parsing, validation, providers, merging, CLI/API parity, wizard, WebUI.
|
|
453
|
+
|
|
454
|
+
## 许可证 / License
|
|
455
|
+
|
|
456
|
+
Apache-2.0. 详见 `LICENSE` / See `LICENSE`.
|