jarvis-ai-assistant 0.1.193__py3-none-any.whl → 0.1.194__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of jarvis-ai-assistant might be problematic. Click here for more details.
- jarvis/__init__.py +1 -1
- jarvis/jarvis_agent/__init__.py +34 -41
- jarvis/jarvis_agent/builtin_input_handler.py +26 -4
- jarvis/jarvis_agent/jarvis.py +38 -22
- jarvis/jarvis_agent/main.py +20 -12
- jarvis/jarvis_agent/output_handler.py +7 -7
- jarvis/jarvis_agent/shell_input_handler.py +14 -11
- jarvis/jarvis_code_agent/code_agent.py +91 -85
- jarvis/jarvis_code_agent/lint.py +92 -105
- jarvis/jarvis_code_analysis/checklists/__init__.py +1 -1
- jarvis/jarvis_code_analysis/checklists/c_cpp.py +1 -1
- jarvis/jarvis_code_analysis/checklists/csharp.py +1 -1
- jarvis/jarvis_code_analysis/checklists/data_format.py +1 -1
- jarvis/jarvis_code_analysis/checklists/devops.py +1 -1
- jarvis/jarvis_code_analysis/checklists/docs.py +1 -1
- jarvis/jarvis_code_analysis/checklists/go.py +1 -1
- jarvis/jarvis_code_analysis/checklists/infrastructure.py +1 -1
- jarvis/jarvis_code_analysis/checklists/java.py +1 -1
- jarvis/jarvis_code_analysis/checklists/javascript.py +1 -1
- jarvis/jarvis_code_analysis/checklists/kotlin.py +1 -1
- jarvis/jarvis_code_analysis/checklists/loader.py +51 -35
- jarvis/jarvis_code_analysis/checklists/php.py +1 -1
- jarvis/jarvis_code_analysis/checklists/python.py +1 -1
- jarvis/jarvis_code_analysis/checklists/ruby.py +1 -1
- jarvis/jarvis_code_analysis/checklists/rust.py +1 -1
- jarvis/jarvis_code_analysis/checklists/shell.py +1 -1
- jarvis/jarvis_code_analysis/checklists/sql.py +1 -1
- jarvis/jarvis_code_analysis/checklists/swift.py +1 -1
- jarvis/jarvis_code_analysis/checklists/web.py +1 -1
- jarvis/jarvis_code_analysis/code_review.py +293 -192
- jarvis/jarvis_dev/main.py +73 -56
- jarvis/jarvis_git_details/main.py +29 -33
- jarvis/jarvis_git_squash/main.py +13 -11
- jarvis/jarvis_git_utils/git_commiter.py +12 -3
- jarvis/jarvis_mcp/__init__.py +8 -10
- jarvis/jarvis_mcp/sse_mcp_client.py +182 -205
- jarvis/jarvis_mcp/stdio_mcp_client.py +93 -120
- jarvis/jarvis_mcp/streamable_mcp_client.py +117 -142
- jarvis/jarvis_methodology/main.py +75 -41
- jarvis/jarvis_multi_agent/__init__.py +24 -16
- jarvis/jarvis_multi_agent/main.py +10 -4
- jarvis/jarvis_platform/__init__.py +1 -1
- jarvis/jarvis_platform/base.py +49 -21
- jarvis/jarvis_platform/human.py +5 -3
- jarvis/jarvis_platform/kimi.py +96 -72
- jarvis/jarvis_platform/openai.py +23 -28
- jarvis/jarvis_platform/registry.py +50 -33
- jarvis/jarvis_platform/tongyi.py +16 -10
- jarvis/jarvis_platform/yuanbao.py +197 -144
- jarvis/jarvis_platform_manager/main.py +4 -2
- jarvis/jarvis_smart_shell/main.py +35 -29
- jarvis/jarvis_tools/ask_user.py +8 -16
- jarvis/jarvis_tools/base.py +3 -2
- jarvis/jarvis_tools/chdir.py +7 -19
- jarvis/jarvis_tools/cli/main.py +14 -10
- jarvis/jarvis_tools/code_plan.py +10 -31
- jarvis/jarvis_tools/create_code_agent.py +10 -13
- jarvis/jarvis_tools/create_sub_agent.py +10 -22
- jarvis/jarvis_tools/edit_file.py +98 -76
- jarvis/jarvis_tools/execute_script.py +46 -46
- jarvis/jarvis_tools/file_analyzer.py +22 -34
- jarvis/jarvis_tools/file_operation.py +69 -62
- jarvis/jarvis_tools/generate_new_tool.py +0 -2
- jarvis/jarvis_tools/methodology.py +19 -23
- jarvis/jarvis_tools/read_code.py +35 -35
- jarvis/jarvis_tools/read_webpage.py +7 -16
- jarvis/jarvis_tools/registry.py +63 -30
- jarvis/jarvis_tools/rewrite_file.py +26 -29
- jarvis/jarvis_tools/search_web.py +5 -8
- jarvis/jarvis_tools/virtual_tty.py +133 -122
- jarvis/jarvis_utils/__init__.py +0 -1
- jarvis/jarvis_utils/builtin_replace_map.py +9 -9
- jarvis/jarvis_utils/config.py +59 -32
- jarvis/jarvis_utils/embedding.py +17 -14
- jarvis/jarvis_utils/file_processors.py +16 -9
- jarvis/jarvis_utils/git_utils.py +140 -99
- jarvis/jarvis_utils/globals.py +1 -1
- jarvis/jarvis_utils/input.py +84 -52
- jarvis/jarvis_utils/methodology.py +28 -21
- jarvis/jarvis_utils/output.py +159 -78
- jarvis/jarvis_utils/tag.py +2 -1
- jarvis/jarvis_utils/utils.py +85 -51
- {jarvis_ai_assistant-0.1.193.dist-info → jarvis_ai_assistant-0.1.194.dist-info}/METADATA +314 -230
- jarvis_ai_assistant-0.1.194.dist-info/RECORD +97 -0
- jarvis/jarvis_agent/file_input_handler.py +0 -112
- jarvis/jarvis_event/__init__.py +0 -0
- jarvis_ai_assistant-0.1.193.dist-info/RECORD +0 -99
- {jarvis_ai_assistant-0.1.193.dist-info → jarvis_ai_assistant-0.1.194.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.1.193.dist-info → jarvis_ai_assistant-0.1.194.dist-info}/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.1.193.dist-info → jarvis_ai_assistant-0.1.194.dist-info}/licenses/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.193.dist-info → jarvis_ai_assistant-0.1.194.dist-info}/top_level.txt +0 -0
|
@@ -10,27 +10,30 @@ import subprocess
|
|
|
10
10
|
import sys
|
|
11
11
|
from typing import List, Optional, Tuple
|
|
12
12
|
|
|
13
|
-
from yaspin import yaspin # type: ignore
|
|
14
|
-
|
|
15
|
-
from jarvis import __version__
|
|
16
13
|
from jarvis.jarvis_agent import Agent
|
|
17
14
|
from jarvis.jarvis_agent.builtin_input_handler import builtin_input_handler
|
|
18
|
-
from jarvis.jarvis_agent.file_input_handler import file_input_handler
|
|
19
15
|
from jarvis.jarvis_agent.shell_input_handler import shell_input_handler
|
|
16
|
+
|
|
20
17
|
# 忽略yaspin的类型检查
|
|
21
18
|
from jarvis.jarvis_code_agent.lint import get_lint_tools
|
|
22
19
|
from jarvis.jarvis_git_utils.git_commiter import GitCommitTool
|
|
23
20
|
from jarvis.jarvis_platform.registry import PlatformRegistry
|
|
24
21
|
from jarvis.jarvis_tools.registry import ToolRegistry
|
|
25
22
|
from jarvis.jarvis_utils.config import is_confirm_before_apply_patch
|
|
26
|
-
from jarvis.jarvis_utils.git_utils import (
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
23
|
+
from jarvis.jarvis_utils.git_utils import (
|
|
24
|
+
find_git_root,
|
|
25
|
+
get_commits_between,
|
|
26
|
+
get_diff,
|
|
27
|
+
get_diff_file_list,
|
|
28
|
+
get_latest_commit_hash,
|
|
29
|
+
get_recent_commits_with_files,
|
|
30
|
+
handle_commit_workflow,
|
|
31
|
+
has_uncommitted_changes,
|
|
32
|
+
)
|
|
31
33
|
from jarvis.jarvis_utils.input import get_multiline_input
|
|
32
34
|
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
33
35
|
from jarvis.jarvis_utils.utils import get_loc_stats, init_env, user_confirm
|
|
36
|
+
from yaspin import yaspin # type: ignore
|
|
34
37
|
|
|
35
38
|
|
|
36
39
|
class CodeAgent:
|
|
@@ -39,21 +42,26 @@ class CodeAgent:
|
|
|
39
42
|
负责处理代码分析、修改和git操作。
|
|
40
43
|
"""
|
|
41
44
|
|
|
42
|
-
def __init__(
|
|
43
|
-
|
|
44
|
-
|
|
45
|
+
def __init__(
|
|
46
|
+
self,
|
|
47
|
+
platform: Optional[str] = None,
|
|
48
|
+
model: Optional[str] = None,
|
|
49
|
+
need_summary: bool = True,
|
|
50
|
+
):
|
|
45
51
|
self.root_dir = os.getcwd()
|
|
46
52
|
tool_registry = ToolRegistry() # type: ignore
|
|
47
|
-
tool_registry.use_tools(
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
53
|
+
tool_registry.use_tools(
|
|
54
|
+
[
|
|
55
|
+
"execute_script",
|
|
56
|
+
"search_web",
|
|
57
|
+
"ask_user",
|
|
58
|
+
"read_code",
|
|
59
|
+
"methodology",
|
|
60
|
+
"chdir",
|
|
61
|
+
"edit_file",
|
|
62
|
+
"rewrite_file",
|
|
63
|
+
]
|
|
64
|
+
)
|
|
57
65
|
code_system_prompt = """
|
|
58
66
|
<code_engineer_guide>
|
|
59
67
|
## 角色定位
|
|
@@ -96,9 +104,11 @@ class CodeAgent:
|
|
|
96
104
|
</code_engineer_guide>
|
|
97
105
|
"""
|
|
98
106
|
# 处理platform参数
|
|
99
|
-
platform_instance = (
|
|
107
|
+
platform_instance = (
|
|
108
|
+
PlatformRegistry().create_platform(platform) # type: ignore
|
|
100
109
|
if platform
|
|
101
|
-
else PlatformRegistry().get_normal_platform()
|
|
110
|
+
else PlatformRegistry().get_normal_platform()
|
|
111
|
+
) # type: ignore
|
|
102
112
|
if model:
|
|
103
113
|
platform_instance.set_model_name(model) # type: ignore
|
|
104
114
|
|
|
@@ -108,26 +118,12 @@ class CodeAgent:
|
|
|
108
118
|
auto_complete=False,
|
|
109
119
|
output_handler=[tool_registry],
|
|
110
120
|
platform=platform_instance,
|
|
111
|
-
input_handler=[
|
|
112
|
-
|
|
113
|
-
builtin_input_handler
|
|
114
|
-
],
|
|
115
|
-
need_summary=need_summary
|
|
121
|
+
input_handler=[shell_input_handler, builtin_input_handler],
|
|
122
|
+
need_summary=need_summary,
|
|
116
123
|
)
|
|
117
124
|
|
|
118
125
|
self.agent.set_after_tool_call_cb(self.after_tool_call_cb)
|
|
119
126
|
|
|
120
|
-
def get_root_dir(self) -> str:
|
|
121
|
-
"""获取项目根目录
|
|
122
|
-
|
|
123
|
-
返回:
|
|
124
|
-
str: 项目根目录路径
|
|
125
|
-
"""
|
|
126
|
-
return self.root_dir
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
127
|
def _init_env(self) -> None:
|
|
132
128
|
"""初始化环境,包括:
|
|
133
129
|
1. 查找git根目录
|
|
@@ -153,33 +149,33 @@ class CodeAgent:
|
|
|
153
149
|
PrettyOutput.print("检测到未提交的修改,是否要提交?", OutputType.WARNING)
|
|
154
150
|
if user_confirm("是否要提交?", True):
|
|
155
151
|
import subprocess
|
|
152
|
+
|
|
156
153
|
try:
|
|
157
154
|
# 获取当前分支的提交总数
|
|
158
|
-
|
|
159
|
-
[
|
|
155
|
+
commit_result = subprocess.run(
|
|
156
|
+
["git", "rev-list", "--count", "HEAD"],
|
|
160
157
|
capture_output=True,
|
|
161
|
-
text=True
|
|
158
|
+
text=True,
|
|
159
|
+
check=True,
|
|
162
160
|
)
|
|
163
|
-
if
|
|
161
|
+
if commit_result.returncode != 0:
|
|
164
162
|
return
|
|
165
|
-
|
|
166
|
-
commit_count = int(
|
|
167
|
-
|
|
163
|
+
|
|
164
|
+
commit_count = int(commit_result.stdout.strip())
|
|
165
|
+
|
|
168
166
|
# 暂存所有修改
|
|
169
|
-
subprocess.run([
|
|
170
|
-
|
|
167
|
+
subprocess.run(["git", "add", "."], check=True)
|
|
168
|
+
|
|
171
169
|
# 提交变更
|
|
172
170
|
subprocess.run(
|
|
173
|
-
[
|
|
174
|
-
check=True
|
|
171
|
+
["git", "commit", "-m", f"CheckPoint #{commit_count + 1}"],
|
|
172
|
+
check=True,
|
|
175
173
|
)
|
|
176
174
|
except subprocess.CalledProcessError as e:
|
|
177
175
|
PrettyOutput.print(f"提交失败: {str(e)}", OutputType.ERROR)
|
|
178
176
|
|
|
179
177
|
def _show_commit_history(
|
|
180
|
-
self,
|
|
181
|
-
start_commit: Optional[str],
|
|
182
|
-
end_commit: Optional[str]
|
|
178
|
+
self, start_commit: Optional[str], end_commit: Optional[str]
|
|
183
179
|
) -> List[Tuple[str, str]]:
|
|
184
180
|
"""显示两个提交之间的提交历史
|
|
185
181
|
|
|
@@ -196,20 +192,14 @@ class CodeAgent:
|
|
|
196
192
|
commits = []
|
|
197
193
|
|
|
198
194
|
if commits:
|
|
199
|
-
commit_messages = (
|
|
200
|
-
"
|
|
201
|
-
"\n".join(
|
|
202
|
-
f"- {commit_hash[:7]}: {message}"
|
|
203
|
-
for commit_hash, message in commits
|
|
204
|
-
)
|
|
195
|
+
commit_messages = "检测到以下提交记录:\n" + "\n".join(
|
|
196
|
+
f"- {commit_hash[:7]}: {message}" for commit_hash, message in commits
|
|
205
197
|
)
|
|
206
198
|
PrettyOutput.print(commit_messages, OutputType.INFO)
|
|
207
199
|
return commits
|
|
208
200
|
|
|
209
201
|
def _handle_commit_confirmation(
|
|
210
|
-
self,
|
|
211
|
-
commits: List[Tuple[str, str]],
|
|
212
|
-
start_commit: Optional[str]
|
|
202
|
+
self, commits: List[Tuple[str, str]], start_commit: Optional[str]
|
|
213
203
|
) -> None:
|
|
214
204
|
"""处理提交确认和可能的重置"""
|
|
215
205
|
if commits and user_confirm("是否接受以上提交记录?", True):
|
|
@@ -217,7 +207,7 @@ class CodeAgent:
|
|
|
217
207
|
["git", "reset", "--mixed", str(start_commit)],
|
|
218
208
|
stdout=subprocess.DEVNULL,
|
|
219
209
|
stderr=subprocess.DEVNULL,
|
|
220
|
-
check=True
|
|
210
|
+
check=True,
|
|
221
211
|
)
|
|
222
212
|
git_commiter = GitCommitTool()
|
|
223
213
|
git_commiter.execute({})
|
|
@@ -241,15 +231,15 @@ class CodeAgent:
|
|
|
241
231
|
# 获取项目统计信息并附加到用户输入
|
|
242
232
|
loc_stats = get_loc_stats()
|
|
243
233
|
commits_info = get_recent_commits_with_files()
|
|
244
|
-
|
|
234
|
+
|
|
245
235
|
project_info = []
|
|
246
236
|
if loc_stats:
|
|
247
237
|
project_info.append(f"代码统计:\n{loc_stats}")
|
|
248
238
|
if commits_info:
|
|
249
239
|
commits_str = "\n".join(
|
|
250
|
-
f"提交 {i+1}: {commit['hash'][:7]} - {commit['message']} ({len(commit['files'])}个文件)\n"
|
|
251
|
-
"\n".join(f" - {file}" for file in commit[
|
|
252
|
-
("\n ..." if len(commit[
|
|
240
|
+
f"提交 {i+1}: {commit['hash'][:7]} - {commit['message']} ({len(commit['files'])}个文件)\n"
|
|
241
|
+
+ "\n".join(f" - {file}" for file in commit["files"][:5])
|
|
242
|
+
+ ("\n ..." if len(commit["files"]) > 5 else "")
|
|
253
243
|
for i, commit in enumerate(commits_info)
|
|
254
244
|
)
|
|
255
245
|
project_info.append(f"最近提交:\n{commits_str}")
|
|
@@ -264,7 +254,14 @@ class CodeAgent:
|
|
|
264
254
|
"""
|
|
265
255
|
|
|
266
256
|
if project_info:
|
|
267
|
-
enhanced_input =
|
|
257
|
+
enhanced_input = (
|
|
258
|
+
f"项目概况:\n"
|
|
259
|
+
+ "\n\n".join(project_info)
|
|
260
|
+
+ "\n\n"
|
|
261
|
+
+ first_tip
|
|
262
|
+
+ "\n\n任务描述:\n"
|
|
263
|
+
+ user_input
|
|
264
|
+
)
|
|
268
265
|
else:
|
|
269
266
|
enhanced_input = first_tip + "\n\n任务描述:\n" + user_input
|
|
270
267
|
|
|
@@ -282,7 +279,7 @@ class CodeAgent:
|
|
|
282
279
|
|
|
283
280
|
except RuntimeError as e:
|
|
284
281
|
return f"Error during execution: {str(e)}"
|
|
285
|
-
|
|
282
|
+
|
|
286
283
|
def after_tool_call_cb(self, agent: Agent) -> None:
|
|
287
284
|
"""工具调用后回调函数。"""
|
|
288
285
|
final_ret = ""
|
|
@@ -290,6 +287,7 @@ class CodeAgent:
|
|
|
290
287
|
if diff:
|
|
291
288
|
start_hash = get_latest_commit_hash()
|
|
292
289
|
PrettyOutput.print(diff, OutputType.CODE, lang="diff")
|
|
290
|
+
modified_files = get_diff_file_list()
|
|
293
291
|
commited = handle_commit_workflow()
|
|
294
292
|
if commited:
|
|
295
293
|
# 获取提交信息
|
|
@@ -298,16 +296,21 @@ class CodeAgent:
|
|
|
298
296
|
|
|
299
297
|
# 添加提交信息到final_ret
|
|
300
298
|
if commits:
|
|
301
|
-
final_ret +=
|
|
302
|
-
|
|
299
|
+
final_ret += (
|
|
300
|
+
f"\n\n代码已修改完成\n补丁内容:\n```diff\n{diff}\n```\n"
|
|
301
|
+
)
|
|
303
302
|
# 修改后的提示逻辑
|
|
304
303
|
lint_tools_info = "\n".join(
|
|
305
304
|
f" - {file}: 使用 {'、'.join(get_lint_tools(file))}"
|
|
306
|
-
for file in modified_files
|
|
305
|
+
for file in modified_files
|
|
307
306
|
if get_lint_tools(file)
|
|
308
307
|
)
|
|
309
308
|
file_list = "\n".join(f" - {file}" for file in modified_files)
|
|
310
|
-
tool_info =
|
|
309
|
+
tool_info = (
|
|
310
|
+
f"建议使用以下lint工具进行检查:\n{lint_tools_info}"
|
|
311
|
+
if lint_tools_info
|
|
312
|
+
else ""
|
|
313
|
+
)
|
|
311
314
|
if lint_tools_info:
|
|
312
315
|
addon_prompt = f"""
|
|
313
316
|
请对以下修改的文件进行静态扫描:
|
|
@@ -328,7 +331,9 @@ class CodeAgent:
|
|
|
328
331
|
agent.prompt += final_ret
|
|
329
332
|
return
|
|
330
333
|
PrettyOutput.print(final_ret, OutputType.USER, lang="markdown")
|
|
331
|
-
if not is_confirm_before_apply_patch() or user_confirm(
|
|
334
|
+
if not is_confirm_before_apply_patch() or user_confirm(
|
|
335
|
+
"是否使用此回复?", default=True
|
|
336
|
+
):
|
|
332
337
|
agent.prompt += final_ret
|
|
333
338
|
return
|
|
334
339
|
agent.prompt += final_ret
|
|
@@ -342,13 +347,16 @@ def main() -> None:
|
|
|
342
347
|
"""Jarvis主入口点。"""
|
|
343
348
|
init_env("欢迎使用 Jarvis-CodeAgent,您的代码工程助手已准备就绪!")
|
|
344
349
|
|
|
345
|
-
parser = argparse.ArgumentParser(description=
|
|
346
|
-
parser.add_argument(
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
350
|
+
parser = argparse.ArgumentParser(description="Jarvis Code Agent")
|
|
351
|
+
parser.add_argument(
|
|
352
|
+
"-p", "--platform", type=str, help="Target platform name", default=None
|
|
353
|
+
)
|
|
354
|
+
parser.add_argument(
|
|
355
|
+
"-m", "--model", type=str, help="Model name to use", default=None
|
|
356
|
+
)
|
|
357
|
+
parser.add_argument(
|
|
358
|
+
"-r", "--requirement", type=str, help="Requirement to process", default=None
|
|
359
|
+
)
|
|
352
360
|
args = parser.parse_args()
|
|
353
361
|
|
|
354
362
|
curr_dir = os.getcwd()
|
|
@@ -362,9 +370,7 @@ def main() -> None:
|
|
|
362
370
|
user_input = get_multiline_input("请输入你的需求(输入空行退出):")
|
|
363
371
|
if not user_input:
|
|
364
372
|
sys.exit(0)
|
|
365
|
-
agent = CodeAgent(platform=args.platform,
|
|
366
|
-
model=args.model,
|
|
367
|
-
need_summary=False)
|
|
373
|
+
agent = CodeAgent(platform=args.platform, model=args.model, need_summary=False)
|
|
368
374
|
agent.run(user_input)
|
|
369
375
|
|
|
370
376
|
except RuntimeError as e:
|
jarvis/jarvis_code_agent/lint.py
CHANGED
|
@@ -15,144 +15,131 @@ from jarvis.jarvis_utils.config import get_data_dir
|
|
|
15
15
|
# 默认的lint工具配置
|
|
16
16
|
LINT_TOOLS = {
|
|
17
17
|
# C/C++
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
18
|
+
".c": ["clang-tidy"],
|
|
19
|
+
".cpp": ["clang-tidy"],
|
|
20
|
+
".cc": ["clang-tidy"],
|
|
21
|
+
".cxx": ["clang-tidy"],
|
|
22
|
+
".h": ["clang-tidy"],
|
|
23
|
+
".hpp": ["clang-tidy"],
|
|
24
|
+
".hxx": ["clang-tidy"],
|
|
25
|
+
".inl": ["clang-tidy"],
|
|
26
|
+
".ipp": ["clang-tidy"],
|
|
28
27
|
# Go
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
".go": ["go vet"],
|
|
31
29
|
# Python
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
30
|
+
".py": ["black", "pylint", "mypy", "isort"],
|
|
31
|
+
".pyw": ["black", "pylint", "mypy", "isort"],
|
|
32
|
+
".pyi": ["black", "pylint", "mypy", "isort"],
|
|
33
|
+
".pyx": ["black", "pylint", "mypy", "isort"],
|
|
34
|
+
".pxd": ["black", "pylint", "mypy", "isort"],
|
|
38
35
|
# Rust
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
36
|
+
".rs": ["cargo clippy", "rustfmt"],
|
|
37
|
+
".rlib": ["cargo clippy", "rustfmt"],
|
|
42
38
|
# Java
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
39
|
+
".java": ["pmd"],
|
|
40
|
+
".class": ["pmd"],
|
|
41
|
+
".jar": ["pmd"],
|
|
47
42
|
# JavaScript/TypeScript
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
43
|
+
".js": ["eslint"],
|
|
44
|
+
".mjs": ["eslint"],
|
|
45
|
+
".cjs": ["eslint"],
|
|
46
|
+
".jsx": ["eslint"],
|
|
47
|
+
".ts": ["eslint", "tsc"],
|
|
48
|
+
".tsx": ["eslint", "tsc"],
|
|
49
|
+
".cts": ["eslint", "tsc"],
|
|
50
|
+
".mts": ["eslint", "tsc"],
|
|
57
51
|
# PHP
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
52
|
+
".php": ["phpstan"],
|
|
53
|
+
".phtml": ["phpstan"],
|
|
54
|
+
".php5": ["phpstan"],
|
|
55
|
+
".php7": ["phpstan"],
|
|
56
|
+
".phps": ["phpstan"],
|
|
64
57
|
# Ruby
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
58
|
+
".rb": ["rubocop"],
|
|
59
|
+
".rake": ["rubocop"],
|
|
60
|
+
".gemspec": ["rubocop"],
|
|
69
61
|
# Swift
|
|
70
|
-
|
|
71
|
-
|
|
62
|
+
".swift": ["swiftlint"],
|
|
72
63
|
# Kotlin
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
64
|
+
".kt": ["ktlint"],
|
|
65
|
+
".kts": ["ktlint"],
|
|
76
66
|
# C#
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
67
|
+
".cs": ["roslynator"],
|
|
68
|
+
".csx": ["roslynator"],
|
|
80
69
|
# SQL
|
|
81
|
-
|
|
82
|
-
|
|
70
|
+
".sql": ["sqlfluff"],
|
|
83
71
|
# Shell/Bash
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
72
|
+
".sh": ["shellcheck"],
|
|
73
|
+
".bash": ["shellcheck"],
|
|
87
74
|
# HTML/CSS
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
75
|
+
".html": ["htmlhint"],
|
|
76
|
+
".htm": ["htmlhint"],
|
|
77
|
+
".xhtml": ["htmlhint"],
|
|
78
|
+
".css": ["stylelint"],
|
|
79
|
+
".scss": ["stylelint"],
|
|
80
|
+
".sass": ["stylelint"],
|
|
81
|
+
".less": ["stylelint"],
|
|
96
82
|
# XML/JSON/YAML
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
83
|
+
".xml": ["xmllint"],
|
|
84
|
+
".xsd": ["xmllint"],
|
|
85
|
+
".dtd": ["xmllint"],
|
|
86
|
+
".tld": ["xmllint"],
|
|
87
|
+
".jsp": ["xmllint"],
|
|
88
|
+
".jspx": ["xmllint"],
|
|
89
|
+
".tag": ["xmllint"],
|
|
90
|
+
".tagx": ["xmllint"],
|
|
91
|
+
".json": ["jsonlint"],
|
|
92
|
+
".jsonl": ["jsonlint"],
|
|
93
|
+
".json5": ["jsonlint"],
|
|
94
|
+
".yaml": ["yamllint"],
|
|
95
|
+
".yml": ["yamllint"],
|
|
111
96
|
# Markdown/Documentation
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
97
|
+
".md": ["markdownlint"],
|
|
98
|
+
".markdown": ["markdownlint"],
|
|
99
|
+
".rst": ["rstcheck"],
|
|
100
|
+
".adoc": ["asciidoctor-lint"],
|
|
117
101
|
# Docker/Terraform/Makefile等无后缀文件
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
102
|
+
"makefile": ["checkmake"],
|
|
103
|
+
"dockerfile": ["hadolint"],
|
|
104
|
+
"docker-compose.yml": ["hadolint"],
|
|
105
|
+
"docker-compose.yaml": ["hadolint"],
|
|
106
|
+
"jenkinsfile": ["jenkinsfile-linter"],
|
|
107
|
+
"build": ["buildifier"],
|
|
108
|
+
"workspace": ["buildifier"],
|
|
109
|
+
".bashrc": ["shellcheck"],
|
|
110
|
+
".bash_profile": ["shellcheck"],
|
|
111
|
+
".zshrc": ["shellcheck"],
|
|
112
|
+
".gitignore": ["git-lint"],
|
|
113
|
+
".editorconfig": ["editorconfig-checker"],
|
|
114
|
+
".eslintrc": ["eslint"],
|
|
115
|
+
".prettierrc": ["prettier"],
|
|
116
|
+
"cmakelists.txt": ["cmake-format"],
|
|
117
|
+
".cmake": ["cmake-format"],
|
|
134
118
|
}
|
|
135
119
|
|
|
120
|
+
|
|
136
121
|
def load_lint_tools_config() -> Dict[str, List[str]]:
|
|
137
122
|
"""从yaml文件加载lint工具配置"""
|
|
138
|
-
config_path = os.path.join(get_data_dir(),
|
|
123
|
+
config_path = os.path.join(get_data_dir(), "lint_tools.yaml")
|
|
139
124
|
if not os.path.exists(config_path):
|
|
140
125
|
return {}
|
|
141
|
-
|
|
142
|
-
with open(config_path,
|
|
126
|
+
|
|
127
|
+
with open(config_path, "r") as f:
|
|
143
128
|
config = yaml.safe_load(f) or {}
|
|
144
129
|
return {k.lower(): v for k, v in config.items()} # 确保key是小写
|
|
145
130
|
|
|
131
|
+
|
|
146
132
|
# 合并默认配置和yaml配置
|
|
147
133
|
LINT_TOOLS.update(load_lint_tools_config())
|
|
148
134
|
|
|
135
|
+
|
|
149
136
|
def get_lint_tools(filename: str) -> List[str]:
|
|
150
137
|
"""
|
|
151
138
|
根据文件扩展名或文件名获取对应的lint工具列表
|
|
152
|
-
|
|
139
|
+
|
|
153
140
|
Args:
|
|
154
141
|
file_extension_or_name: 文件扩展名(如'.py')或文件名(如'Makefile')
|
|
155
|
-
|
|
142
|
+
|
|
156
143
|
Returns:
|
|
157
144
|
对应的lint工具列表,如果找不到则返回空列表
|
|
158
145
|
"""
|