[aide] impl: 子计划3: aide flow 流程图集成完成 - PlantUML 校验/构建钩子增强
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"task_id": "2025-12-15T17-28-53",
|
||||
"current_phase": "impl",
|
||||
"current_step": 11,
|
||||
"current_step": 12,
|
||||
"started_at": "2025-12-15T17:28:53+08:00",
|
||||
"history": [
|
||||
{
|
||||
@@ -90,6 +90,14 @@
|
||||
"step": 11,
|
||||
"summary": "子计划1: 配置系统增强完成 - 自文档化配置模板、gitignore配置、plantuml.jar",
|
||||
"git_commit": "79facec0a3db9ffcf936772930cc695ca9bf263d"
|
||||
},
|
||||
{
|
||||
"timestamp": "2025-12-15T18:11:39+08:00",
|
||||
"action": "next-step",
|
||||
"phase": "impl",
|
||||
"step": 12,
|
||||
"summary": "子计划2: aide flow 状态查看功能完成 - status/list/show 子命令",
|
||||
"git_commit": "6a1b230cc98ff5535fd8cbc1d9490293e2ef6845"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
120170
|
||||
120815
|
||||
@@ -5,6 +5,7 @@ from __future__ import annotations
|
||||
import shutil
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from aide.core import output
|
||||
from aide.flow.errors import FlowError
|
||||
@@ -20,9 +21,10 @@ def run_pre_commit_hooks(
|
||||
from_phase: str | None,
|
||||
to_phase: str,
|
||||
action: str,
|
||||
config: dict[str, Any] | None = None,
|
||||
) -> None:
|
||||
if from_phase == "flow-design" and action in {"next-part", "back-part"}:
|
||||
_hook_plantuml(root=root)
|
||||
_hook_plantuml(root=root, config=config)
|
||||
if from_phase == "docs" and action in {"next-part", "back-part"}:
|
||||
_hook_changelog_on_leave_docs(root=root, git=git, status=status)
|
||||
|
||||
@@ -32,11 +34,49 @@ def run_post_commit_hooks(*, to_phase: str, action: str) -> None:
|
||||
output.info("请更新 CHANGELOG.md")
|
||||
|
||||
|
||||
def _hook_plantuml(*, root: Path) -> None:
|
||||
docs_dir = root / "docs"
|
||||
discuss_dir = root / "discuss"
|
||||
def _get_plantuml_command(config: dict[str, Any] | None) -> list[str] | None:
|
||||
"""获取 PlantUML 命令,优先使用配置的 jar 文件。"""
|
||||
if config:
|
||||
jar_path = config.get("plantuml", {}).get("jar_path")
|
||||
java_path = config.get("plantuml", {}).get("java_path", "java")
|
||||
|
||||
if jar_path:
|
||||
# 尝试解析 jar 路径
|
||||
jar_file = Path(jar_path)
|
||||
if not jar_file.is_absolute():
|
||||
# 相对路径,相对于 aide-program 目录
|
||||
aide_program_dir = Path(__file__).parent.parent.parent
|
||||
jar_file = aide_program_dir / jar_path
|
||||
|
||||
if jar_file.exists():
|
||||
return [java_path, "-jar", str(jar_file)]
|
||||
|
||||
# 回退到系统 plantuml 命令
|
||||
if shutil.which("plantuml"):
|
||||
return ["plantuml"]
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def _hook_plantuml(*, root: Path, config: dict[str, Any] | None = None) -> None:
|
||||
"""PlantUML 校验和构建钩子。"""
|
||||
# 获取流程图目录
|
||||
diagram_path = ".aide/diagrams"
|
||||
if config:
|
||||
diagram_path = config.get("flow", {}).get("diagram_path", diagram_path)
|
||||
|
||||
diagram_dir = root / diagram_path
|
||||
|
||||
# 收集所有 .puml 文件
|
||||
candidates: list[Path] = []
|
||||
for base in (docs_dir, discuss_dir):
|
||||
|
||||
# 从配置的流程图目录
|
||||
if diagram_dir.exists():
|
||||
candidates.extend([p for p in diagram_dir.rglob("*.puml") if p.is_file()])
|
||||
candidates.extend([p for p in diagram_dir.rglob("*.plantuml") if p.is_file()])
|
||||
|
||||
# 也检查 docs 和 discuss 目录(向后兼容)
|
||||
for base in (root / "docs", root / "discuss"):
|
||||
if not base.exists():
|
||||
continue
|
||||
candidates.extend([p for p in base.rglob("*.puml") if p.is_file()])
|
||||
@@ -45,20 +85,42 @@ def _hook_plantuml(*, root: Path) -> None:
|
||||
if not candidates:
|
||||
return
|
||||
|
||||
if shutil.which("plantuml") is None:
|
||||
output.warn("未找到 plantuml,已跳过 PlantUML 校验/PNG 生成")
|
||||
# 获取 PlantUML 命令
|
||||
plantuml_cmd = _get_plantuml_command(config)
|
||||
if plantuml_cmd is None:
|
||||
output.warn("未找到 PlantUML(jar 或系统命令),已跳过校验/PNG 生成")
|
||||
return
|
||||
|
||||
# 先校验所有文件
|
||||
errors: list[str] = []
|
||||
for file_path in candidates:
|
||||
result = subprocess.run(
|
||||
["plantuml", "-tpng", str(file_path)],
|
||||
plantuml_cmd + ["-checkonly", str(file_path)],
|
||||
cwd=root,
|
||||
text=True,
|
||||
capture_output=True,
|
||||
)
|
||||
if result.returncode != 0:
|
||||
detail = (result.stderr or "").strip() or (result.stdout or "").strip()
|
||||
raise FlowError(f"PlantUML 处理失败: {file_path} {detail}".strip())
|
||||
errors.append(f"{file_path.name}: {detail}")
|
||||
|
||||
if errors:
|
||||
error_msg = "\n".join(errors)
|
||||
raise FlowError(f"PlantUML 语法校验失败:\n{error_msg}")
|
||||
|
||||
# 校验通过,生成 PNG
|
||||
for file_path in candidates:
|
||||
result = subprocess.run(
|
||||
plantuml_cmd + ["-tpng", str(file_path)],
|
||||
cwd=root,
|
||||
text=True,
|
||||
capture_output=True,
|
||||
)
|
||||
if result.returncode != 0:
|
||||
detail = (result.stderr or "").strip() or (result.stdout or "").strip()
|
||||
raise FlowError(f"PlantUML PNG 生成失败: {file_path} {detail}".strip())
|
||||
|
||||
output.ok(f"PlantUML 处理完成: {len(candidates)} 个文件")
|
||||
|
||||
|
||||
def _hook_changelog_on_leave_docs(*, root: Path, git: GitIntegration, status: FlowStatus | None) -> None:
|
||||
|
||||
@@ -144,6 +144,7 @@ class FlowTracker:
|
||||
else:
|
||||
validator.validate_phase_exists(to_phase)
|
||||
|
||||
config = self.cfg.load_config()
|
||||
run_pre_commit_hooks(
|
||||
root=self.root,
|
||||
git=self.git,
|
||||
@@ -151,6 +152,7 @@ class FlowTracker:
|
||||
from_phase=from_phase,
|
||||
to_phase=to_phase,
|
||||
action=action,
|
||||
config=config,
|
||||
)
|
||||
|
||||
message = _build_commit_message(action=action, phase=to_phase, text=text)
|
||||
|
||||
Reference in New Issue
Block a user