aury-boot 0.0.4__py3-none-any.whl → 0.0.5__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.
- aury/boot/__init__.py +2 -2
- aury/boot/_version.py +2 -2
- aury/boot/application/__init__.py +45 -36
- aury/boot/application/app/__init__.py +12 -8
- aury/boot/application/app/base.py +12 -0
- aury/boot/application/app/components.py +137 -44
- aury/boot/application/app/middlewares.py +2 -0
- aury/boot/application/app/startup.py +249 -0
- aury/boot/application/config/__init__.py +36 -1
- aury/boot/application/config/multi_instance.py +200 -0
- aury/boot/application/config/settings.py +341 -12
- aury/boot/application/constants/components.py +6 -0
- aury/boot/application/errors/handlers.py +17 -3
- aury/boot/application/middleware/logging.py +8 -120
- aury/boot/application/rpc/__init__.py +2 -2
- aury/boot/commands/__init__.py +30 -10
- aury/boot/commands/app.py +131 -1
- aury/boot/commands/docs.py +104 -17
- aury/boot/commands/init.py +27 -8
- aury/boot/commands/server/app.py +2 -3
- aury/boot/commands/templates/project/AGENTS.md.tpl +217 -0
- aury/boot/commands/templates/project/README.md.tpl +2 -2
- aury/boot/commands/templates/project/aury_docs/00-overview.md.tpl +59 -0
- aury/boot/commands/templates/project/aury_docs/01-model.md.tpl +183 -0
- aury/boot/commands/templates/project/aury_docs/02-repository.md.tpl +206 -0
- aury/boot/commands/templates/project/aury_docs/03-service.md.tpl +398 -0
- aury/boot/commands/templates/project/aury_docs/04-schema.md.tpl +95 -0
- aury/boot/commands/templates/project/aury_docs/05-api.md.tpl +116 -0
- aury/boot/commands/templates/project/aury_docs/06-exception.md.tpl +118 -0
- aury/boot/commands/templates/project/aury_docs/07-cache.md.tpl +122 -0
- aury/boot/commands/templates/project/aury_docs/08-scheduler.md.tpl +32 -0
- aury/boot/commands/templates/project/aury_docs/09-tasks.md.tpl +38 -0
- aury/boot/commands/templates/project/aury_docs/10-storage.md.tpl +115 -0
- aury/boot/commands/templates/project/aury_docs/11-logging.md.tpl +92 -0
- aury/boot/commands/templates/project/aury_docs/12-admin.md.tpl +56 -0
- aury/boot/commands/templates/project/aury_docs/13-channel.md.tpl +92 -0
- aury/boot/commands/templates/project/aury_docs/14-mq.md.tpl +102 -0
- aury/boot/commands/templates/project/aury_docs/15-events.md.tpl +147 -0
- aury/boot/commands/templates/project/config.py.tpl +1 -1
- aury/boot/commands/templates/project/env.example.tpl +73 -5
- aury/boot/commands/templates/project/modules/tasks.py.tpl +1 -1
- aury/boot/contrib/admin_console/auth.py +2 -3
- aury/boot/contrib/admin_console/install.py +1 -1
- aury/boot/domain/models/mixins.py +48 -1
- aury/boot/domain/pagination/__init__.py +94 -0
- aury/boot/domain/repository/impl.py +1 -1
- aury/boot/domain/repository/interface.py +1 -1
- aury/boot/domain/transaction/__init__.py +8 -9
- aury/boot/infrastructure/__init__.py +86 -29
- aury/boot/infrastructure/cache/backends.py +102 -18
- aury/boot/infrastructure/cache/base.py +12 -0
- aury/boot/infrastructure/cache/manager.py +153 -91
- aury/boot/infrastructure/channel/__init__.py +24 -0
- aury/boot/infrastructure/channel/backends/__init__.py +9 -0
- aury/boot/infrastructure/channel/backends/memory.py +83 -0
- aury/boot/infrastructure/channel/backends/redis.py +88 -0
- aury/boot/infrastructure/channel/base.py +92 -0
- aury/boot/infrastructure/channel/manager.py +203 -0
- aury/boot/infrastructure/clients/__init__.py +22 -0
- aury/boot/infrastructure/clients/rabbitmq/__init__.py +9 -0
- aury/boot/infrastructure/clients/rabbitmq/config.py +46 -0
- aury/boot/infrastructure/clients/rabbitmq/manager.py +288 -0
- aury/boot/infrastructure/clients/redis/__init__.py +28 -0
- aury/boot/infrastructure/clients/redis/config.py +51 -0
- aury/boot/infrastructure/clients/redis/manager.py +264 -0
- aury/boot/infrastructure/database/config.py +1 -2
- aury/boot/infrastructure/database/manager.py +16 -38
- aury/boot/infrastructure/events/__init__.py +18 -21
- aury/boot/infrastructure/events/backends/__init__.py +11 -0
- aury/boot/infrastructure/events/backends/memory.py +86 -0
- aury/boot/infrastructure/events/backends/rabbitmq.py +193 -0
- aury/boot/infrastructure/events/backends/redis.py +162 -0
- aury/boot/infrastructure/events/base.py +127 -0
- aury/boot/infrastructure/events/manager.py +224 -0
- aury/boot/infrastructure/mq/__init__.py +24 -0
- aury/boot/infrastructure/mq/backends/__init__.py +9 -0
- aury/boot/infrastructure/mq/backends/rabbitmq.py +179 -0
- aury/boot/infrastructure/mq/backends/redis.py +167 -0
- aury/boot/infrastructure/mq/base.py +143 -0
- aury/boot/infrastructure/mq/manager.py +239 -0
- aury/boot/infrastructure/scheduler/manager.py +7 -3
- aury/boot/infrastructure/storage/__init__.py +9 -9
- aury/boot/infrastructure/storage/base.py +17 -5
- aury/boot/infrastructure/storage/factory.py +0 -1
- aury/boot/infrastructure/tasks/__init__.py +2 -2
- aury/boot/infrastructure/tasks/manager.py +47 -29
- aury/boot/testing/base.py +2 -2
- {aury_boot-0.0.4.dist-info → aury_boot-0.0.5.dist-info}/METADATA +19 -2
- aury_boot-0.0.5.dist-info/RECORD +176 -0
- aury/boot/commands/templates/project/DEVELOPMENT.md.tpl +0 -1397
- aury/boot/infrastructure/events/bus.py +0 -362
- aury/boot/infrastructure/events/config.py +0 -52
- aury/boot/infrastructure/events/consumer.py +0 -134
- aury/boot/infrastructure/events/models.py +0 -63
- aury_boot-0.0.4.dist-info/RECORD +0 -137
- /aury/boot/commands/templates/project/{CLI.md.tpl → aury_docs/99-cli.md.tpl} +0 -0
- {aury_boot-0.0.4.dist-info → aury_boot-0.0.5.dist-info}/WHEEL +0 -0
- {aury_boot-0.0.4.dist-info → aury_boot-0.0.5.dist-info}/entry_points.txt +0 -0
aury/boot/commands/__init__.py
CHANGED
|
@@ -1,6 +1,21 @@
|
|
|
1
1
|
"""命令行工具模块。
|
|
2
2
|
|
|
3
|
-
统一入口:
|
|
3
|
+
统一入口: aury
|
|
4
|
+
|
|
5
|
+
CLI 继承接口:
|
|
6
|
+
子框架(如 aury-django、aury-cloud)可以通过以下接口继承基础命令:
|
|
7
|
+
|
|
8
|
+
- register_commands(app): 将所有命令注册到目标 app
|
|
9
|
+
- get_command_modules(): 获取所有命令模块,供进一步定制
|
|
10
|
+
|
|
11
|
+
示例:
|
|
12
|
+
```python
|
|
13
|
+
from typer import Typer
|
|
14
|
+
from aury.boot.commands import register_commands
|
|
15
|
+
|
|
16
|
+
app = Typer(name="aury-django")
|
|
17
|
+
register_commands(app) # 继承所有命令
|
|
18
|
+
```
|
|
4
19
|
"""
|
|
5
20
|
|
|
6
21
|
from __future__ import annotations
|
|
@@ -9,22 +24,27 @@ from __future__ import annotations
|
|
|
9
24
|
from .config import ProjectConfig, get_project_config, save_project_config
|
|
10
25
|
|
|
11
26
|
|
|
12
|
-
# 延迟导入 app
|
|
27
|
+
# 延迟导入 app、main、register_commands、get_command_modules,避免加载重型依赖
|
|
13
28
|
def __getattr__(name: str):
|
|
14
|
-
if name in ("app", "main"):
|
|
15
|
-
from .app import main
|
|
29
|
+
if name in ("app", "main", "register_commands", "get_command_modules"):
|
|
30
|
+
from .app import _get_app, get_command_modules, main, register_commands
|
|
16
31
|
if name == "main":
|
|
17
|
-
return
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
32
|
+
return main
|
|
33
|
+
if name == "app":
|
|
34
|
+
return _get_app()
|
|
35
|
+
if name == "register_commands":
|
|
36
|
+
return register_commands
|
|
37
|
+
if name == "get_command_modules":
|
|
38
|
+
return get_command_modules
|
|
21
39
|
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
22
40
|
|
|
23
41
|
|
|
24
42
|
__all__ = [
|
|
25
|
-
"app",
|
|
26
|
-
"main",
|
|
27
43
|
"ProjectConfig",
|
|
44
|
+
"app",
|
|
45
|
+
"get_command_modules",
|
|
28
46
|
"get_project_config",
|
|
47
|
+
"main",
|
|
48
|
+
"register_commands",
|
|
29
49
|
"save_project_config",
|
|
30
50
|
]
|
aury/boot/commands/app.py
CHANGED
|
@@ -18,6 +18,22 @@
|
|
|
18
18
|
aury worker # 运行 Worker
|
|
19
19
|
aury migrate up # 执行数据库迁移
|
|
20
20
|
aury docs all --force # 更新所有文档
|
|
21
|
+
|
|
22
|
+
CLI 继承:
|
|
23
|
+
子框架(如 aury-django、aury-cloud)可以通过 `register_commands` 继承所有基础命令:
|
|
24
|
+
|
|
25
|
+
```python
|
|
26
|
+
from typer import Typer
|
|
27
|
+
from aury.boot.commands import register_commands
|
|
28
|
+
|
|
29
|
+
app = Typer(name="aury-django")
|
|
30
|
+
register_commands(app) # 继承所有 aury-boot 命令
|
|
31
|
+
|
|
32
|
+
# 添加 django 特有命令
|
|
33
|
+
@app.command()
|
|
34
|
+
def startapp(name: str):
|
|
35
|
+
...
|
|
36
|
+
```
|
|
21
37
|
"""
|
|
22
38
|
|
|
23
39
|
from __future__ import annotations
|
|
@@ -92,7 +108,119 @@ def main() -> None:
|
|
|
92
108
|
_get_app()()
|
|
93
109
|
|
|
94
110
|
|
|
95
|
-
|
|
111
|
+
def register_commands(
|
|
112
|
+
target_app: typer.Typer,
|
|
113
|
+
*,
|
|
114
|
+
include_init: bool = True,
|
|
115
|
+
include_add: bool = True,
|
|
116
|
+
include_generate: bool = True,
|
|
117
|
+
include_server: bool = True,
|
|
118
|
+
include_scheduler: bool = True,
|
|
119
|
+
include_worker: bool = True,
|
|
120
|
+
include_migrate: bool = True,
|
|
121
|
+
include_docker: bool = True,
|
|
122
|
+
include_docs: bool = True,
|
|
123
|
+
) -> None:
|
|
124
|
+
"""将 aury-boot 的所有命令注册到目标 Typer app。
|
|
125
|
+
|
|
126
|
+
用于子框架(如 aury-django、aury-cloud)继承基础命令。
|
|
127
|
+
|
|
128
|
+
Args:
|
|
129
|
+
target_app: 目标 Typer 应用
|
|
130
|
+
include_*: 是否包含对应的命令组
|
|
131
|
+
|
|
132
|
+
使用示例:
|
|
133
|
+
```python
|
|
134
|
+
from typer import Typer
|
|
135
|
+
from aury.boot.commands import register_commands
|
|
136
|
+
|
|
137
|
+
app = Typer(name="aury-django")
|
|
138
|
+
|
|
139
|
+
# 继承所有 aury-boot 命令
|
|
140
|
+
register_commands(app)
|
|
141
|
+
|
|
142
|
+
# 或选择性继承
|
|
143
|
+
register_commands(app, include_docker=False)
|
|
144
|
+
|
|
145
|
+
# 添加 django 特有命令
|
|
146
|
+
django_app = Typer(name="django")
|
|
147
|
+
|
|
148
|
+
@django_app.command()
|
|
149
|
+
def startapp(name: str):
|
|
150
|
+
'''Django startapp'''
|
|
151
|
+
...
|
|
152
|
+
|
|
153
|
+
app.add_typer(django_app, name="django")
|
|
154
|
+
```
|
|
155
|
+
"""
|
|
156
|
+
# 延迟导入子命令
|
|
157
|
+
if include_init:
|
|
158
|
+
from .init import init
|
|
159
|
+
target_app.command(name="init", help="🎯 初始化项目脚手架")(init)
|
|
160
|
+
|
|
161
|
+
if include_add:
|
|
162
|
+
from .add import app as add_app
|
|
163
|
+
target_app.add_typer(add_app, name="add", help="➕ 添加可选模块")
|
|
164
|
+
|
|
165
|
+
if include_generate:
|
|
166
|
+
from .generate import app as generate_app
|
|
167
|
+
target_app.add_typer(generate_app, name="generate", help="⚡ 代码生成器")
|
|
168
|
+
|
|
169
|
+
if include_server:
|
|
170
|
+
from .server import app as server_app
|
|
171
|
+
target_app.add_typer(server_app, name="server", help="🖥️ 服务器管理")
|
|
172
|
+
|
|
173
|
+
if include_scheduler:
|
|
174
|
+
from .scheduler import app as scheduler_app
|
|
175
|
+
target_app.add_typer(scheduler_app, name="scheduler", help="🕐 独立运行调度器")
|
|
176
|
+
|
|
177
|
+
if include_worker:
|
|
178
|
+
from .worker import app as worker_app
|
|
179
|
+
target_app.add_typer(worker_app, name="worker", help="⚙️ 运行任务队列 Worker")
|
|
180
|
+
|
|
181
|
+
if include_migrate:
|
|
182
|
+
from .migrate import app as migrate_app
|
|
183
|
+
target_app.add_typer(migrate_app, name="migrate", help="🗃️ 数据库迁移")
|
|
184
|
+
|
|
185
|
+
if include_docker:
|
|
186
|
+
from .docker import app as docker_app
|
|
187
|
+
target_app.add_typer(docker_app, name="docker", help="🐳 Docker 配置")
|
|
188
|
+
|
|
189
|
+
if include_docs:
|
|
190
|
+
from .docs import app as docs_app
|
|
191
|
+
target_app.add_typer(docs_app, name="docs", help="📚 生成/更新项目文档")
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
def get_command_modules() -> dict[str, type]:
|
|
195
|
+
"""获取所有命令模块,供子框架进一步定制。
|
|
196
|
+
|
|
197
|
+
Returns:
|
|
198
|
+
dict: 命令名 -> 模块对象
|
|
199
|
+
|
|
200
|
+
使用示例:
|
|
201
|
+
```python
|
|
202
|
+
from aury.boot.commands import get_command_modules
|
|
203
|
+
|
|
204
|
+
modules = get_command_modules()
|
|
205
|
+
# {'init': <module>, 'add': <module>, 'server': <module>, ...}
|
|
206
|
+
```
|
|
207
|
+
"""
|
|
208
|
+
from . import add, docker, docs, generate, init, migrate, scheduler, server, worker
|
|
209
|
+
|
|
210
|
+
return {
|
|
211
|
+
"init": init,
|
|
212
|
+
"add": add,
|
|
213
|
+
"generate": generate,
|
|
214
|
+
"server": server,
|
|
215
|
+
"scheduler": scheduler,
|
|
216
|
+
"worker": worker,
|
|
217
|
+
"migrate": migrate,
|
|
218
|
+
"docker": docker,
|
|
219
|
+
"docs": docs,
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
# 允许 `from .app import app`
|
|
96
224
|
def __getattr__(name: str):
|
|
97
225
|
if name == "app":
|
|
98
226
|
return _get_app()
|
|
@@ -101,5 +229,7 @@ def __getattr__(name: str):
|
|
|
101
229
|
|
|
102
230
|
__all__ = [
|
|
103
231
|
"app",
|
|
232
|
+
"get_command_modules",
|
|
104
233
|
"main",
|
|
234
|
+
"register_commands",
|
|
105
235
|
]
|
aury/boot/commands/docs.py
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
"""文档生成命令。
|
|
2
2
|
|
|
3
3
|
提供命令行工具用于在现有项目中生成/更新文档:
|
|
4
|
-
- aury docs
|
|
4
|
+
- aury docs agents 生成/更新 AGENTS.md(AI 编程助手上下文)
|
|
5
|
+
- aury docs dev 生成/更新 docs/ 目录(开发文档包)
|
|
5
6
|
- aury docs cli 生成/更新 CLI.md
|
|
6
7
|
- aury docs env 生成/更新 .env.example
|
|
7
8
|
- aury docs all 生成/更新所有文档
|
|
8
9
|
|
|
9
10
|
使用示例:
|
|
10
|
-
aury docs
|
|
11
|
+
aury docs agents # 生成 AI 编程助手上下文文档
|
|
12
|
+
aury docs dev # 生成 docs/ 开发文档包
|
|
11
13
|
aury docs cli # 生成 CLI 文档
|
|
12
14
|
aury docs env # 生成环境变量示例
|
|
13
15
|
aury docs all # 生成所有文档
|
|
@@ -79,10 +81,17 @@ def _detect_project_info(project_dir: Path) -> dict[str, str]:
|
|
|
79
81
|
|
|
80
82
|
|
|
81
83
|
def _render_template(template_name: str, context: dict[str, str]) -> str:
|
|
82
|
-
"""渲染模板。
|
|
84
|
+
"""渲染模板。
|
|
85
|
+
|
|
86
|
+
支持根目录模板和 aury_docs/ 子目录模板。
|
|
87
|
+
"""
|
|
88
|
+
# 先在根目录找
|
|
83
89
|
template_path = TEMPLATES_DIR / template_name
|
|
84
90
|
if not template_path.exists():
|
|
85
|
-
|
|
91
|
+
# 再在 aury_docs/ 子目录找
|
|
92
|
+
template_path = AURY_DOCS_TPL_DIR / template_name
|
|
93
|
+
if not template_path.exists():
|
|
94
|
+
raise FileNotFoundError(f"模板文件不存在: {template_name}")
|
|
86
95
|
|
|
87
96
|
content = template_path.read_text(encoding="utf-8")
|
|
88
97
|
return content.format(**context)
|
|
@@ -116,8 +125,8 @@ def _write_file(
|
|
|
116
125
|
return True
|
|
117
126
|
|
|
118
127
|
|
|
119
|
-
@app.command(name="
|
|
120
|
-
def
|
|
128
|
+
@app.command(name="agents")
|
|
129
|
+
def generate_agents_doc(
|
|
121
130
|
project_dir: Path = typer.Argument(
|
|
122
131
|
Path("."),
|
|
123
132
|
help="项目目录路径",
|
|
@@ -139,20 +148,84 @@ def generate_dev_doc(
|
|
|
139
148
|
help="预览模式,不实际写入文件",
|
|
140
149
|
),
|
|
141
150
|
) -> None:
|
|
142
|
-
"""生成/更新
|
|
151
|
+
"""生成/更新 AGENTS.md(AI 编程助手上下文文档)。"""
|
|
143
152
|
context = _detect_project_info(project_dir)
|
|
144
153
|
|
|
145
154
|
console.print(f"[cyan]📚 检测到项目: {context['project_name']}[/cyan]")
|
|
146
155
|
|
|
147
156
|
try:
|
|
148
|
-
content = _render_template("
|
|
149
|
-
output_path = project_dir / "
|
|
157
|
+
content = _render_template("AGENTS.md.tpl", context)
|
|
158
|
+
output_path = project_dir / "AGENTS.md"
|
|
150
159
|
_write_file(output_path, content, force=force, dry_run=dry_run)
|
|
151
160
|
except Exception as e:
|
|
152
161
|
console.print(f"[red]❌ 生成失败: {e}[/red]")
|
|
153
162
|
raise typer.Exit(1)
|
|
154
163
|
|
|
155
164
|
|
|
165
|
+
# aury_docs/ 模板目录
|
|
166
|
+
AURY_DOCS_TPL_DIR = TEMPLATES_DIR / "aury_docs"
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def _get_aury_docs_templates() -> list[Path]:
|
|
170
|
+
"""动态扫描 aury_docs/ 模板目录。"""
|
|
171
|
+
if not AURY_DOCS_TPL_DIR.exists():
|
|
172
|
+
return []
|
|
173
|
+
return sorted(AURY_DOCS_TPL_DIR.glob("*.md.tpl"))
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
@app.command(name="dev")
|
|
177
|
+
def generate_dev_doc(
|
|
178
|
+
project_dir: Path = typer.Argument(
|
|
179
|
+
Path("."),
|
|
180
|
+
help="项目目录路径",
|
|
181
|
+
exists=True,
|
|
182
|
+
file_okay=False,
|
|
183
|
+
dir_okay=True,
|
|
184
|
+
resolve_path=True,
|
|
185
|
+
),
|
|
186
|
+
force: bool = typer.Option(
|
|
187
|
+
False,
|
|
188
|
+
"--force",
|
|
189
|
+
"-f",
|
|
190
|
+
help="强制覆盖已存在的文件",
|
|
191
|
+
),
|
|
192
|
+
dry_run: bool = typer.Option(
|
|
193
|
+
False,
|
|
194
|
+
"--dry-run",
|
|
195
|
+
"-n",
|
|
196
|
+
help="预览模式,不实际写入文件",
|
|
197
|
+
),
|
|
198
|
+
) -> None:
|
|
199
|
+
"""生成/更新 aury_docs/ 开发文档包。"""
|
|
200
|
+
context = _detect_project_info(project_dir)
|
|
201
|
+
|
|
202
|
+
console.print(f"[cyan]📚 检测到项目: {context['project_name']}[/cyan]")
|
|
203
|
+
console.print()
|
|
204
|
+
|
|
205
|
+
# 确保输出目录存在
|
|
206
|
+
aury_docs_dir = project_dir / "aury_docs"
|
|
207
|
+
if not dry_run:
|
|
208
|
+
aury_docs_dir.mkdir(parents=True, exist_ok=True)
|
|
209
|
+
|
|
210
|
+
success_count = 0
|
|
211
|
+
for tpl_path in _get_aury_docs_templates():
|
|
212
|
+
try:
|
|
213
|
+
output_name = tpl_path.stem # 去掉 .tpl 后缀,保留 .md
|
|
214
|
+
output_path = aury_docs_dir / output_name
|
|
215
|
+
content = tpl_path.read_text(encoding="utf-8")
|
|
216
|
+
content = content.format(**context)
|
|
217
|
+
if _write_file(output_path, content, force=force, dry_run=dry_run):
|
|
218
|
+
success_count += 1
|
|
219
|
+
except Exception as e:
|
|
220
|
+
console.print(f"[red]❌ 生成 {tpl_path.name} 失败: {e}[/red]")
|
|
221
|
+
|
|
222
|
+
console.print()
|
|
223
|
+
if dry_run:
|
|
224
|
+
console.print(f"[dim]🔍 预览模式完成,将生成 {success_count} 个文档到 aury_docs/ 目录[/dim]")
|
|
225
|
+
else:
|
|
226
|
+
console.print(f"[green]✨ 完成!成功生成 {success_count} 个文档到 aury_docs/ 目录[/green]")
|
|
227
|
+
|
|
228
|
+
|
|
156
229
|
@app.command(name="cli")
|
|
157
230
|
def generate_cli_doc(
|
|
158
231
|
project_dir: Path = typer.Argument(
|
|
@@ -176,14 +249,18 @@ def generate_cli_doc(
|
|
|
176
249
|
help="预览模式,不实际写入文件",
|
|
177
250
|
),
|
|
178
251
|
) -> None:
|
|
179
|
-
"""生成/更新
|
|
252
|
+
"""生成/更新 aury_docs/99-cli.md 命令行文档。"""
|
|
180
253
|
context = _detect_project_info(project_dir)
|
|
181
254
|
|
|
182
255
|
console.print(f"[cyan]📚 检测到项目: {context['project_name']}[/cyan]")
|
|
183
256
|
|
|
184
257
|
try:
|
|
185
|
-
|
|
186
|
-
|
|
258
|
+
tpl_path = AURY_DOCS_TPL_DIR / "99-cli.md.tpl"
|
|
259
|
+
content = tpl_path.read_text(encoding="utf-8")
|
|
260
|
+
content = content.format(**context)
|
|
261
|
+
output_path = project_dir / "aury_docs" / "99-cli.md"
|
|
262
|
+
if not dry_run:
|
|
263
|
+
output_path.parent.mkdir(parents=True, exist_ok=True)
|
|
187
264
|
_write_file(output_path, content, force=force, dry_run=dry_run)
|
|
188
265
|
except Exception as e:
|
|
189
266
|
console.print(f"[red]❌ 生成失败: {e}[/red]")
|
|
@@ -250,20 +327,30 @@ def generate_all_docs(
|
|
|
250
327
|
help="预览模式,不实际写入文件",
|
|
251
328
|
),
|
|
252
329
|
) -> None:
|
|
253
|
-
"""生成/更新所有文档(
|
|
330
|
+
"""生成/更新所有文档(AGENTS.md, docs/, CLI.md, .env.example)。"""
|
|
254
331
|
context = _detect_project_info(project_dir)
|
|
255
332
|
|
|
256
333
|
console.print(f"[cyan]📚 检测到项目: {context['project_name']}[/cyan]")
|
|
257
334
|
console.print()
|
|
258
335
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
("
|
|
336
|
+
# 根目录文档
|
|
337
|
+
root_docs: list[tuple[str, str, str]] = [
|
|
338
|
+
("AGENTS.md.tpl", "AGENTS.md", "AI 编程助手上下文"),
|
|
262
339
|
("env.example.tpl", ".env.example", "环境变量示例"),
|
|
263
340
|
]
|
|
264
341
|
|
|
342
|
+
# aury_docs/ 开发文档
|
|
343
|
+
aury_docs_templates = _get_aury_docs_templates()
|
|
344
|
+
dev_docs = [
|
|
345
|
+
(tpl.name, f"aury_docs/{tpl.stem}", f"开发文档: {tpl.stem}")
|
|
346
|
+
for tpl in aury_docs_templates
|
|
347
|
+
]
|
|
348
|
+
|
|
349
|
+
# 合并所有文档
|
|
350
|
+
all_docs = root_docs + dev_docs
|
|
351
|
+
|
|
265
352
|
success_count = 0
|
|
266
|
-
for template_name, output_name, description in
|
|
353
|
+
for template_name, output_name, description in all_docs:
|
|
267
354
|
try:
|
|
268
355
|
content = _render_template(template_name, context)
|
|
269
356
|
output_path = project_dir / output_name
|
aury/boot/commands/init.py
CHANGED
|
@@ -156,8 +156,7 @@ TEMPLATE_FILE_MAP = {
|
|
|
156
156
|
".env.example": "env.example.tpl",
|
|
157
157
|
".gitignore": "gitignore.tpl",
|
|
158
158
|
"README.md": "README.md.tpl",
|
|
159
|
-
"
|
|
160
|
-
"CLI.md": "CLI.md.tpl",
|
|
159
|
+
"AGENTS.md": "AGENTS.md.tpl",
|
|
161
160
|
"conftest.py": "conftest.py.tpl",
|
|
162
161
|
"admin_console/__init__.py": "admin_console_init.py.tpl",
|
|
163
162
|
}
|
|
@@ -712,8 +711,7 @@ def init(
|
|
|
712
711
|
(code_root / "admin_console" / "__init__.py", "admin_console/__init__.py", False),
|
|
713
712
|
(base_path / "tests" / "conftest.py", "conftest.py", False), # tests 放在项目根目录
|
|
714
713
|
(base_path / "README.md", "README.md", True), # 覆盖 uv init 创建的默认 README
|
|
715
|
-
(base_path / "
|
|
716
|
-
(base_path / "CLI.md", "CLI.md", False), # CLI 命令参考
|
|
714
|
+
(base_path / "AGENTS.md", "AGENTS.md", False), # AI 编程助手上下文
|
|
717
715
|
(base_path / ".gitignore", ".gitignore", False), # Git 忽略文件
|
|
718
716
|
]
|
|
719
717
|
|
|
@@ -806,13 +804,34 @@ def init(
|
|
|
806
804
|
else:
|
|
807
805
|
console.print(" [dim]ℹ️ migrations/ 目录已存在,跳过[/dim]")
|
|
808
806
|
|
|
809
|
-
# 5.
|
|
807
|
+
# 5. 生成开发文档 (aury_docs/) - 动态扫描模板目录
|
|
808
|
+
console.print("\n[bold]📚 生成开发文档...[/bold]")
|
|
809
|
+
aury_docs_tpl_dir = TEMPLATES_DIR / "aury_docs"
|
|
810
|
+
aury_docs_dir = base_path / "aury_docs"
|
|
811
|
+
aury_docs_dir.mkdir(parents=True, exist_ok=True)
|
|
812
|
+
docs_count = 0
|
|
813
|
+
if aury_docs_tpl_dir.exists():
|
|
814
|
+
for tpl_path in sorted(aury_docs_tpl_dir.glob("*.md.tpl")):
|
|
815
|
+
output_name = tpl_path.stem # 去掉 .tpl 后缀,保留 .md
|
|
816
|
+
output_path = aury_docs_dir / output_name
|
|
817
|
+
if output_path.exists() and not force:
|
|
818
|
+
continue
|
|
819
|
+
try:
|
|
820
|
+
content = tpl_path.read_text(encoding="utf-8")
|
|
821
|
+
content = content.format(**template_vars)
|
|
822
|
+
output_path.write_text(content, encoding="utf-8")
|
|
823
|
+
docs_count += 1
|
|
824
|
+
except Exception:
|
|
825
|
+
pass
|
|
826
|
+
console.print(f" [green]✅ 已生成 {docs_count} 个文档到 aury_docs/[/green]")
|
|
827
|
+
|
|
828
|
+
# 6. 生成 Docker 配置
|
|
810
829
|
if with_docker:
|
|
811
830
|
console.print("\n[bold]🐳 生成 Docker 配置...[/bold]")
|
|
812
831
|
from .docker import docker_init
|
|
813
832
|
docker_init(force=force)
|
|
814
833
|
|
|
815
|
-
#
|
|
834
|
+
# 7. 显示结果
|
|
816
835
|
console.print("\n")
|
|
817
836
|
|
|
818
837
|
tree = Tree(f"[bold cyan]{project_name}/[/bold cyan]")
|
|
@@ -821,8 +840,8 @@ def init(
|
|
|
821
840
|
tree.add("[dim]alembic.ini[/dim]")
|
|
822
841
|
tree.add("[dim]pyproject.toml[/dim]")
|
|
823
842
|
tree.add("[dim]README.md[/dim]")
|
|
824
|
-
tree.add("[dim]
|
|
825
|
-
tree.add("[
|
|
843
|
+
tree.add("[dim]AGENTS.md[/dim]")
|
|
844
|
+
tree.add("[blue]aury_docs/[/blue]")
|
|
826
845
|
if with_docker:
|
|
827
846
|
tree.add("[dim]Dockerfile[/dim]")
|
|
828
847
|
tree.add("[dim]docker-compose.yml[/dim]")
|
aury/boot/commands/server/app.py
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
import contextlib
|
|
5
6
|
import os
|
|
6
7
|
from pathlib import Path
|
|
7
8
|
import sys
|
|
@@ -339,13 +340,11 @@ def dev(
|
|
|
339
340
|
typer.echo(f" 应用模块: {app_module_path}")
|
|
340
341
|
|
|
341
342
|
# 在应用启动完成后打印一次服务地址
|
|
342
|
-
|
|
343
|
+
with contextlib.suppress(Exception):
|
|
343
344
|
app_instance.add_event_handler(
|
|
344
345
|
"startup",
|
|
345
346
|
lambda: typer.echo(f"✅ 服务已就绪: http://{server_host}:{server_port}"),
|
|
346
347
|
)
|
|
347
|
-
except Exception:
|
|
348
|
-
pass
|
|
349
348
|
|
|
350
349
|
# 默认包含/排除规则(watchfiles 支持)
|
|
351
350
|
reload_includes = [
|