auto-coder 0.1.400__py3-none-any.whl → 2.0.0__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 auto-coder might be problematic. Click here for more details.

Files changed (579) hide show
  1. auto_coder-2.0.0.dist-info/LICENSE +158 -0
  2. auto_coder-2.0.0.dist-info/METADATA +558 -0
  3. auto_coder-2.0.0.dist-info/RECORD +795 -0
  4. {auto_coder-0.1.400.dist-info → auto_coder-2.0.0.dist-info}/WHEEL +1 -1
  5. {auto_coder-0.1.400.dist-info → auto_coder-2.0.0.dist-info}/entry_points.txt +3 -3
  6. autocoder/__init__.py +31 -0
  7. autocoder/agent/auto_filegroup.py +32 -13
  8. autocoder/agent/auto_learn_from_commit.py +9 -1
  9. autocoder/agent/base_agentic/__init__.py +3 -0
  10. autocoder/agent/base_agentic/agent_hub.py +1 -1
  11. autocoder/agent/base_agentic/base_agent.py +235 -136
  12. autocoder/agent/base_agentic/default_tools.py +119 -118
  13. autocoder/agent/base_agentic/test_base_agent.py +1 -1
  14. autocoder/agent/base_agentic/tool_registry.py +32 -20
  15. autocoder/agent/base_agentic/tools/read_file_tool_resolver.py +25 -4
  16. autocoder/agent/base_agentic/tools/write_to_file_tool_resolver.py +24 -11
  17. autocoder/agent/base_agentic/types.py +42 -0
  18. autocoder/agent/entry_command_agent/chat.py +73 -59
  19. autocoder/auto_coder.py +31 -40
  20. autocoder/auto_coder_rag.py +11 -1084
  21. autocoder/auto_coder_runner.py +1029 -2310
  22. autocoder/auto_coder_terminal.py +26 -0
  23. autocoder/auto_coder_terminal_v3.py +190 -0
  24. autocoder/chat/conf_command.py +224 -124
  25. autocoder/chat/models_command.py +361 -299
  26. autocoder/chat/rules_command.py +79 -31
  27. autocoder/chat_auto_coder.py +1021 -372
  28. autocoder/chat_auto_coder_lang.py +23 -732
  29. autocoder/commands/auto_command.py +26 -9
  30. autocoder/commands/auto_web.py +1 -1
  31. autocoder/commands/tools.py +44 -44
  32. autocoder/common/__init__.py +150 -128
  33. autocoder/common/ac_style_command_parser/__init__.py +39 -2
  34. autocoder/common/ac_style_command_parser/config.py +422 -0
  35. autocoder/common/ac_style_command_parser/parser.py +292 -78
  36. autocoder/common/ac_style_command_parser/test_parser.py +241 -16
  37. autocoder/common/ac_style_command_parser/test_typed_parser.py +342 -0
  38. autocoder/common/ac_style_command_parser/typed_parser.py +653 -0
  39. autocoder/common/action_yml_file_manager.py +25 -13
  40. autocoder/common/agent_events/__init__.py +52 -0
  41. autocoder/common/agent_events/agent_event_emitter.py +193 -0
  42. autocoder/common/agent_events/event_factory.py +177 -0
  43. autocoder/common/agent_events/examples.py +307 -0
  44. autocoder/common/agent_events/types.py +113 -0
  45. autocoder/common/agent_events/utils.py +68 -0
  46. autocoder/common/agent_hooks/__init__.py +44 -0
  47. autocoder/common/agent_hooks/examples.py +582 -0
  48. autocoder/common/agent_hooks/hook_executor.py +217 -0
  49. autocoder/common/agent_hooks/hook_manager.py +288 -0
  50. autocoder/common/agent_hooks/types.py +133 -0
  51. autocoder/common/agent_hooks/utils.py +99 -0
  52. autocoder/common/agent_query_queue/queue_executor.py +324 -0
  53. autocoder/common/agent_query_queue/queue_manager.py +325 -0
  54. autocoder/common/agents/__init__.py +11 -0
  55. autocoder/common/agents/agent_manager.py +323 -0
  56. autocoder/common/agents/agent_parser.py +189 -0
  57. autocoder/common/agents/example_usage.py +344 -0
  58. autocoder/common/agents/integration_example.py +330 -0
  59. autocoder/common/agents/test_agent_parser.py +545 -0
  60. autocoder/common/async_utils.py +101 -0
  61. autocoder/common/auto_coder_lang.py +23 -972
  62. autocoder/common/autocoderargs_parser/__init__.py +14 -0
  63. autocoder/common/autocoderargs_parser/parser.py +184 -0
  64. autocoder/common/autocoderargs_parser/tests/__init__.py +1 -0
  65. autocoder/common/autocoderargs_parser/tests/test_args_parser.py +235 -0
  66. autocoder/common/autocoderargs_parser/tests/test_token_parser.py +195 -0
  67. autocoder/common/autocoderargs_parser/token_parser.py +290 -0
  68. autocoder/common/buildin_tokenizer.py +2 -4
  69. autocoder/common/code_auto_generate.py +149 -74
  70. autocoder/common/code_auto_generate_diff.py +163 -70
  71. autocoder/common/code_auto_generate_editblock.py +179 -89
  72. autocoder/common/code_auto_generate_strict_diff.py +167 -72
  73. autocoder/common/code_auto_merge_editblock.py +13 -6
  74. autocoder/common/code_modification_ranker.py +1 -1
  75. autocoder/common/command_completer.py +3 -3
  76. autocoder/common/command_file_manager/manager.py +183 -47
  77. autocoder/common/command_file_manager/test_command_file_manager.py +507 -0
  78. autocoder/common/command_templates.py +1 -1
  79. autocoder/common/conf_utils.py +2 -4
  80. autocoder/common/conversations/config.py +11 -3
  81. autocoder/common/conversations/get_conversation_manager.py +100 -2
  82. autocoder/common/conversations/llm_stats_models.py +264 -0
  83. autocoder/common/conversations/manager.py +112 -28
  84. autocoder/common/conversations/models.py +16 -2
  85. autocoder/common/conversations/storage/index_manager.py +134 -10
  86. autocoder/common/core_config/__init__.py +63 -0
  87. autocoder/common/core_config/agentic_mode_manager.py +109 -0
  88. autocoder/common/core_config/base_manager.py +123 -0
  89. autocoder/common/core_config/compatibility.py +151 -0
  90. autocoder/common/core_config/config_manager.py +156 -0
  91. autocoder/common/core_config/conversation_manager.py +31 -0
  92. autocoder/common/core_config/exclude_manager.py +72 -0
  93. autocoder/common/core_config/file_manager.py +177 -0
  94. autocoder/common/core_config/human_as_model_manager.py +129 -0
  95. autocoder/common/core_config/lib_manager.py +54 -0
  96. autocoder/common/core_config/main_manager.py +81 -0
  97. autocoder/common/core_config/mode_manager.py +126 -0
  98. autocoder/common/core_config/models.py +70 -0
  99. autocoder/common/core_config/test_memory_manager.py +1056 -0
  100. autocoder/common/env_manager.py +282 -0
  101. autocoder/common/env_manager_usage_example.py +211 -0
  102. autocoder/common/file_checkpoint/conversation_checkpoint.py +19 -19
  103. autocoder/common/file_checkpoint/manager.py +264 -48
  104. autocoder/common/file_checkpoint/test_backup.py +1 -18
  105. autocoder/common/file_checkpoint/test_manager.py +270 -1
  106. autocoder/common/file_checkpoint/test_store.py +1 -17
  107. autocoder/common/file_handler/__init__.py +23 -0
  108. autocoder/common/file_handler/active_context_handler.py +159 -0
  109. autocoder/common/file_handler/add_files_handler.py +409 -0
  110. autocoder/common/file_handler/chat_handler.py +180 -0
  111. autocoder/common/file_handler/coding_handler.py +401 -0
  112. autocoder/common/file_handler/commit_handler.py +200 -0
  113. autocoder/common/file_handler/lib_handler.py +156 -0
  114. autocoder/common/file_handler/list_files_handler.py +111 -0
  115. autocoder/common/file_handler/mcp_handler.py +268 -0
  116. autocoder/common/file_handler/models_handler.py +493 -0
  117. autocoder/common/file_handler/remove_files_handler.py +172 -0
  118. autocoder/common/file_monitor/test_file_monitor.py +307 -0
  119. autocoder/common/git_utils.py +51 -10
  120. autocoder/common/global_cancel.py +15 -6
  121. autocoder/common/ignorefiles/test_ignore_file_utils.py +1 -1
  122. autocoder/common/international/__init__.py +31 -0
  123. autocoder/common/international/demo_international.py +92 -0
  124. autocoder/common/international/message_manager.py +157 -0
  125. autocoder/common/international/messages/__init__.py +56 -0
  126. autocoder/common/international/messages/async_command_messages.py +507 -0
  127. autocoder/common/international/messages/auto_coder_messages.py +2208 -0
  128. autocoder/common/international/messages/chat_auto_coder_messages.py +1547 -0
  129. autocoder/common/international/messages/command_help_messages.py +986 -0
  130. autocoder/common/international/messages/conversation_command_messages.py +191 -0
  131. autocoder/common/international/messages/git_helper_plugin_messages.py +159 -0
  132. autocoder/common/international/messages/queue_command_messages.py +751 -0
  133. autocoder/common/international/messages/rules_command_messages.py +77 -0
  134. autocoder/common/international/messages/sdk_messages.py +1707 -0
  135. autocoder/common/international/messages/token_helper_plugin_messages.py +361 -0
  136. autocoder/common/international/messages/tool_display_messages.py +1212 -0
  137. autocoder/common/international/messages/workflow_exception_messages.py +473 -0
  138. autocoder/common/international/test_international.py +612 -0
  139. autocoder/common/linter_core/__init__.py +28 -0
  140. autocoder/common/linter_core/base_linter.py +61 -0
  141. autocoder/common/linter_core/config_loader.py +271 -0
  142. autocoder/common/linter_core/formatters/__init__.py +0 -0
  143. autocoder/common/linter_core/formatters/base_formatter.py +38 -0
  144. autocoder/common/linter_core/formatters/raw_formatter.py +17 -0
  145. autocoder/common/linter_core/linter.py +166 -0
  146. autocoder/common/linter_core/linter_factory.py +216 -0
  147. autocoder/common/linter_core/linter_manager.py +333 -0
  148. autocoder/common/linter_core/linters/__init__.py +9 -0
  149. autocoder/common/linter_core/linters/java_linter.py +342 -0
  150. autocoder/common/linter_core/linters/python_linter.py +115 -0
  151. autocoder/common/linter_core/linters/typescript_linter.py +119 -0
  152. autocoder/common/linter_core/models/__init__.py +7 -0
  153. autocoder/common/linter_core/models/lint_result.py +91 -0
  154. autocoder/common/linter_core/models.py +33 -0
  155. autocoder/common/linter_core/tests/__init__.py +3 -0
  156. autocoder/common/linter_core/tests/test_config_loader.py +323 -0
  157. autocoder/common/linter_core/tests/test_config_loading.py +308 -0
  158. autocoder/common/linter_core/tests/test_factory_manager.py +234 -0
  159. autocoder/common/linter_core/tests/test_formatters.py +147 -0
  160. autocoder/common/linter_core/tests/test_integration.py +317 -0
  161. autocoder/common/linter_core/tests/test_java_linter.py +496 -0
  162. autocoder/common/linter_core/tests/test_linters.py +265 -0
  163. autocoder/common/linter_core/tests/test_models.py +81 -0
  164. autocoder/common/linter_core/tests/verify_config_loading.py +296 -0
  165. autocoder/common/linter_core/tests/verify_fixes.py +183 -0
  166. autocoder/common/llm_friendly_package/__init__.py +31 -0
  167. autocoder/common/llm_friendly_package/base_manager.py +102 -0
  168. autocoder/common/llm_friendly_package/docs_manager.py +121 -0
  169. autocoder/common/llm_friendly_package/library_manager.py +171 -0
  170. autocoder/common/{llm_friendly_package.py → llm_friendly_package/main_manager.py} +204 -231
  171. autocoder/common/llm_friendly_package/models.py +40 -0
  172. autocoder/common/llm_friendly_package/test_llm_friendly_package.py +536 -0
  173. autocoder/common/llms/__init__.py +15 -0
  174. autocoder/common/llms/demo_error_handling.py +85 -0
  175. autocoder/common/llms/factory.py +142 -0
  176. autocoder/common/llms/manager.py +264 -0
  177. autocoder/common/llms/pricing.py +121 -0
  178. autocoder/common/llms/registry.py +288 -0
  179. autocoder/common/llms/schema.py +77 -0
  180. autocoder/common/llms/simple_demo.py +45 -0
  181. autocoder/common/llms/test_quick_model.py +116 -0
  182. autocoder/common/llms/test_remove_functionality.py +182 -0
  183. autocoder/common/llms/tests/__init__.py +1 -0
  184. autocoder/common/llms/tests/test_manager.py +330 -0
  185. autocoder/common/llms/tests/test_registry.py +364 -0
  186. autocoder/common/mcp_tools/__init__.py +62 -0
  187. autocoder/common/{mcp_tools.py → mcp_tools/executor.py} +49 -40
  188. autocoder/common/{mcp_hub.py → mcp_tools/hub.py} +42 -68
  189. autocoder/common/{mcp_server_install.py → mcp_tools/installer.py} +16 -28
  190. autocoder/common/{mcp_server.py → mcp_tools/server.py} +176 -48
  191. autocoder/common/mcp_tools/test_keyboard_interrupt.py +93 -0
  192. autocoder/common/mcp_tools/test_mcp_tools.py +391 -0
  193. autocoder/common/{mcp_server_types.py → mcp_tools/types.py} +121 -48
  194. autocoder/common/mcp_tools/verify_functionality.py +202 -0
  195. autocoder/common/model_speed_tester.py +32 -26
  196. autocoder/common/priority_directory_finder/__init__.py +142 -0
  197. autocoder/common/priority_directory_finder/examples.py +230 -0
  198. autocoder/common/priority_directory_finder/finder.py +283 -0
  199. autocoder/common/priority_directory_finder/models.py +236 -0
  200. autocoder/common/priority_directory_finder/test_priority_directory_finder.py +431 -0
  201. autocoder/common/project_scanner/__init__.py +18 -0
  202. autocoder/common/project_scanner/compat.py +77 -0
  203. autocoder/common/project_scanner/scanner.py +436 -0
  204. autocoder/common/project_tracker/__init__.py +27 -0
  205. autocoder/common/project_tracker/api.py +228 -0
  206. autocoder/common/project_tracker/demo.py +272 -0
  207. autocoder/common/project_tracker/tracker.py +487 -0
  208. autocoder/common/project_tracker/types.py +53 -0
  209. autocoder/common/pruner/__init__.py +67 -0
  210. autocoder/common/pruner/agentic_conversation_pruner.py +746 -0
  211. autocoder/common/{context_pruner.py → pruner/context_pruner.py} +137 -40
  212. autocoder/common/pruner/conversation_message_ids_api.py +386 -0
  213. autocoder/common/pruner/conversation_message_ids_manager.py +347 -0
  214. autocoder/common/pruner/conversation_message_ids_pruner.py +473 -0
  215. autocoder/common/pruner/conversation_normalizer.py +347 -0
  216. autocoder/common/{conversation_pruner.py → pruner/conversation_pruner.py} +26 -6
  217. autocoder/common/pruner/test_agentic_conversation_pruner.py +784 -0
  218. autocoder/common/pruner/test_context_pruner.py +546 -0
  219. autocoder/common/pruner/test_conversation_normalizer.py +502 -0
  220. autocoder/common/pruner/test_tool_content_detector.py +324 -0
  221. autocoder/common/pruner/tool_content_detector.py +227 -0
  222. autocoder/common/pruner/tools/__init__.py +18 -0
  223. autocoder/common/pruner/tools/query_message_ids.py +264 -0
  224. autocoder/common/pruner/tools/test_agentic_pruning_logic.py +432 -0
  225. autocoder/common/pruner/tools/test_message_ids_pruning_only.py +192 -0
  226. autocoder/common/pull_requests/__init__.py +9 -1
  227. autocoder/common/pull_requests/utils.py +122 -1
  228. autocoder/common/rag_manager/rag_manager.py +36 -40
  229. autocoder/common/rulefiles/__init__.py +53 -1
  230. autocoder/common/rulefiles/api.py +250 -0
  231. autocoder/common/rulefiles/core/__init__.py +14 -0
  232. autocoder/common/rulefiles/core/manager.py +241 -0
  233. autocoder/common/rulefiles/core/selector.py +805 -0
  234. autocoder/common/rulefiles/models/__init__.py +20 -0
  235. autocoder/common/rulefiles/models/index.py +16 -0
  236. autocoder/common/rulefiles/models/init_rule.py +18 -0
  237. autocoder/common/rulefiles/models/rule_file.py +18 -0
  238. autocoder/common/rulefiles/models/rule_relevance.py +14 -0
  239. autocoder/common/rulefiles/models/summary.py +16 -0
  240. autocoder/common/rulefiles/test_rulefiles.py +776 -0
  241. autocoder/common/rulefiles/utils/__init__.py +34 -0
  242. autocoder/common/rulefiles/utils/monitor.py +86 -0
  243. autocoder/common/rulefiles/utils/parser.py +230 -0
  244. autocoder/common/save_formatted_log.py +67 -10
  245. autocoder/common/search_replace.py +8 -1
  246. autocoder/common/search_replace_patch/__init__.py +24 -0
  247. autocoder/common/search_replace_patch/base.py +115 -0
  248. autocoder/common/search_replace_patch/manager.py +248 -0
  249. autocoder/common/search_replace_patch/patch_replacer.py +304 -0
  250. autocoder/common/search_replace_patch/similarity_replacer.py +306 -0
  251. autocoder/common/search_replace_patch/string_replacer.py +181 -0
  252. autocoder/common/search_replace_patch/tests/__init__.py +3 -0
  253. autocoder/common/search_replace_patch/tests/run_tests.py +126 -0
  254. autocoder/common/search_replace_patch/tests/test_base.py +188 -0
  255. autocoder/common/search_replace_patch/tests/test_empty_line_insert.py +233 -0
  256. autocoder/common/search_replace_patch/tests/test_integration.py +389 -0
  257. autocoder/common/search_replace_patch/tests/test_manager.py +351 -0
  258. autocoder/common/search_replace_patch/tests/test_patch_replacer.py +316 -0
  259. autocoder/common/search_replace_patch/tests/test_regex_replacer.py +306 -0
  260. autocoder/common/search_replace_patch/tests/test_similarity_replacer.py +384 -0
  261. autocoder/common/shell_commands/__init__.py +197 -0
  262. autocoder/common/shell_commands/background_process_notifier.py +346 -0
  263. autocoder/common/shell_commands/command_executor.py +1127 -0
  264. autocoder/common/shell_commands/error_recovery.py +541 -0
  265. autocoder/common/shell_commands/exceptions.py +120 -0
  266. autocoder/common/shell_commands/interactive_executor.py +476 -0
  267. autocoder/common/shell_commands/interactive_pexpect_process.py +623 -0
  268. autocoder/common/shell_commands/interactive_process.py +744 -0
  269. autocoder/common/shell_commands/interactive_session_manager.py +1014 -0
  270. autocoder/common/shell_commands/monitoring.py +529 -0
  271. autocoder/common/shell_commands/process_cleanup.py +386 -0
  272. autocoder/common/shell_commands/process_manager.py +606 -0
  273. autocoder/common/shell_commands/test_interactive_pexpect_process.py +281 -0
  274. autocoder/common/shell_commands/tests/__init__.py +6 -0
  275. autocoder/common/shell_commands/tests/conftest.py +118 -0
  276. autocoder/common/shell_commands/tests/test_background_process_notifier.py +703 -0
  277. autocoder/common/shell_commands/tests/test_command_executor.py +448 -0
  278. autocoder/common/shell_commands/tests/test_error_recovery.py +305 -0
  279. autocoder/common/shell_commands/tests/test_exceptions.py +299 -0
  280. autocoder/common/shell_commands/tests/test_execute_batch.py +588 -0
  281. autocoder/common/shell_commands/tests/test_indented_batch_commands.py +244 -0
  282. autocoder/common/shell_commands/tests/test_integration.py +664 -0
  283. autocoder/common/shell_commands/tests/test_monitoring.py +546 -0
  284. autocoder/common/shell_commands/tests/test_performance.py +632 -0
  285. autocoder/common/shell_commands/tests/test_process_cleanup.py +397 -0
  286. autocoder/common/shell_commands/tests/test_process_manager.py +606 -0
  287. autocoder/common/shell_commands/tests/test_timeout_config.py +343 -0
  288. autocoder/common/shell_commands/tests/test_timeout_manager.py +520 -0
  289. autocoder/common/shell_commands/timeout_config.py +315 -0
  290. autocoder/common/shell_commands/timeout_manager.py +352 -0
  291. autocoder/common/terminal_paste/__init__.py +14 -0
  292. autocoder/common/terminal_paste/demo.py +145 -0
  293. autocoder/common/terminal_paste/demo_paste_functionality.py +95 -0
  294. autocoder/common/terminal_paste/paste_handler.py +200 -0
  295. autocoder/common/terminal_paste/paste_manager.py +118 -0
  296. autocoder/common/terminal_paste/tests/__init__.py +1 -0
  297. autocoder/common/terminal_paste/tests/test_paste_handler.py +182 -0
  298. autocoder/common/terminal_paste/tests/test_paste_manager.py +126 -0
  299. autocoder/common/terminal_paste/utils.py +163 -0
  300. autocoder/common/test_autocoder_args.py +232 -0
  301. autocoder/common/test_env_manager.py +173 -0
  302. autocoder/common/test_env_manager_integration.py +159 -0
  303. autocoder/common/text_similarity/__init__.py +9 -0
  304. autocoder/common/text_similarity/demo.py +216 -0
  305. autocoder/common/text_similarity/examples.py +266 -0
  306. autocoder/common/text_similarity/test_text_similarity.py +306 -0
  307. autocoder/common/text_similarity/text_similarity.py +194 -0
  308. autocoder/common/text_similarity/utils.py +125 -0
  309. autocoder/common/todos/__init__.py +61 -0
  310. autocoder/common/todos/cache/__init__.py +16 -0
  311. autocoder/common/todos/cache/base_cache.py +89 -0
  312. autocoder/common/todos/cache/cache_manager.py +228 -0
  313. autocoder/common/todos/cache/memory_cache.py +225 -0
  314. autocoder/common/todos/config.py +155 -0
  315. autocoder/common/todos/exceptions.py +35 -0
  316. autocoder/common/todos/get_todo_manager.py +161 -0
  317. autocoder/common/todos/manager.py +537 -0
  318. autocoder/common/todos/models.py +239 -0
  319. autocoder/common/todos/storage/__init__.py +14 -0
  320. autocoder/common/todos/storage/base_storage.py +76 -0
  321. autocoder/common/todos/storage/file_storage.py +278 -0
  322. autocoder/common/tokens/__init__.py +15 -0
  323. autocoder/common/tokens/counter.py +44 -2
  324. autocoder/common/tools_manager/__init__.py +17 -0
  325. autocoder/common/tools_manager/examples.py +162 -0
  326. autocoder/common/tools_manager/manager.py +385 -0
  327. autocoder/common/tools_manager/models.py +39 -0
  328. autocoder/common/tools_manager/test_tools_manager.py +303 -0
  329. autocoder/common/tools_manager/utils.py +191 -0
  330. autocoder/common/v2/agent/agentic_callbacks.py +270 -0
  331. autocoder/common/v2/agent/agentic_edit.py +2729 -2052
  332. autocoder/common/v2/agent/agentic_edit_change_manager.py +474 -0
  333. autocoder/common/v2/agent/agentic_edit_tools/__init__.py +43 -2
  334. autocoder/common/v2/agent/agentic_edit_tools/ac_mod_list_tool_resolver.py +279 -0
  335. autocoder/common/v2/agent/agentic_edit_tools/ac_mod_read_tool_resolver.py +40 -0
  336. autocoder/common/v2/agent/agentic_edit_tools/ac_mod_write_tool_resolver.py +52 -0
  337. autocoder/common/v2/agent/agentic_edit_tools/ask_followup_question_tool_resolver.py +8 -0
  338. autocoder/common/v2/agent/agentic_edit_tools/background_task_tool_resolver.py +1167 -0
  339. autocoder/common/v2/agent/agentic_edit_tools/base_tool_resolver.py +2 -2
  340. autocoder/common/v2/agent/agentic_edit_tools/conversation_message_ids_read_tool_resolver.py +214 -0
  341. autocoder/common/v2/agent/agentic_edit_tools/conversation_message_ids_write_tool_resolver.py +299 -0
  342. autocoder/common/v2/agent/agentic_edit_tools/count_tokens_tool_resolver.py +290 -0
  343. autocoder/common/v2/agent/agentic_edit_tools/execute_command_tool_resolver.py +565 -30
  344. autocoder/common/v2/agent/agentic_edit_tools/execute_workflow_tool_resolver.py +485 -0
  345. autocoder/common/v2/agent/agentic_edit_tools/extract_to_text_tool_resolver.py +225 -0
  346. autocoder/common/v2/agent/agentic_edit_tools/lint_report.py +79 -0
  347. autocoder/common/v2/agent/agentic_edit_tools/linter_config_models.py +343 -0
  348. autocoder/common/v2/agent/agentic_edit_tools/linter_enabled_tool_resolver.py +189 -0
  349. autocoder/common/v2/agent/agentic_edit_tools/list_files_tool_resolver.py +169 -101
  350. autocoder/common/v2/agent/agentic_edit_tools/load_extra_document_tool_resolver.py +349 -0
  351. autocoder/common/v2/agent/agentic_edit_tools/read_file_tool_resolver.py +244 -51
  352. autocoder/common/v2/agent/agentic_edit_tools/replace_in_file_tool_resolver.py +667 -147
  353. autocoder/common/v2/agent/agentic_edit_tools/run_named_subagents_tool_resolver.py +691 -0
  354. autocoder/common/v2/agent/agentic_edit_tools/search_files_tool_resolver.py +409 -140
  355. autocoder/common/v2/agent/agentic_edit_tools/session_interactive_tool_resolver.py +115 -0
  356. autocoder/common/v2/agent/agentic_edit_tools/session_start_tool_resolver.py +190 -0
  357. autocoder/common/v2/agent/agentic_edit_tools/session_stop_tool_resolver.py +76 -0
  358. autocoder/common/v2/agent/agentic_edit_tools/test_write_to_file_tool_resolver.py +209 -194
  359. autocoder/common/v2/agent/agentic_edit_tools/todo_read_tool_resolver.py +135 -0
  360. autocoder/common/v2/agent/agentic_edit_tools/todo_write_tool_resolver.py +328 -0
  361. autocoder/common/v2/agent/agentic_edit_tools/use_mcp_tool_resolver.py +2 -2
  362. autocoder/common/v2/agent/agentic_edit_tools/web_crawl_tool_resolver.py +557 -0
  363. autocoder/common/v2/agent/agentic_edit_tools/web_search_tool_resolver.py +600 -0
  364. autocoder/common/v2/agent/agentic_edit_tools/write_to_file_tool_resolver.py +56 -121
  365. autocoder/common/v2/agent/agentic_edit_types.py +386 -10
  366. autocoder/common/v2/agent/runner/__init__.py +31 -0
  367. autocoder/common/v2/agent/runner/base_runner.py +92 -0
  368. autocoder/common/v2/agent/runner/file_based_event_runner.py +217 -0
  369. autocoder/common/v2/agent/runner/sdk_runner.py +182 -0
  370. autocoder/common/v2/agent/runner/terminal_runner.py +396 -0
  371. autocoder/common/v2/agent/runner/tool_display.py +589 -0
  372. autocoder/common/v2/agent/test_agentic_callbacks.py +265 -0
  373. autocoder/common/v2/agent/test_agentic_edit.py +194 -0
  374. autocoder/common/v2/agent/tool_caller/__init__.py +24 -0
  375. autocoder/common/v2/agent/tool_caller/default_tool_resolver_map.py +135 -0
  376. autocoder/common/v2/agent/tool_caller/integration_test.py +172 -0
  377. autocoder/common/v2/agent/tool_caller/plugins/__init__.py +14 -0
  378. autocoder/common/v2/agent/tool_caller/plugins/base_plugin.py +126 -0
  379. autocoder/common/v2/agent/tool_caller/plugins/examples/__init__.py +13 -0
  380. autocoder/common/v2/agent/tool_caller/plugins/examples/logging_plugin.py +164 -0
  381. autocoder/common/v2/agent/tool_caller/plugins/examples/security_filter_plugin.py +198 -0
  382. autocoder/common/v2/agent/tool_caller/plugins/plugin_interface.py +141 -0
  383. autocoder/common/v2/agent/tool_caller/test_tool_caller.py +278 -0
  384. autocoder/common/v2/agent/tool_caller/tool_call_plugin_manager.py +331 -0
  385. autocoder/common/v2/agent/tool_caller/tool_caller.py +337 -0
  386. autocoder/common/v2/agent/tool_caller/usage_example.py +193 -0
  387. autocoder/common/v2/code_agentic_editblock_manager.py +4 -4
  388. autocoder/common/v2/code_auto_generate.py +136 -78
  389. autocoder/common/v2/code_auto_generate_diff.py +135 -79
  390. autocoder/common/v2/code_auto_generate_editblock.py +174 -99
  391. autocoder/common/v2/code_auto_generate_strict_diff.py +151 -71
  392. autocoder/common/v2/code_auto_merge.py +1 -1
  393. autocoder/common/v2/code_auto_merge_editblock.py +13 -1
  394. autocoder/common/v2/code_diff_manager.py +3 -3
  395. autocoder/common/v2/code_editblock_manager.py +4 -14
  396. autocoder/common/v2/code_manager.py +1 -1
  397. autocoder/common/v2/code_strict_diff_manager.py +2 -2
  398. autocoder/common/wrap_llm_hint/__init__.py +10 -0
  399. autocoder/common/wrap_llm_hint/test_wrap_llm_hint.py +1067 -0
  400. autocoder/common/wrap_llm_hint/utils.py +432 -0
  401. autocoder/common/wrap_llm_hint/wrap_llm_hint.py +323 -0
  402. autocoder/completer/__init__.py +8 -0
  403. autocoder/completer/command_completer_v2.py +1051 -0
  404. autocoder/default_project/__init__.py +501 -0
  405. autocoder/dispacher/__init__.py +4 -12
  406. autocoder/dispacher/actions/action.py +165 -7
  407. autocoder/dispacher/actions/plugins/action_regex_project.py +2 -2
  408. autocoder/index/entry.py +117 -125
  409. autocoder/{agent → index/filter}/agentic_filter.py +323 -334
  410. autocoder/index/filter/normal_filter.py +5 -11
  411. autocoder/index/filter/quick_filter.py +1 -1
  412. autocoder/index/index.py +36 -9
  413. autocoder/index/tests/__init__.py +1 -0
  414. autocoder/index/tests/run_tests.py +195 -0
  415. autocoder/index/tests/test_entry.py +303 -0
  416. autocoder/index/tests/test_index_manager.py +314 -0
  417. autocoder/index/tests/test_module_integration.py +300 -0
  418. autocoder/index/tests/test_symbols_utils.py +183 -0
  419. autocoder/inner/__init__.py +4 -0
  420. autocoder/inner/agentic.py +932 -0
  421. autocoder/inner/async_command_handler.py +992 -0
  422. autocoder/inner/conversation_command_handlers.py +623 -0
  423. autocoder/inner/merge_command_handler.py +213 -0
  424. autocoder/inner/queue_command_handler.py +684 -0
  425. autocoder/models.py +95 -266
  426. autocoder/plugins/git_helper_plugin.py +31 -29
  427. autocoder/plugins/token_helper_plugin.py +156 -37
  428. autocoder/pyproject/__init__.py +32 -29
  429. autocoder/rag/agentic_rag.py +215 -75
  430. autocoder/rag/cache/simple_cache.py +1 -2
  431. autocoder/rag/loaders/image_loader.py +1 -1
  432. autocoder/rag/long_context_rag.py +42 -26
  433. autocoder/rag/qa_conversation_strategy.py +1 -1
  434. autocoder/rag/terminal/__init__.py +17 -0
  435. autocoder/rag/terminal/args.py +581 -0
  436. autocoder/rag/terminal/bootstrap.py +61 -0
  437. autocoder/rag/terminal/command_handlers.py +653 -0
  438. autocoder/rag/terminal/formatters/__init__.py +20 -0
  439. autocoder/rag/terminal/formatters/base.py +70 -0
  440. autocoder/rag/terminal/formatters/json_format.py +66 -0
  441. autocoder/rag/terminal/formatters/stream_json.py +95 -0
  442. autocoder/rag/terminal/formatters/text.py +28 -0
  443. autocoder/rag/terminal/init.py +120 -0
  444. autocoder/rag/terminal/utils.py +106 -0
  445. autocoder/rag/test_agentic_rag.py +389 -0
  446. autocoder/rag/test_doc_filter.py +3 -3
  447. autocoder/rag/test_long_context_rag.py +1 -1
  448. autocoder/rag/test_token_limiter.py +517 -10
  449. autocoder/rag/token_counter.py +3 -0
  450. autocoder/rag/token_limiter.py +19 -15
  451. autocoder/rag/tools/__init__.py +26 -2
  452. autocoder/rag/tools/bochaai_example.py +343 -0
  453. autocoder/rag/tools/bochaai_sdk.py +541 -0
  454. autocoder/rag/tools/metaso_example.py +268 -0
  455. autocoder/rag/tools/metaso_sdk.py +417 -0
  456. autocoder/rag/tools/recall_tool.py +28 -7
  457. autocoder/rag/tools/run_integration_tests.py +204 -0
  458. autocoder/rag/tools/test_all_providers.py +318 -0
  459. autocoder/rag/tools/test_bochaai_integration.py +482 -0
  460. autocoder/rag/tools/test_final_integration.py +215 -0
  461. autocoder/rag/tools/test_metaso_integration.py +424 -0
  462. autocoder/rag/tools/test_metaso_real.py +171 -0
  463. autocoder/rag/tools/test_web_crawl_tool.py +639 -0
  464. autocoder/rag/tools/test_web_search_tool.py +509 -0
  465. autocoder/rag/tools/todo_read_tool.py +202 -0
  466. autocoder/rag/tools/todo_write_tool.py +412 -0
  467. autocoder/rag/tools/web_crawl_tool.py +634 -0
  468. autocoder/rag/tools/web_search_tool.py +558 -0
  469. autocoder/rag/tools/web_tools_example.py +119 -0
  470. autocoder/rag/types.py +16 -0
  471. autocoder/rag/variable_holder.py +4 -2
  472. autocoder/rags.py +86 -79
  473. autocoder/regexproject/__init__.py +23 -21
  474. autocoder/run_context.py +9 -0
  475. autocoder/sdk/__init__.py +50 -161
  476. autocoder/sdk/api.py +370 -0
  477. autocoder/sdk/async_runner/__init__.py +26 -0
  478. autocoder/sdk/async_runner/async_executor.py +650 -0
  479. autocoder/sdk/async_runner/async_handler.py +356 -0
  480. autocoder/sdk/async_runner/markdown_processor.py +595 -0
  481. autocoder/sdk/async_runner/task_metadata.py +284 -0
  482. autocoder/sdk/async_runner/worktree_manager.py +438 -0
  483. autocoder/sdk/cli/__init__.py +2 -5
  484. autocoder/sdk/cli/formatters.py +28 -204
  485. autocoder/sdk/cli/handlers.py +77 -44
  486. autocoder/sdk/cli/main.py +158 -170
  487. autocoder/sdk/cli/options.py +95 -22
  488. autocoder/sdk/constants.py +139 -51
  489. autocoder/sdk/core/auto_coder_core.py +484 -267
  490. autocoder/sdk/core/bridge.py +298 -118
  491. autocoder/sdk/exceptions.py +18 -12
  492. autocoder/sdk/formatters/__init__.py +19 -0
  493. autocoder/sdk/formatters/input.py +64 -0
  494. autocoder/sdk/formatters/output.py +247 -0
  495. autocoder/sdk/formatters/stream.py +54 -0
  496. autocoder/sdk/models/__init__.py +6 -5
  497. autocoder/sdk/models/options.py +55 -18
  498. autocoder/sdk/utils/formatters.py +27 -195
  499. autocoder/suffixproject/__init__.py +28 -25
  500. autocoder/terminal/__init__.py +14 -0
  501. autocoder/terminal/app.py +454 -0
  502. autocoder/terminal/args.py +32 -0
  503. autocoder/terminal/bootstrap.py +178 -0
  504. autocoder/terminal/command_processor.py +521 -0
  505. autocoder/terminal/command_registry.py +57 -0
  506. autocoder/terminal/help.py +97 -0
  507. autocoder/terminal/tasks/__init__.py +5 -0
  508. autocoder/terminal/tasks/background.py +77 -0
  509. autocoder/terminal/tasks/task_event.py +70 -0
  510. autocoder/terminal/ui/__init__.py +13 -0
  511. autocoder/terminal/ui/completer.py +268 -0
  512. autocoder/terminal/ui/keybindings.py +75 -0
  513. autocoder/terminal/ui/session.py +41 -0
  514. autocoder/terminal/ui/toolbar.py +64 -0
  515. autocoder/terminal/utils/__init__.py +13 -0
  516. autocoder/terminal/utils/errors.py +18 -0
  517. autocoder/terminal/utils/paths.py +19 -0
  518. autocoder/terminal/utils/shell.py +43 -0
  519. autocoder/terminal_v3/__init__.py +10 -0
  520. autocoder/terminal_v3/app.py +201 -0
  521. autocoder/terminal_v3/handlers/__init__.py +5 -0
  522. autocoder/terminal_v3/handlers/command_handler.py +131 -0
  523. autocoder/terminal_v3/models/__init__.py +6 -0
  524. autocoder/terminal_v3/models/conversation_buffer.py +214 -0
  525. autocoder/terminal_v3/models/message.py +50 -0
  526. autocoder/terminal_v3/models/tool_display.py +247 -0
  527. autocoder/terminal_v3/ui/__init__.py +7 -0
  528. autocoder/terminal_v3/ui/keybindings.py +56 -0
  529. autocoder/terminal_v3/ui/layout.py +141 -0
  530. autocoder/terminal_v3/ui/styles.py +43 -0
  531. autocoder/tsproject/__init__.py +23 -23
  532. autocoder/utils/auto_coder_utils/chat_stream_out.py +1 -1
  533. autocoder/utils/llms.py +88 -80
  534. autocoder/utils/math_utils.py +101 -0
  535. autocoder/utils/model_provider_selector.py +16 -4
  536. autocoder/utils/operate_config_api.py +33 -5
  537. autocoder/utils/thread_utils.py +2 -2
  538. autocoder/version.py +4 -2
  539. autocoder/workflow_agents/__init__.py +84 -0
  540. autocoder/workflow_agents/agent.py +143 -0
  541. autocoder/workflow_agents/exceptions.py +573 -0
  542. autocoder/workflow_agents/executor.py +489 -0
  543. autocoder/workflow_agents/loader.py +737 -0
  544. autocoder/workflow_agents/runner.py +267 -0
  545. autocoder/workflow_agents/types.py +172 -0
  546. autocoder/workflow_agents/utils.py +434 -0
  547. autocoder/workflow_agents/workflow_manager.py +211 -0
  548. auto_coder-0.1.400.dist-info/METADATA +0 -396
  549. auto_coder-0.1.400.dist-info/RECORD +0 -425
  550. auto_coder-0.1.400.dist-info/licenses/LICENSE +0 -201
  551. autocoder/auto_coder_server.py +0 -672
  552. autocoder/benchmark.py +0 -138
  553. autocoder/common/ac_style_command_parser/example.py +0 -7
  554. autocoder/common/cleaner.py +0 -31
  555. autocoder/common/command_completer_v2.py +0 -615
  556. autocoder/common/directory_cache/__init__.py +0 -1
  557. autocoder/common/directory_cache/cache.py +0 -192
  558. autocoder/common/directory_cache/test_cache.py +0 -190
  559. autocoder/common/file_checkpoint/examples.py +0 -217
  560. autocoder/common/llm_friendly_package_example.py +0 -138
  561. autocoder/common/llm_friendly_package_test.py +0 -63
  562. autocoder/common/pull_requests/test_module.py +0 -1
  563. autocoder/common/rulefiles/autocoderrules_utils.py +0 -484
  564. autocoder/common/text.py +0 -30
  565. autocoder/common/v2/agent/agentic_edit_tools/list_package_info_tool_resolver.py +0 -42
  566. autocoder/common/v2/agent/agentic_edit_tools/test_execute_command_tool_resolver.py +0 -70
  567. autocoder/common/v2/agent/agentic_edit_tools/test_search_files_tool_resolver.py +0 -163
  568. autocoder/common/v2/agent/agentic_tool_display.py +0 -183
  569. autocoder/plugins/dynamic_completion_example.py +0 -148
  570. autocoder/plugins/sample_plugin.py +0 -160
  571. autocoder/sdk/cli/__main__.py +0 -26
  572. autocoder/sdk/cli/completion_wrapper.py +0 -38
  573. autocoder/sdk/cli/install_completion.py +0 -301
  574. autocoder/sdk/models/messages.py +0 -209
  575. autocoder/sdk/session/__init__.py +0 -32
  576. autocoder/sdk/session/session.py +0 -106
  577. autocoder/sdk/session/session_manager.py +0 -56
  578. {auto_coder-0.1.400.dist-info → auto_coder-2.0.0.dist-info}/top_level.txt +0 -0
  579. /autocoder/{sdk/example.py → common/agent_query_queue/__init__.py} +0 -0
