Skip to content

Commit 078b1b9

Browse files
committed
fix conflict
2 parents 4e60785 + 6968133 commit 078b1b9

File tree

11 files changed

+139
-105
lines changed

11 files changed

+139
-105
lines changed

baselines/run_agent.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def run_agent_for_repo(
5252
repo_name = repo_name.replace(".", "-")
5353

5454
# Call the commit0 get-tests command to retrieve test files
55-
test_files_str = get_tests(repo_name, stdout=False)
55+
test_files_str = get_tests(repo_name, verbose=0)
5656
test_files = sorted(list(set([i.split(":")[0] for i in test_files_str])))
5757

5858
repo_path = os.path.join(commit0_config.base_dir, repo_name)

commit0/cli.py

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,13 @@ def build(
144144
num_workers: int = typer.Option(8, help="Number of workers"),
145145
commit0_dot_file_path: str = typer.Option(
146146
".commit0.yaml",
147-
help="Path to the commit0 dot file, where the setup config is stored",
147+
help="Path to the commit0 dot file, where the setup config is stored"),
148+
verbose: int = typer.Option(
149+
1,
150+
"--verbose",
151+
"-v",
152+
help="Set this to 2 for more logging information",
153+
count=True,
148154
),
149155
) -> None:
150156
"""Build Commit0 split you choose in Setup Stage."""
@@ -163,6 +169,7 @@ def build(
163169
commit0_config["dataset_split"],
164170
commit0_config["repo_split"],
165171
num_workers,
172+
verbose,
166173
)
167174

168175

@@ -179,7 +186,7 @@ def get_tests(
179186

180187
typer.echo(f"Getting tests for repository: {repo_name}")
181188

182-
commit0.harness.get_pytest_ids.main(repo_name, stdout=True)
189+
commit0.harness.get_pytest_ids.main(repo_name, verbose=1)
183190

184191

185192
@commit0_app.command()
@@ -202,7 +209,13 @@ def test(
202209
] = False,
203210
commit0_dot_file_path: str = typer.Option(
204211
".commit0.yaml",
205-
help="Path to the commit0 dot file, where the setup config is stored",
212+
help="Path to the commit0 dot file, where the setup config is stored"),
213+
verbose: int = typer.Option(
214+
1,
215+
"--verbose",
216+
"-v",
217+
help="Set this to 2 for more logging information",
218+
count=True,
206219
),
207220
) -> None:
208221
"""Run tests on a Commit0 repository."""
@@ -236,7 +249,7 @@ def test(
236249
backend,
237250
timeout,
238251
num_cpus,
239-
stdout=True,
252+
verbose,
240253
)
241254

242255

commit0/harness/build.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ def main(
1919
dataset_split: str,
2020
repo_split: str,
2121
num_workers: int,
22+
verbose: int,
2223
) -> None:
2324
dataset: Iterator[RepoInstance] = load_dataset(dataset_name, split=dataset_split) # type: ignore
2425
specs = []
@@ -30,7 +31,11 @@ def main(
3031
specs.append(spec)
3132

3233
client = docker.from_env()
33-
build_repo_images(client, specs, num_workers)
34+
build_repo_images(client, specs, num_workers, verbose)
35+
for spec in specs:
36+
image = client.images.get(spec.repo_image_key)
37+
repository, tag = spec.repo_image_tag.split(":")
38+
image.tag(repository, tag)
3439

3540

3641
__all__ = []

commit0/harness/docker_build.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ def build_repo_images(
196196
client: docker.DockerClient,
197197
dataset: list,
198198
max_workers: int = 4,
199+
verbose: int = 1,
199200
) -> tuple[list[str], list[str]]:
200201
"""Builds the repo images required for the dataset if they do not already exist.
201202
@@ -204,6 +205,7 @@ def build_repo_images(
204205
client (docker.DockerClient): Docker client to use for building the images
205206
dataset (list): List of test specs or dataset to build images for
206207
max_workers (int): Maximum number of workers to use for building images
208+
verbose (int): Level of verbosity
207209
208210
Return:
209211
------

commit0/harness/docker_utils.py

Lines changed: 81 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import traceback
1111
from pathlib import Path
1212
from io import BytesIO
13-
from typing import Optional, List, Union
13+
from typing import Optional, List
1414

1515
import docker.errors
1616
from docker.models.containers import Container
@@ -126,7 +126,7 @@ def write_to_container(container: Container, data: str, dst: Path) -> None:
126126
def cleanup_container(
127127
client: docker.DockerClient,
128128
container: Container,
129-
logger: Union[None, str, logging.Logger],
129+
logger: logging.Logger,
130130
) -> None:
131131
"""Stop and remove a Docker container.
132132
Performs this forcefully if the container cannot be stopped with the python API.
@@ -135,51 +135,21 @@ def cleanup_container(
135135
----
136136
client (docker.DockerClient): Docker client.
137137
container (docker.Container): Container to remove.
138-
logger (Union[str, logging.Logger], optional): Logger instance or log level as string for logging container creation messages. Defaults to None.
138+
logger (logging.Logger): Logger instance or log level as string for logging container creation messages.
139139
140140
"""
141141
if not container:
142142
return
143143

144144
container_id = container.id
145145

146-
if not logger:
147-
# if logger is None, print to stdout
148-
def log_error(x: str) -> None:
149-
print(x)
150-
151-
def log_info(x: str) -> None:
152-
print(x)
153-
154-
raise_error = True
155-
elif logger == "quiet":
156-
# if logger is "quiet", don't print anything
157-
def log_info(x: str) -> None:
158-
return None
159-
160-
def log_error(x: str) -> None:
161-
return None
162-
163-
raise_error = True
164-
else:
165-
assert isinstance(logger, logging.Logger)
166-
167-
# if logger is a logger object, use it
168-
def log_error(x: str) -> None:
169-
logger.info(x)
170-
171-
def log_info(x: str) -> None:
172-
logger.info(x)
173-
174-
raise_error = False
175-
176146
# Attempt to stop the container
177147
try:
178148
if container:
179-
log_info(f"Attempting to stop container {container.name}...")
149+
logger.info(f"Attempting to stop container {container.name}...")
180150
container.kill()
181151
except Exception as e:
182-
log_error(
152+
logger.error(
183153
f"Failed to stop container {container.name}: {e}. Trying to forcefully kill..."
184154
)
185155
try:
@@ -190,54 +160,109 @@ def log_info(x: str) -> None:
190160

191161
# If container PID found, forcefully kill the container
192162
if pid > 0:
193-
log_info(
163+
logger.info(
194164
f"Forcefully killing container {container.name} with PID {pid}..."
195165
)
196166
os.kill(pid, signal.SIGKILL)
197167
else:
198-
log_error(f"PID for container {container.name}: {pid} - not killing.")
168+
logger.error(
169+
f"PID for container {container.name}: {pid} - not killing."
170+
)
199171
except Exception as e2:
200-
if raise_error:
201-
raise e2
202-
log_error(
172+
raise Exception(
203173
f"Failed to forcefully kill container {container.name}: {e2}\n"
204174
f"{traceback.format_exc()}"
205175
)
206176

207177
# Attempt to remove the container
208178
try:
209-
log_info(f"Attempting to remove container {container.name}...")
179+
logger.info(f"Attempting to remove container {container.name}...")
210180
container.remove(force=True)
211-
log_info(f"Container {container.name} removed.")
181+
logger.info(f"Container {container.name} removed.")
212182
except Exception as e:
213-
if raise_error:
214-
raise e
215-
log_error(
183+
raise Exception(
216184
f"Failed to remove container {container.name}: {e}\n"
217185
f"{traceback.format_exc()}"
218186
)
219187

220188

189+
def image_exists_locally(
190+
client: docker.DockerClient, image_name: str, tag: str, logger: logging.Logger
191+
) -> bool:
192+
"""Check if a Docker image exists locally.
193+
194+
Args:
195+
----
196+
client (docker.DockerClient): Docker client instance.
197+
image_name (str): The name of the Docker image.
198+
tag (str, optional): Tag of the Docker image.
199+
logger (logging.Logger): Logger instance.
200+
201+
Returns:
202+
-------
203+
bool: True if the image exists locally, False otherwise.
204+
205+
"""
206+
images = client.images.list(name=image_name)
207+
for image in images:
208+
if f"{image_name}:{tag}" in image.tags:
209+
logger.info(f"Using {image_name}:{tag} found locally.")
210+
return True
211+
logger.info(f"{image_name}:{tag} cannot be found locally")
212+
return False
213+
214+
215+
def pull_image_from_docker_hub(
216+
client: docker.DockerClient, image_name: str, tag: str, logger: logging.Logger
217+
) -> None:
218+
"""Pull a Docker image from Docker Hub.
219+
220+
Args:
221+
----
222+
client (docker.DockerClient): Docker client instance.
223+
image_name (str): The name of the Docker image.
224+
tag (str, optional): Tag of the Docker image.
225+
logger (logging.Logger): Logger instance.
226+
227+
Returns:
228+
-------
229+
docker.models.images.Image: The pulled Docker image.
230+
231+
Raises:
232+
------
233+
docker.errors.ImageNotFound: If the image is not found on Docker Hub.
234+
docker.errors.APIError: If there's an issue with the Docker API during the pull.
235+
236+
"""
237+
try:
238+
client.images.pull(image_name, tag=tag)
239+
logger.info(f"Loaded {image_name}:{tag} from Docker Hub.")
240+
except docker.errors.ImageNotFound:
241+
raise Exception(f"Image {image_name}:{tag} not found on Docker Hub.")
242+
except docker.errors.APIError as e:
243+
raise Exception(f"Error pulling image: {e}")
244+
245+
221246
def create_container(
222247
client: docker.DockerClient,
223248
image_name: str,
224-
container_name: Optional[str] = None,
249+
container_name: str,
250+
logger: logging.Logger,
225251
user: Optional[str] = None,
226252
command: Optional[str] = "tail -f /dev/null",
227253
nano_cpus: Optional[int] = None,
228-
logger: Optional[Union[str, logging.Logger]] = None,
229254
) -> Container:
230255
"""Start a Docker container using the specified image.
231256
232257
Args:
233258
----
234259
client (docker.DockerClient): Docker client.
235260
image_name (str): The name of the Docker image.
236-
container_name (str, optional): Name for the Docker container. Defaults to None.
261+
container_name (str): Name for the Docker container.
262+
logger (logging.Logger): Logger instance or log level as string for logging container creation messages.
237263
user (str, option): Log in as which user. Defaults to None.
238264
command (str, optional): Command to run in the container. Defaults to None.
239265
nano_cpus (int, optional): The number of CPUs for the container. Defaults to None.
240-
logger (Union[str, logging.Logger], optional): Logger instance or log level as string for logging container creation messages. Defaults to None.
241266
242267
Returns:
243268
-------
@@ -249,41 +274,13 @@ def create_container(
249274
Exception: For other general errors.
250275
251276
"""
252-
try:
253-
# Pull the image if it doesn't already exist
254-
client.images.pull(image_name)
255-
except docker.errors.APIError as e:
256-
raise docker.errors.APIError(f"Error pulling image: {str(e)}")
257-
258-
if not logger:
259-
# if logger is None, print to stdout
260-
def log_error(x: str) -> None:
261-
print(x)
262-
263-
def log_info(x: str) -> None:
264-
print(x)
265-
266-
elif logger == "quiet":
267-
# if logger is "quiet", don't print anything
268-
def log_info(x: str) -> None:
269-
return None
270-
271-
def log_error(x: str) -> None:
272-
return None
273-
274-
else:
275-
assert isinstance(logger, logging.Logger)
276-
277-
# if logger is a logger object, use it
278-
def log_error(x: str) -> None:
279-
logger.info(x)
280-
281-
def log_info(x: str) -> None:
282-
logger.info(x)
277+
image, tag = image_name.split(":")
278+
if not image_exists_locally(client, image, tag, logger):
279+
pull_image_from_docker_hub(client, image, tag, logger)
283280

284281
container = None
285282
try:
286-
log_info(f"Creating container for {image_name}...")
283+
logger.info(f"Creating container for {image_name}...")
287284
container = client.containers.run(
288285
image=image_name,
289286
name=container_name,
@@ -292,12 +289,12 @@ def log_info(x: str) -> None:
292289
nano_cpus=nano_cpus,
293290
detach=True,
294291
)
295-
log_info(f"Container for {image_name} created: {container.id}")
292+
logger.info(f"Container for {image_name} created: {container.id}")
296293
return container
297294
except Exception as e:
298295
# If an error occurs, clean up the container and raise an exception
299-
log_error(f"Error creating container for {image_name}: {e}")
300-
log_info(traceback.format_exc())
296+
logger.error(f"Error creating container for {image_name}: {e}")
297+
logger.info(traceback.format_exc())
301298
assert container is not None
302299
cleanup_container(client, container, logger)
303300
raise

commit0/harness/evaluate.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ def main(
5757
backend,
5858
timeout,
5959
num_cpus,
60-
stdout=False,
60+
verbose=0,
6161
): None
6262
for repo, test_dir in pairs
6363
}
@@ -70,7 +70,7 @@ def main(
7070
for name in tqdm(log_dirs):
7171
report_file = os.path.join(name, "report.json")
7272
name = name.split("/")[2]
73-
test_ids = get_tests(name, stdout=False)
73+
test_ids = get_tests(name, verbose=0)
7474
if not os.path.exists(report_file):
7575
out.append(
7676
{

commit0/harness/execution_context.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ def __init__(
9999
self.client = docker.from_env()
100100
self.container = create_container(
101101
client=self.client,
102-
image_name=spec.repo_image_key,
102+
image_name=spec.repo_image_tag,
103103
container_name=spec.get_container_name(),
104104
nano_cpus=num_cpus,
105105
logger=logger,

0 commit comments

Comments
 (0)