1
1
import logging
2
2
import os
3
3
import subprocess
4
-
4
+ from pathlib import Path
5
5
import hydra
6
6
from datasets import load_dataset
7
7
import traceback
15
15
from commit0 .harness .get_pytest_ids import main as get_tests
16
16
from tqdm import tqdm
17
17
from concurrent .futures import ThreadPoolExecutor , as_completed
18
-
19
-
20
- logging .basicConfig (
21
- level = logging .INFO , format = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
22
- )
23
- logger = logging .getLogger (__name__ )
18
+ from commit0 .harness .constants import RUN_AIDER_LOG_DIR
19
+ from commit0 .harness .docker_build import setup_logger
24
20
25
21
26
22
def get_aider_cmd (
@@ -29,6 +25,7 @@ def get_aider_cmd(
29
25
message_to_aider : str ,
30
26
test_cmd : str ,
31
27
lint_cmd : str ,
28
+ log_dir : Path ,
32
29
) -> str :
33
30
"""Get the Aider command based on the given context."""
34
31
base_cmd = f'aider --model { model } --file { files } --message "{ message_to_aider } "'
@@ -37,9 +34,45 @@ def get_aider_cmd(
37
34
if test_cmd :
38
35
base_cmd += f" --auto-test --test --test-cmd '{ test_cmd } '"
39
36
base_cmd += " --yes"
37
+
38
+ # Store Aider input and chat history in log directory
39
+ input_history_file = log_dir / ".aider.input.history"
40
+ chat_history_file = log_dir / ".aider.chat.history.md"
41
+
42
+ base_cmd += f" --input-history-file { input_history_file } "
43
+ base_cmd += f" --chat-history-file { chat_history_file } "
40
44
return base_cmd
41
45
42
46
47
+ def execute_aider_cmd (
48
+ aider_cmd : str ,
49
+ logger : logging .Logger ,
50
+ ) -> None :
51
+ """Execute the Aider command."""
52
+ try :
53
+ process = subprocess .Popen (
54
+ aider_cmd ,
55
+ shell = True ,
56
+ stdout = subprocess .PIPE ,
57
+ stderr = subprocess .PIPE ,
58
+ universal_newlines = True ,
59
+ )
60
+ stdout , stderr = process .communicate ()
61
+ logger .info (f"STDOUT: { stdout } " )
62
+ logger .info (f"STDERR: { stderr } " )
63
+ except subprocess .CalledProcessError as e :
64
+ logger .error (f"Command failed with exit code { e .returncode } " )
65
+ logger .error (f"STDOUT: { e .stdout } " )
66
+ logger .error (f"STDERR: { e .stderr } " )
67
+
68
+ except OSError as e :
69
+ if e .errno == 63 : # File name too long error
70
+ logger .error ("Command failed due to file name being too long" )
71
+ logger .error (f"Command: { '' .join (aider_cmd )} " )
72
+ else :
73
+ logger .error (f"OSError occurred: { e } " )
74
+
75
+
43
76
def run_aider_for_repo (
44
77
commit0_config : Commit0Config | None ,
45
78
aider_config : AiderConfig | None ,
@@ -56,7 +89,7 @@ def run_aider_for_repo(
56
89
repo_name = repo_name .replace ("." , "-" )
57
90
58
91
# Call the commit0 get-tests command to retrieve test files
59
- test_files_str = get_tests (repo_name , stdout = True )
92
+ test_files_str = get_tests (repo_name , stdout = False )
60
93
61
94
test_files = sorted (list (set ([i .split (":" )[0 ] for i in test_files_str ])))
62
95
@@ -75,39 +108,55 @@ def run_aider_for_repo(
75
108
else :
76
109
lint_cmd = ""
77
110
78
- for test_file in test_files :
79
- test_cmd = f"python -m commit0 test { repo_name } { test_file } "
111
+ if aider_config .run_tests :
112
+ for test_file in test_files :
113
+ test_cmd = f"python -m commit0 test { repo_name } { test_file } "
114
+ # set up logging
115
+ test_file_name = test_file .replace (".py" , "" ).replace ("/" , "__" )
116
+ log_dir = RUN_AIDER_LOG_DIR / repo_name / "ai" / test_file_name
117
+ log_dir .mkdir (parents = True , exist_ok = True )
118
+ log_file = log_dir / "run_aider.log"
119
+ logger = setup_logger (repo_name , log_file )
120
+
121
+ aider_cmd = get_aider_cmd (
122
+ aider_config .llm_name ,
123
+ target_edit_files_cmd_args ,
124
+ message_to_aider ,
125
+ test_cmd ,
126
+ lint_cmd ,
127
+ log_dir ,
128
+ )
129
+
130
+ # write aider command to log file
131
+ aider_cmd_file = Path (log_dir / "aider_cmd.sh" )
132
+ aider_cmd_file .write_text (aider_cmd )
133
+
134
+ # write test command to log file
135
+ test_cmd_file = Path (log_dir / "test_cmd.sh" )
136
+ test_cmd_file .write_text (test_cmd )
137
+
138
+ execute_aider_cmd (aider_cmd , logger )
139
+
140
+ else :
141
+ # set up logging
142
+ log_dir = RUN_AIDER_LOG_DIR / repo_name / "ai" / "no_test"
143
+ log_dir .mkdir (parents = True , exist_ok = True )
144
+ log_file = log_dir / "run_aider.log"
145
+ logger = setup_logger (repo_name , log_file )
80
146
81
147
aider_cmd = get_aider_cmd (
82
148
aider_config .llm_name ,
83
149
target_edit_files_cmd_args ,
84
150
message_to_aider ,
85
- test_cmd ,
151
+ "" ,
86
152
lint_cmd ,
153
+ log_dir ,
87
154
)
155
+ # write aider command to log file
156
+ aider_cmd_file = Path (log_dir / "aider_cmd.sh" )
157
+ aider_cmd_file .write_text (aider_cmd )
88
158
89
- try :
90
- process = subprocess .Popen (
91
- aider_cmd ,
92
- shell = True ,
93
- stdout = subprocess .PIPE ,
94
- stderr = subprocess .PIPE ,
95
- universal_newlines = True ,
96
- )
97
- stdout , stderr = process .communicate ()
98
- logger .info (f"STDOUT: { stdout } " )
99
- logger .info (f"STDERR: { stderr } " )
100
- except subprocess .CalledProcessError as e :
101
- logger .error (f"Command failed with exit code { e .returncode } " )
102
- logger .error (f"STDOUT: { e .stdout } " )
103
- logger .error (f"STDERR: { e .stderr } " )
104
-
105
- except OSError as e :
106
- if e .errno == 63 : # File name too long error
107
- logger .error ("Command failed due to file name being too long" )
108
- logger .error (f"Command: { '' .join (aider_cmd )} " )
109
- else :
110
- logger .error (f"OSError occurred: { e } " )
159
+ execute_aider_cmd (aider_cmd , logger )
111
160
112
161
113
162
def pre_aider_processing (aider_config : AiderConfig ) -> None :
@@ -150,7 +199,7 @@ def main() -> None:
150
199
and example ["repo" ].split ("/" )[- 1 ]
151
200
in SPLIT .get (commit0_config .repo_split , [])
152
201
)
153
- ][: 1 ]
202
+ ]
154
203
155
204
pre_aider_processing (aider_config )
156
205
0 commit comments