@@ -0,0 +1,496 @@
1
+ """
2
+ Tests for Java linter implementation.
3
+ """
4
+
5
+ import pytest
6
+ from unittest.mock import Mock, patch, MagicMock
7
+ import subprocess
8
+ import platform
9
+ import tempfile
10
+ import os
11
+ from pathlib import Path
12
+
13
+ from autocoder.common.linter_core.linters.java_linter import JavaLinter
14
+ from autocoder.common.linter_core.models.lint_result import LintResult
15
+
16
+
17
+ class TestJavaLinter:
18
+ """Test cases for JavaLinter."""
19
+
20
+ @pytest.fixture
21
+ def java_linter(self):
22
+ """Create a JavaLinter instance."""
23
+ return JavaLinter()
24
+
25
+ def test_init_default_config(self):
26
+ """Test JavaLinter initialization with default config."""
27
+ linter = JavaLinter()
28
+ assert linter.javac_args == []
29
+ assert linter.javac_timeout_secs == 30
30
+
31
+ def test_init_custom_config(self):
32
+ """Test JavaLinter initialization with custom config."""
33
+ config = {
34
+ 'javac_args': ['-Xlint:all'],
35
+ 'javac_timeout': 60
36
+ }
37
+ linter = JavaLinter(config)
38
+ assert linter.javac_args == ['-Xlint:all']
39
+ assert linter.javac_timeout_secs == 60
40
+
41
+ def test_supported_extensions(self, java_linter):
42
+ """Test supported file extensions."""
43
+ assert java_linter.supported_extensions == ['.java']
44
+
45
+ def test_language_name(self, java_linter):
46
+ """Test language name property."""
47
+ assert java_linter.language_name == "Java"
48
+
49
+ @patch('subprocess.run')
50
+ def test_is_available_true(self, mock_run, java_linter):
51
+ """Test is_available when javac is installed."""
52
+ mock_run.return_value = MagicMock(returncode=0)
53
+ assert java_linter.is_available() is True
54
+ mock_run.assert_called_once_with(
55
+ ['javac', '-version'],
56
+ capture_output=True,
57
+ check=True,
58
+ timeout=10
59
+ )
60
+
61
+ @patch('subprocess.run')
62
+ def test_is_available_false(self, mock_run, java_linter):
63
+ """Test is_available when javac is not installed."""
64
+ mock_run.side_effect = FileNotFoundError()
65
+ assert java_linter.is_available() is False
66
+
67
+ @patch('subprocess.run')
68
+ @patch('time.time')
69
+ def test_lint_file_no_errors(self, mock_time, mock_run):
70
+ """Test linting a file with no errors."""
71
+ # Setup
72
+ mock_time.side_effect = [0, 1] # Start and end time
73
+ linter = JavaLinter()
74
+ mock_run.return_value = MagicMock(
75
+ stdout="",
76
+ stderr="" # No errors
77
+ )
78
+
79
+ # Execute
80
+ result = linter.lint_file('Test.java')
81
+
82
+ # Verify
83
+ assert result.linter_name == "JavaLinter"
84
+ assert len(result.files_checked) == 1
85
+ assert 'Test.java' in result.files_checked[0]
86
+ assert not result.has_issues # No output means no issues
87
+ assert result.metadata['tools_used'] == ['javac']
88
+ assert result.execution_time == 1
89
+ assert result.success is True
90
+
91
+ @patch('subprocess.run')
92
+ @patch('time.time')
93
+ @patch('platform.system')
94
+ def test_lint_file_with_errors_unix(self, mock_platform, mock_time, mock_run):
95
+ """Test linting a file with syntax errors on Unix."""
96
+ # Setup
97
+ mock_platform.return_value = 'Linux'
98
+ mock_time.side_effect = [0, 1.5]
99
+ linter = JavaLinter()
100
+ mock_run.return_value = MagicMock(
101
+ stdout="",
102
+ stderr="Test.java:5: error: ';' expected\n int x = 10\n ^\n1 error"
103
+ )
104
+
105
+ # Execute
106
+ result = linter.lint_file('Test.java')
107
+
108
+ # Verify
109
+ assert result.has_issues
110
+ assert "=== javac ===" in result.lint_output
111
+ assert "';' expected" in result.lint_output
112
+ assert result.metadata['tools_used'] == ['javac']
113
+ assert result.success is True
114
+
115
+ # Check the command used (should have javac, -d, temp_dir, --release, 8, -Xlint:all, -proc:none, Test.java)
116
+ call_args = mock_run.call_args[0][0]
117
+ assert call_args[0] == 'javac'
118
+ assert call_args[1] == '-d'
119
+ # call_args[2] will be the temporary directory path
120
+ assert call_args[3] == '--release'
121
+ assert call_args[4] == '8'
122
+ assert call_args[5] == '-Xlint:all'
123
+ assert call_args[6] == '-proc:none'
124
+ assert call_args[-1] == 'Test.java' # File path is last
125
+
126
+ @patch('subprocess.run')
127
+ @patch('time.time')
128
+ @patch('platform.system')
129
+ def test_lint_file_with_errors_windows(self, mock_platform, mock_time, mock_run):
130
+ """Test linting a file with syntax errors on Windows."""
131
+ # Setup
132
+ mock_platform.return_value = 'Windows'
133
+ mock_time.side_effect = [0, 2]
134
+ linter = JavaLinter()
135
+ mock_run.return_value = MagicMock(
136
+ stdout="",
137
+ stderr="Test.java:3: error: class, interface, or enum expected"
138
+ )
139
+
140
+ # Execute
141
+ result = linter.lint_file('Test.java')
142
+
143
+ # Verify
144
+ assert result.has_issues
145
+ assert "class, interface, or enum expected" in result.lint_output
146
+ assert result.metadata['tools_used'] == ['javac']
147
+
148
+ # Check the command used (should have javac, -d, temp_dir, --release, 8, -Xlint:all, -proc:none, Test.java)
149
+ call_args = mock_run.call_args[0][0]
150
+ assert call_args[0] == 'javac'
151
+ assert call_args[1] == '-d'
152
+ # call_args[2] will be the temporary directory path
153
+ assert call_args[3] == '--release'
154
+ assert call_args[4] == '8'
155
+ assert call_args[5] == '-Xlint:all'
156
+ assert call_args[6] == '-proc:none'
157
+ assert call_args[-1] == 'Test.java' # File path is last
158
+
159
+ @patch('subprocess.run')
160
+ def test_lint_file_with_custom_args(self, mock_run):
161
+ """Test linting with custom javac arguments."""
162
+ linter = JavaLinter({
163
+ 'javac_args': ['-Xlint:all', '-encoding', 'UTF-8']
164
+ })
165
+ mock_run.return_value = MagicMock(stdout="", stderr="")
166
+
167
+ linter.lint_file('Test.java')
168
+
169
+ # Verify javac was called with custom arguments
170
+ call_args = mock_run.call_args[0][0]
171
+ assert call_args[0] == 'javac'
172
+ assert call_args[1] == '-d'
173
+ # call_args[2] will be the temporary directory path
174
+ assert call_args[3] == '--release'
175
+ assert call_args[4] == '8'
176
+ assert call_args[5] == '-Xlint:all'
177
+ assert call_args[6] == '-proc:none'
178
+ # Custom arguments should appear before the file path
179
+ assert '-Xlint:all' in call_args
180
+ assert '-encoding' in call_args
181
+ assert 'UTF-8' in call_args
182
+ assert call_args[-1] == 'Test.java' # File path is last
183
+
184
+ @patch('subprocess.run')
185
+ def test_lint_file_timeout(self, mock_run):
186
+ """Test handling of timeout during linting."""
187
+ linter = JavaLinter()
188
+ mock_run.side_effect = subprocess.TimeoutExpired(['javac'], 30)
189
+
190
+ result = linter.lint_file('Test.java')
191
+ assert result.success is False
192
+ assert "javac execution timed out" in result.error_message
193
+
194
+ @patch('subprocess.run')
195
+ def test_lint_file_general_error(self, mock_run):
196
+ """Test handling of general errors during linting."""
197
+ linter = JavaLinter()
198
+ mock_run.side_effect = Exception("Unexpected error")
199
+
200
+ result = linter.lint_file('Test.java')
201
+ assert result.success is False
202
+ assert "Error running javac: Unexpected error" in result.error_message
203
+
204
+ @pytest.mark.skipif(not JavaLinter().is_available(), reason="javac not available")
205
+ def test_real_lint_valid_java_file(self, tmp_path):
206
+ """Test linting a real valid Java file."""
207
+ # Create a valid Java file
208
+ java_content = '''
209
+ public class HelloWorld {
210
+ public static void main(String[] args) {
211
+ System.out.println("Hello, World!");
212
+ }
213
+ }
214
+ '''
215
+ java_file = tmp_path / "HelloWorld.java"
216
+ java_file.write_text(java_content)
217
+
218
+ # Lint the file
219
+ linter = JavaLinter()
220
+ result = linter.lint_file(java_file)
221
+
222
+ # Verify results
223
+ assert result.success is True
224
+ assert str(java_file) in result.files_checked
225
+ assert not result.has_issues # No syntax errors
226
+ assert result.lint_output == "" # No output means no errors
227
+ assert result.metadata['tools_used'] == ['javac']
228
+ assert result.execution_time > 0
229
+
230
+ @pytest.mark.skipif(not JavaLinter().is_available(), reason="javac not available")
231
+ def test_real_lint_invalid_java_file(self, tmp_path):
232
+ """Test linting a real Java file with syntax errors."""
233
+ # Create a Java file with syntax errors
234
+ java_content = '''
235
+ public class TestErrors {
236
+ public static void main(String[] args) {
237
+ // Missing semicolon
238
+ int x = 10
239
+
240
+ // Undefined variable
241
+ System.out.println(undefinedVar);
242
+
243
+ // Unclosed string
244
+ String message = "Hello
245
+ }
246
+ }
247
+ '''
248
+ java_file = tmp_path / "TestErrors.java"
249
+ java_file.write_text(java_content)
250
+
251
+ # Lint the file
252
+ linter = JavaLinter()
253
+ result = linter.lint_file(java_file)
254
+
255
+ # Verify results
256
+ assert result.success is True # Linting succeeded even with syntax errors
257
+ assert str(java_file) in result.files_checked
258
+ assert result.has_issues # Should have syntax errors
259
+ assert "=== javac ===" in result.lint_output
260
+ assert "error:" in result.lint_output # javac reports errors
261
+ # Common error patterns we expect
262
+ assert ("';' expected" in result.lint_output or
263
+ "expected" in result.lint_output) # Missing semicolon
264
+ assert result.metadata['tools_used'] == ['javac']
265
+ assert result.execution_time > 0
266
+
267
+ @pytest.mark.skipif(not JavaLinter().is_available(), reason="javac not available")
268
+ def test_real_lint_with_custom_args(self, tmp_path):
269
+ """Test linting with custom javac arguments."""
270
+ # Create a Java file with warnings
271
+ java_content = '''
272
+ import java.util.*; // Wildcard import
273
+
274
+ public class TestWarnings {
275
+ public static void main(String[] args) {
276
+ List list = new ArrayList(); // Raw type usage
277
+ list.add("test");
278
+ }
279
+ }
280
+ '''
281
+ java_file = tmp_path / "TestWarnings.java"
282
+ java_file.write_text(java_content)
283
+
284
+ # Lint with -Xlint:all to show warnings
285
+ linter = JavaLinter({'javac_args': ['-Xlint:all']})
286
+ result = linter.lint_file(java_file)
287
+
288
+ # Verify results
289
+ assert result.success is True
290
+ assert str(java_file) in result.files_checked
291
+ # With -Xlint:all, we might get warnings about raw types
292
+ # Note: warnings might not always appear in stderr, depends on javac version
293
+ assert result.metadata['tools_used'] == ['javac']
294
+
295
+ def test_project_type_detection(self, tmp_path):
296
+ """Test automatic project type detection."""
297
+ linter = JavaLinter()
298
+
299
+ # Test Maven detection
300
+ (tmp_path / "pom.xml").touch()
301
+ assert linter._detect_project_type(tmp_path) == 'maven'
302
+
303
+ # Test Gradle detection
304
+ (tmp_path / "pom.xml").unlink()
305
+ (tmp_path / "build.gradle").touch()
306
+ assert linter._detect_project_type(tmp_path) == 'gradle'
307
+
308
+ # Test Gradle Kotlin DSL detection
309
+ (tmp_path / "build.gradle").unlink()
310
+ (tmp_path / "build.gradle.kts").touch()
311
+ assert linter._detect_project_type(tmp_path) == 'gradle'
312
+
313
+ # Test local project (no build files)
314
+ (tmp_path / "build.gradle.kts").unlink()
315
+ assert linter._detect_project_type(tmp_path) == 'local'
316
+
317
+ def test_find_project_root(self, tmp_path):
318
+ """Test finding project root directory."""
319
+ linter = JavaLinter()
320
+
321
+ # Create project structure
322
+ project_root = tmp_path / "myproject"
323
+ src_dir = project_root / "src" / "main" / "java" / "com" / "example"
324
+ src_dir.mkdir(parents=True)
325
+ (project_root / "pom.xml").touch()
326
+
327
+ java_file = src_dir / "Test.java"
328
+ java_file.touch()
329
+
330
+ # Test finding project root
331
+ found_root = linter._find_project_root(java_file)
332
+ assert found_root == project_root
333
+
334
+ def test_find_local_jars(self, tmp_path):
335
+ """Test finding local JAR files."""
336
+ linter = JavaLinter({'lib_dirs': ['lib', 'libs']})
337
+
338
+ # Create lib directory with JARs
339
+ lib_dir = tmp_path / "lib"
340
+ lib_dir.mkdir()
341
+ (lib_dir / "commons-lang3.jar").touch()
342
+ (lib_dir / "guava.jar").touch()
343
+
344
+ libs_dir = tmp_path / "libs"
345
+ libs_dir.mkdir()
346
+ (libs_dir / "junit.jar").touch()
347
+
348
+ # Find JARs
349
+ classpath = linter._find_local_jars(tmp_path)
350
+ assert classpath is not None
351
+ assert "commons-lang3.jar" in classpath
352
+ assert "guava.jar" in classpath
353
+ assert "junit.jar" in classpath
354
+
355
+ def test_find_source_path(self, tmp_path):
356
+ """Test finding source paths."""
357
+ linter = JavaLinter({'source_paths': ['src', 'src/main/java', 'src/test/java']})
358
+
359
+ # Create source directories
360
+ (tmp_path / "src").mkdir()
361
+ (tmp_path / "src" / "main" / "java").mkdir(parents=True)
362
+
363
+ # Find source paths
364
+ source_path = linter._find_source_path(tmp_path)
365
+ assert source_path is not None
366
+ assert str(tmp_path / "src") in source_path
367
+ assert str(tmp_path / "src" / "main" / "java") in source_path
368
+
369
+ def test_check_for_module_info(self, tmp_path):
370
+ """Test JPMS module detection."""
371
+ linter = JavaLinter({'source_paths': ['src']})
372
+
373
+ # Create source directory
374
+ src_dir = tmp_path / "src"
375
+ src_dir.mkdir()
376
+
377
+ # Initially no module-info
378
+ assert linter._check_for_module_info(tmp_path) is False
379
+
380
+ # Add module-info.java
381
+ (src_dir / "module-info.java").touch()
382
+ assert linter._check_for_module_info(tmp_path) is True
383
+
384
+ @patch('subprocess.run')
385
+ def test_maven_classpath_resolution(self, mock_run, tmp_path):
386
+ """Test Maven dependency resolution."""
387
+ linter = JavaLinter({'enable_dependency_resolution': True})
388
+
389
+ # Create pom.xml
390
+ (tmp_path / "pom.xml").touch()
391
+
392
+ # Mock Maven output
393
+ with tempfile.NamedTemporaryFile(mode='w', delete=False) as tmp:
394
+ tmp.write("/path/to/lib1.jar:/path/to/lib2.jar")
395
+ tmp_file = tmp.name
396
+
397
+ def side_effect(*args, **kwargs):
398
+ # Write to the output file specified in the command
399
+ cmd = args[0]
400
+ for i, arg in enumerate(cmd):
401
+ if arg.startswith('-Dmdep.outputFile='):
402
+ output_file = arg.split('=')[1]
403
+ with open(output_file, 'w') as f:
404
+ f.write("/path/to/lib1.jar:/path/to/lib2.jar")
405
+ return MagicMock(returncode=0, stdout="", stderr="")
406
+
407
+ mock_run.side_effect = side_effect
408
+
409
+ # Resolve classpath
410
+ classpath = linter._resolve_maven_classpath(tmp_path)
411
+
412
+ # Verify
413
+ assert classpath is not None
414
+ assert "lib1.jar" in classpath
415
+ assert "lib2.jar" in classpath
416
+
417
+ # Clean up
418
+ if os.path.exists(tmp_file):
419
+ os.unlink(tmp_file)
420
+
421
+ @patch('subprocess.run')
422
+ def test_gradle_classpath_resolution(self, mock_run, tmp_path):
423
+ """Test Gradle dependency resolution."""
424
+ linter = JavaLinter({'enable_dependency_resolution': True})
425
+
426
+ # Create build.gradle
427
+ (tmp_path / "build.gradle").touch()
428
+
429
+ # Mock Gradle output
430
+ mock_run.return_value = MagicMock(
431
+ returncode=0,
432
+ stdout="/path/to/gradle-lib1.jar:/path/to/gradle-lib2.jar",
433
+ stderr=""
434
+ )
435
+
436
+ # Resolve classpath
437
+ classpath = linter._resolve_gradle_classpath(tmp_path)
438
+
439
+ # Verify
440
+ assert classpath is not None
441
+ assert "gradle-lib1.jar" in classpath
442
+ assert "gradle-lib2.jar" in classpath
443
+
444
+ @patch('subprocess.run')
445
+ def test_lint_with_dependencies(self, mock_run, tmp_path):
446
+ """Test linting with resolved dependencies."""
447
+ # Create project structure
448
+ (tmp_path / "pom.xml").touch()
449
+ src_dir = tmp_path / "src" / "main" / "java"
450
+ src_dir.mkdir(parents=True)
451
+
452
+ java_file = src_dir / "Test.java"
453
+ java_file.write_text("""
454
+ import org.apache.commons.lang3.StringUtils;
455
+
456
+ public class Test {
457
+ public static void main(String[] args) {
458
+ String result = StringUtils.capitalize("hello");
459
+ }
460
+ }
461
+ """)
462
+
463
+ # Configure linter
464
+ linter = JavaLinter({
465
+ 'enable_dependency_resolution': True,
466
+ 'source_paths': ['src/main/java']
467
+ })
468
+
469
+ # Mock Maven to return commons-lang3 in classpath
470
+ def maven_side_effect(*args, **kwargs):
471
+ cmd = args[0]
472
+ if 'dependency:build-classpath' in cmd:
473
+ for arg in cmd:
474
+ if arg.startswith('-Dmdep.outputFile='):
475
+ output_file = arg.split('=')[1]
476
+ with open(output_file, 'w') as f:
477
+ f.write("/path/to/commons-lang3.jar")
478
+ return MagicMock(returncode=0)
479
+ # For javac call
480
+ return MagicMock(returncode=0, stdout="", stderr="")
481
+
482
+ mock_run.side_effect = maven_side_effect
483
+
484
+ # Lint the file
485
+ result = linter.lint_file(java_file)
486
+
487
+ # Verify
488
+ assert result.success is True
489
+ assert result.metadata.get('classpath_resolved') is True
490
+ assert result.metadata.get('project_type') == 'maven'
491
+
492
+ # Check that javac was called with classpath
493
+ javac_calls = [call for call in mock_run.call_args_list if 'javac' in str(call)]
494
+ assert len(javac_calls) > 0
495
+ javac_args = javac_calls[0][0][0]
496
+ assert '-classpath' in javac_args or '--module-path' in javac_args