jarvis-ai-assistant 0.3.30__py3-none-any.whl → 0.7.6__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.
Files changed (181) hide show
  1. jarvis/__init__.py +1 -1
  2. jarvis/jarvis_agent/__init__.py +458 -152
  3. jarvis/jarvis_agent/agent_manager.py +17 -13
  4. jarvis/jarvis_agent/builtin_input_handler.py +2 -6
  5. jarvis/jarvis_agent/config_editor.py +2 -7
  6. jarvis/jarvis_agent/event_bus.py +82 -12
  7. jarvis/jarvis_agent/file_context_handler.py +329 -0
  8. jarvis/jarvis_agent/file_methodology_manager.py +3 -4
  9. jarvis/jarvis_agent/jarvis.py +628 -55
  10. jarvis/jarvis_agent/language_extractors/__init__.py +57 -0
  11. jarvis/jarvis_agent/language_extractors/c_extractor.py +21 -0
  12. jarvis/jarvis_agent/language_extractors/cpp_extractor.py +21 -0
  13. jarvis/jarvis_agent/language_extractors/go_extractor.py +21 -0
  14. jarvis/jarvis_agent/language_extractors/java_extractor.py +84 -0
  15. jarvis/jarvis_agent/language_extractors/javascript_extractor.py +79 -0
  16. jarvis/jarvis_agent/language_extractors/python_extractor.py +21 -0
  17. jarvis/jarvis_agent/language_extractors/rust_extractor.py +21 -0
  18. jarvis/jarvis_agent/language_extractors/typescript_extractor.py +84 -0
  19. jarvis/jarvis_agent/language_support_info.py +486 -0
  20. jarvis/jarvis_agent/main.py +34 -10
  21. jarvis/jarvis_agent/memory_manager.py +7 -16
  22. jarvis/jarvis_agent/methodology_share_manager.py +10 -16
  23. jarvis/jarvis_agent/prompt_manager.py +1 -1
  24. jarvis/jarvis_agent/prompts.py +193 -171
  25. jarvis/jarvis_agent/protocols.py +8 -12
  26. jarvis/jarvis_agent/run_loop.py +105 -9
  27. jarvis/jarvis_agent/session_manager.py +2 -3
  28. jarvis/jarvis_agent/share_manager.py +20 -22
  29. jarvis/jarvis_agent/shell_input_handler.py +1 -2
  30. jarvis/jarvis_agent/stdio_redirect.py +295 -0
  31. jarvis/jarvis_agent/task_analyzer.py +31 -6
  32. jarvis/jarvis_agent/task_manager.py +11 -27
  33. jarvis/jarvis_agent/tool_executor.py +2 -3
  34. jarvis/jarvis_agent/tool_share_manager.py +12 -24
  35. jarvis/jarvis_agent/utils.py +5 -1
  36. jarvis/jarvis_agent/web_bridge.py +189 -0
  37. jarvis/jarvis_agent/web_output_sink.py +53 -0
  38. jarvis/jarvis_agent/web_server.py +786 -0
  39. jarvis/jarvis_c2rust/__init__.py +26 -0
  40. jarvis/jarvis_c2rust/cli.py +575 -0
  41. jarvis/jarvis_c2rust/collector.py +250 -0
  42. jarvis/jarvis_c2rust/constants.py +26 -0
  43. jarvis/jarvis_c2rust/library_replacer.py +1254 -0
  44. jarvis/jarvis_c2rust/llm_module_agent.py +1272 -0
  45. jarvis/jarvis_c2rust/loaders.py +207 -0
  46. jarvis/jarvis_c2rust/models.py +28 -0
  47. jarvis/jarvis_c2rust/optimizer.py +2157 -0
  48. jarvis/jarvis_c2rust/scanner.py +1681 -0
  49. jarvis/jarvis_c2rust/transpiler.py +2983 -0
  50. jarvis/jarvis_c2rust/utils.py +385 -0
  51. jarvis/jarvis_code_agent/build_validation_config.py +132 -0
  52. jarvis/jarvis_code_agent/code_agent.py +1371 -220
  53. jarvis/jarvis_code_agent/code_analyzer/__init__.py +65 -0
  54. jarvis/jarvis_code_agent/code_analyzer/base_language.py +74 -0
  55. jarvis/jarvis_code_agent/code_analyzer/build_validator/__init__.py +44 -0
  56. jarvis/jarvis_code_agent/code_analyzer/build_validator/base.py +106 -0
  57. jarvis/jarvis_code_agent/code_analyzer/build_validator/cmake.py +74 -0
  58. jarvis/jarvis_code_agent/code_analyzer/build_validator/detector.py +125 -0
  59. jarvis/jarvis_code_agent/code_analyzer/build_validator/fallback.py +72 -0
  60. jarvis/jarvis_code_agent/code_analyzer/build_validator/go.py +70 -0
  61. jarvis/jarvis_code_agent/code_analyzer/build_validator/java_gradle.py +53 -0
  62. jarvis/jarvis_code_agent/code_analyzer/build_validator/java_maven.py +47 -0
  63. jarvis/jarvis_code_agent/code_analyzer/build_validator/makefile.py +61 -0
  64. jarvis/jarvis_code_agent/code_analyzer/build_validator/nodejs.py +110 -0
  65. jarvis/jarvis_code_agent/code_analyzer/build_validator/python.py +154 -0
  66. jarvis/jarvis_code_agent/code_analyzer/build_validator/rust.py +110 -0
  67. jarvis/jarvis_code_agent/code_analyzer/build_validator/validator.py +153 -0
  68. jarvis/jarvis_code_agent/code_analyzer/build_validator.py +43 -0
  69. jarvis/jarvis_code_agent/code_analyzer/context_manager.py +648 -0
  70. jarvis/jarvis_code_agent/code_analyzer/context_recommender.py +18 -0
  71. jarvis/jarvis_code_agent/code_analyzer/dependency_analyzer.py +132 -0
  72. jarvis/jarvis_code_agent/code_analyzer/file_ignore.py +330 -0
  73. jarvis/jarvis_code_agent/code_analyzer/impact_analyzer.py +781 -0
  74. jarvis/jarvis_code_agent/code_analyzer/language_registry.py +185 -0
  75. jarvis/jarvis_code_agent/code_analyzer/language_support.py +110 -0
  76. jarvis/jarvis_code_agent/code_analyzer/languages/__init__.py +49 -0
  77. jarvis/jarvis_code_agent/code_analyzer/languages/c_cpp_language.py +299 -0
  78. jarvis/jarvis_code_agent/code_analyzer/languages/go_language.py +215 -0
  79. jarvis/jarvis_code_agent/code_analyzer/languages/java_language.py +212 -0
  80. jarvis/jarvis_code_agent/code_analyzer/languages/javascript_language.py +254 -0
  81. jarvis/jarvis_code_agent/code_analyzer/languages/python_language.py +269 -0
  82. jarvis/jarvis_code_agent/code_analyzer/languages/rust_language.py +281 -0
  83. jarvis/jarvis_code_agent/code_analyzer/languages/typescript_language.py +280 -0
  84. jarvis/jarvis_code_agent/code_analyzer/llm_context_recommender.py +605 -0
  85. jarvis/jarvis_code_agent/code_analyzer/structured_code.py +556 -0
  86. jarvis/jarvis_code_agent/code_analyzer/symbol_extractor.py +252 -0
  87. jarvis/jarvis_code_agent/code_analyzer/tree_sitter_extractor.py +58 -0
  88. jarvis/jarvis_code_agent/lint.py +501 -8
  89. jarvis/jarvis_code_agent/utils.py +141 -0
  90. jarvis/jarvis_code_analysis/code_review.py +493 -584
  91. jarvis/jarvis_data/config_schema.json +128 -12
  92. jarvis/jarvis_git_squash/main.py +4 -5
  93. jarvis/jarvis_git_utils/git_commiter.py +82 -75
  94. jarvis/jarvis_mcp/sse_mcp_client.py +22 -29
  95. jarvis/jarvis_mcp/stdio_mcp_client.py +12 -13
  96. jarvis/jarvis_mcp/streamable_mcp_client.py +15 -14
  97. jarvis/jarvis_memory_organizer/memory_organizer.py +55 -74
  98. jarvis/jarvis_methodology/main.py +32 -48
  99. jarvis/jarvis_multi_agent/__init__.py +287 -55
  100. jarvis/jarvis_multi_agent/main.py +36 -4
  101. jarvis/jarvis_platform/base.py +524 -202
  102. jarvis/jarvis_platform/human.py +7 -8
  103. jarvis/jarvis_platform/kimi.py +30 -36
  104. jarvis/jarvis_platform/openai.py +88 -25
  105. jarvis/jarvis_platform/registry.py +26 -10
  106. jarvis/jarvis_platform/tongyi.py +24 -25
  107. jarvis/jarvis_platform/yuanbao.py +32 -43
  108. jarvis/jarvis_platform_manager/main.py +66 -77
  109. jarvis/jarvis_platform_manager/service.py +8 -13
  110. jarvis/jarvis_rag/cli.py +53 -55
  111. jarvis/jarvis_rag/embedding_manager.py +13 -18
  112. jarvis/jarvis_rag/llm_interface.py +8 -9
  113. jarvis/jarvis_rag/query_rewriter.py +10 -21
  114. jarvis/jarvis_rag/rag_pipeline.py +24 -27
  115. jarvis/jarvis_rag/reranker.py +4 -5
  116. jarvis/jarvis_rag/retriever.py +28 -30
  117. jarvis/jarvis_sec/__init__.py +305 -0
  118. jarvis/jarvis_sec/agents.py +143 -0
  119. jarvis/jarvis_sec/analysis.py +276 -0
  120. jarvis/jarvis_sec/checkers/__init__.py +32 -0
  121. jarvis/jarvis_sec/checkers/c_checker.py +2680 -0
  122. jarvis/jarvis_sec/checkers/rust_checker.py +1108 -0
  123. jarvis/jarvis_sec/cli.py +139 -0
  124. jarvis/jarvis_sec/clustering.py +1439 -0
  125. jarvis/jarvis_sec/file_manager.py +427 -0
  126. jarvis/jarvis_sec/parsers.py +73 -0
  127. jarvis/jarvis_sec/prompts.py +268 -0
  128. jarvis/jarvis_sec/report.py +336 -0
  129. jarvis/jarvis_sec/review.py +453 -0
  130. jarvis/jarvis_sec/status.py +264 -0
  131. jarvis/jarvis_sec/types.py +20 -0
  132. jarvis/jarvis_sec/utils.py +499 -0
  133. jarvis/jarvis_sec/verification.py +848 -0
  134. jarvis/jarvis_sec/workflow.py +226 -0
  135. jarvis/jarvis_smart_shell/main.py +38 -87
  136. jarvis/jarvis_stats/cli.py +2 -2
  137. jarvis/jarvis_stats/stats.py +8 -8
  138. jarvis/jarvis_stats/storage.py +15 -21
  139. jarvis/jarvis_stats/visualizer.py +1 -1
  140. jarvis/jarvis_tools/clear_memory.py +3 -20
  141. jarvis/jarvis_tools/cli/main.py +21 -23
  142. jarvis/jarvis_tools/edit_file.py +1019 -132
  143. jarvis/jarvis_tools/execute_script.py +83 -25
  144. jarvis/jarvis_tools/file_analyzer.py +6 -9
  145. jarvis/jarvis_tools/generate_new_tool.py +14 -21
  146. jarvis/jarvis_tools/lsp_client.py +1552 -0
  147. jarvis/jarvis_tools/methodology.py +2 -3
  148. jarvis/jarvis_tools/read_code.py +1736 -35
  149. jarvis/jarvis_tools/read_symbols.py +140 -0
  150. jarvis/jarvis_tools/read_webpage.py +12 -13
  151. jarvis/jarvis_tools/registry.py +427 -200
  152. jarvis/jarvis_tools/retrieve_memory.py +20 -19
  153. jarvis/jarvis_tools/rewrite_file.py +72 -158
  154. jarvis/jarvis_tools/save_memory.py +3 -15
  155. jarvis/jarvis_tools/search_web.py +18 -18
  156. jarvis/jarvis_tools/sub_agent.py +36 -43
  157. jarvis/jarvis_tools/sub_code_agent.py +25 -26
  158. jarvis/jarvis_tools/virtual_tty.py +55 -33
  159. jarvis/jarvis_utils/clipboard.py +7 -10
  160. jarvis/jarvis_utils/config.py +232 -45
  161. jarvis/jarvis_utils/embedding.py +8 -5
  162. jarvis/jarvis_utils/fzf.py +8 -8
  163. jarvis/jarvis_utils/git_utils.py +225 -36
  164. jarvis/jarvis_utils/globals.py +3 -3
  165. jarvis/jarvis_utils/http.py +1 -1
  166. jarvis/jarvis_utils/input.py +99 -48
  167. jarvis/jarvis_utils/jsonnet_compat.py +465 -0
  168. jarvis/jarvis_utils/methodology.py +52 -48
  169. jarvis/jarvis_utils/utils.py +819 -491
  170. jarvis_ai_assistant-0.7.6.dist-info/METADATA +600 -0
  171. jarvis_ai_assistant-0.7.6.dist-info/RECORD +218 -0
  172. {jarvis_ai_assistant-0.3.30.dist-info → jarvis_ai_assistant-0.7.6.dist-info}/entry_points.txt +4 -0
  173. jarvis/jarvis_agent/config.py +0 -92
  174. jarvis/jarvis_agent/edit_file_handler.py +0 -296
  175. jarvis/jarvis_platform/ai8.py +0 -332
  176. jarvis/jarvis_tools/ask_user.py +0 -54
  177. jarvis_ai_assistant-0.3.30.dist-info/METADATA +0 -381
  178. jarvis_ai_assistant-0.3.30.dist-info/RECORD +0 -137
  179. {jarvis_ai_assistant-0.3.30.dist-info → jarvis_ai_assistant-0.7.6.dist-info}/WHEEL +0 -0
  180. {jarvis_ai_assistant-0.3.30.dist-info → jarvis_ai_assistant-0.7.6.dist-info}/licenses/LICENSE +0 -0
  181. {jarvis_ai_assistant-0.3.30.dist-info → jarvis_ai_assistant-0.7.6.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,132 @@
1
+ """依赖分析器基础模块。
2
+
3
+ 提供依赖分析的基础类和接口,具体语言的实现应在各自的语言支持模块中。
4
+ """
5
+
6
+ import os
7
+ from dataclasses import dataclass
8
+ from typing import Dict, List, Set, Optional
9
+
10
+ from .file_ignore import filter_walk_dirs
11
+
12
+ @dataclass
13
+ class Dependency:
14
+ """Represents an import dependency."""
15
+ from_module: str
16
+ imported_symbol: Optional[str] = None # None means import entire module
17
+ file_path: str = ""
18
+ line: int = 0
19
+
20
+ class DependencyGraph:
21
+ """Represents the dependency graph of a project."""
22
+
23
+ def __init__(self):
24
+ # file_path -> set of file_paths it depends on
25
+ self.dependencies: Dict[str, Set[str]] = {}
26
+ # file_path -> set of file_paths that depend on it
27
+ self.dependents: Dict[str, Set[str]] = {}
28
+
29
+ def add_dependency(self, file_path: str, dependency_path: str):
30
+ """Adds a dependency from file_path to dependency_path."""
31
+ if file_path not in self.dependencies:
32
+ self.dependencies[file_path] = set()
33
+ self.dependencies[file_path].add(dependency_path)
34
+
35
+ if dependency_path not in self.dependents:
36
+ self.dependents[dependency_path] = set()
37
+ self.dependents[dependency_path].add(file_path)
38
+
39
+ def get_dependencies(self, file_path: str) -> List[str]:
40
+ """Gets the list of files that file_path depends on."""
41
+ return list(self.dependencies.get(file_path, set()))
42
+
43
+ def get_dependents(self, file_path: str) -> List[str]:
44
+ """Gets the list of files that depend on file_path."""
45
+ return list(self.dependents.get(file_path, set()))
46
+
47
+ def clear_file_dependencies(self, file_path: str):
48
+ """Removes all dependency information for a specific file."""
49
+ if file_path in self.dependencies:
50
+ # Remove this file's dependencies on others
51
+ deps_to_remove = self.dependencies.pop(file_path)
52
+ for dep in deps_to_remove:
53
+ if dep in self.dependents and file_path in self.dependents[dep]:
54
+ self.dependents[dep].remove(file_path)
55
+ if not self.dependents[dep]:
56
+ del self.dependents[dep]
57
+
58
+ # Remove other files' dependencies on this file
59
+ if file_path in self.dependents:
60
+ dependents_to_remove = self.dependents.pop(file_path)
61
+ for dep_file in dependents_to_remove:
62
+ if dep_file in self.dependencies and file_path in self.dependencies[dep_file]:
63
+ self.dependencies[dep_file].remove(file_path)
64
+ if not self.dependencies[dep_file]:
65
+ del self.dependencies[dep_file]
66
+
67
+
68
+ class DependencyAnalyzer:
69
+ """Analyzes import dependencies in a source code file.
70
+
71
+ 这是依赖分析器的基类,具体语言的实现应该在各自的语言支持模块中。
72
+ 例如:PythonDependencyAnalyzer 在 languages/python_language.py 中。
73
+ """
74
+
75
+ def analyze_imports(self, file_path: str, content: str) -> List[Dependency]:
76
+ """
77
+ Analyzes the import statements in the code.
78
+ This method should be implemented by language-specific subclasses.
79
+
80
+ Args:
81
+ file_path: 文件路径
82
+ content: 文件内容
83
+
84
+ Returns:
85
+ 依赖列表
86
+ """
87
+ raise NotImplementedError("Subclasses must implement this method.")
88
+
89
+ def build_dependency_graph(self, project_root: str) -> DependencyGraph:
90
+ """
91
+ Builds a dependency graph for the entire project.
92
+ This would involve iterating over all source files.
93
+
94
+ Args:
95
+ project_root: 项目根目录
96
+
97
+ Returns:
98
+ 依赖图
99
+ """
100
+ graph = DependencyGraph()
101
+
102
+ # Walk through all source files in the project
103
+ for root, dirs, files in os.walk(project_root):
104
+ # Skip hidden directories and common ignore patterns
105
+ dirs[:] = filter_walk_dirs(dirs)
106
+
107
+ for file in files:
108
+ file_path = os.path.join(root, file)
109
+ if not self._is_source_file(file_path):
110
+ continue
111
+
112
+ try:
113
+ with open(file_path, 'r', encoding='utf-8', errors='replace') as f:
114
+ content = f.read()
115
+
116
+ dependencies = self.analyze_imports(file_path, content)
117
+ for dep in dependencies:
118
+ # Resolve dependency path (this should be done by language-specific analyzer)
119
+ # For now, we'll just store the module name
120
+ pass
121
+ except Exception:
122
+ # Skip files that can't be read or parsed
123
+ continue
124
+
125
+ return graph
126
+
127
+ def _is_source_file(self, file_path: str) -> bool:
128
+ """Check if a file is a source file that should be analyzed.
129
+
130
+ This should be overridden by subclasses.
131
+ """
132
+ return False
@@ -0,0 +1,330 @@
1
+ """文件忽略工具模块。
2
+
3
+ 提供统一的文件/目录忽略逻辑,用于代码分析、依赖分析等场景。
4
+ """
5
+
6
+ from pathlib import Path
7
+ from typing import List, Set, Optional, Callable
8
+
9
+
10
+ class FileIgnorePatterns:
11
+ """文件忽略模式集合。
12
+
13
+ 定义了各种常见的需要忽略的文件和目录模式。
14
+ """
15
+
16
+ # 隐藏目录/文件(以 . 开头)
17
+ HIDDEN_PATTERNS: Set[str] = {'.git', '.svn', '.hg', '.bzr'}
18
+
19
+ # 版本控制目录
20
+ VCS_DIRS: Set[str] = {'.git', '.svn', '.hg', '.bzr', '.gitignore'}
21
+
22
+ # Python 相关
23
+ PYTHON_DIRS: Set[str] = {
24
+ '__pycache__', '.pytest_cache', '.mypy_cache', '.ruff_cache',
25
+ '.tox', '.coverage', 'htmlcov', '.hypothesis', '.ipynb_checkpoints',
26
+ '.pyre', '.pytype', 'develop-eggs', 'downloads', 'eggs', '.eggs',
27
+ 'lib', 'lib64', 'parts', 'sdist', 'var', 'wheels', 'pip-wheel-metadata',
28
+ 'share', '*.egg-info', '.installed.cfg', 'MANIFEST'
29
+ }
30
+ PYTHON_VENV_DIRS: Set[str] = {'venv', 'env', '.venv', 'virtualenv', 'ENV'}
31
+
32
+ # Rust 相关
33
+ RUST_DIRS: Set[str] = {'target', 'Cargo.lock'}
34
+
35
+ # Go 相关
36
+ GO_DIRS: Set[str] = {'vendor', 'bin', 'coverage.out'}
37
+
38
+ # Node.js 相关
39
+ NODE_DIRS: Set[str] = {
40
+ 'node_modules', '.npm', '.yarn', '.pnpm', '.turbo', '.next', '.nuxt',
41
+ 'out', 'dist', 'coverage', 'build'
42
+ }
43
+
44
+ # Java 相关
45
+ JAVA_DIRS: Set[str] = {'target', '.gradle', 'build', 'out', '*.class'}
46
+
47
+ # C/C++ 相关
48
+ C_CPP_DIRS: Set[str] = {
49
+ 'build', 'cmake-build-*', 'out', 'bin', 'obj', '*.o', '*.a', '*.so',
50
+ '*.obj', '*.dll', '*.dylib', '*.exe', '*.pdb'
51
+ }
52
+
53
+ # .NET 相关
54
+ DOTNET_DIRS: Set[str] = {'bin', 'obj', 'packages'}
55
+
56
+ # 构建产物目录(通用)
57
+ BUILD_DIRS: Set[str] = {
58
+ 'build', 'out', 'target', 'dist', 'bin', 'obj', 'cmake-build-*'
59
+ }
60
+
61
+ # 依赖目录(通用)
62
+ DEPENDENCY_DIRS: Set[str] = {
63
+ 'third_party', 'vendor', 'deps', 'dependencies', 'libs', 'libraries',
64
+ 'external', 'node_modules', 'packages'
65
+ }
66
+
67
+ # 测试目录
68
+ TEST_DIRS: Set[str] = {
69
+ 'test', 'tests', '__tests__', 'spec', 'testsuite', 'testdata',
70
+ 'test_data', 'testdata', 'fixtures', 'mocks'
71
+ }
72
+
73
+ # 性能测试目录
74
+ BENCHMARK_DIRS: Set[str] = {
75
+ 'benchmark', 'benchmarks', 'perf', 'performance', 'bench', 'benches',
76
+ 'profiling', 'profiler'
77
+ }
78
+
79
+ # 示例目录
80
+ EXAMPLE_DIRS: Set[str] = {
81
+ 'example', 'examples', 'samples', 'sample', 'demo', 'demos'
82
+ }
83
+
84
+ # 临时/缓存目录
85
+ TEMP_DIRS: Set[str] = {
86
+ 'tmp', 'temp', 'cache', '.cache', '*.tmp', '*.log', '*.swp', '*.swo'
87
+ }
88
+
89
+ # 文档目录
90
+ DOC_DIRS: Set[str] = {'docs', 'doc', 'documentation'}
91
+
92
+ # 生成代码目录
93
+ GENERATED_DIRS: Set[str] = {'generated', 'gen', 'auto-generated'}
94
+
95
+ # 其他
96
+ OTHER_DIRS: Set[str] = {
97
+ 'playground', 'sandbox', '.idea', '.vscode', '.DS_Store', 'Thumbs.db'
98
+ }
99
+
100
+ # Jarvis 特定
101
+ JARVIS_DIRS: Set[str] = {'.jarvis'}
102
+
103
+ @classmethod
104
+ def get_all_ignore_dirs(cls) -> Set[str]:
105
+ """获取所有需要忽略的目录名称集合。
106
+
107
+ Returns:
108
+ 所有忽略目录名称的集合
109
+ """
110
+ return (
111
+ cls.VCS_DIRS |
112
+ cls.PYTHON_DIRS |
113
+ cls.PYTHON_VENV_DIRS |
114
+ cls.RUST_DIRS |
115
+ cls.GO_DIRS |
116
+ cls.NODE_DIRS |
117
+ cls.JAVA_DIRS |
118
+ cls.C_CPP_DIRS |
119
+ cls.DOTNET_DIRS |
120
+ cls.BUILD_DIRS |
121
+ cls.DEPENDENCY_DIRS |
122
+ cls.TEST_DIRS |
123
+ cls.BENCHMARK_DIRS |
124
+ cls.EXAMPLE_DIRS |
125
+ cls.TEMP_DIRS |
126
+ cls.DOC_DIRS |
127
+ cls.GENERATED_DIRS |
128
+ cls.OTHER_DIRS |
129
+ cls.JARVIS_DIRS
130
+ )
131
+
132
+ @classmethod
133
+ def get_code_analysis_ignore_dirs(cls) -> Set[str]:
134
+ """获取代码分析时应该忽略的目录(不包含测试目录)。
135
+
136
+ Returns:
137
+ 代码分析忽略目录集合
138
+ """
139
+ return (
140
+ cls.VCS_DIRS |
141
+ cls.PYTHON_DIRS |
142
+ cls.PYTHON_VENV_DIRS |
143
+ cls.RUST_DIRS |
144
+ cls.GO_DIRS |
145
+ cls.NODE_DIRS |
146
+ cls.JAVA_DIRS |
147
+ cls.C_CPP_DIRS |
148
+ cls.DOTNET_DIRS |
149
+ cls.BUILD_DIRS |
150
+ cls.DEPENDENCY_DIRS |
151
+ cls.BENCHMARK_DIRS |
152
+ cls.EXAMPLE_DIRS |
153
+ cls.TEMP_DIRS |
154
+ cls.DOC_DIRS |
155
+ cls.GENERATED_DIRS |
156
+ cls.OTHER_DIRS |
157
+ cls.JARVIS_DIRS
158
+ )
159
+
160
+ @classmethod
161
+ def get_dependency_analysis_ignore_dirs(cls) -> Set[str]:
162
+ """获取依赖分析时应该忽略的目录。
163
+
164
+ Returns:
165
+ 依赖分析忽略目录集合
166
+ """
167
+ return (
168
+ cls.VCS_DIRS |
169
+ cls.BUILD_DIRS |
170
+ cls.DEPENDENCY_DIRS |
171
+ cls.TEST_DIRS |
172
+ cls.BENCHMARK_DIRS |
173
+ cls.EXAMPLE_DIRS |
174
+ cls.TEMP_DIRS |
175
+ cls.DOC_DIRS |
176
+ cls.GENERATED_DIRS |
177
+ cls.OTHER_DIRS |
178
+ cls.JARVIS_DIRS
179
+ )
180
+
181
+
182
+ class FileIgnoreFilter:
183
+ """文件忽略过滤器。
184
+
185
+ 提供统一的文件/目录过滤逻辑。
186
+ """
187
+
188
+ def __init__(
189
+ self,
190
+ ignore_dirs: Optional[Set[str]] = None,
191
+ ignore_hidden: bool = True,
192
+ custom_filter: Optional[Callable[[str], bool]] = None,
193
+ ):
194
+ """初始化文件忽略过滤器。
195
+
196
+ Args:
197
+ ignore_dirs: 要忽略的目录名称集合,如果为None则使用默认集合
198
+ ignore_hidden: 是否忽略隐藏目录(以 . 开头)
199
+ custom_filter: 自定义过滤函数,接收目录名,返回True表示忽略
200
+ """
201
+ if ignore_dirs is None:
202
+ ignore_dirs = FileIgnorePatterns.get_code_analysis_ignore_dirs()
203
+
204
+ self.ignore_dirs = ignore_dirs
205
+ self.ignore_hidden = ignore_hidden
206
+ self.custom_filter = custom_filter
207
+
208
+ def should_ignore_dir(self, dir_name: str) -> bool:
209
+ """判断是否应该忽略某个目录。
210
+
211
+ Args:
212
+ dir_name: 目录名称(不包含路径)
213
+
214
+ Returns:
215
+ 如果应该忽略返回True,否则返回False
216
+ """
217
+ # 检查隐藏目录
218
+ if self.ignore_hidden and dir_name.startswith('.'):
219
+ return True
220
+
221
+ # 检查忽略目录集合
222
+ if dir_name in self.ignore_dirs:
223
+ return True
224
+
225
+ # 检查自定义过滤器
226
+ if self.custom_filter and self.custom_filter(dir_name):
227
+ return True
228
+
229
+ return False
230
+
231
+ def should_ignore_path(self, path: str) -> bool:
232
+ """判断是否应该忽略某个路径(文件或目录)。
233
+
234
+ Args:
235
+ path: 文件或目录路径
236
+
237
+ Returns:
238
+ 如果应该忽略返回True,否则返回False
239
+ """
240
+ path_obj = Path(path)
241
+
242
+ # 检查路径中的任何部分是否应该被忽略
243
+ for part in path_obj.parts:
244
+ if self.should_ignore_dir(part):
245
+ return True
246
+
247
+ return False
248
+
249
+ def filter_dirs(self, dirs: List[str]) -> List[str]:
250
+ """过滤目录列表,移除应该忽略的目录。
251
+
252
+ 这个方法可以直接用于 os.walk 的 dirs 列表修改:
253
+ dirs[:] = filter.filter_dirs(dirs)
254
+
255
+ Args:
256
+ dirs: 目录名称列表
257
+
258
+ Returns:
259
+ 过滤后的目录列表
260
+ """
261
+ return [d for d in dirs if not self.should_ignore_dir(d)]
262
+
263
+ def filter_paths(self, paths: List[str]) -> List[str]:
264
+ """过滤路径列表,移除应该忽略的路径。
265
+
266
+ Args:
267
+ paths: 路径列表
268
+
269
+ Returns:
270
+ 过滤后的路径列表
271
+ """
272
+ return [p for p in paths if not self.should_ignore_path(p)]
273
+
274
+
275
+ # 预定义的过滤器实例
276
+ DEFAULT_FILTER = FileIgnoreFilter()
277
+ CODE_ANALYSIS_FILTER = FileIgnoreFilter(
278
+ ignore_dirs=FileIgnorePatterns.get_code_analysis_ignore_dirs()
279
+ )
280
+ DEPENDENCY_ANALYSIS_FILTER = FileIgnoreFilter(
281
+ ignore_dirs=FileIgnorePatterns.get_dependency_analysis_ignore_dirs()
282
+ )
283
+ ALL_IGNORE_FILTER = FileIgnoreFilter(
284
+ ignore_dirs=FileIgnorePatterns.get_all_ignore_dirs()
285
+ )
286
+
287
+
288
+ def should_ignore_dir(dir_name: str, ignore_dirs: Optional[Set[str]] = None) -> bool:
289
+ """便捷函数:判断是否应该忽略目录。
290
+
291
+ Args:
292
+ dir_name: 目录名称
293
+ ignore_dirs: 忽略目录集合,如果为None使用默认集合
294
+
295
+ Returns:
296
+ 如果应该忽略返回True
297
+ """
298
+ if ignore_dirs is None:
299
+ ignore_dirs = FileIgnorePatterns.get_code_analysis_ignore_dirs()
300
+
301
+ # 隐藏目录
302
+ if dir_name.startswith('.'):
303
+ return True
304
+
305
+ # 忽略目录集合
306
+ return dir_name in ignore_dirs
307
+
308
+
309
+ def filter_walk_dirs(dirs: List[str], ignore_dirs: Optional[Set[str]] = None) -> List[str]:
310
+ """便捷函数:过滤 os.walk 的 dirs 列表。
311
+
312
+ 用法:
313
+ for root, dirs, files in os.walk(path):
314
+ dirs[:] = filter_walk_dirs(dirs)
315
+
316
+ Args:
317
+ dirs: os.walk 返回的目录列表
318
+ ignore_dirs: 忽略目录集合,如果为None使用默认集合
319
+
320
+ Returns:
321
+ 过滤后的目录列表
322
+ """
323
+ if ignore_dirs is None:
324
+ ignore_dirs = FileIgnorePatterns.get_code_analysis_ignore_dirs()
325
+
326
+ return [
327
+ d for d in dirs
328
+ if not (d.startswith('.') or d in ignore_dirs)
329
+ ]
330
+