jarvis-ai-assistant 0.7.8__py3-none-any.whl → 1.0.2__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.
- jarvis/__init__.py +1 -1
- jarvis/jarvis_agent/__init__.py +567 -222
- jarvis/jarvis_agent/agent_manager.py +19 -12
- jarvis/jarvis_agent/builtin_input_handler.py +79 -11
- jarvis/jarvis_agent/config_editor.py +7 -2
- jarvis/jarvis_agent/event_bus.py +24 -13
- jarvis/jarvis_agent/events.py +19 -1
- jarvis/jarvis_agent/file_context_handler.py +67 -64
- jarvis/jarvis_agent/file_methodology_manager.py +38 -24
- jarvis/jarvis_agent/jarvis.py +186 -114
- jarvis/jarvis_agent/language_extractors/__init__.py +8 -1
- jarvis/jarvis_agent/language_extractors/c_extractor.py +7 -4
- jarvis/jarvis_agent/language_extractors/cpp_extractor.py +9 -4
- jarvis/jarvis_agent/language_extractors/go_extractor.py +7 -4
- jarvis/jarvis_agent/language_extractors/java_extractor.py +27 -20
- jarvis/jarvis_agent/language_extractors/javascript_extractor.py +22 -17
- jarvis/jarvis_agent/language_extractors/python_extractor.py +7 -4
- jarvis/jarvis_agent/language_extractors/rust_extractor.py +7 -4
- jarvis/jarvis_agent/language_extractors/typescript_extractor.py +22 -17
- jarvis/jarvis_agent/language_support_info.py +250 -219
- jarvis/jarvis_agent/main.py +19 -23
- jarvis/jarvis_agent/memory_manager.py +9 -6
- jarvis/jarvis_agent/methodology_share_manager.py +21 -15
- jarvis/jarvis_agent/output_handler.py +4 -2
- jarvis/jarvis_agent/prompt_builder.py +7 -6
- jarvis/jarvis_agent/prompt_manager.py +113 -8
- jarvis/jarvis_agent/prompts.py +317 -85
- jarvis/jarvis_agent/protocols.py +5 -2
- jarvis/jarvis_agent/run_loop.py +192 -32
- jarvis/jarvis_agent/session_manager.py +7 -3
- jarvis/jarvis_agent/share_manager.py +23 -13
- jarvis/jarvis_agent/shell_input_handler.py +12 -8
- jarvis/jarvis_agent/stdio_redirect.py +25 -26
- jarvis/jarvis_agent/task_analyzer.py +29 -23
- jarvis/jarvis_agent/task_list.py +869 -0
- jarvis/jarvis_agent/task_manager.py +26 -23
- jarvis/jarvis_agent/tool_executor.py +6 -5
- jarvis/jarvis_agent/tool_share_manager.py +24 -14
- jarvis/jarvis_agent/user_interaction.py +3 -3
- jarvis/jarvis_agent/utils.py +9 -1
- jarvis/jarvis_agent/web_bridge.py +37 -17
- jarvis/jarvis_agent/web_output_sink.py +5 -2
- jarvis/jarvis_agent/web_server.py +165 -36
- jarvis/jarvis_c2rust/__init__.py +1 -1
- jarvis/jarvis_c2rust/cli.py +260 -141
- jarvis/jarvis_c2rust/collector.py +37 -18
- jarvis/jarvis_c2rust/constants.py +60 -0
- jarvis/jarvis_c2rust/library_replacer.py +242 -1010
- jarvis/jarvis_c2rust/library_replacer_checkpoint.py +133 -0
- jarvis/jarvis_c2rust/library_replacer_llm.py +287 -0
- jarvis/jarvis_c2rust/library_replacer_loader.py +191 -0
- jarvis/jarvis_c2rust/library_replacer_output.py +134 -0
- jarvis/jarvis_c2rust/library_replacer_prompts.py +124 -0
- jarvis/jarvis_c2rust/library_replacer_utils.py +188 -0
- jarvis/jarvis_c2rust/llm_module_agent.py +98 -1044
- jarvis/jarvis_c2rust/llm_module_agent_apply.py +170 -0
- jarvis/jarvis_c2rust/llm_module_agent_executor.py +288 -0
- jarvis/jarvis_c2rust/llm_module_agent_loader.py +170 -0
- jarvis/jarvis_c2rust/llm_module_agent_prompts.py +268 -0
- jarvis/jarvis_c2rust/llm_module_agent_types.py +57 -0
- jarvis/jarvis_c2rust/llm_module_agent_utils.py +150 -0
- jarvis/jarvis_c2rust/llm_module_agent_validator.py +119 -0
- jarvis/jarvis_c2rust/loaders.py +28 -10
- jarvis/jarvis_c2rust/models.py +5 -2
- jarvis/jarvis_c2rust/optimizer.py +192 -1974
- jarvis/jarvis_c2rust/optimizer_build_fix.py +286 -0
- jarvis/jarvis_c2rust/optimizer_clippy.py +766 -0
- jarvis/jarvis_c2rust/optimizer_config.py +49 -0
- jarvis/jarvis_c2rust/optimizer_docs.py +183 -0
- jarvis/jarvis_c2rust/optimizer_options.py +48 -0
- jarvis/jarvis_c2rust/optimizer_progress.py +469 -0
- jarvis/jarvis_c2rust/optimizer_report.py +52 -0
- jarvis/jarvis_c2rust/optimizer_unsafe.py +309 -0
- jarvis/jarvis_c2rust/optimizer_utils.py +469 -0
- jarvis/jarvis_c2rust/optimizer_visibility.py +185 -0
- jarvis/jarvis_c2rust/scanner.py +229 -166
- jarvis/jarvis_c2rust/transpiler.py +531 -2732
- jarvis/jarvis_c2rust/transpiler_agents.py +503 -0
- jarvis/jarvis_c2rust/transpiler_build.py +1294 -0
- jarvis/jarvis_c2rust/transpiler_codegen.py +204 -0
- jarvis/jarvis_c2rust/transpiler_compile.py +146 -0
- jarvis/jarvis_c2rust/transpiler_config.py +178 -0
- jarvis/jarvis_c2rust/transpiler_context.py +122 -0
- jarvis/jarvis_c2rust/transpiler_executor.py +516 -0
- jarvis/jarvis_c2rust/transpiler_generation.py +278 -0
- jarvis/jarvis_c2rust/transpiler_git.py +163 -0
- jarvis/jarvis_c2rust/transpiler_mod_utils.py +225 -0
- jarvis/jarvis_c2rust/transpiler_modules.py +336 -0
- jarvis/jarvis_c2rust/transpiler_planning.py +394 -0
- jarvis/jarvis_c2rust/transpiler_review.py +1196 -0
- jarvis/jarvis_c2rust/transpiler_symbols.py +176 -0
- jarvis/jarvis_c2rust/utils.py +269 -79
- jarvis/jarvis_code_agent/after_change.py +233 -0
- jarvis/jarvis_code_agent/build_validation_config.py +37 -30
- jarvis/jarvis_code_agent/builtin_rules.py +68 -0
- jarvis/jarvis_code_agent/code_agent.py +976 -1517
- jarvis/jarvis_code_agent/code_agent_build.py +227 -0
- jarvis/jarvis_code_agent/code_agent_diff.py +246 -0
- jarvis/jarvis_code_agent/code_agent_git.py +525 -0
- jarvis/jarvis_code_agent/code_agent_impact.py +177 -0
- jarvis/jarvis_code_agent/code_agent_lint.py +283 -0
- jarvis/jarvis_code_agent/code_agent_llm.py +159 -0
- jarvis/jarvis_code_agent/code_agent_postprocess.py +105 -0
- jarvis/jarvis_code_agent/code_agent_prompts.py +46 -0
- jarvis/jarvis_code_agent/code_agent_rules.py +305 -0
- jarvis/jarvis_code_agent/code_analyzer/__init__.py +52 -48
- jarvis/jarvis_code_agent/code_analyzer/base_language.py +12 -10
- jarvis/jarvis_code_agent/code_analyzer/build_validator/__init__.py +12 -11
- jarvis/jarvis_code_agent/code_analyzer/build_validator/base.py +16 -12
- jarvis/jarvis_code_agent/code_analyzer/build_validator/cmake.py +26 -17
- jarvis/jarvis_code_agent/code_analyzer/build_validator/detector.py +558 -104
- jarvis/jarvis_code_agent/code_analyzer/build_validator/fallback.py +27 -16
- jarvis/jarvis_code_agent/code_analyzer/build_validator/go.py +22 -18
- jarvis/jarvis_code_agent/code_analyzer/build_validator/java_gradle.py +21 -16
- jarvis/jarvis_code_agent/code_analyzer/build_validator/java_maven.py +20 -16
- jarvis/jarvis_code_agent/code_analyzer/build_validator/makefile.py +27 -16
- jarvis/jarvis_code_agent/code_analyzer/build_validator/nodejs.py +47 -23
- jarvis/jarvis_code_agent/code_analyzer/build_validator/python.py +71 -37
- jarvis/jarvis_code_agent/code_analyzer/build_validator/rust.py +162 -35
- jarvis/jarvis_code_agent/code_analyzer/build_validator/validator.py +111 -57
- jarvis/jarvis_code_agent/code_analyzer/build_validator.py +18 -12
- jarvis/jarvis_code_agent/code_analyzer/context_manager.py +185 -183
- jarvis/jarvis_code_agent/code_analyzer/context_recommender.py +2 -1
- jarvis/jarvis_code_agent/code_analyzer/dependency_analyzer.py +24 -15
- jarvis/jarvis_code_agent/code_analyzer/file_ignore.py +227 -141
- jarvis/jarvis_code_agent/code_analyzer/impact_analyzer.py +321 -247
- jarvis/jarvis_code_agent/code_analyzer/language_registry.py +37 -29
- jarvis/jarvis_code_agent/code_analyzer/language_support.py +21 -13
- jarvis/jarvis_code_agent/code_analyzer/languages/__init__.py +15 -9
- jarvis/jarvis_code_agent/code_analyzer/languages/c_cpp_language.py +75 -45
- jarvis/jarvis_code_agent/code_analyzer/languages/go_language.py +87 -52
- jarvis/jarvis_code_agent/code_analyzer/languages/java_language.py +84 -51
- jarvis/jarvis_code_agent/code_analyzer/languages/javascript_language.py +94 -64
- jarvis/jarvis_code_agent/code_analyzer/languages/python_language.py +109 -71
- jarvis/jarvis_code_agent/code_analyzer/languages/rust_language.py +97 -63
- jarvis/jarvis_code_agent/code_analyzer/languages/typescript_language.py +103 -69
- jarvis/jarvis_code_agent/code_analyzer/llm_context_recommender.py +271 -268
- jarvis/jarvis_code_agent/code_analyzer/symbol_extractor.py +76 -64
- jarvis/jarvis_code_agent/code_analyzer/tree_sitter_extractor.py +92 -19
- jarvis/jarvis_code_agent/diff_visualizer.py +998 -0
- jarvis/jarvis_code_agent/lint.py +223 -524
- jarvis/jarvis_code_agent/rule_share_manager.py +158 -0
- jarvis/jarvis_code_agent/rules/clean_code.md +144 -0
- jarvis/jarvis_code_agent/rules/code_review.md +115 -0
- jarvis/jarvis_code_agent/rules/documentation.md +165 -0
- jarvis/jarvis_code_agent/rules/generate_rules.md +52 -0
- jarvis/jarvis_code_agent/rules/performance.md +158 -0
- jarvis/jarvis_code_agent/rules/refactoring.md +139 -0
- jarvis/jarvis_code_agent/rules/security.md +160 -0
- jarvis/jarvis_code_agent/rules/tdd.md +78 -0
- jarvis/jarvis_code_agent/test_rules/cpp_test.md +118 -0
- jarvis/jarvis_code_agent/test_rules/go_test.md +98 -0
- jarvis/jarvis_code_agent/test_rules/java_test.md +99 -0
- jarvis/jarvis_code_agent/test_rules/javascript_test.md +113 -0
- jarvis/jarvis_code_agent/test_rules/php_test.md +117 -0
- jarvis/jarvis_code_agent/test_rules/python_test.md +91 -0
- jarvis/jarvis_code_agent/test_rules/ruby_test.md +102 -0
- jarvis/jarvis_code_agent/test_rules/rust_test.md +86 -0
- jarvis/jarvis_code_agent/utils.py +36 -26
- jarvis/jarvis_code_analysis/checklists/loader.py +21 -21
- jarvis/jarvis_code_analysis/code_review.py +64 -33
- jarvis/jarvis_data/config_schema.json +285 -192
- jarvis/jarvis_git_squash/main.py +8 -6
- jarvis/jarvis_git_utils/git_commiter.py +53 -76
- jarvis/jarvis_mcp/__init__.py +5 -2
- jarvis/jarvis_mcp/sse_mcp_client.py +40 -30
- jarvis/jarvis_mcp/stdio_mcp_client.py +27 -19
- jarvis/jarvis_mcp/streamable_mcp_client.py +35 -26
- jarvis/jarvis_memory_organizer/memory_organizer.py +78 -55
- jarvis/jarvis_methodology/main.py +48 -39
- jarvis/jarvis_multi_agent/__init__.py +56 -23
- jarvis/jarvis_multi_agent/main.py +15 -18
- jarvis/jarvis_platform/base.py +179 -111
- jarvis/jarvis_platform/human.py +27 -16
- jarvis/jarvis_platform/kimi.py +52 -45
- jarvis/jarvis_platform/openai.py +101 -40
- jarvis/jarvis_platform/registry.py +51 -33
- jarvis/jarvis_platform/tongyi.py +68 -38
- jarvis/jarvis_platform/yuanbao.py +59 -43
- jarvis/jarvis_platform_manager/main.py +68 -76
- jarvis/jarvis_platform_manager/service.py +24 -14
- jarvis/jarvis_rag/README_CONFIG.md +314 -0
- jarvis/jarvis_rag/README_DYNAMIC_LOADING.md +311 -0
- jarvis/jarvis_rag/README_ONLINE_MODELS.md +230 -0
- jarvis/jarvis_rag/__init__.py +57 -4
- jarvis/jarvis_rag/cache.py +3 -1
- jarvis/jarvis_rag/cli.py +48 -68
- jarvis/jarvis_rag/embedding_interface.py +39 -0
- jarvis/jarvis_rag/embedding_manager.py +7 -230
- jarvis/jarvis_rag/embeddings/__init__.py +41 -0
- jarvis/jarvis_rag/embeddings/base.py +114 -0
- jarvis/jarvis_rag/embeddings/cohere.py +66 -0
- jarvis/jarvis_rag/embeddings/edgefn.py +117 -0
- jarvis/jarvis_rag/embeddings/local.py +260 -0
- jarvis/jarvis_rag/embeddings/openai.py +62 -0
- jarvis/jarvis_rag/embeddings/registry.py +293 -0
- jarvis/jarvis_rag/llm_interface.py +8 -6
- jarvis/jarvis_rag/query_rewriter.py +8 -9
- jarvis/jarvis_rag/rag_pipeline.py +61 -52
- jarvis/jarvis_rag/reranker.py +7 -75
- jarvis/jarvis_rag/reranker_interface.py +32 -0
- jarvis/jarvis_rag/rerankers/__init__.py +41 -0
- jarvis/jarvis_rag/rerankers/base.py +109 -0
- jarvis/jarvis_rag/rerankers/cohere.py +67 -0
- jarvis/jarvis_rag/rerankers/edgefn.py +140 -0
- jarvis/jarvis_rag/rerankers/jina.py +79 -0
- jarvis/jarvis_rag/rerankers/local.py +89 -0
- jarvis/jarvis_rag/rerankers/registry.py +293 -0
- jarvis/jarvis_rag/retriever.py +58 -43
- jarvis/jarvis_sec/__init__.py +66 -141
- jarvis/jarvis_sec/agents.py +21 -17
- jarvis/jarvis_sec/analysis.py +80 -33
- jarvis/jarvis_sec/checkers/__init__.py +7 -13
- jarvis/jarvis_sec/checkers/c_checker.py +356 -164
- jarvis/jarvis_sec/checkers/rust_checker.py +47 -29
- jarvis/jarvis_sec/cli.py +43 -21
- jarvis/jarvis_sec/clustering.py +430 -272
- jarvis/jarvis_sec/file_manager.py +99 -55
- jarvis/jarvis_sec/parsers.py +9 -6
- jarvis/jarvis_sec/prompts.py +4 -3
- jarvis/jarvis_sec/report.py +44 -22
- jarvis/jarvis_sec/review.py +180 -107
- jarvis/jarvis_sec/status.py +50 -41
- jarvis/jarvis_sec/types.py +3 -0
- jarvis/jarvis_sec/utils.py +160 -83
- jarvis/jarvis_sec/verification.py +411 -181
- jarvis/jarvis_sec/workflow.py +132 -21
- jarvis/jarvis_smart_shell/main.py +28 -41
- jarvis/jarvis_stats/cli.py +14 -12
- jarvis/jarvis_stats/stats.py +28 -19
- jarvis/jarvis_stats/storage.py +14 -8
- jarvis/jarvis_stats/visualizer.py +12 -7
- jarvis/jarvis_tools/base.py +5 -2
- jarvis/jarvis_tools/clear_memory.py +13 -9
- jarvis/jarvis_tools/cli/main.py +23 -18
- jarvis/jarvis_tools/edit_file.py +572 -873
- jarvis/jarvis_tools/execute_script.py +10 -7
- jarvis/jarvis_tools/file_analyzer.py +7 -8
- jarvis/jarvis_tools/meta_agent.py +287 -0
- jarvis/jarvis_tools/methodology.py +5 -3
- jarvis/jarvis_tools/read_code.py +305 -1438
- jarvis/jarvis_tools/read_symbols.py +50 -17
- jarvis/jarvis_tools/read_webpage.py +19 -18
- jarvis/jarvis_tools/registry.py +435 -156
- jarvis/jarvis_tools/retrieve_memory.py +16 -11
- jarvis/jarvis_tools/save_memory.py +8 -6
- jarvis/jarvis_tools/search_web.py +31 -31
- jarvis/jarvis_tools/sub_agent.py +32 -28
- jarvis/jarvis_tools/sub_code_agent.py +44 -60
- jarvis/jarvis_tools/task_list_manager.py +1811 -0
- jarvis/jarvis_tools/virtual_tty.py +29 -19
- jarvis/jarvis_utils/__init__.py +4 -0
- jarvis/jarvis_utils/builtin_replace_map.py +2 -1
- jarvis/jarvis_utils/clipboard.py +9 -8
- jarvis/jarvis_utils/collections.py +331 -0
- jarvis/jarvis_utils/config.py +699 -194
- jarvis/jarvis_utils/dialogue_recorder.py +294 -0
- jarvis/jarvis_utils/embedding.py +6 -3
- jarvis/jarvis_utils/file_processors.py +7 -1
- jarvis/jarvis_utils/fzf.py +9 -3
- jarvis/jarvis_utils/git_utils.py +71 -42
- jarvis/jarvis_utils/globals.py +116 -32
- jarvis/jarvis_utils/http.py +6 -2
- jarvis/jarvis_utils/input.py +318 -83
- jarvis/jarvis_utils/jsonnet_compat.py +119 -104
- jarvis/jarvis_utils/methodology.py +37 -28
- jarvis/jarvis_utils/output.py +201 -44
- jarvis/jarvis_utils/utils.py +986 -628
- {jarvis_ai_assistant-0.7.8.dist-info → jarvis_ai_assistant-1.0.2.dist-info}/METADATA +49 -33
- jarvis_ai_assistant-1.0.2.dist-info/RECORD +304 -0
- jarvis/jarvis_code_agent/code_analyzer/structured_code.py +0 -556
- jarvis/jarvis_tools/generate_new_tool.py +0 -205
- jarvis/jarvis_tools/lsp_client.py +0 -1552
- jarvis/jarvis_tools/rewrite_file.py +0 -105
- jarvis_ai_assistant-0.7.8.dist-info/RECORD +0 -218
- {jarvis_ai_assistant-0.7.8.dist-info → jarvis_ai_assistant-1.0.2.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.7.8.dist-info → jarvis_ai_assistant-1.0.2.dist-info}/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.7.8.dist-info → jarvis_ai_assistant-1.0.2.dist-info}/licenses/LICENSE +0 -0
- {jarvis_ai_assistant-0.7.8.dist-info → jarvis_ai_assistant-1.0.2.dist-info}/top_level.txt +0 -0
jarvis/jarvis_c2rust/cli.py
CHANGED
|
@@ -15,17 +15,18 @@ from __future__ import annotations
|
|
|
15
15
|
|
|
16
16
|
import os
|
|
17
17
|
from pathlib import Path
|
|
18
|
-
from typing import
|
|
18
|
+
from typing import List
|
|
19
|
+
from typing import Optional
|
|
19
20
|
|
|
20
21
|
import typer
|
|
21
|
-
from jarvis.
|
|
22
|
+
from jarvis.jarvis_utils.output import PrettyOutput
|
|
23
|
+
|
|
22
24
|
from jarvis.jarvis_c2rust.library_replacer import (
|
|
23
25
|
apply_library_replacement as _apply_library_replacement,
|
|
24
26
|
)
|
|
27
|
+
from jarvis.jarvis_c2rust.llm_module_agent import execute_llm_plan as _execute_llm_plan
|
|
28
|
+
from jarvis.jarvis_c2rust.scanner import run_scan as _run_scan
|
|
25
29
|
from jarvis.jarvis_utils.utils import init_env
|
|
26
|
-
from jarvis.jarvis_c2rust.llm_module_agent import (
|
|
27
|
-
execute_llm_plan as _execute_llm_plan,
|
|
28
|
-
)
|
|
29
30
|
|
|
30
31
|
|
|
31
32
|
def _check_optimize_completed(crate_dir: Path) -> bool:
|
|
@@ -35,22 +36,24 @@ def _check_optimize_completed(crate_dir: Path) -> bool:
|
|
|
35
36
|
特别是 clippy_elimination:如果有告警,必须完成;如果没有告警,可以跳过。
|
|
36
37
|
"""
|
|
37
38
|
import json
|
|
39
|
+
|
|
38
40
|
from jarvis.jarvis_c2rust.constants import C2RUST_DIRNAME
|
|
39
|
-
|
|
41
|
+
|
|
40
42
|
progress_path = crate_dir / C2RUST_DIRNAME / "optimize_progress.json"
|
|
41
43
|
if not progress_path.exists():
|
|
42
44
|
# 如果没有进度文件,说明还没开始,不算完成
|
|
43
45
|
return False
|
|
44
|
-
|
|
46
|
+
|
|
45
47
|
try:
|
|
46
48
|
with progress_path.open("r", encoding="utf-8") as f:
|
|
47
49
|
progress = json.load(f)
|
|
48
|
-
|
|
50
|
+
|
|
49
51
|
steps_completed = set(progress.get("steps_completed", []))
|
|
50
|
-
|
|
52
|
+
|
|
51
53
|
# 检查是否有 clippy 告警
|
|
52
54
|
# 直接调用 optimizer 模块中的函数(虽然是私有函数,但我们需要它来检查)
|
|
53
55
|
import subprocess
|
|
56
|
+
|
|
54
57
|
try:
|
|
55
58
|
res = subprocess.run(
|
|
56
59
|
["cargo", "clippy", "--", "-W", "clippy::all"],
|
|
@@ -61,22 +64,30 @@ def _check_optimize_completed(crate_dir: Path) -> bool:
|
|
|
61
64
|
)
|
|
62
65
|
stderr_output = (res.stderr or "").strip()
|
|
63
66
|
stdout_output = (res.stdout or "").strip()
|
|
64
|
-
output = (
|
|
67
|
+
output = (
|
|
68
|
+
(stderr_output + "\n" + stdout_output).strip()
|
|
69
|
+
if (stderr_output and stdout_output)
|
|
70
|
+
else (stderr_output or stdout_output or "").strip()
|
|
71
|
+
)
|
|
65
72
|
output_lower = output.lower()
|
|
66
|
-
has_warnings =
|
|
73
|
+
has_warnings = (
|
|
74
|
+
"warning:" in output_lower
|
|
75
|
+
or "warn(" in output_lower
|
|
76
|
+
or ("clippy::" in output_lower and res.returncode != 0)
|
|
77
|
+
)
|
|
67
78
|
except Exception:
|
|
68
79
|
# 如果检查失败,保守地认为有告警(需要完成)
|
|
69
80
|
has_warnings = True
|
|
70
|
-
|
|
81
|
+
|
|
71
82
|
# 如果有告警,clippy_elimination 必须在 steps_completed 中
|
|
72
83
|
if has_warnings:
|
|
73
84
|
if "clippy_elimination" not in steps_completed:
|
|
74
85
|
return False
|
|
75
|
-
|
|
86
|
+
|
|
76
87
|
# 检查其他必要的步骤(根据 enable_* 选项,但这里我们假设都启用了)
|
|
77
88
|
# 注意:这里我们只检查 clippy_elimination,其他步骤(unsafe_cleanup, visibility_opt, doc_opt)
|
|
78
89
|
# 可能因为 enable_* 选项而未执行,所以不强制要求
|
|
79
|
-
|
|
90
|
+
|
|
80
91
|
return True
|
|
81
92
|
except Exception:
|
|
82
93
|
# 如果读取失败,保守地认为未完成
|
|
@@ -85,6 +96,7 @@ def _check_optimize_completed(crate_dir: Path) -> bool:
|
|
|
85
96
|
|
|
86
97
|
app = typer.Typer(help="C2Rust 命令行工具")
|
|
87
98
|
|
|
99
|
+
|
|
88
100
|
# 显式定义根回调,确保为命令组而非单函数入口
|
|
89
101
|
@app.callback()
|
|
90
102
|
def _root():
|
|
@@ -92,7 +104,7 @@ def _root():
|
|
|
92
104
|
C2Rust 命令行工具
|
|
93
105
|
"""
|
|
94
106
|
# 设置环境变量,标识当前运行在 c2rust 环境中
|
|
95
|
-
os.environ["
|
|
107
|
+
os.environ["c2rust_enabled"] = "1"
|
|
96
108
|
# 不做任何处理,仅作为命令组的占位,使 'scan' 作为子命令出现
|
|
97
109
|
init_env("")
|
|
98
110
|
pass
|
|
@@ -104,15 +116,21 @@ def _load_config() -> dict:
|
|
|
104
116
|
返回包含 root_symbols、disabled_libraries 和 additional_notes 的字典。
|
|
105
117
|
"""
|
|
106
118
|
import json
|
|
107
|
-
|
|
108
|
-
|
|
119
|
+
|
|
120
|
+
from jarvis.jarvis_c2rust.constants import C2RUST_DIRNAME
|
|
121
|
+
from jarvis.jarvis_c2rust.constants import CONFIG_JSON
|
|
122
|
+
|
|
109
123
|
data_dir = Path(".") / C2RUST_DIRNAME
|
|
110
124
|
config_path = data_dir / CONFIG_JSON
|
|
111
|
-
default_config = {
|
|
112
|
-
|
|
125
|
+
default_config = {
|
|
126
|
+
"root_symbols": [],
|
|
127
|
+
"disabled_libraries": [],
|
|
128
|
+
"additional_notes": "",
|
|
129
|
+
}
|
|
130
|
+
|
|
113
131
|
if not config_path.exists():
|
|
114
132
|
return default_config
|
|
115
|
-
|
|
133
|
+
|
|
116
134
|
try:
|
|
117
135
|
with config_path.open("r", encoding="utf-8") as f:
|
|
118
136
|
config = json.load(f)
|
|
@@ -128,12 +146,11 @@ def _load_config() -> dict:
|
|
|
128
146
|
return default_config
|
|
129
147
|
|
|
130
148
|
|
|
131
|
-
RUN_STATE_JSON = "run_state.json"
|
|
132
|
-
|
|
133
|
-
|
|
134
149
|
def _get_run_state_path() -> Path:
|
|
135
150
|
"""获取 run 状态文件路径"""
|
|
136
151
|
from jarvis.jarvis_c2rust.constants import C2RUST_DIRNAME
|
|
152
|
+
from jarvis.jarvis_c2rust.constants import RUN_STATE_JSON
|
|
153
|
+
|
|
137
154
|
data_dir = Path(".") / C2RUST_DIRNAME
|
|
138
155
|
return data_dir / RUN_STATE_JSON
|
|
139
156
|
|
|
@@ -141,7 +158,7 @@ def _get_run_state_path() -> Path:
|
|
|
141
158
|
def _load_run_state() -> dict:
|
|
142
159
|
"""加载 run 状态文件"""
|
|
143
160
|
import json
|
|
144
|
-
|
|
161
|
+
|
|
145
162
|
state_path = _get_run_state_path()
|
|
146
163
|
default_state = {
|
|
147
164
|
"scan": {"completed": False, "timestamp": None},
|
|
@@ -150,10 +167,10 @@ def _load_run_state() -> dict:
|
|
|
150
167
|
"transpile": {"completed": False, "timestamp": None},
|
|
151
168
|
"optimize": {"completed": False, "timestamp": None},
|
|
152
169
|
}
|
|
153
|
-
|
|
170
|
+
|
|
154
171
|
if not state_path.exists():
|
|
155
172
|
return default_state
|
|
156
|
-
|
|
173
|
+
|
|
157
174
|
try:
|
|
158
175
|
with state_path.open("r", encoding="utf-8") as f:
|
|
159
176
|
state = json.load(f)
|
|
@@ -172,27 +189,31 @@ def _save_run_state(stage: str, completed: bool = True) -> None:
|
|
|
172
189
|
"""保存 run 状态文件"""
|
|
173
190
|
import json
|
|
174
191
|
import time
|
|
175
|
-
|
|
192
|
+
|
|
176
193
|
state_path = _get_run_state_path()
|
|
177
194
|
state = _load_run_state()
|
|
178
|
-
|
|
195
|
+
|
|
179
196
|
state[stage] = {
|
|
180
197
|
"completed": completed,
|
|
181
|
-
"timestamp": time.strftime("%Y-%m-%dT%H:%M:%S", time.localtime())
|
|
198
|
+
"timestamp": time.strftime("%Y-%m-%dT%H:%M:%S", time.localtime())
|
|
199
|
+
if completed
|
|
200
|
+
else None,
|
|
182
201
|
}
|
|
183
|
-
|
|
202
|
+
|
|
184
203
|
try:
|
|
185
204
|
state_path.parent.mkdir(parents=True, exist_ok=True)
|
|
186
205
|
with state_path.open("w", encoding="utf-8") as f:
|
|
187
206
|
json.dump(state, f, ensure_ascii=False, indent=2)
|
|
188
207
|
except Exception as e:
|
|
189
|
-
|
|
208
|
+
PrettyOutput.auto_print(f"⚠️ [c2rust-run] 保存状态文件失败: {e}")
|
|
190
209
|
|
|
191
210
|
|
|
192
211
|
@app.command("config")
|
|
193
212
|
def config(
|
|
194
213
|
files: Optional[List[Path]] = typer.Option(
|
|
195
|
-
None,
|
|
214
|
+
None,
|
|
215
|
+
"--files",
|
|
216
|
+
help="头文件(.h/.hh/.hpp/.hxx)或函数名列表文件(每行一个函数名,忽略空行与以#开头的注释)",
|
|
196
217
|
),
|
|
197
218
|
root_list_syms: Optional[str] = typer.Option(
|
|
198
219
|
None, "--root-list-syms", help="根符号列表内联(逗号分隔)"
|
|
@@ -203,58 +224,60 @@ def config(
|
|
|
203
224
|
additional_notes: Optional[str] = typer.Option(
|
|
204
225
|
None, "--additional-notes", help="附加说明(将在所有 agent 的提示词中追加)"
|
|
205
226
|
),
|
|
206
|
-
show: bool = typer.Option(
|
|
207
|
-
|
|
208
|
-
),
|
|
209
|
-
clear: bool = typer.Option(
|
|
210
|
-
False, "--clear", help="清空配置(重置为默认值)"
|
|
211
|
-
),
|
|
227
|
+
show: bool = typer.Option(False, "--show", help="显示当前配置内容"),
|
|
228
|
+
clear: bool = typer.Option(False, "--clear", help="清空配置(重置为默认值)"),
|
|
212
229
|
) -> None:
|
|
213
230
|
"""
|
|
214
231
|
管理转译配置文件(.jarvis/c2rust/config.json)。
|
|
215
|
-
|
|
232
|
+
|
|
216
233
|
可以设置根符号列表(root_symbols)、禁用库列表(disabled_libraries)和附加说明(additional_notes)。
|
|
217
234
|
这些配置会被 transpile 命令自动读取和使用。
|
|
218
|
-
|
|
235
|
+
|
|
219
236
|
示例:
|
|
220
237
|
# 从头文件自动提取函数名并设置根符号列表
|
|
221
238
|
jarvis-c2rust config --files bzlib.h
|
|
222
|
-
|
|
239
|
+
|
|
223
240
|
# 从多个头文件提取函数名
|
|
224
241
|
jarvis-c2rust config --files a.h b.hpp c.hxx
|
|
225
|
-
|
|
242
|
+
|
|
226
243
|
# 从函数名列表文件设置根符号列表
|
|
227
244
|
jarvis-c2rust config --files roots.txt
|
|
228
|
-
|
|
245
|
+
|
|
229
246
|
# 从命令行设置根符号列表
|
|
230
247
|
jarvis-c2rust config --root-list-syms "func1,func2,func3"
|
|
231
|
-
|
|
248
|
+
|
|
232
249
|
# 设置禁用库列表
|
|
233
250
|
jarvis-c2rust config --disabled-libs "libc,libm"
|
|
234
|
-
|
|
251
|
+
|
|
235
252
|
# 设置附加说明(将在所有 agent 的提示词中追加)
|
|
236
253
|
jarvis-c2rust config --additional-notes "注意:所有函数必须处理错误情况,避免 panic"
|
|
237
|
-
|
|
254
|
+
|
|
238
255
|
# 同时设置多个参数
|
|
239
256
|
jarvis-c2rust config --files bzlib.h --disabled-libs "libc" --additional-notes "特殊要求说明"
|
|
240
|
-
|
|
257
|
+
|
|
241
258
|
# 查看当前配置
|
|
242
259
|
jarvis-c2rust config --show
|
|
243
|
-
|
|
260
|
+
|
|
244
261
|
# 清空配置
|
|
245
262
|
jarvis-c2rust config --clear
|
|
246
263
|
"""
|
|
247
264
|
import json
|
|
248
|
-
|
|
249
|
-
|
|
265
|
+
|
|
266
|
+
from jarvis.jarvis_c2rust.constants import C2RUST_DIRNAME
|
|
267
|
+
from jarvis.jarvis_c2rust.constants import CONFIG_JSON
|
|
268
|
+
|
|
250
269
|
data_dir = Path(".") / C2RUST_DIRNAME
|
|
251
270
|
config_path = data_dir / CONFIG_JSON
|
|
252
271
|
data_dir.mkdir(parents=True, exist_ok=True)
|
|
253
|
-
|
|
272
|
+
|
|
254
273
|
# 读取现有配置
|
|
255
|
-
default_config = {
|
|
274
|
+
default_config = {
|
|
275
|
+
"root_symbols": [],
|
|
276
|
+
"disabled_libraries": [],
|
|
277
|
+
"additional_notes": "",
|
|
278
|
+
}
|
|
256
279
|
current_config = default_config.copy()
|
|
257
|
-
|
|
280
|
+
|
|
258
281
|
if config_path.exists():
|
|
259
282
|
try:
|
|
260
283
|
with config_path.open("r", encoding="utf-8") as f:
|
|
@@ -262,79 +285,115 @@ def config(
|
|
|
262
285
|
if not isinstance(current_config, dict):
|
|
263
286
|
current_config = default_config.copy()
|
|
264
287
|
except Exception as e:
|
|
265
|
-
|
|
288
|
+
PrettyOutput.auto_print(
|
|
289
|
+
f"⚠️ [c2rust-config] 读取现有配置失败: {e},将使用默认值"
|
|
290
|
+
)
|
|
266
291
|
current_config = default_config.copy()
|
|
267
|
-
|
|
292
|
+
|
|
268
293
|
# 如果只是查看配置
|
|
269
294
|
if show:
|
|
270
|
-
|
|
271
|
-
|
|
295
|
+
PrettyOutput.auto_print(f"📋 [c2rust-config] 当前配置文件: {config_path}")
|
|
296
|
+
PrettyOutput.auto_print(
|
|
297
|
+
json.dumps(current_config, ensure_ascii=False, indent=2)
|
|
298
|
+
)
|
|
272
299
|
return
|
|
273
|
-
|
|
300
|
+
|
|
274
301
|
# 如果清空配置
|
|
275
302
|
if clear:
|
|
276
303
|
current_config = default_config.copy()
|
|
277
304
|
with config_path.open("w", encoding="utf-8") as f:
|
|
278
305
|
json.dump(current_config, f, ensure_ascii=False, indent=2)
|
|
279
|
-
|
|
306
|
+
PrettyOutput.auto_print(f"✅ [c2rust-config] 配置已清空: {config_path}")
|
|
280
307
|
return
|
|
281
|
-
|
|
308
|
+
|
|
282
309
|
# 读取根符号列表(从现有配置开始,以便追加而不是替换)
|
|
283
310
|
root_symbols: List[str] = list(current_config.get("root_symbols", []))
|
|
284
311
|
header_exts = {".h", ".hh", ".hpp", ".hxx"}
|
|
285
|
-
|
|
312
|
+
|
|
286
313
|
if files:
|
|
287
314
|
for file_path in files:
|
|
288
315
|
try:
|
|
289
316
|
file_path = Path(file_path).resolve()
|
|
290
317
|
if not file_path.exists():
|
|
291
|
-
|
|
318
|
+
PrettyOutput.auto_print(
|
|
319
|
+
f"⚠️ [c2rust-config] 警告: 文件不存在,跳过: {file_path}"
|
|
320
|
+
)
|
|
292
321
|
continue
|
|
293
|
-
|
|
322
|
+
|
|
294
323
|
# 检查是否是头文件
|
|
295
324
|
if file_path.suffix.lower() in header_exts:
|
|
296
325
|
# 从头文件提取函数名
|
|
297
|
-
|
|
326
|
+
PrettyOutput.auto_print(
|
|
327
|
+
f"📋 [c2rust-config] 从头文件提取函数名: {file_path}"
|
|
328
|
+
)
|
|
298
329
|
try:
|
|
299
|
-
from jarvis.jarvis_c2rust.collector import collect_function_names as _collect_fn_names
|
|
300
330
|
# 使用临时文件存储提取的函数名
|
|
301
331
|
import tempfile
|
|
302
|
-
|
|
332
|
+
|
|
333
|
+
from jarvis.jarvis_c2rust.collector import (
|
|
334
|
+
collect_function_names as _collect_fn_names,
|
|
335
|
+
)
|
|
336
|
+
|
|
337
|
+
with tempfile.NamedTemporaryFile(
|
|
338
|
+
mode="w", suffix=".txt", delete=False, encoding="utf-8"
|
|
339
|
+
) as tmp:
|
|
303
340
|
tmp_path = Path(tmp.name)
|
|
304
|
-
_collect_fn_names(
|
|
341
|
+
_collect_fn_names(
|
|
342
|
+
files=[file_path],
|
|
343
|
+
out_path=tmp_path,
|
|
344
|
+
compile_commands_root=None,
|
|
345
|
+
)
|
|
305
346
|
# 读取提取的函数名
|
|
306
347
|
txt = tmp_path.read_text(encoding="utf-8")
|
|
307
|
-
collected = [
|
|
348
|
+
collected = [
|
|
349
|
+
ln.strip() for ln in txt.splitlines() if ln.strip()
|
|
350
|
+
]
|
|
308
351
|
root_symbols.extend(collected)
|
|
309
|
-
|
|
352
|
+
PrettyOutput.auto_print(
|
|
353
|
+
f"✅ [c2rust-config] 从头文件 {file_path.name} 提取了 {len(collected)} 个函数名"
|
|
354
|
+
)
|
|
310
355
|
# 清理临时文件
|
|
311
356
|
try:
|
|
312
357
|
tmp_path.unlink()
|
|
313
358
|
except Exception:
|
|
314
359
|
pass
|
|
315
360
|
except Exception as e:
|
|
316
|
-
|
|
361
|
+
PrettyOutput.auto_print(
|
|
362
|
+
f"❌ [c2rust-config] 从头文件提取函数名失败: {file_path}: {e}"
|
|
363
|
+
)
|
|
317
364
|
raise typer.Exit(code=1)
|
|
318
365
|
else:
|
|
319
366
|
# 读取函数名列表文件(每行一个函数名)
|
|
320
367
|
txt = file_path.read_text(encoding="utf-8")
|
|
321
|
-
collected = [
|
|
368
|
+
collected = [
|
|
369
|
+
ln.strip()
|
|
370
|
+
for ln in txt.splitlines()
|
|
371
|
+
if ln.strip() and not ln.strip().startswith("#")
|
|
372
|
+
]
|
|
322
373
|
root_symbols.extend(collected)
|
|
323
|
-
|
|
374
|
+
PrettyOutput.auto_print(
|
|
375
|
+
f"📋 [c2rust-config] 从文件 {file_path.name} 读取了 {len(collected)} 个根符号"
|
|
376
|
+
)
|
|
324
377
|
except typer.Exit:
|
|
325
378
|
raise
|
|
326
379
|
except Exception as e:
|
|
327
|
-
|
|
380
|
+
PrettyOutput.auto_print(
|
|
381
|
+
f"❌ [c2rust-config] 处理文件失败: {file_path}: {e}"
|
|
382
|
+
)
|
|
328
383
|
raise typer.Exit(code=1)
|
|
329
|
-
|
|
384
|
+
|
|
330
385
|
# 标记是否处理了 root_list_syms,以便即使结果为空也更新配置
|
|
331
386
|
processed_root_list_syms = False
|
|
332
387
|
if isinstance(root_list_syms, str) and root_list_syms.strip():
|
|
333
|
-
parts = [
|
|
388
|
+
parts = [
|
|
389
|
+
s.strip() for s in root_list_syms.replace("\n", ",").split(",") if s.strip()
|
|
390
|
+
]
|
|
334
391
|
root_symbols.extend(parts)
|
|
335
392
|
processed_root_list_syms = True
|
|
336
|
-
|
|
337
|
-
|
|
393
|
+
PrettyOutput.auto_print(
|
|
394
|
+
f"📋 [c2rust-config] 从命令行读取根符号: {len(parts)} 个"
|
|
395
|
+
)
|
|
396
|
+
|
|
338
397
|
# 去重根符号列表(如果处理了 files 或 root_list_syms,或者 root_symbols 非空,则更新配置)
|
|
339
398
|
if files or processed_root_list_syms or root_symbols:
|
|
340
399
|
try:
|
|
@@ -342,36 +401,53 @@ def config(
|
|
|
342
401
|
except Exception:
|
|
343
402
|
root_symbols = sorted(list(set(root_symbols)))
|
|
344
403
|
current_config["root_symbols"] = root_symbols
|
|
345
|
-
|
|
346
|
-
|
|
404
|
+
PrettyOutput.auto_print(
|
|
405
|
+
f"✅ [c2rust-config] 已设置根符号列表: {len(root_symbols)} 个"
|
|
406
|
+
)
|
|
407
|
+
|
|
347
408
|
# 读取禁用库列表
|
|
348
409
|
if isinstance(disabled_libs, str) and disabled_libs.strip():
|
|
349
|
-
disabled_list = [
|
|
410
|
+
disabled_list = [
|
|
411
|
+
s.strip() for s in disabled_libs.replace("\n", ",").split(",") if s.strip()
|
|
412
|
+
]
|
|
350
413
|
if disabled_list:
|
|
351
414
|
current_config["disabled_libraries"] = disabled_list
|
|
352
|
-
|
|
353
|
-
|
|
415
|
+
PrettyOutput.auto_print(
|
|
416
|
+
f"✅ [c2rust-config] 已设置禁用库列表: {', '.join(disabled_list)}"
|
|
417
|
+
)
|
|
418
|
+
|
|
354
419
|
# 读取附加说明
|
|
355
420
|
if isinstance(additional_notes, str):
|
|
356
421
|
current_config["additional_notes"] = additional_notes.strip()
|
|
357
422
|
if additional_notes.strip():
|
|
358
|
-
|
|
423
|
+
PrettyOutput.auto_print(
|
|
424
|
+
f"✅ [c2rust-config] 已设置附加说明: {len(additional_notes.strip())} 字符"
|
|
425
|
+
)
|
|
359
426
|
else:
|
|
360
|
-
|
|
361
|
-
|
|
427
|
+
PrettyOutput.auto_print("✅ [c2rust-config] 已清空附加说明")
|
|
428
|
+
|
|
362
429
|
# 如果没有提供任何参数,提示用户
|
|
363
|
-
if
|
|
364
|
-
|
|
430
|
+
if (
|
|
431
|
+
not files
|
|
432
|
+
and not root_list_syms
|
|
433
|
+
and not disabled_libs
|
|
434
|
+
and additional_notes is None
|
|
435
|
+
):
|
|
436
|
+
PrettyOutput.auto_print(
|
|
437
|
+
"⚠️ [c2rust-config] 未提供任何参数,使用 --show 查看当前配置,或使用 --help 查看帮助"
|
|
438
|
+
)
|
|
365
439
|
return
|
|
366
|
-
|
|
440
|
+
|
|
367
441
|
# 保存配置
|
|
368
442
|
try:
|
|
369
443
|
with config_path.open("w", encoding="utf-8") as f:
|
|
370
444
|
json.dump(current_config, f, ensure_ascii=False, indent=2)
|
|
371
|
-
|
|
372
|
-
|
|
445
|
+
PrettyOutput.auto_print(f"✅ [c2rust-config] 配置已保存: {config_path}")
|
|
446
|
+
PrettyOutput.auto_print(
|
|
447
|
+
json.dumps(current_config, ensure_ascii=False, indent=2)
|
|
448
|
+
)
|
|
373
449
|
except Exception as e:
|
|
374
|
-
|
|
450
|
+
PrettyOutput.auto_print(f"❌ [c2rust-config] 保存配置失败: {e}")
|
|
375
451
|
raise typer.Exit(code=1)
|
|
376
452
|
|
|
377
453
|
|
|
@@ -384,7 +460,10 @@ def run(
|
|
|
384
460
|
help="用于 LLM 相关阶段(lib-replace/prepare/transpile/optimize)的模型组",
|
|
385
461
|
),
|
|
386
462
|
max_retries: int = typer.Option(
|
|
387
|
-
0,
|
|
463
|
+
0,
|
|
464
|
+
"-m",
|
|
465
|
+
"--max-retries",
|
|
466
|
+
help="transpile 构建/修复与审查的最大重试次数(0 表示不限制)",
|
|
388
467
|
),
|
|
389
468
|
interactive: bool = typer.Option(
|
|
390
469
|
False,
|
|
@@ -403,7 +482,7 @@ def run(
|
|
|
403
482
|
支持断点续跑:根据状态文件(.jarvis/c2rust/run_state.json)自动跳过已完成的阶段。
|
|
404
483
|
|
|
405
484
|
约束:
|
|
406
|
-
|
|
485
|
+
|
|
407
486
|
- 根符号列表和禁用库列表从配置文件(.jarvis/c2rust/config.json)读取
|
|
408
487
|
使用 jarvis-c2rust config 命令设置这些配置(例如:jarvis-c2rust config --files bzlib.h)
|
|
409
488
|
|
|
@@ -413,7 +492,7 @@ def run(
|
|
|
413
492
|
|
|
414
493
|
- optimize 阶段采用默认优化配置,自动检测 crate 根目录并进行保守优化(unsafe 清理、结构优化、可见性优化、文档补充)
|
|
415
494
|
"""
|
|
416
|
-
|
|
495
|
+
|
|
417
496
|
try:
|
|
418
497
|
# 加载状态文件
|
|
419
498
|
if reset:
|
|
@@ -421,55 +500,76 @@ def run(
|
|
|
421
500
|
state_path = _get_run_state_path()
|
|
422
501
|
if state_path.exists():
|
|
423
502
|
state_path.unlink()
|
|
424
|
-
|
|
503
|
+
PrettyOutput.auto_print("⚠️ [c2rust-run] 已重置状态,将从头开始执行")
|
|
425
504
|
state = _load_run_state()
|
|
426
505
|
else:
|
|
427
506
|
state = _load_run_state()
|
|
428
507
|
# 显示当前状态
|
|
429
|
-
completed_stages = [
|
|
508
|
+
completed_stages = [
|
|
509
|
+
s for s, info in state.items() if info.get("completed", False)
|
|
510
|
+
]
|
|
430
511
|
if completed_stages:
|
|
431
|
-
|
|
432
|
-
|
|
512
|
+
PrettyOutput.auto_print(
|
|
513
|
+
f"🚀 [c2rust-run] 检测到已完成阶段: {', '.join(completed_stages)},将从断点继续"
|
|
514
|
+
)
|
|
515
|
+
|
|
433
516
|
# Step 1: scan
|
|
434
517
|
if not state.get("scan", {}).get("completed", False):
|
|
435
|
-
|
|
436
|
-
_run_scan(
|
|
437
|
-
|
|
518
|
+
PrettyOutput.auto_print("🚀 [c2rust-run] scan: 开始")
|
|
519
|
+
_run_scan(
|
|
520
|
+
dot=None,
|
|
521
|
+
only_dot=False,
|
|
522
|
+
subgraphs_dir=None,
|
|
523
|
+
only_subgraphs=False,
|
|
524
|
+
png=False,
|
|
525
|
+
non_interactive=True,
|
|
526
|
+
)
|
|
527
|
+
PrettyOutput.auto_print("✅ [c2rust-run] scan: 完成")
|
|
438
528
|
# 保存状态(因为直接调用 _run_scan 函数,需要手动保存状态)
|
|
439
529
|
_save_run_state("scan", completed=True)
|
|
440
530
|
else:
|
|
441
|
-
|
|
531
|
+
PrettyOutput.auto_print("🚀 [c2rust-run] scan: 已完成,跳过")
|
|
442
532
|
|
|
443
533
|
# Step 2: lib-replace(从配置文件读取根列表和禁用库列表)
|
|
444
534
|
if not state.get("lib_replace", {}).get("completed", False):
|
|
445
535
|
# 从配置文件读取基础配置
|
|
446
536
|
config = _load_config()
|
|
447
537
|
root_names: List[str] = list(config.get("root_symbols", []))
|
|
448
|
-
disabled_list: Optional[List[str]] =
|
|
449
|
-
|
|
538
|
+
disabled_list: Optional[List[str]] = (
|
|
539
|
+
config.get("disabled_libraries", []) or None
|
|
540
|
+
)
|
|
541
|
+
|
|
450
542
|
# 去重并校验(允许为空时回退为自动根集)
|
|
451
543
|
if root_names:
|
|
452
544
|
try:
|
|
453
545
|
root_names = list(dict.fromkeys(root_names))
|
|
454
546
|
except Exception:
|
|
455
547
|
root_names = sorted(list(set(root_names)))
|
|
456
|
-
|
|
548
|
+
|
|
457
549
|
candidates_list: Optional[List[str]] = root_names if root_names else None
|
|
458
550
|
if not candidates_list:
|
|
459
|
-
|
|
460
|
-
|
|
551
|
+
PrettyOutput.auto_print(
|
|
552
|
+
"⚠️ [c2rust-run] lib-replace: 根列表为空,将回退为自动检测的根集合(基于扫描结果)"
|
|
553
|
+
)
|
|
554
|
+
|
|
461
555
|
if disabled_list:
|
|
462
|
-
|
|
556
|
+
PrettyOutput.auto_print(
|
|
557
|
+
f"📋 [c2rust-run] lib-replace: 从配置文件读取禁用库: {', '.join(disabled_list)}"
|
|
558
|
+
)
|
|
463
559
|
|
|
464
560
|
# 执行 lib-replace(默认库 std)
|
|
465
561
|
library = "std"
|
|
466
|
-
root_count_str =
|
|
467
|
-
|
|
562
|
+
root_count_str = (
|
|
563
|
+
str(len(candidates_list)) if candidates_list is not None else "auto"
|
|
564
|
+
)
|
|
565
|
+
PrettyOutput.auto_print(
|
|
566
|
+
f"🚀 [c2rust-run] lib-replace: 开始(库: {library},根数: {root_count_str})"
|
|
567
|
+
)
|
|
468
568
|
ret = _apply_library_replacement(
|
|
469
569
|
db_path=Path("."),
|
|
470
570
|
library_name=library,
|
|
471
571
|
llm_group=llm_group,
|
|
472
|
-
candidates=candidates_list,
|
|
572
|
+
candidates=candidates_list, # None 表示自动检测全部根
|
|
473
573
|
out_symbols_path=None,
|
|
474
574
|
out_mapping_path=None,
|
|
475
575
|
max_funcs=None,
|
|
@@ -477,34 +577,42 @@ def run(
|
|
|
477
577
|
non_interactive=not interactive,
|
|
478
578
|
)
|
|
479
579
|
try:
|
|
480
|
-
order_msg =
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
580
|
+
order_msg = (
|
|
581
|
+
f"\n[c2rust-run] lib-replace: 转译顺序: {ret['order']}"
|
|
582
|
+
if "order" in ret
|
|
583
|
+
else ""
|
|
584
|
+
)
|
|
585
|
+
PrettyOutput.auto_print(
|
|
586
|
+
f"✅ [c2rust-run] lib-replace: 替代映射: {ret['mapping']}\n"
|
|
587
|
+
f"✅ [c2rust-run] lib-replace: 新符号表: {ret['symbols']}"
|
|
588
|
+
+ order_msg
|
|
486
589
|
)
|
|
487
590
|
except Exception as _e:
|
|
488
|
-
|
|
591
|
+
PrettyOutput.auto_print(
|
|
592
|
+
f"⚠️ [c2rust-run] lib-replace: 结果输出时发生非致命错误: {_e}"
|
|
593
|
+
)
|
|
489
594
|
# 保存状态(因为直接调用 _apply_library_replacement 函数,需要手动保存状态)
|
|
490
595
|
_save_run_state("lib_replace", completed=True)
|
|
491
596
|
else:
|
|
492
|
-
|
|
597
|
+
PrettyOutput.auto_print("🚀 [c2rust-run] lib-replace: 已完成,跳过")
|
|
493
598
|
|
|
494
599
|
# Step 3: prepare
|
|
495
600
|
if not state.get("prepare", {}).get("completed", False):
|
|
496
|
-
|
|
497
|
-
_execute_llm_plan(
|
|
498
|
-
|
|
601
|
+
PrettyOutput.auto_print("🚀 [c2rust-run] prepare: 开始")
|
|
602
|
+
_execute_llm_plan(
|
|
603
|
+
apply=True, llm_group=llm_group, non_interactive=not interactive
|
|
604
|
+
)
|
|
605
|
+
PrettyOutput.auto_print("✅ [c2rust-run] prepare: 完成")
|
|
499
606
|
# 保存状态(因为直接调用 _execute_llm_plan 函数,需要手动保存状态)
|
|
500
607
|
_save_run_state("prepare", completed=True)
|
|
501
608
|
else:
|
|
502
|
-
|
|
609
|
+
PrettyOutput.auto_print("🚀 [c2rust-run] prepare: 已完成,跳过")
|
|
503
610
|
|
|
504
611
|
# Step 4: transpile
|
|
505
612
|
if not state.get("transpile", {}).get("completed", False):
|
|
506
|
-
|
|
613
|
+
PrettyOutput.auto_print("🚀 [c2rust-run] transpile: 开始")
|
|
507
614
|
from jarvis.jarvis_c2rust.transpiler import run_transpile as _run_transpile
|
|
615
|
+
|
|
508
616
|
# 从配置文件读取配置(transpile 内部会自动读取)
|
|
509
617
|
_run_transpile(
|
|
510
618
|
project_root=Path("."),
|
|
@@ -515,23 +623,33 @@ def run(
|
|
|
515
623
|
root_symbols=None, # 从配置文件恢复
|
|
516
624
|
non_interactive=not interactive,
|
|
517
625
|
)
|
|
518
|
-
|
|
626
|
+
PrettyOutput.auto_print("✅ [c2rust-run] transpile: 完成")
|
|
519
627
|
# 保存状态(因为直接调用 _run_transpile 函数,需要手动保存状态)
|
|
520
628
|
_save_run_state("transpile", completed=True)
|
|
521
629
|
else:
|
|
522
|
-
|
|
630
|
+
PrettyOutput.auto_print("🚀 [c2rust-run] transpile: 已完成,跳过")
|
|
523
631
|
|
|
524
632
|
# Step 5: optimize
|
|
525
633
|
if not state.get("optimize", {}).get("completed", False):
|
|
526
634
|
try:
|
|
527
|
-
|
|
528
|
-
from jarvis.jarvis_c2rust.optimizer import
|
|
635
|
+
PrettyOutput.auto_print("🚀 [c2rust-run] optimize: 开始")
|
|
636
|
+
from jarvis.jarvis_c2rust.optimizer import (
|
|
637
|
+
optimize_project as _optimize_project,
|
|
638
|
+
)
|
|
529
639
|
from jarvis.jarvis_c2rust.utils import default_crate_dir
|
|
640
|
+
|
|
530
641
|
# 使用与 transpile 相同的逻辑确定项目根目录和 crate 目录
|
|
531
642
|
project_root = Path(".")
|
|
532
643
|
crate_dir = default_crate_dir(project_root)
|
|
533
|
-
|
|
534
|
-
|
|
644
|
+
PrettyOutput.auto_print(
|
|
645
|
+
f"📋 [c2rust-run] optimize: 使用项目根目录: {project_root}, crate 目录: {crate_dir}"
|
|
646
|
+
)
|
|
647
|
+
res = _optimize_project(
|
|
648
|
+
project_root=project_root,
|
|
649
|
+
crate_dir=crate_dir,
|
|
650
|
+
llm_group=llm_group,
|
|
651
|
+
non_interactive=not interactive,
|
|
652
|
+
)
|
|
535
653
|
summary = (
|
|
536
654
|
f"[c2rust-run] optimize: 结果摘要:\n"
|
|
537
655
|
f" files_scanned: {res.get('files_scanned')}\n"
|
|
@@ -541,35 +659,36 @@ def run(
|
|
|
541
659
|
f" docs_added: {res.get('docs_added')}\n"
|
|
542
660
|
f" cargo_checks: {res.get('cargo_checks')}\n"
|
|
543
661
|
)
|
|
544
|
-
|
|
545
|
-
|
|
662
|
+
PrettyOutput.auto_print(summary)
|
|
663
|
+
|
|
546
664
|
# 检查优化是否真正完成(所有步骤都完成,包括 clippy 告警修复)
|
|
547
665
|
optimize_truly_completed = _check_optimize_completed(crate_dir)
|
|
548
666
|
if optimize_truly_completed:
|
|
549
|
-
|
|
667
|
+
PrettyOutput.auto_print("✅ [c2rust-run] optimize: 完成")
|
|
550
668
|
# 保存状态(因为直接调用 _optimize_project 函数,需要手动保存状态)
|
|
551
669
|
_save_run_state("optimize", completed=True)
|
|
552
670
|
else:
|
|
553
|
-
|
|
671
|
+
PrettyOutput.auto_print(
|
|
672
|
+
"⚠️ [c2rust-run] optimize: 部分步骤未完成(如 clippy 告警未完全修复),下次将继续"
|
|
673
|
+
)
|
|
554
674
|
# 不保存状态,下次恢复时会继续执行优化
|
|
555
675
|
except Exception as _e:
|
|
556
|
-
|
|
676
|
+
PrettyOutput.auto_print(f"❌ [c2rust-run] optimize: 错误: {_e}")
|
|
557
677
|
raise
|
|
558
678
|
else:
|
|
559
|
-
|
|
560
|
-
|
|
679
|
+
PrettyOutput.auto_print("🚀 [c2rust-run] optimize: 已完成,跳过")
|
|
680
|
+
|
|
561
681
|
# 所有阶段完成
|
|
562
|
-
|
|
682
|
+
PrettyOutput.auto_print("🎉 [c2rust-run] 所有阶段已完成!")
|
|
563
683
|
except Exception as e:
|
|
564
|
-
|
|
684
|
+
PrettyOutput.auto_print(f"❌ [c2rust-run] 错误: {e}")
|
|
565
685
|
raise typer.Exit(code=1)
|
|
566
686
|
|
|
567
687
|
|
|
568
|
-
|
|
569
688
|
def main() -> None:
|
|
570
689
|
"""主入口"""
|
|
571
690
|
app()
|
|
572
691
|
|
|
573
692
|
|
|
574
693
|
if __name__ == "__main__":
|
|
575
|
-
main()
|
|
694
|
+
main()
|