📃 docs: 部分完成

This commit is contained in:
2025-12-13 04:37:41 +08:00
parent 52dffe2803
commit b2c26cb9db
9 changed files with 4628 additions and 0 deletions

View File

@@ -0,0 +1,599 @@
# aide env 设计
## 一、命令概述
### 1.1 功能定位
`aide env` 命令用于检测和修复项目开发环境,确保所有必需的工具和依赖都已正确安装。
### 1.2 执行时机
- `/aide:init` 命令中调用(两次)
- 用户手动检查环境时
- 环境配置变更后
### 1.3 命令格式
```bash
aide env ensure [--runtime]
```
**选项**
- `--runtime`:仅检查 aide 运行时环境(不依赖配置文件)
---
## 二、功能需求
### 2.1 aide env ensure --runtime
**用途**:检查 aide 程序自身运行所需的环境
**检查项**
1. Python 版本(>= 3.10
2. 必需的 Python 库tomli/tomllib, tomli-w
**特点**
- 不读取项目配置文件
-`aide init` 之前执行
- 失败时给出明确的安装建议
**输出示例**
成功:
```
✓ 环境就绪 (python:3.12)
```
失败:
```
✗ Python 版本不满足要求 (需要 >=3.10, 当前 3.8)
建议: 安装 Python 3.10+ 或使用 pyenv 管理版本
文档: https://www.python.org/downloads/
```
### 2.2 aide env ensure
**用途**:检查项目开发环境
**检查项**
1. Python 版本(根据配置文件)
2. 虚拟环境(根据配置文件)
3. 可选工具git, uv 等,根据配置文件)
**特点**
- 读取 `.aide/config.toml`
-`aide init` 之后执行
- 可以自动修复部分问题
**输出示例**
成功(无问题):
```
✓ 环境就绪 (python:3.12, git:2.40.0)
```
成功(自动修复):
```
⚠ 已修复: 创建虚拟环境 .venv
✓ 环境就绪 (python:3.12)
```
失败(无法修复):
```
✗ Python 版本不满足要求 (需要 >=3.11, 当前 3.10)
建议: 升级 Python 到 3.11+ 或修改配置文件
配置: .aide/config.toml (env.python.version)
```
---
## 三、实现设计
### 3.1 函数接口
```python
def cmd_env(args: list[str]) -> int:
"""aide env 命令处理
Args:
args: 命令参数
Returns:
退出码0 表示成功)
"""
pass
def env_ensure(runtime_only: bool = False) -> int:
"""环境检测和修复
Args:
runtime_only: 是否仅检查运行时环境
Returns:
退出码0 表示成功)
"""
pass
```
### 3.2 实现流程
#### 3.2.1 aide env ensure --runtime
```python
import sys
import subprocess
from pathlib import Path
from core.output import ok, err
def env_ensure_runtime() -> int:
"""检查 aide 运行时环境"""
# 1. 检查 Python 版本
python_version = sys.version_info
if python_version.major < 3 or (python_version.major == 3 and python_version.minor < 10):
err(
f"Python 版本不满足要求 (需要 >=3.10, 当前 {python_version.major}.{python_version.minor})",
[
"建议: 安装 Python 3.10+ 或使用 pyenv 管理版本",
"文档: https://www.python.org/downloads/"
]
)
return 3
# 2. 检查必需的库
try:
# Python 3.11+ 内置 tomllib
if python_version.minor >= 11:
import tomllib
else:
import tomli as tomllib
import tomli_w
except ImportError as e:
err(
f"缺少必需的 Python 库: {e.name}",
[
"建议: 运行 'pip install tomli tomli-w'",
"或使用 uv: 'uv pip install tomli tomli-w'"
]
)
return 3
# 3. 输出成功信息
version_str = f"{python_version.major}.{python_version.minor}.{python_version.micro}"
ok(f"环境就绪 (python:{version_str})")
return 0
```
#### 3.2.2 aide env ensure
```python
from core.config import Config
from core.output import ok, warn, err
def env_ensure_project() -> int:
"""检查项目开发环境"""
# 1. 加载配置
try:
config = Config(Path.cwd())
config.load()
except FileNotFoundError:
err(
"配置文件不存在",
[
"位置: .aide/config.toml",
"建议: 运行 'aide init' 创建配置文件"
]
)
return 4
except Exception as e:
err(
"配置文件读取失败",
[
f"原因: {str(e)}",
"建议: 检查配置文件格式"
]
)
return 4
# 2. 检查 Python 版本
required_version = config.get("env.python.version", ">=3.10")
if not check_python_version(required_version):
err(
f"Python 版本不满足要求 (需要 {required_version}, 当前 {get_python_version()})",
[
"建议: 升级 Python 或修改配置文件",
"配置: .aide/config.toml (env.python.version)"
]
)
return 3
# 3. 检查虚拟环境
venv_path = config.get("env.python.venv", ".venv")
venv_result = check_venv(venv_path)
if venv_result == "missing":
# 尝试创建虚拟环境
if create_venv(venv_path):
warn(f"已修复: 创建虚拟环境 {venv_path}")
else:
err(
f"虚拟环境不存在且无法创建 ({venv_path})",
[
"建议: 手动创建虚拟环境",
f"命令: python3 -m venv {venv_path}"
]
)
return 3
# 4. 检查可选工具
tools_info = []
# 检查 git
if config.get("env.tools.git", True):
git_version = get_tool_version("git")
if git_version:
tools_info.append(f"git:{git_version}")
else:
warn("git 未安装(可选)")
# 检查 uv
if config.get("env.tools.uv", False):
uv_version = get_tool_version("uv")
if uv_version:
tools_info.append(f"uv:{uv_version}")
else:
warn("uv 未安装(可选)")
# 5. 输出成功信息
python_version = get_python_version()
info_parts = [f"python:{python_version}"] + tools_info
ok(f"环境就绪 ({', '.join(info_parts)})")
return 0
```
### 3.3 辅助函数
#### 3.3.1 版本检查
```python
import re
from packaging import version
def check_python_version(requirement: str) -> bool:
"""检查 Python 版本是否满足要求
Args:
requirement: 版本要求(如 ">=3.10"
Returns:
是否满足要求
"""
current = get_python_version()
# 解析要求
match = re.match(r'(>=|<=|>|<|==)?(\d+\.\d+(?:\.\d+)?)', requirement)
if not match:
return True # 无法解析,假设满足
operator, required = match.groups()
operator = operator or "=="
# 比较版本
try:
current_ver = version.parse(current)
required_ver = version.parse(required)
if operator == ">=":
return current_ver >= required_ver
elif operator == "<=":
return current_ver <= required_ver
elif operator == ">":
return current_ver > required_ver
elif operator == "<":
return current_ver < required_ver
elif operator == "==":
return current_ver == required_ver
except Exception:
return True
return True
def get_python_version() -> str:
"""获取当前 Python 版本
Returns:
版本字符串(如 "3.12.0"
"""
v = sys.version_info
return f"{v.major}.{v.minor}.{v.micro}"
```
#### 3.3.2 虚拟环境检查
```python
import subprocess
def check_venv(venv_path: str) -> str:
"""检查虚拟环境状态
Args:
venv_path: 虚拟环境路径
Returns:
状态:'ok', 'missing', 'invalid'
"""
venv_dir = Path(venv_path)
if not venv_dir.exists():
return "missing"
# 检查是否是有效的虚拟环境
if sys.platform == "win32":
python_exe = venv_dir / "Scripts" / "python.exe"
else:
python_exe = venv_dir / "bin" / "python"
if python_exe.exists():
return "ok"
else:
return "invalid"
def create_venv(venv_path: str) -> bool:
"""创建虚拟环境
Args:
venv_path: 虚拟环境路径
Returns:
是否创建成功
"""
try:
subprocess.run(
[sys.executable, "-m", "venv", venv_path],
check=True,
capture_output=True,
text=True
)
return True
except subprocess.CalledProcessError:
return False
except Exception:
return False
```
#### 3.3.3 工具版本检查
```python
def get_tool_version(tool: str) -> str | None:
"""获取工具版本
Args:
tool: 工具名称(如 "git", "uv"
Returns:
版本字符串,未安装则返回 None
"""
try:
result = subprocess.run(
[tool, "--version"],
capture_output=True,
text=True,
timeout=5
)
if result.returncode == 0:
# 解析版本号
output = result.stdout.strip()
match = re.search(r'(\d+\.\d+\.\d+)', output)
if match:
return match.group(1)
return "unknown"
except (subprocess.TimeoutExpired, FileNotFoundError):
pass
return None
```
---
## 四、错误处理
### 4.1 错误分类
| 错误类型 | 退出码 | 处理方式 |
|---------|--------|---------|
| Python 版本不满足 | 3 | 显示当前版本和要求,给出升级建议 |
| 配置文件不存在 | 4 | 提示运行 aide init |
| 配置文件格式错误 | 4 | 显示错误位置和原因 |
| 虚拟环境无法创建 | 3 | 显示创建命令 |
| 必需工具未安装 | 3 | 显示安装建议 |
### 4.2 错误恢复
```python
def env_ensure_with_retry(runtime_only: bool = False, max_retries: int = 3) -> int:
"""带重试的环境检测
Args:
runtime_only: 是否仅检查运行时
max_retries: 最大重试次数
Returns:
退出码
"""
for attempt in range(max_retries):
result = env_ensure(runtime_only)
if result == 0:
return 0
if attempt < max_retries - 1:
info(f"重试 ({attempt + 1}/{max_retries})...")
return result
```
---
## 五、测试用例
### 5.1 runtime 模式测试
```python
def test_env_ensure_runtime_success():
"""测试运行时环境检测成功"""
result = env_ensure_runtime()
assert result == 0
def test_env_ensure_runtime_old_python(monkeypatch):
"""测试 Python 版本过低"""
# 模拟 Python 3.8
monkeypatch.setattr(sys, "version_info", (3, 8, 0, "final", 0))
result = env_ensure_runtime()
assert result == 3
def test_env_ensure_runtime_missing_lib(monkeypatch):
"""测试缺少必需库"""
# 模拟 import 失败
def mock_import(name, *args, **kwargs):
if name in ["tomli", "tomllib"]:
raise ImportError(f"No module named '{name}'")
return __import__(name, *args, **kwargs)
monkeypatch.setattr("builtins.__import__", mock_import)
result = env_ensure_runtime()
assert result == 3
```
### 5.2 项目环境测试
```python
def test_env_ensure_project_success(tmp_path, monkeypatch):
"""测试项目环境检测成功"""
monkeypatch.chdir(tmp_path)
# 创建配置文件
cmd_init([])
# 检测环境
result = env_ensure_project()
assert result == 0
def test_env_ensure_project_no_config(tmp_path, monkeypatch):
"""测试配置文件不存在"""
monkeypatch.chdir(tmp_path)
result = env_ensure_project()
assert result == 4
def test_env_ensure_project_create_venv(tmp_path, monkeypatch):
"""测试自动创建虚拟环境"""
monkeypatch.chdir(tmp_path)
# 创建配置文件
cmd_init([])
# 确保虚拟环境不存在
venv_path = tmp_path / ".venv"
if venv_path.exists():
shutil.rmtree(venv_path)
# 检测环境(应该自动创建虚拟环境)
result = env_ensure_project()
assert result == 0
assert venv_path.exists()
```
### 5.3 版本检查测试
```python
def test_check_python_version():
"""测试 Python 版本检查"""
# 测试各种版本要求
assert check_python_version(">=3.10") == True # 假设当前是 3.12
assert check_python_version(">=3.15") == False
assert check_python_version("==3.12") == True
assert check_python_version("<4.0") == True
def test_get_python_version():
"""测试获取 Python 版本"""
version = get_python_version()
assert re.match(r'\d+\.\d+\.\d+', version)
```
---
## 六、性能要求
### 6.1 执行时间
- `--runtime` 模式:< 100ms
- 项目环境检测无修复< 500ms
- 项目环境检测创建虚拟环境< 10s
### 6.2 资源占用
- 内存< 50MB
- CPU主要是 I/O 操作
---
## 七、集成测试
### 7.1 完整工作流
```python
def test_env_workflow(tmp_path, monkeypatch):
"""测试完整的环境检测工作流"""
monkeypatch.chdir(tmp_path)
# 1. 检查运行时环境
result = env_ensure_runtime()
assert result == 0
# 2. 初始化项目
result = cmd_init([])
assert result == 0
# 3. 检查项目环境
result = env_ensure_project()
assert result == 0
# 4. 验证虚拟环境已创建
assert (tmp_path / ".venv").exists()
```
---
## 八、总结
### 8.1 核心要点
1. 两种模式runtime project
2. 自动修复部分问题如创建虚拟环境
3. 清晰的错误信息和建议
4. 完善的版本检查逻辑
### 8.2 实现检查清单
- [ ] 实现 cmd_env 函数
- [ ] 实现 env_ensure_runtime 函数
- [ ] 实现 env_ensure_project 函数
- [ ] 实现版本检查函数
- [ ] 实现虚拟环境检查和创建
- [ ] 实现工具版本检查
- [ ] 编写单元测试
- [ ] 编写集成测试
- [ ] 性能测试
---
**版本**v1.0
**更新日期**2025-12-13