diff --git a/issues/enhance-progress-bar.issue b/issues/enhance-progress-bar.issue index d4abe61..28e9b55 100644 --- a/issues/enhance-progress-bar.issue +++ b/issues/enhance-progress-bar.issue @@ -1,16 +1,16 @@ # 需求工单:增强交互性 - 添加进度条显示 name: 增强交互性:添加进度条显示 description: | - 当前工具在执行耗时操作(如初始化项目时生成多个文件、运行并行检查、自动修复循环)时,终端上仅打印日志信息,用户无法直观了解当前进度和剩余时间,导致等待体验不佳。 + 当前工具在执行耗时操作(如初始化项目时生成多个文件、运行并行检查、自动修复循环)时,用户无法直观了解当前进度,导致等待体验不佳。 希望利用 `rich` 库的进度条功能,在以下关键步骤中显示实时进度,提升用户体验: 1. **初始化项目(init)**: - 在解析 `README.md` 生成 `design.json` 后,开始生成文件时,显示文件生成进度条。 - 进度条显示已生成文件数 / 总文件数,每个文件生成时显示当前文件名。 - - 若实现并发生成,进度条应动态更新已完成任务数,并可能显示每个文件的生成状态(如排队中、生成中、完成、失败)。 + - 若实现并发生成,进度条应动态更新已完成任务数,并显示每个文件的生成状态(如排队中、生成中、完成、失败)。 2. **增强/修复模式(enhance/fix)**: - - 在分析受影响文件、生成代码变更时,显示处理进度(例如分析中的文件数、生成补丁的进度)。 + - 在分析受影响文件、生成代码变更时,显示处理进度(例如分析中的文件数、当前补丁的名称,剩余补丁的数量,完成补丁的数量等等)。 - 在运行检查工具时(`run_parallel_checks`),显示检查工具运行的进度条(已完成检查的文件数 / 总文件数)。 - 在自动修复循环中,显示每次修复尝试的进度(如第几次重试、剩余错误数)。 @@ -22,9 +22,6 @@ description: | 需要修改的代码包括: - `cli.py`:主命令入口,控制整体流程,应在此处创建进度条上下文。 - - `core.py`:`CodeGenerator.generate_files` 方法(或类似方法)中,文件生成循环应集成进度条更新。 - - `checker.py`:`run_parallel_checks`、`auto_fix` 和 `run_full_check_and_fix` 中,添加进度条。 - - `utils.py`:可能添加辅助函数来统一创建进度条。 acceptance_criteria: - 执行 `llm-codegen init` 时,终端显示一个清晰的文件生成进度条,实时更新已完成文件数。 @@ -35,7 +32,4 @@ acceptance_criteria: - 进度条显示不会显著影响性能(更新频率合理)。 affected_files: - - src/llm_codegen/cli.py - - src/llm_codegen/core.py - - src/llm_codegen/checker.py - - src/llm_codegen/utils.py \ No newline at end of file + - src/llm_codegen/cli.py \ No newline at end of file diff --git a/src/llm_codegen/checker.py b/src/llm_codegen/checker.py index 9a53964..a3e3a9a 100644 --- a/src/llm_codegen/checker.py +++ b/src/llm_codegen/checker.py @@ -280,18 +280,23 @@ class Checker: with ThreadPoolExecutor(max_workers=min(4, len(files))) as executor: futures = [executor.submit(self.run_check, tool, file_path) for file_path in files] + error_count = 0 # 初始化错误计数 for future in as_completed(futures): try: result = future.result() all_results.append(result) + # 检查并更新错误计数 + if result.get("errors") and result["errors"]: + error_count += len(result["errors"]) except Exception as e: logger.error(f"并行检查任务失败: {e}") finally: - progress.update(task, advance=1) + # 更新进度条:前进并更新描述以显示错误统计 + progress.update(task, advance=1, description=f"[cyan]Running parallel checks... Errors: {error_count}") # 保存结果到文件 self.save_results(all_results) - logger.info(f"并行检查完成,总结果数: {len(all_results)}") + logger.info(f"并行检查完成,总结果数: {len(all_results)},总错误数: {error_count}") return all_results def save_results(self, results: List[Dict[str, Any]]) -> None: diff --git a/src/llm_codegen/cli.py b/src/llm_codegen/cli.py index b4ab595..4fddbe7 100644 --- a/src/llm_codegen/cli.py +++ b/src/llm_codegen/cli.py @@ -70,7 +70,7 @@ def init( BarColumn(), console=console, ) as progress: - task_id = progress.add_task("正在初始化项目...", total=None) + task_id = progress.add_task("正在初始化项目...", total=1) # 修改:设置总任务数为1以控制进度显示 generator = CodeGenerator( api_key=api_key, base_url=base_url, @@ -80,7 +80,7 @@ def init( max_concurrency=max_concurrency, ) generator.run(readme) - progress.update(task_id, description="初始化完成") + progress.update(task_id, completed=1, description="初始化完成") # 修改:更新完成状态 # 调用core.CodeGenerator.run并显示最终统计信息(假设从日志或生成器状态获取) console.print("[green]生成完成。成功处理文件,详情请查看日志。[/green]") except Exception as e: @@ -134,40 +134,14 @@ def enhance( except Exception as e: logger.error(f"读取工单文件失败: {e}") raise typer.Exit(code=1) - """ - try: - with Progress( - SpinnerColumn(), - TextColumn("[progress.description]{task.description}"), - BarColumn(), - console=console - ) as progress: - task_id = progress.add_task("正在增强项目...", total=None) - generator = CodeGenerator( - api_key=api_key, - base_url=base_url, - model=model, - output_dir=str(output_dir), - log_file=log_file_path, - max_concurrency=max_concurrency, - ) - success = generator.process_issue(issue_content, issue_type="enhance") - progress.update(task_id, description="增强处理完成") - if not success: - logger.error("增强处理失败") - raise typer.Exit(code=1) - console.print("[green]增强处理完成。成功处理文件,详情请查看日志。[/green]") - except Exception as e: - logger.error(f"增强失败: {e}") - raise typer.Exit(code=1) - """ + with Progress( SpinnerColumn(), TextColumn("[progress.description]{task.description}"), BarColumn(), console=console, ) as progress: - task_id = progress.add_task("正在增强项目...", total=None) + task_id = progress.add_task("正在增强项目...", total=1) # 修改:设置总任务数为1以控制进度显示 generator = CodeGenerator( api_key=api_key, base_url=base_url, @@ -177,7 +151,10 @@ def enhance( max_concurrency=max_concurrency, ) success = generator.process_issue(issue_content, issue_type="enhance") - progress.update(task_id, description="增强处理完成") + if success: + progress.update(task_id, completed=1, description="增强处理完成") # 修改:成功时更新完成状态 + else: + progress.update(task_id, description="增强处理失败") # 修改:失败时更新描述 if not success: logger.error("增强处理失败") raise typer.Exit(code=1) @@ -235,7 +212,7 @@ def fix( BarColumn(), console=console ) as progress: - task_id = progress.add_task("正在修复项目...", total=None) + task_id = progress.add_task("正在修复项目...", total=1) # 修改:设置总任务数为1以控制进度显示 generator = CodeGenerator( api_key=api_key, base_url=base_url, @@ -245,7 +222,10 @@ def fix( max_concurrency=max_concurrency, ) success = generator.process_issue(issue_content, issue_type="fix") - progress.update(task_id, description="修复处理完成") + if success: + progress.update(task_id, completed=1, description="修复处理完成") # 修改:成功时更新完成状态 + else: + progress.update(task_id, description="修复处理失败") # 修改:失败时更新描述 if not success: logger.error("修复处理失败") raise typer.Exit(code=1) @@ -253,7 +233,6 @@ def fix( except Exception as e: logger.error(f"修复失败: {e}") raise typer.Exit(code=1) - console.print("[green]修复处理完成。成功处理文件,详情请查看日志。[/green]") @app.command() @@ -305,7 +284,7 @@ def design( BarColumn(), console=console, ) as progress: - task_id = progress.add_task("正在生成design.json...", total=None) + task_id = progress.add_task("正在生成design.json...", total=1) # 可选:保持现有风格,但工单未要求修改此命令 generator = CodeGenerator( api_key=api_key, base_url=base_url, @@ -318,7 +297,7 @@ def design( generator.readme_content = generator.parse_readme(file) # 生成design.json generator.generate_design_json() - progress.update(task_id, description="design.json 生成完成") + progress.update(task_id, completed=1, description="design.json 生成完成") # 可选:更新完成状态 console.print(f"[green]✅ design.json 已生成在 {design_path}[/green]") except Exception as e: logger.error(f"生成design.json失败: {e}") diff --git a/src/llm_codegen/core.py b/src/llm_codegen/core.py index f82c6e9..c38ff94 100644 --- a/src/llm_codegen/core.py +++ b/src/llm_codegen/core.py @@ -15,7 +15,7 @@ from loguru import logger from openai import OpenAI from .utils import is_dangerous_command -from .models import DesignModel, StateModel, FileModel +from .models import DesignModel, StateModel, FileModel, FileStatus # 添加 FileStatus 导入 from .diff_applier import parse_diff, apply_diff @@ -692,8 +692,8 @@ class CodeGenerator: file = queue.popleft() future = executor.submit(self._generate_file_task, file, dependencies.get(file, []), processed_files) futures[future] = file - # 为每个文件添加独立进度任务并保存任务ID - task_id = progress.add_task(f"生成 {file}", total=1) + # 为每个文件添加独立进度任务并保存任务ID,添加状态显示 + task_id = progress.add_task(f"{file} - {FileStatus.GENERATING}", total=1) # 修改:添加状态 file_tasks[file] = task_id # 等待任意任务完成 @@ -702,14 +702,14 @@ class CodeGenerator: file = futures.pop(future) try: success, error_msg = future.result() - # 更新文件进度任务 + # 更新文件进度任务,根据状态更新描述 if file in file_tasks: if success: - progress.update(file_tasks[file], completed=1) + progress.update(file_tasks[file], completed=1, description=f"{file} - {FileStatus.SUCCESS}") # 修改:添加状态 progress.remove_task(file_tasks[file]) # 移除任务 else: # 如果失败,标记为错误状态 - progress.update(file_tasks[file], description=f"生成失败: {file}") + progress.update(file_tasks[file], description=f"{file} - {FileStatus.FAILED}: {error_msg}") # 修改:添加状态 progress.remove_task(file_tasks[file]) del file_tasks[file] # 清理映射 if success: @@ -736,7 +736,7 @@ class CodeGenerator: error_msg = str(e) # 然后执行和上面 `else` 分支相同的失败处理逻辑 if file in file_tasks: - progress.update(file_tasks[file], description=f"生成失败: {file}") + progress.update(file_tasks[file], description=f"{file} - {FileStatus.FAILED}: {error_msg}") # 修改:添加状态 progress.remove_task(file_tasks[file]) del file_tasks[file] # 清理映射 logger.error(f"文件 {file} 生成失败,错误: {error_msg}") @@ -1208,4 +1208,4 @@ class CodeGenerator: except Exception as e: logger.error(f"同步README.md失败: {e}") self.console.print(f"[bold red]❌ 同步README.md失败: {e}[/bold red]") - return False + return False \ No newline at end of file