Add files via upload
This commit is contained in:
639
README.md
639
README.md
@@ -1 +1,638 @@
|
|||||||
# scaffold_ddd
|
# DDD 脚手架生成工具
|
||||||
|
|
||||||
|
一个功能强大、高度可配置的领域驱动设计(DDD)项目脚手架生成工具,支持模块化单体架构。
|
||||||
|
|
||||||
|
## 核心特性
|
||||||
|
|
||||||
|
### 灵活的架构支持
|
||||||
|
|
||||||
|
- **多上下文管理**:一次生成多个有界上下文(Bounded Context)
|
||||||
|
- **分层架构**:支持 API、Domain、Application、Infrastructure、Interfaces 等标准 DDD 分层
|
||||||
|
- **目录结构自定义**:支持标准 Maven 结构或自定义扁平结构
|
||||||
|
- **模块化命名**:灵活的模块命名模式,满足不同团队规范
|
||||||
|
|
||||||
|
### 强大的配置能力
|
||||||
|
|
||||||
|
- **树形目录配置**:直观的嵌套结构定义,所见即所得
|
||||||
|
- **文件模板系统**:在配置中直接定义文件内容和模板
|
||||||
|
- **模板变量**:完全可配置的变量系统,支持多层引用
|
||||||
|
- **占位符选项**:自动生成 `.keep`、`package-info.java`、README 等文件
|
||||||
|
|
||||||
|
### 安全的回滚机制
|
||||||
|
|
||||||
|
- **文件哈希验证**:基于 SHA256 哈希确保文件未被修改
|
||||||
|
- **智能跳过**:自动跳过用户修改的文件,不会误删
|
||||||
|
- **父目录保护**:自动保护包含用户文件的目录结构
|
||||||
|
- **清单追踪**:完整记录所有生成的文件和目录
|
||||||
|
|
||||||
|
### 其他实用功能
|
||||||
|
|
||||||
|
- **Dry-run 模式**:预览生成结果,不实际创建文件
|
||||||
|
- **覆盖策略**:skip、overwrite、fail 三种策略可选
|
||||||
|
- **详细日志**:支持 verbose 模式,方便调试
|
||||||
|
- **向后兼容**:完全兼容旧版配置格式
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 快速开始
|
||||||
|
|
||||||
|
### 安装
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 克隆仓库
|
||||||
|
git clone <repository-url>
|
||||||
|
cd <project-directory>
|
||||||
|
|
||||||
|
# 无需额外依赖,Python 3.8+ 即可运行
|
||||||
|
python scaffold_ddd.py --help
|
||||||
|
```
|
||||||
|
|
||||||
|
### 初始化配置
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 生成示例配置文件
|
||||||
|
python scaffold_ddd.py --init-config scaffold.json
|
||||||
|
|
||||||
|
# 编辑配置文件
|
||||||
|
vim scaffold.json
|
||||||
|
```
|
||||||
|
|
||||||
|
### 生成项目
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 基本用法
|
||||||
|
python scaffold_ddd.py --config scaffold.json --contexts auth,user
|
||||||
|
|
||||||
|
# 预览模式(不实际创建文件)
|
||||||
|
python scaffold_ddd.py --config scaffold.json --contexts auth --dry-run
|
||||||
|
|
||||||
|
# 详细日志
|
||||||
|
python scaffold_ddd.py --config scaffold.json --contexts auth -v
|
||||||
|
```
|
||||||
|
|
||||||
|
### 回滚
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 预览回滚
|
||||||
|
python scaffold_ddd.py --rollback modules/auth/manifest.json --dry-run
|
||||||
|
|
||||||
|
# 执行回滚
|
||||||
|
python scaffold_ddd.py --rollback modules/auth/manifest.json
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 配置文件详解
|
||||||
|
|
||||||
|
### 基本配置
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"root": "modules", // 上下文根目录
|
||||||
|
"package_base": "top.ysit.travel", // 基础包名
|
||||||
|
"contexts": ["auth", "user"], // 要生成的上下文列表
|
||||||
|
"layers": [ // 要生成的层
|
||||||
|
"api",
|
||||||
|
"domain",
|
||||||
|
"application",
|
||||||
|
"infrastructure",
|
||||||
|
"interfaces"
|
||||||
|
],
|
||||||
|
"use_standard_structure": false, // 是否使用标准 Maven 结构
|
||||||
|
"overwrite": "skip" // 覆盖策略:skip | overwrite | fail
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 模块命名配置
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"naming": {
|
||||||
|
"module_name_pattern": "{layer}", // 模块名模式
|
||||||
|
"context_dir_pattern": "{context}" // 上下文目录模式
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**示例**:
|
||||||
|
- `{layer}` → 生成 `api/`, `domain/`, `application/`
|
||||||
|
- `{context}-{layer}` → 生成 `auth-api/`, `auth-domain/`
|
||||||
|
|
||||||
|
### 占位符配置
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"placeholders": {
|
||||||
|
"create_keep_files": true, // 为空目录创建 .keep 文件
|
||||||
|
"create_package_info": true, // 创建 package-info.java
|
||||||
|
"create_layer_readme": false, // 创建层级 README
|
||||||
|
"create_context_readme": false // 创建上下文 README
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 模板变量配置
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"template_vars": {
|
||||||
|
"package": "{package_base}.{context}",
|
||||||
|
"context_package": "{package_base}.{context}",
|
||||||
|
"layer_package": "{package}.{layer}",
|
||||||
|
"author": "Your Name",
|
||||||
|
"organization": "Your Org"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**内置变量**:
|
||||||
|
- `{context}` - 上下文名称(如 `auth`)
|
||||||
|
- `{layer}` - 层名称(如 `domain`)
|
||||||
|
- `{module}` - 模块名称(如 `auth-domain`)
|
||||||
|
- `{package_base}` - 基础包名(如 `top.ysit.travel`)
|
||||||
|
|
||||||
|
**自定义变量**:支持引用其他变量,自动多轮解析
|
||||||
|
|
||||||
|
### 目录结构配置
|
||||||
|
|
||||||
|
#### 方式一:树形结构(推荐)
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"layer_dirs": {
|
||||||
|
"api": {
|
||||||
|
"contract": {},
|
||||||
|
"event": {},
|
||||||
|
"client": {},
|
||||||
|
"_files": {
|
||||||
|
"package-info.java": "package {layer_package};\n"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"domain": {
|
||||||
|
"model": {
|
||||||
|
"aggregate": {
|
||||||
|
"_files": {
|
||||||
|
".gitkeep": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"entity": {},
|
||||||
|
"vo": {}
|
||||||
|
},
|
||||||
|
"repository": {},
|
||||||
|
"service": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 方式二:列表格式(兼容旧版)
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"layer_dirs": {
|
||||||
|
"domain": [
|
||||||
|
"model/aggregate",
|
||||||
|
"model/entity",
|
||||||
|
"repository"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 使用示例
|
||||||
|
|
||||||
|
### 示例 1: 生成单个上下文
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python scaffold_ddd.py \
|
||||||
|
--config scaffold.json \
|
||||||
|
--contexts auth
|
||||||
|
```
|
||||||
|
|
||||||
|
**生成结构**:
|
||||||
|
```
|
||||||
|
modules/
|
||||||
|
└── auth/
|
||||||
|
├── manifest.json
|
||||||
|
├── api/
|
||||||
|
│ ├── package-info.java
|
||||||
|
│ ├── contract/
|
||||||
|
│ ├── event/
|
||||||
|
│ └── client/
|
||||||
|
├── domain/
|
||||||
|
│ ├── package-info.java
|
||||||
|
│ ├── model/
|
||||||
|
│ │ ├── aggregate/
|
||||||
|
│ │ ├── entity/
|
||||||
|
│ │ └── vo/
|
||||||
|
│ ├── repository/
|
||||||
|
│ └── service/
|
||||||
|
└── ...
|
||||||
|
```
|
||||||
|
|
||||||
|
### 示例 2: 生成多个上下文
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python scaffold_ddd.py \
|
||||||
|
--config scaffold.json \
|
||||||
|
--contexts auth,user,order
|
||||||
|
```
|
||||||
|
|
||||||
|
### 示例 3: 使用命令行参数覆盖配置
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python scaffold_ddd.py \
|
||||||
|
--config scaffold.json \
|
||||||
|
--contexts auth \
|
||||||
|
--package-base com.mycompany.project \
|
||||||
|
--overwrite overwrite
|
||||||
|
```
|
||||||
|
|
||||||
|
### 示例 4: 预览生成结果
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python scaffold_ddd.py \
|
||||||
|
--config scaffold.json \
|
||||||
|
--contexts auth \
|
||||||
|
--dry-run \
|
||||||
|
--manifest-stdout
|
||||||
|
```
|
||||||
|
|
||||||
|
### 示例 5: 安全回滚
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. 先预览回滚效果
|
||||||
|
python scaffold_ddd.py --rollback modules/auth/manifest.json --dry-run -v
|
||||||
|
|
||||||
|
# 2. 确认无误后执行
|
||||||
|
python scaffold_ddd.py --rollback modules/auth/manifest.json
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 高级功能
|
||||||
|
|
||||||
|
### 1. 文件模板
|
||||||
|
|
||||||
|
在配置中直接定义文件内容:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"layer_dirs": {
|
||||||
|
"domain": {
|
||||||
|
"exception": {
|
||||||
|
"_files": {
|
||||||
|
"DomainException.java": "package {context_package}.domain.exception;\n\n/**\n * Base domain exception for {context} context\n * @author {author}\n */\npublic class DomainException extends RuntimeException {\n public DomainException(String message) {\n super(message);\n }\n}\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 从外部文件读取
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"_files": {
|
||||||
|
"README.md": {
|
||||||
|
"content_from": "templates/domain_readme.md"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 智能回滚
|
||||||
|
|
||||||
|
**场景 1**:所有文件未修改
|
||||||
|
```bash
|
||||||
|
$ python scaffold_ddd.py --rollback modules/auth/manifest.json
|
||||||
|
INFO ✓ Verified 34 file(s) by hash
|
||||||
|
INFO Deleted 35 file(s)
|
||||||
|
INFO Deleted empty context directory: modules\auth
|
||||||
|
INFO Rollback completed successfully
|
||||||
|
```
|
||||||
|
|
||||||
|
**场景 2**:部分文件被修改
|
||||||
|
```bash
|
||||||
|
$ python scaffold_ddd.py --rollback modules/auth/manifest.json
|
||||||
|
WARNING ⚠ Hash verification failed for 2 file(s). These files will be skipped.
|
||||||
|
WARNING - modules\auth\api\README.md
|
||||||
|
INFO Deleted 32 file(s)
|
||||||
|
INFO Protected 5 path(s) due to skipped files
|
||||||
|
WARNING ⚠ Rollback completed with 2 file(s) skipped
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. 自定义包结构
|
||||||
|
|
||||||
|
**标准结构**(`use_standard_structure: true`):
|
||||||
|
```
|
||||||
|
modules/auth/domain/
|
||||||
|
└── src/main/java/
|
||||||
|
└── top/ysit/travel/auth/domain/
|
||||||
|
├── model/
|
||||||
|
└── repository/
|
||||||
|
```
|
||||||
|
|
||||||
|
**扁平结构**(`use_standard_structure: false`):
|
||||||
|
```
|
||||||
|
modules/auth/domain/
|
||||||
|
├── model/
|
||||||
|
└── repository/
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 完整配置示例
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"root": "modules",
|
||||||
|
"package_base": "top.ysit.travel",
|
||||||
|
"contexts": ["auth", "user", "order"],
|
||||||
|
"layers": ["api", "domain", "application", "infrastructure", "interfaces"],
|
||||||
|
"java_source_dir": "src/main/java",
|
||||||
|
"resources_dir": "src/main/resources",
|
||||||
|
"overwrite": "skip",
|
||||||
|
"dry_run": false,
|
||||||
|
"emit_manifest": true,
|
||||||
|
"manifest_name": "manifest.json",
|
||||||
|
"use_standard_structure": false,
|
||||||
|
|
||||||
|
"naming": {
|
||||||
|
"module_name_pattern": "{layer}",
|
||||||
|
"context_dir_pattern": "{context}"
|
||||||
|
},
|
||||||
|
|
||||||
|
"placeholders": {
|
||||||
|
"create_keep_files": true,
|
||||||
|
"create_package_info": true,
|
||||||
|
"create_layer_readme": false,
|
||||||
|
"create_context_readme": false
|
||||||
|
},
|
||||||
|
|
||||||
|
"template_vars": {
|
||||||
|
"package": "{package_base}.{context}",
|
||||||
|
"context_package": "{package_base}.{context}",
|
||||||
|
"layer_package": "{package}.{layer}",
|
||||||
|
"author": "DDD Scaffold Tool",
|
||||||
|
"organization": "YSIT",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
|
||||||
|
"layer_dirs": {
|
||||||
|
"api": {
|
||||||
|
"contract": {},
|
||||||
|
"event": {},
|
||||||
|
"client": {},
|
||||||
|
"_files": {
|
||||||
|
"package-info.java": "/**\n * API contracts for {context} context.\n * @author {author}\n */\npackage {layer_package};\n"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"domain": {
|
||||||
|
"model": {
|
||||||
|
"aggregate": {
|
||||||
|
"_files": {
|
||||||
|
".gitkeep": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"entity": {},
|
||||||
|
"vo": {},
|
||||||
|
"enum": {}
|
||||||
|
},
|
||||||
|
"repository": {},
|
||||||
|
"event": {},
|
||||||
|
"service": {},
|
||||||
|
"exception": {
|
||||||
|
"_files": {
|
||||||
|
"DomainException.java": "package {context_package}.domain.exception;\n\npublic class DomainException extends RuntimeException {\n public DomainException(String message) {\n super(message);\n }\n}\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"application": {
|
||||||
|
"command": {},
|
||||||
|
"usecase": {},
|
||||||
|
"query": {
|
||||||
|
"dto": {}
|
||||||
|
},
|
||||||
|
"assembler": {},
|
||||||
|
"port": {
|
||||||
|
"in": {},
|
||||||
|
"out": {}
|
||||||
|
},
|
||||||
|
"security": {},
|
||||||
|
"handler": {}
|
||||||
|
},
|
||||||
|
|
||||||
|
"infrastructure": {
|
||||||
|
"persistence": {
|
||||||
|
"mapper": {},
|
||||||
|
"po": {},
|
||||||
|
"convert": {},
|
||||||
|
"repository": {}
|
||||||
|
},
|
||||||
|
"event": {},
|
||||||
|
"config": {}
|
||||||
|
},
|
||||||
|
|
||||||
|
"interfaces": {
|
||||||
|
"web": {
|
||||||
|
"request": {},
|
||||||
|
"response": {}
|
||||||
|
},
|
||||||
|
"facade": {},
|
||||||
|
"doc": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 命令行参数
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python scaffold_ddd.py [OPTIONS]
|
||||||
|
|
||||||
|
Options:
|
||||||
|
--config PATH 配置文件路径
|
||||||
|
--init-config PATH 生成示例配置文件
|
||||||
|
--root DIR 上下文根目录(覆盖配置)
|
||||||
|
--package-base PKG 基础包名(覆盖配置)
|
||||||
|
--contexts CONTEXTS 逗号分隔的上下文列表
|
||||||
|
--layers LAYERS 逗号分隔的层列表
|
||||||
|
--overwrite POLICY 覆盖策略:skip | overwrite | fail
|
||||||
|
--dry-run 预览模式,不创建文件
|
||||||
|
--no-manifest 不生成 manifest.json
|
||||||
|
--manifest-stdout 输出 manifest 到标准输出
|
||||||
|
--manifest-write-in-dry-run 在 dry-run 模式也写入 manifest
|
||||||
|
--rollback MANIFEST_PATH 使用指定 manifest 回滚
|
||||||
|
-v, --verbose 详细日志输出
|
||||||
|
--help 显示帮助信息
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 常见问题
|
||||||
|
|
||||||
|
### Q1: 如何选择目录结构?
|
||||||
|
|
||||||
|
**标准 Maven 结构** (`use_standard_structure: true`):
|
||||||
|
- 适合传统 Maven/Gradle 项目
|
||||||
|
- IDE 友好,自动识别源码目录
|
||||||
|
- 目录层级较深
|
||||||
|
|
||||||
|
**扁平结构** (`use_standard_structure: false`):
|
||||||
|
- 目录结构简洁
|
||||||
|
- 适合模块化单体架构
|
||||||
|
- 需要手动配置 IDE 源码目录
|
||||||
|
|
||||||
|
### Q2: 回滚会删除我修改的文件吗?
|
||||||
|
|
||||||
|
**不会!** 回滚功能使用 SHA256 哈希验证:
|
||||||
|
- 自动跳过被修改的文件
|
||||||
|
- 保护包含被修改文件的父目录
|
||||||
|
- 详细日志显示被跳过的文件
|
||||||
|
|
||||||
|
### Q3: 如何处理包名?
|
||||||
|
|
||||||
|
使用模板变量灵活控制:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"template_vars": {
|
||||||
|
"package": "{package_base}.{context}",
|
||||||
|
"layer_package": "{package}.{layer}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
在文件模板中引用:
|
||||||
|
```java
|
||||||
|
package {layer_package}; // → top.ysit.travel.auth.domain
|
||||||
|
```
|
||||||
|
|
||||||
|
### Q4: 可以只生成部分层吗?
|
||||||
|
|
||||||
|
可以!使用 `--layers` 参数:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python scaffold_ddd.py \
|
||||||
|
--config scaffold.json \
|
||||||
|
--contexts auth \
|
||||||
|
--layers api,domain
|
||||||
|
```
|
||||||
|
|
||||||
|
### Q5: 如何在团队中共享配置?
|
||||||
|
|
||||||
|
1. 将 `scaffold.json` 提交到版本控制
|
||||||
|
2. 团队成员使用相同的配置文件
|
||||||
|
3. 根据项目需要在 CI/CD 中自动生成
|
||||||
|
|
||||||
|
### Q6: 支持哪些编程语言?
|
||||||
|
|
||||||
|
虽然默认配置面向 Java,但通过自定义配置可以支持任何语言:
|
||||||
|
- 修改文件扩展名
|
||||||
|
- 自定义文件模板
|
||||||
|
- 调整目录结构
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 最佳实践
|
||||||
|
|
||||||
|
### 1. 版本控制策略
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 提交配置文件
|
||||||
|
git add scaffold.json scaffold_ddd.py
|
||||||
|
git commit -m "Add DDD scaffold configuration"
|
||||||
|
|
||||||
|
# 不要提交生成的代码到主分支
|
||||||
|
echo "modules/" >> .gitignore
|
||||||
|
|
||||||
|
# 或者只提交初始骨架,后续开发不提交
|
||||||
|
git add modules/auth/domain/model/
|
||||||
|
git commit -m "Add domain model skeleton"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 配置组织
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"_comment": {
|
||||||
|
"description": "Auth context scaffold configuration",
|
||||||
|
"author": "Team Name",
|
||||||
|
"last_updated": "2026-01-11"
|
||||||
|
},
|
||||||
|
|
||||||
|
"template_vars": {
|
||||||
|
"_comment": "Package naming conventions",
|
||||||
|
"package": "{package_base}.{context}",
|
||||||
|
...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 渐进式采用
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 步骤 1: 预览效果
|
||||||
|
python scaffold_ddd.py --config scaffold.json --contexts auth --dry-run
|
||||||
|
|
||||||
|
# 步骤 2: 生成一个上下文测试
|
||||||
|
python scaffold_ddd.py --config scaffold.json --contexts auth
|
||||||
|
|
||||||
|
# 步骤 3: 确认无误后生成所有上下文
|
||||||
|
python scaffold_ddd.py --config scaffold.json
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. 模板复用
|
||||||
|
|
||||||
|
将常用文件模板提取到外部:
|
||||||
|
|
||||||
|
```
|
||||||
|
templates/
|
||||||
|
├── domain_exception.java
|
||||||
|
├── package-info.java
|
||||||
|
└── README.md
|
||||||
|
|
||||||
|
scaffold.json:
|
||||||
|
{
|
||||||
|
"_files": {
|
||||||
|
"DomainException.java": {
|
||||||
|
"content_from": "templates/domain_exception.java"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 贡献指南
|
||||||
|
|
||||||
|
欢迎提交 Issue 和 Pull Request!
|
||||||
|
|
||||||
|
### 报告问题
|
||||||
|
|
||||||
|
提交 Issue 时请包含:
|
||||||
|
- Python 版本
|
||||||
|
- 完整的配置文件
|
||||||
|
- 错误信息和日志
|
||||||
|
- 重现步骤
|
||||||
|
|
||||||
|
### 提交代码
|
||||||
|
|
||||||
|
1. Fork 项目
|
||||||
|
2. 创建特性分支
|
||||||
|
3. 提交变更
|
||||||
|
4. 创建 Pull Request
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
MIT License - 详见 [LICENSE](LICENSE) 文件
|
||||||
|
|||||||
1299
scaffold_ddd.py
Normal file
1299
scaffold_ddd.py
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user