Update code
This commit is contained in:
133
dev-assistant-mcp/dist/tools/lintCheck.js
vendored
Normal file
133
dev-assistant-mcp/dist/tools/lintCheck.js
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
import { exec } from "child_process";
|
||||
import { promisify } from "util";
|
||||
import { existsSync } from "fs";
|
||||
import { join } from "path";
|
||||
const execAsync = promisify(exec);
|
||||
export const lintCheckTool = {
|
||||
name: "lint_check",
|
||||
description: "对项目执行代码检查。自动检测项目类型并运行对应的 lint 工具(ESLint、TypeScript 编译检查、Pylint 等),返回结构化的错误列表。",
|
||||
inputSchema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
project_path: {
|
||||
type: "string",
|
||||
description: "项目根目录(绝对路径)",
|
||||
},
|
||||
fix: {
|
||||
type: "boolean",
|
||||
description: "是否自动修复可修复的问题(默认 false)",
|
||||
},
|
||||
files: {
|
||||
type: "string",
|
||||
description: "指定检查的文件或 glob(可选,默认检查整个项目)",
|
||||
},
|
||||
},
|
||||
required: ["project_path"],
|
||||
},
|
||||
};
|
||||
async function runCommand(cmd, cwd, timeout = 30000) {
|
||||
try {
|
||||
const { stdout, stderr } = await execAsync(cmd, {
|
||||
cwd,
|
||||
timeout,
|
||||
maxBuffer: 1024 * 1024 * 5,
|
||||
shell: process.platform === "win32" ? "powershell.exe" : "/bin/bash",
|
||||
});
|
||||
return { stdout, stderr, code: 0 };
|
||||
}
|
||||
catch (error) {
|
||||
return {
|
||||
stdout: error.stdout || "",
|
||||
stderr: error.stderr || "",
|
||||
code: error.code ?? 1,
|
||||
};
|
||||
}
|
||||
}
|
||||
export async function executeLintCheck(args) {
|
||||
const { project_path, fix = false, files } = args;
|
||||
const results = [];
|
||||
const hasFile = (name) => existsSync(join(project_path, name));
|
||||
const hasNodeModules = hasFile("node_modules");
|
||||
// TypeScript 编译检查
|
||||
if (hasFile("tsconfig.json")) {
|
||||
const result = await runCommand("npx tsc --noEmit --pretty", project_path);
|
||||
const errorCount = (result.stdout.match(/error TS/g) || []).length;
|
||||
results.push({
|
||||
tool: "TypeScript (tsc --noEmit)",
|
||||
success: result.code === 0,
|
||||
errorCount,
|
||||
warningCount: 0,
|
||||
output: result.stdout || result.stderr || "(无输出)",
|
||||
});
|
||||
}
|
||||
// ESLint
|
||||
if (hasFile(".eslintrc.js") || hasFile(".eslintrc.json") || hasFile(".eslintrc.yml") || hasFile("eslint.config.js") || hasFile("eslint.config.mjs")) {
|
||||
const target = files || "src/";
|
||||
const fixFlag = fix ? " --fix" : "";
|
||||
const result = await runCommand(`npx eslint ${target}${fixFlag} --format stylish`, project_path);
|
||||
const errorMatch = result.stdout.match(/(\d+) errors?/);
|
||||
const warnMatch = result.stdout.match(/(\d+) warnings?/);
|
||||
results.push({
|
||||
tool: `ESLint${fix ? " (--fix)" : ""}`,
|
||||
success: result.code === 0,
|
||||
errorCount: errorMatch ? parseInt(errorMatch[1]) : 0,
|
||||
warningCount: warnMatch ? parseInt(warnMatch[1]) : 0,
|
||||
output: result.stdout || result.stderr || "✅ 无问题",
|
||||
});
|
||||
}
|
||||
// Python: pylint / flake8
|
||||
if (hasFile("requirements.txt") || hasFile("setup.py") || hasFile("pyproject.toml")) {
|
||||
const target = files || ".";
|
||||
// 优先 flake8
|
||||
const result = await runCommand(`python -m flake8 ${target} --max-line-length=120 --count`, project_path);
|
||||
if (result.code !== 127) { // 127 = command not found
|
||||
const lines = result.stdout.trim().split("\n").filter(Boolean);
|
||||
results.push({
|
||||
tool: "Flake8",
|
||||
success: result.code === 0,
|
||||
errorCount: lines.length,
|
||||
warningCount: 0,
|
||||
output: result.stdout || result.stderr || "✅ 无问题",
|
||||
});
|
||||
}
|
||||
}
|
||||
// 如果什么检查工具都没找到
|
||||
if (results.length === 0) {
|
||||
// 尝试通用的 package.json lint 脚本
|
||||
if (hasFile("package.json")) {
|
||||
const result = await runCommand("npm run lint 2>&1 || echo LINT_SCRIPT_NOT_FOUND", project_path);
|
||||
if (!result.stdout.includes("LINT_SCRIPT_NOT_FOUND") && !result.stdout.includes("Missing script")) {
|
||||
results.push({
|
||||
tool: "npm run lint",
|
||||
success: result.code === 0,
|
||||
errorCount: result.code === 0 ? 0 : 1,
|
||||
warningCount: 0,
|
||||
output: result.stdout || result.stderr,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
if (results.length === 0) {
|
||||
return `# Lint 检查结果\n\n⚠️ 未检测到 lint 工具配置(ESLint、tsconfig、pylint 等)\n项目路径: ${project_path}\n\n建议:\n- TypeScript 项目:添加 tsconfig.json\n- JS 项目:npm init @eslint/config\n- Python 项目:pip install flake8`;
|
||||
}
|
||||
// 组装报告
|
||||
const totalErrors = results.reduce((sum, r) => sum + r.errorCount, 0);
|
||||
const totalWarnings = results.reduce((sum, r) => sum + r.warningCount, 0);
|
||||
const allPassed = results.every((r) => r.success);
|
||||
const output = [
|
||||
`# Lint 检查报告`,
|
||||
``,
|
||||
`📂 项目: ${project_path}`,
|
||||
`${allPassed ? "✅ 全部通过" : "❌ 发现问题"} | 错误: ${totalErrors} | 警告: ${totalWarnings}`,
|
||||
``,
|
||||
];
|
||||
for (const r of results) {
|
||||
output.push(`## ${r.success ? "✅" : "❌"} ${r.tool}`, `错误: ${r.errorCount} | 警告: ${r.warningCount}`, "```", r.output.slice(0, 3000), // 限制输出长度
|
||||
"```", ``);
|
||||
}
|
||||
if (!allPassed && !fix) {
|
||||
output.push(`💡 提示: 可以设置 fix=true 自动修复可修复的问题`);
|
||||
}
|
||||
return output.join("\n");
|
||||
}
|
||||
//# sourceMappingURL=lintCheck.js.map
|
||||
Reference in New Issue
Block a user