699 lines
16 KiB
Markdown
699 lines
16 KiB
Markdown
|
|
# 配置文件规范
|
|||
|
|
|
|||
|
|
## 一、概述
|
|||
|
|
|
|||
|
|
### 1.1 配置文件定位
|
|||
|
|
|
|||
|
|
- **文件路径**:`.aide/config.toml`
|
|||
|
|
- **格式**:TOML(Tom's Obvious, Minimal Language)
|
|||
|
|
- **特点**:自文档化,包含详细注释
|
|||
|
|
- **创建时机**:`aide init` 命令执行时
|
|||
|
|
|
|||
|
|
### 1.2 设计原则
|
|||
|
|
|
|||
|
|
1. **自文档化**:每个配置项都有注释说明
|
|||
|
|
2. **合理默认值**:开箱即用,无需修改
|
|||
|
|
3. **类型安全**:明确的数据类型
|
|||
|
|
4. **向后兼容**:新版本保持旧配置可用
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 二、配置文件结构
|
|||
|
|
|
|||
|
|
### 2.1 完整示例
|
|||
|
|
|
|||
|
|
```toml
|
|||
|
|
# Aide 项目配置文件
|
|||
|
|
# 由 aide init 自动生成
|
|||
|
|
# 版本: 1.0
|
|||
|
|
|
|||
|
|
[task]
|
|||
|
|
# 任务原文档路径(prep 阶段使用)
|
|||
|
|
source = "task-now.md"
|
|||
|
|
|
|||
|
|
# 任务细则文档路径(exec 阶段使用)
|
|||
|
|
spec = "task-spec.md"
|
|||
|
|
|
|||
|
|
[env]
|
|||
|
|
# 环境配置
|
|||
|
|
|
|||
|
|
[env.python]
|
|||
|
|
# Python 版本要求(语义化版本)
|
|||
|
|
version = ">=3.10"
|
|||
|
|
|
|||
|
|
# 虚拟环境路径(相对于项目根目录)
|
|||
|
|
venv = ".venv"
|
|||
|
|
|
|||
|
|
[env.tools]
|
|||
|
|
# 可选工具配置
|
|||
|
|
|
|||
|
|
# 是否需要 uv(Python 包管理器)
|
|||
|
|
uv = false
|
|||
|
|
|
|||
|
|
# 是否需要 git
|
|||
|
|
git = true
|
|||
|
|
|
|||
|
|
[flow]
|
|||
|
|
# 流程追踪配置(后续实现)
|
|||
|
|
|
|||
|
|
# 环节列表
|
|||
|
|
phases = ["flow-design", "impl", "verify", "docs", "finish"]
|
|||
|
|
|
|||
|
|
# PlantUML 流程图目录
|
|||
|
|
flowchart_dir = "program_flowchart"
|
|||
|
|
|
|||
|
|
[decide]
|
|||
|
|
# 待定项确认配置(后续实现)
|
|||
|
|
|
|||
|
|
# Web 服务端口
|
|||
|
|
port = 3721
|
|||
|
|
|
|||
|
|
# 决策记录保存目录
|
|||
|
|
decisions_dir = ".aide/decisions"
|
|||
|
|
|
|||
|
|
[output]
|
|||
|
|
# 输出配置
|
|||
|
|
|
|||
|
|
# 是否启用颜色输出
|
|||
|
|
color = true
|
|||
|
|
|
|||
|
|
# 输出语言(当前仅支持 zh-CN)
|
|||
|
|
language = "zh-CN"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2.2 配置项说明
|
|||
|
|
|
|||
|
|
#### 2.2.1 [task] 任务配置
|
|||
|
|
|
|||
|
|
| 键 | 类型 | 默认值 | 说明 |
|
|||
|
|
|---|------|--------|------|
|
|||
|
|
| `source` | string | `"task-now.md"` | 任务原文档路径 |
|
|||
|
|
| `spec` | string | `"task-spec.md"` | 任务细则文档路径 |
|
|||
|
|
|
|||
|
|
**使用场景**:
|
|||
|
|
- `prep` 命令未传入参数时,使用 `task.source`
|
|||
|
|
- `exec` 命令未传入参数时,使用 `task.spec`
|
|||
|
|
|
|||
|
|
#### 2.2.2 [env.python] Python 环境配置
|
|||
|
|
|
|||
|
|
| 键 | 类型 | 默认值 | 说明 |
|
|||
|
|
|---|------|--------|------|
|
|||
|
|
| `version` | string | `">=3.10"` | Python 版本要求 |
|
|||
|
|
| `venv` | string | `".venv"` | 虚拟环境路径 |
|
|||
|
|
|
|||
|
|
**版本格式**:
|
|||
|
|
- `">=3.10"` - 大于等于 3.10
|
|||
|
|
- `">=3.10,<4.0"` - 3.10 到 4.0 之间
|
|||
|
|
- `"3.12"` - 精确匹配 3.12
|
|||
|
|
|
|||
|
|
#### 2.2.3 [env.tools] 工具配置
|
|||
|
|
|
|||
|
|
| 键 | 类型 | 默认值 | 说明 |
|
|||
|
|
|---|------|--------|------|
|
|||
|
|
| `uv` | boolean | `false` | 是否需要 uv |
|
|||
|
|
| `git` | boolean | `true` | 是否需要 git |
|
|||
|
|
|
|||
|
|
#### 2.2.4 [flow] 流程配置(后续实现)
|
|||
|
|
|
|||
|
|
| 键 | 类型 | 默认值 | 说明 |
|
|||
|
|
|---|------|--------|------|
|
|||
|
|
| `phases` | array | `["flow-design", "impl", "verify", "docs", "finish"]` | 环节列表 |
|
|||
|
|
| `flowchart_dir` | string | `"program_flowchart"` | 流程图目录 |
|
|||
|
|
|
|||
|
|
#### 2.2.5 [decide] 待定项配置(后续实现)
|
|||
|
|
|
|||
|
|
| 键 | 类型 | 默认值 | 说明 |
|
|||
|
|
|---|------|--------|------|
|
|||
|
|
| `port` | integer | `3721` | Web 服务端口 |
|
|||
|
|
| `decisions_dir` | string | `".aide/decisions"` | 决策记录目录 |
|
|||
|
|
|
|||
|
|
#### 2.2.6 [output] 输出配置
|
|||
|
|
|
|||
|
|
| 键 | 类型 | 默认值 | 说明 |
|
|||
|
|
|---|------|--------|------|
|
|||
|
|
| `color` | boolean | `true` | 是否启用颜色 |
|
|||
|
|
| `language` | string | `"zh-CN"` | 输出语言 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 三、配置文件操作
|
|||
|
|
|
|||
|
|
### 3.1 读取配置
|
|||
|
|
|
|||
|
|
**Python 实现示例**:
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
import tomllib # Python 3.11+
|
|||
|
|
# 或
|
|||
|
|
import tomli # Python 3.10
|
|||
|
|
|
|||
|
|
from pathlib import Path
|
|||
|
|
|
|||
|
|
def load_config(project_root: Path) -> dict:
|
|||
|
|
"""加载配置文件
|
|||
|
|
|
|||
|
|
Args:
|
|||
|
|
project_root: 项目根目录
|
|||
|
|
|
|||
|
|
Returns:
|
|||
|
|
配置字典
|
|||
|
|
|
|||
|
|
Raises:
|
|||
|
|
FileNotFoundError: 配置文件不存在
|
|||
|
|
tomllib.TOMLDecodeError: 配置文件格式错误
|
|||
|
|
"""
|
|||
|
|
config_path = project_root / ".aide" / "config.toml"
|
|||
|
|
|
|||
|
|
if not config_path.exists():
|
|||
|
|
raise FileNotFoundError(f"配置文件不存在: {config_path}")
|
|||
|
|
|
|||
|
|
with open(config_path, "rb") as f:
|
|||
|
|
return tomllib.load(f)
|
|||
|
|
|
|||
|
|
def get_config_value(config: dict, key: str, default=None):
|
|||
|
|
"""获取配置值(支持点号分隔的键)
|
|||
|
|
|
|||
|
|
Args:
|
|||
|
|
config: 配置字典
|
|||
|
|
key: 配置键(如 "task.source")
|
|||
|
|
default: 默认值
|
|||
|
|
|
|||
|
|
Returns:
|
|||
|
|
配置值
|
|||
|
|
|
|||
|
|
Example:
|
|||
|
|
>>> config = {"task": {"source": "task-now.md"}}
|
|||
|
|
>>> get_config_value(config, "task.source")
|
|||
|
|
'task-now.md'
|
|||
|
|
"""
|
|||
|
|
keys = key.split(".")
|
|||
|
|
value = config
|
|||
|
|
|
|||
|
|
for k in keys:
|
|||
|
|
if isinstance(value, dict) and k in value:
|
|||
|
|
value = value[k]
|
|||
|
|
else:
|
|||
|
|
return default
|
|||
|
|
|
|||
|
|
return value
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3.2 写入配置
|
|||
|
|
|
|||
|
|
**Python 实现示例**:
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
import tomli_w
|
|||
|
|
from pathlib import Path
|
|||
|
|
|
|||
|
|
def save_config(project_root: Path, config: dict) -> None:
|
|||
|
|
"""保存配置文件
|
|||
|
|
|
|||
|
|
Args:
|
|||
|
|
project_root: 项目根目录
|
|||
|
|
config: 配置字典
|
|||
|
|
"""
|
|||
|
|
config_path = project_root / ".aide" / "config.toml"
|
|||
|
|
|
|||
|
|
with open(config_path, "wb") as f:
|
|||
|
|
tomli_w.dump(config, f)
|
|||
|
|
|
|||
|
|
def set_config_value(config: dict, key: str, value) -> dict:
|
|||
|
|
"""设置配置值(支持点号分隔的键)
|
|||
|
|
|
|||
|
|
Args:
|
|||
|
|
config: 配置字典
|
|||
|
|
key: 配置键(如 "task.source")
|
|||
|
|
value: 配置值
|
|||
|
|
|
|||
|
|
Returns:
|
|||
|
|
更新后的配置字典
|
|||
|
|
|
|||
|
|
Example:
|
|||
|
|
>>> config = {"task": {"source": "task-now.md"}}
|
|||
|
|
>>> set_config_value(config, "task.source", "new-task.md")
|
|||
|
|
{'task': {'source': 'new-task.md'}}
|
|||
|
|
"""
|
|||
|
|
keys = key.split(".")
|
|||
|
|
current = config
|
|||
|
|
|
|||
|
|
# 导航到倒数第二层
|
|||
|
|
for k in keys[:-1]:
|
|||
|
|
if k not in current:
|
|||
|
|
current[k] = {}
|
|||
|
|
current = current[k]
|
|||
|
|
|
|||
|
|
# 设置最后一层的值
|
|||
|
|
current[keys[-1]] = value
|
|||
|
|
|
|||
|
|
return config
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3.3 验证配置
|
|||
|
|
|
|||
|
|
**验证规则**:
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
from typing import Any
|
|||
|
|
|
|||
|
|
def validate_config(config: dict) -> list[str]:
|
|||
|
|
"""验证配置文件
|
|||
|
|
|
|||
|
|
Args:
|
|||
|
|
config: 配置字典
|
|||
|
|
|
|||
|
|
Returns:
|
|||
|
|
错误列表(空列表表示无错误)
|
|||
|
|
"""
|
|||
|
|
errors = []
|
|||
|
|
|
|||
|
|
# 验证必需的顶层键
|
|||
|
|
required_sections = ["task", "env", "output"]
|
|||
|
|
for section in required_sections:
|
|||
|
|
if section not in config:
|
|||
|
|
errors.append(f"缺少必需的配置节: [{section}]")
|
|||
|
|
|
|||
|
|
# 验证 task 配置
|
|||
|
|
if "task" in config:
|
|||
|
|
if "source" not in config["task"]:
|
|||
|
|
errors.append("缺少配置项: task.source")
|
|||
|
|
if "spec" not in config["task"]:
|
|||
|
|
errors.append("缺少配置项: task.spec")
|
|||
|
|
|
|||
|
|
# 验证 env.python 配置
|
|||
|
|
if "env" in config and "python" in config["env"]:
|
|||
|
|
python_config = config["env"]["python"]
|
|||
|
|
if "version" not in python_config:
|
|||
|
|
errors.append("缺少配置项: env.python.version")
|
|||
|
|
else:
|
|||
|
|
# 验证版本格式
|
|||
|
|
version = python_config["version"]
|
|||
|
|
if not is_valid_version_spec(version):
|
|||
|
|
errors.append(f"无效的版本格式: {version}")
|
|||
|
|
|
|||
|
|
# 验证 output 配置
|
|||
|
|
if "output" in config:
|
|||
|
|
output_config = config["output"]
|
|||
|
|
if "language" in output_config:
|
|||
|
|
lang = output_config["language"]
|
|||
|
|
if lang not in ["zh-CN", "en-US"]:
|
|||
|
|
errors.append(f"不支持的语言: {lang}")
|
|||
|
|
|
|||
|
|
return errors
|
|||
|
|
|
|||
|
|
def is_valid_version_spec(spec: str) -> bool:
|
|||
|
|
"""验证版本规格字符串
|
|||
|
|
|
|||
|
|
Args:
|
|||
|
|
spec: 版本规格(如 ">=3.10")
|
|||
|
|
|
|||
|
|
Returns:
|
|||
|
|
是否有效
|
|||
|
|
"""
|
|||
|
|
import re
|
|||
|
|
# 简化的版本规格验证
|
|||
|
|
pattern = r'^(>=|<=|>|<|==)?\d+\.\d+(\.\d+)?$'
|
|||
|
|
return bool(re.match(pattern, spec))
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 四、默认配置生成
|
|||
|
|
|
|||
|
|
### 4.1 生成逻辑
|
|||
|
|
|
|||
|
|
`aide init` 命令应该生成包含注释的默认配置:
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
def generate_default_config() -> str:
|
|||
|
|
"""生成默认配置文件内容(带注释)
|
|||
|
|
|
|||
|
|
Returns:
|
|||
|
|
TOML 格式的配置文件内容
|
|||
|
|
"""
|
|||
|
|
return '''# Aide 项目配置文件
|
|||
|
|
# 由 aide init 自动生成
|
|||
|
|
# 文档: https://github.com/your-org/aide
|
|||
|
|
|
|||
|
|
[task]
|
|||
|
|
# 任务原文档路径(prep 阶段使用)
|
|||
|
|
# 可通过 /aide:prep [路径] 覆盖
|
|||
|
|
source = "task-now.md"
|
|||
|
|
|
|||
|
|
# 任务细则文档路径(exec 阶段使用)
|
|||
|
|
# 可通过 /aide:exec [路径] 覆盖
|
|||
|
|
spec = "task-spec.md"
|
|||
|
|
|
|||
|
|
[env]
|
|||
|
|
# 环境配置
|
|||
|
|
|
|||
|
|
[env.python]
|
|||
|
|
# Python 版本要求(语义化版本)
|
|||
|
|
# 格式: ">=3.10" 或 ">=3.10,<4.0"
|
|||
|
|
version = ">=3.10"
|
|||
|
|
|
|||
|
|
# 虚拟环境路径(相对于项目根目录)
|
|||
|
|
venv = ".venv"
|
|||
|
|
|
|||
|
|
[env.tools]
|
|||
|
|
# 可选工具配置
|
|||
|
|
|
|||
|
|
# 是否需要 uv(Python 包管理器)
|
|||
|
|
uv = false
|
|||
|
|
|
|||
|
|
# 是否需要 git
|
|||
|
|
git = true
|
|||
|
|
|
|||
|
|
[flow]
|
|||
|
|
# 流程追踪配置(aide flow 命令使用)
|
|||
|
|
|
|||
|
|
# 环节列表(不建议修改)
|
|||
|
|
phases = ["flow-design", "impl", "verify", "docs", "finish"]
|
|||
|
|
|
|||
|
|
# PlantUML 流程图目录
|
|||
|
|
flowchart_dir = "program_flowchart"
|
|||
|
|
|
|||
|
|
[decide]
|
|||
|
|
# 待定项确认配置(aide decide 命令使用)
|
|||
|
|
|
|||
|
|
# Web 服务端口
|
|||
|
|
port = 3721
|
|||
|
|
|
|||
|
|
# 决策记录保存目录
|
|||
|
|
decisions_dir = ".aide/decisions"
|
|||
|
|
|
|||
|
|
[output]
|
|||
|
|
# 输出配置
|
|||
|
|
|
|||
|
|
# 是否启用颜色输出
|
|||
|
|
# 可通过环境变量 NO_COLOR 禁用
|
|||
|
|
color = true
|
|||
|
|
|
|||
|
|
# 输出语言(当前仅支持 zh-CN)
|
|||
|
|
language = "zh-CN"
|
|||
|
|
'''
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4.2 配置文件创建流程
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
from pathlib import Path
|
|||
|
|
|
|||
|
|
def create_config_file(project_root: Path) -> bool:
|
|||
|
|
"""创建配置文件
|
|||
|
|
|
|||
|
|
Args:
|
|||
|
|
project_root: 项目根目录
|
|||
|
|
|
|||
|
|
Returns:
|
|||
|
|
是否创建成功(False 表示文件已存在)
|
|||
|
|
"""
|
|||
|
|
aide_dir = project_root / ".aide"
|
|||
|
|
config_path = aide_dir / "config.toml"
|
|||
|
|
|
|||
|
|
# 检查是否已存在
|
|||
|
|
if config_path.exists():
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
# 确保 .aide 目录存在
|
|||
|
|
aide_dir.mkdir(exist_ok=True)
|
|||
|
|
|
|||
|
|
# 写入默认配置
|
|||
|
|
config_content = generate_default_config()
|
|||
|
|
config_path.write_text(config_content, encoding="utf-8")
|
|||
|
|
|
|||
|
|
return True
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 五、配置访问接口
|
|||
|
|
|
|||
|
|
### 5.1 Config 类设计
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
from pathlib import Path
|
|||
|
|
from typing import Any, Optional
|
|||
|
|
|
|||
|
|
class Config:
|
|||
|
|
"""配置管理类"""
|
|||
|
|
|
|||
|
|
def __init__(self, project_root: Path):
|
|||
|
|
"""初始化配置
|
|||
|
|
|
|||
|
|
Args:
|
|||
|
|
project_root: 项目根目录
|
|||
|
|
"""
|
|||
|
|
self.project_root = project_root
|
|||
|
|
self.config_path = project_root / ".aide" / "config.toml"
|
|||
|
|
self._config: Optional[dict] = None
|
|||
|
|
|
|||
|
|
def load(self) -> None:
|
|||
|
|
"""加载配置文件"""
|
|||
|
|
if not self.config_path.exists():
|
|||
|
|
raise FileNotFoundError(f"配置文件不存在: {self.config_path}")
|
|||
|
|
|
|||
|
|
with open(self.config_path, "rb") as f:
|
|||
|
|
self._config = tomllib.load(f)
|
|||
|
|
|
|||
|
|
def get(self, key: str, default: Any = None) -> Any:
|
|||
|
|
"""获取配置值
|
|||
|
|
|
|||
|
|
Args:
|
|||
|
|
key: 配置键(支持点号分隔)
|
|||
|
|
default: 默认值
|
|||
|
|
|
|||
|
|
Returns:
|
|||
|
|
配置值
|
|||
|
|
"""
|
|||
|
|
if self._config is None:
|
|||
|
|
self.load()
|
|||
|
|
|
|||
|
|
return get_config_value(self._config, key, default)
|
|||
|
|
|
|||
|
|
def set(self, key: str, value: Any) -> None:
|
|||
|
|
"""设置配置值
|
|||
|
|
|
|||
|
|
Args:
|
|||
|
|
key: 配置键(支持点号分隔)
|
|||
|
|
value: 配置值
|
|||
|
|
"""
|
|||
|
|
if self._config is None:
|
|||
|
|
self.load()
|
|||
|
|
|
|||
|
|
set_config_value(self._config, key, value)
|
|||
|
|
self.save()
|
|||
|
|
|
|||
|
|
def save(self) -> None:
|
|||
|
|
"""保存配置文件"""
|
|||
|
|
if self._config is None:
|
|||
|
|
return
|
|||
|
|
|
|||
|
|
with open(self.config_path, "wb") as f:
|
|||
|
|
tomli_w.dump(self._config, f)
|
|||
|
|
|
|||
|
|
def validate(self) -> list[str]:
|
|||
|
|
"""验证配置
|
|||
|
|
|
|||
|
|
Returns:
|
|||
|
|
错误列表
|
|||
|
|
"""
|
|||
|
|
if self._config is None:
|
|||
|
|
self.load()
|
|||
|
|
|
|||
|
|
return validate_config(self._config)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 5.2 使用示例
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
# 初始化配置
|
|||
|
|
config = Config(Path.cwd())
|
|||
|
|
|
|||
|
|
# 获取配置值
|
|||
|
|
task_source = config.get("task.source", "task-now.md")
|
|||
|
|
python_version = config.get("env.python.version", ">=3.10")
|
|||
|
|
|
|||
|
|
# 设置配置值
|
|||
|
|
config.set("task.source", "new-task.md")
|
|||
|
|
config.set("env.python.version", ">=3.11")
|
|||
|
|
|
|||
|
|
# 验证配置
|
|||
|
|
errors = config.validate()
|
|||
|
|
if errors:
|
|||
|
|
for error in errors:
|
|||
|
|
print(f"✗ 配置错误: {error}")
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 六、配置迁移
|
|||
|
|
|
|||
|
|
### 6.1 版本兼容性
|
|||
|
|
|
|||
|
|
当配置文件格式升级时,需要提供迁移机制:
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
def migrate_config(config: dict, from_version: str, to_version: str) -> dict:
|
|||
|
|
"""迁移配置文件
|
|||
|
|
|
|||
|
|
Args:
|
|||
|
|
config: 旧配置
|
|||
|
|
from_version: 源版本
|
|||
|
|
to_version: 目标版本
|
|||
|
|
|
|||
|
|
Returns:
|
|||
|
|
新配置
|
|||
|
|
"""
|
|||
|
|
if from_version == "1.0" and to_version == "1.1":
|
|||
|
|
# 示例:添加新的配置项
|
|||
|
|
if "output" not in config:
|
|||
|
|
config["output"] = {
|
|||
|
|
"color": True,
|
|||
|
|
"language": "zh-CN"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return config
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 6.2 配置备份
|
|||
|
|
|
|||
|
|
修改配置前应该备份:
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
import shutil
|
|||
|
|
from datetime import datetime
|
|||
|
|
|
|||
|
|
def backup_config(config_path: Path) -> Path:
|
|||
|
|
"""备份配置文件
|
|||
|
|
|
|||
|
|
Args:
|
|||
|
|
config_path: 配置文件路径
|
|||
|
|
|
|||
|
|
Returns:
|
|||
|
|
备份文件路径
|
|||
|
|
"""
|
|||
|
|
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
|||
|
|
backup_path = config_path.with_suffix(f".toml.backup.{timestamp}")
|
|||
|
|
shutil.copy2(config_path, backup_path)
|
|||
|
|
return backup_path
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 七、错误处理
|
|||
|
|
|
|||
|
|
### 7.1 常见错误
|
|||
|
|
|
|||
|
|
| 错误类型 | 处理方式 |
|
|||
|
|
|---------|---------|
|
|||
|
|
| 配置文件不存在 | 提示使用 `aide init` 创建 |
|
|||
|
|
| 配置文件格式错误 | 显示具体错误位置和原因 |
|
|||
|
|
| 配置项缺失 | 使用默认值并警告 |
|
|||
|
|
| 配置值类型错误 | 显示期望类型和实际类型 |
|
|||
|
|
|
|||
|
|
### 7.2 错误信息示例
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
def handle_config_error(error: Exception, config_path: Path) -> None:
|
|||
|
|
"""处理配置错误
|
|||
|
|
|
|||
|
|
Args:
|
|||
|
|
error: 异常对象
|
|||
|
|
config_path: 配置文件路径
|
|||
|
|
"""
|
|||
|
|
if isinstance(error, FileNotFoundError):
|
|||
|
|
err(
|
|||
|
|
"配置文件不存在",
|
|||
|
|
[
|
|||
|
|
f"位置: {config_path}",
|
|||
|
|
"建议: 运行 'aide init' 创建配置文件"
|
|||
|
|
]
|
|||
|
|
)
|
|||
|
|
elif isinstance(error, tomllib.TOMLDecodeError):
|
|||
|
|
err(
|
|||
|
|
f"配置文件格式错误 (第{error.lineno}行)",
|
|||
|
|
[
|
|||
|
|
f"位置: {config_path}:{error.lineno}",
|
|||
|
|
f"原因: {error.msg}",
|
|||
|
|
"建议: 检查 TOML 语法,确保格式正确"
|
|||
|
|
]
|
|||
|
|
)
|
|||
|
|
else:
|
|||
|
|
err(
|
|||
|
|
"配置文件读取失败",
|
|||
|
|
[
|
|||
|
|
f"位置: {config_path}",
|
|||
|
|
f"原因: {str(error)}"
|
|||
|
|
]
|
|||
|
|
)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 八、测试要求
|
|||
|
|
|
|||
|
|
### 8.1 测试用例
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
def test_load_config():
|
|||
|
|
"""测试加载配置"""
|
|||
|
|
# 创建测试配置
|
|||
|
|
# 加载配置
|
|||
|
|
# 验证配置内容
|
|||
|
|
|
|||
|
|
def test_get_config_value():
|
|||
|
|
"""测试获取配置值"""
|
|||
|
|
# 测试简单键
|
|||
|
|
# 测试嵌套键
|
|||
|
|
# 测试不存在的键
|
|||
|
|
# 测试默认值
|
|||
|
|
|
|||
|
|
def test_set_config_value():
|
|||
|
|
"""测试设置配置值"""
|
|||
|
|
# 测试设置简单键
|
|||
|
|
# 测试设置嵌套键
|
|||
|
|
# 测试创建新键
|
|||
|
|
|
|||
|
|
def test_validate_config():
|
|||
|
|
"""测试配置验证"""
|
|||
|
|
# 测试有效配置
|
|||
|
|
# 测试缺少必需项
|
|||
|
|
# 测试无效值类型
|
|||
|
|
# 测试无效版本格式
|
|||
|
|
|
|||
|
|
def test_config_migration():
|
|||
|
|
"""测试配置迁移"""
|
|||
|
|
# 测试版本升级
|
|||
|
|
# 测试向后兼容
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 九、总结
|
|||
|
|
|
|||
|
|
### 9.1 核心要点
|
|||
|
|
|
|||
|
|
1. 使用 TOML 格式,自文档化
|
|||
|
|
2. 提供合理的默认值
|
|||
|
|
3. 支持点号分隔的键访问
|
|||
|
|
4. 完善的错误处理和验证
|
|||
|
|
5. 配置迁移和备份机制
|
|||
|
|
|
|||
|
|
### 9.2 实现检查清单
|
|||
|
|
|
|||
|
|
- [ ] 实现配置文件读取(load_config)
|
|||
|
|
- [ ] 实现配置文件写入(save_config)
|
|||
|
|
- [ ] 实现配置值获取(get_config_value)
|
|||
|
|
- [ ] 实现配置值设置(set_config_value)
|
|||
|
|
- [ ] 实现配置验证(validate_config)
|
|||
|
|
- [ ] 实现默认配置生成(generate_default_config)
|
|||
|
|
- [ ] 实现 Config 类
|
|||
|
|
- [ ] 编写配置测试用例
|
|||
|
|
- [ ] 验证 TOML 格式正确性
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
**版本**:v1.0
|
|||
|
|
**更新日期**:2025-12-13
|