You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

126 lines
3.9 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import argparse
import os
import sys
from pathlib import Path
# 直接复用你在 test.py 里已经配置好的 client里面含有 API Key 和 base_url
try:
from test import client # type: ignore
except Exception as import_error: # noqa: PIE786
raise SystemExit(
"无法从 test.py 导入 client。请先确保 test.py 能正常运行,或在此脚本中自行创建 client。"
) from import_error
def detect_language_by_suffix(file_path: Path) -> str:
suffix = file_path.suffix.lower()
mapping = {
".py": "python",
".js": "javascript",
".ts": "typescript",
".tsx": "tsx",
".jsx": "jsx",
".java": "java",
".go": "go",
".rs": "rust",
".rb": "ruby",
".php": "php",
".cs": "csharp",
".cpp": "cpp",
".cc": "cpp",
".cxx": "cpp",
".c": "c",
".h": "c",
".json": "json",
".yaml": "yaml",
".yml": "yaml",
".md": "markdown",
".sql": "sql",
".sh": "bash",
".ps1": "powershell",
}
return mapping.get(suffix, "")
def read_text_file(file_path: Path) -> str:
try:
return file_path.read_text(encoding="utf-8")
except UnicodeDecodeError:
# 回退到系统默认编码
return file_path.read_text(errors="replace")
def build_messages(code_path: Path, code_content: str, instruction: str):
language = detect_language_by_suffix(code_path)
system_prompt = (
"你是严谨的代码审查与重构助手,请用中文回答。"
"输出请使用结构化 Markdown包含\n"
"1) 概览\n2) 问题清单(按严重程度排序,标注位置/片段)\n"
"3) 可执行的修复建议\n4) 示例修复代码(只给关键片段)\n"
"5) 边界与测试要点\n"
"除非必要,不要重复粘贴整份源码。"
)
user_prompt = (
f"任务:{instruction.strip()}\n"
f"文件:{code_path.name}\n"
"代码如下:\n"
f"```{language}\n{code_content}\n```"
)
return [
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_prompt},
]
def analyze_file(input_path: Path, output_path: Path, instruction: str, model: str = "deepseek-chat") -> None:
code = read_text_file(input_path)
messages = build_messages(input_path, code, instruction)
resp = client.chat.completions.create(
model=model,
messages=messages,
stream=False,
temperature=0.2,
)
content = resp.choices[0].message.content if resp.choices else ""
output_path.write_text(content, encoding="utf-8")
def main(argv: list[str]) -> int:
parser = argparse.ArgumentParser(
description="分析指定代码文件,输出结构化反馈到文件(复用 test.py 的 client",
)
parser.add_argument("input", help="要分析的源代码文件路径")
parser.add_argument("output", help="把反馈写入到的目标文件路径,例如 review.md")
parser.add_argument(
"--instruction",
default="请找出代码问题、潜在缺陷、可读性/性能/安全改进,并给出修复建议",
help="自定义任务说明(可选)",
)
parser.add_argument(
"--model",
default="deepseek-chat",
help="模型名称(默认 deepseek-chat",
)
args = parser.parse_args(argv)
input_path = Path(args.input).expanduser().resolve()
output_path = Path(args.output).expanduser().resolve()
if not input_path.exists():
raise SystemExit(f"输入文件不存在: {input_path}")
output_path.parent.mkdir(parents=True, exist_ok=True)
analyze_file(input_path, output_path, args.instruction, model=args.model)
print(f"分析完成,结果已写入: {output_path}")
return 0
if __name__ == "__main__":
raise SystemExit(main(sys.argv[1:]))