From 5f7c91afa1723e327f04f14f245c3e51d3e49fc7 Mon Sep 17 00:00:00 2001 From: "sayurinana(vm)" Date: Mon, 15 Dec 2025 18:12:50 +0800 Subject: [PATCH] =?UTF-8?q?[aide]=20impl:=20=E5=AD=90=E8=AE=A1=E5=88=923:?= =?UTF-8?q?=20aide=20flow=20=E6=B5=81=E7=A8=8B=E5=9B=BE=E9=9B=86=E6=88=90?= =?UTF-8?q?=E5=AE=8C=E6=88=90=20-=20PlantUML=20=E6=A0=A1=E9=AA=8C/?= =?UTF-8?q?=E6=9E=84=E5=BB=BA=E9=92=A9=E5=AD=90=E5=A2=9E=E5=BC=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .aide/flow-status.json | 10 +++- .aide/flow-status.lock | 2 +- aide-program/aide/flow/hooks.py | 80 +++++++++++++++++++++++++++---- aide-program/aide/flow/tracker.py | 2 + 4 files changed, 83 insertions(+), 11 deletions(-) diff --git a/.aide/flow-status.json b/.aide/flow-status.json index 971fef3..0521619 100644 --- a/.aide/flow-status.json +++ b/.aide/flow-status.json @@ -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" } ] } diff --git a/.aide/flow-status.lock b/.aide/flow-status.lock index 1df1ee0..a824ea8 100755 --- a/.aide/flow-status.lock +++ b/.aide/flow-status.lock @@ -1 +1 @@ -120170 \ No newline at end of file +120815 \ No newline at end of file diff --git a/aide-program/aide/flow/hooks.py b/aide-program/aide/flow/hooks.py index 1d0107d..543fb74 100644 --- a/aide-program/aide/flow/hooks.py +++ b/aide-program/aide/flow/hooks.py @@ -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: diff --git a/aide-program/aide/flow/tracker.py b/aide-program/aide/flow/tracker.py index 0596de2..4634ce3 100644 --- a/aide-program/aide/flow/tracker.py +++ b/aide-program/aide/flow/tracker.py @@ -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)