Skip to content

Commit 42d0900

Browse files
committed
Fix CI: pre-commit (exclude logs/, ruff) + pytest (route integration test through codeclash CLI)
1 parent 0e6ad97 commit 42d0900

6 files changed

Lines changed: 48 additions & 35 deletions

File tree

.pre-commit-config.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
ci:
22
autoupdate_commit_msg: "chore: update pre-commit hooks"
33

4-
exclude: '\.ipynb\.py$'
4+
# Skip notebooks-as-py and committed sample logs (raw game data + imported bot source).
5+
exclude: '\.ipynb\.py$|^logs/'
56

67
repos:
78
- repo: https://github.com/pre-commit/pre-commit-hooks

codeclash/cli/app.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
import time
1313
import uuid
1414
from pathlib import Path
15-
from typing import Optional
1615

1716
import typer
1817
import yaml
@@ -39,9 +38,7 @@
3938
def run(
4039
config_path: Path = typer.Argument(..., help="Path to the tournament config file."),
4140
cleanup: bool = typer.Option(False, "--cleanup", "-c", help="Clean up the game environment after running."),
42-
output_dir: Optional[Path] = typer.Option(
43-
None, "--output-dir", "-o", help="Output directory (default: logs/<user>)."
44-
),
41+
output_dir: Path | None = typer.Option(None, "--output-dir", "-o", help="Output directory (default: logs/<user>)."),
4542
suffix: str = typer.Option("", "--suffix", "-s", help="Suffix for the output folder name (no leading dot)."),
4643
keep_containers: bool = typer.Option(
4744
False, "--keep-containers", "-k", help="Do not remove containers after games/agent finish."

codeclash/cli/ladder.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import getpass
44
import time
55
from pathlib import Path
6-
from typing import Optional
76

87
import typer
98
import yaml
@@ -53,9 +52,7 @@ def make(
5352
def run(
5453
config_path: Path = typer.Argument(..., help="Path to the ladder config (with `player` + `ladder`)."),
5554
cleanup: bool = typer.Option(False, "--cleanup", "-c", help="Clean up the game environment after running."),
56-
output_dir: Optional[Path] = typer.Option(
57-
None, "--output-dir", "-o", help="Output directory (default: logs/<user>)."
58-
),
55+
output_dir: Path | None = typer.Option(None, "--output-dir", "-o", help="Output directory (default: logs/<user>)."),
5956
suffix: str = typer.Option("", "--suffix", "-s", help="Suffix for the output folder name (no leading dot)."),
6057
keep_containers: bool = typer.Option(
6158
False, "--keep-containers", "-k", help="Do not remove containers after games/agent finish."

scripts/replay_battlesnake.py

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
The jsonl format: one metadata line, per-turn v1 state frames ({game,turn,board,you}),
1414
and a final result line ({winnerName,isDraw}).
1515
"""
16+
1617
import argparse
1718
import json
1819
import sys
@@ -48,19 +49,28 @@ def load(path):
4849
frames = []
4950
for t in turns:
5051
b = by_turn[t]
51-
frames.append({
52-
"turn": t,
53-
"food": [[c["x"], c["y"]] for c in b.get("food", [])],
54-
"hazards": [[c["x"], c["y"]] for c in b.get("hazards", [])],
55-
"snakes": [{
56-
"name": s["name"],
57-
"health": s.get("health", 0),
58-
"body": [[c["x"], c["y"]] for c in s["body"]],
59-
} for s in b["snakes"]],
60-
})
52+
frames.append(
53+
{
54+
"turn": t,
55+
"food": [[c["x"], c["y"]] for c in b.get("food", [])],
56+
"hazards": [[c["x"], c["y"]] for c in b.get("hazards", [])],
57+
"snakes": [
58+
{
59+
"name": s["name"],
60+
"health": s.get("health", 0),
61+
"body": [[c["x"], c["y"]] for c in s["body"]],
62+
}
63+
for s in b["snakes"]
64+
],
65+
}
66+
)
6167
return {
62-
"w": b0["width"], "h": b0["height"], "frames": frames, "colors": colors,
63-
"winner": result.get("winnerName"), "draw": result.get("isDraw", False),
68+
"w": b0["width"],
69+
"h": b0["height"],
70+
"frames": frames,
71+
"colors": colors,
72+
"winner": result.get("winnerName"),
73+
"draw": result.get("isDraw", False),
6474
}
6575

6676

@@ -69,7 +79,7 @@ def to_ascii(g):
6979
grid = [["." for _ in range(g["w"])] for _ in range(g["h"])]
7080
for fx, fy in f["food"]:
7181
grid[fy][fx] = "*"
72-
for i, s in enumerate(f["snakes"]):
82+
for s in f["snakes"]:
7383
ch = s["name"][0].upper()
7484
for j, (x, y) in enumerate(s["body"]):
7585
grid[y][x] = ch if j else ch.lower() # head lowercase-ish marker

scripts/replay_robotrumble.py

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
(unit id -> {"Ok": {"type":"Move"|"Attack","direction":...}} or {"Ok":"None"}).
1919
Blue is the first (blue) bot, Red is the second.
2020
"""
21+
2122
import argparse
2223
import json
2324
import sys
@@ -55,14 +56,16 @@ def load(path, blue_name=None, red_name=None):
5556
ok = act["Ok"]
5657
if isinstance(ok, dict):
5758
atype, adir = ok.get("type"), ok.get("direction")
58-
units.append({
59-
"team": o.get("team"),
60-
"hp": o.get("health", 0),
61-
"x": o["coords"][0],
62-
"y": o["coords"][1],
63-
"act": atype,
64-
"dir": adir,
65-
})
59+
units.append(
60+
{
61+
"team": o.get("team"),
62+
"hp": o.get("health", 0),
63+
"x": o["coords"][0],
64+
"y": o["coords"][1],
65+
"act": atype,
66+
"dir": adir,
67+
}
68+
)
6669
frames.append({"turn": t["state"].get("turn"), "units": units})
6770

6871
winner_raw = data.get("winner")
@@ -97,9 +100,11 @@ def to_ascii(g):
97100
for u in f["units"]:
98101
counts[u["team"]] += 1
99102
hp[u["team"]] += u["hp"]
100-
print(f"\n--- turn {f['turn']} --- "
101-
f"{g['names']['Blue']}(B): {counts['Blue']} units / {hp['Blue']} hp "
102-
f"{g['names']['Red']}(R): {counts['Red']} units / {hp['Red']} hp")
103+
print(
104+
f"\n--- turn {f['turn']} --- "
105+
f"{g['names']['Blue']}(B): {counts['Blue']} units / {hp['Blue']} hp "
106+
f"{g['names']['Red']}(R): {counts['Red']} units / {hp['Red']} hp"
107+
)
103108
for row in grid:
104109
print(" ".join(row))
105110
print(f"\nWinner: {'TIE' if g['draw'] else g['winner']}")

tests/test_integration.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,13 @@
99

1010

1111
def test_pvp_battlesnake():
12-
from main import main_cli
12+
from typer.testing import CliRunner
13+
14+
from codeclash.cli.app import app
1315

1416
config_path = CONFIG_DIR / "test" / "battlesnake_pvp_test.yaml"
15-
main_cli(["-c", str(config_path)])
17+
result = CliRunner().invoke(app, ["run", "-c", str(config_path)])
18+
assert result.exit_code == 0, result.output
1619

1720

1821
def test_single_player_battlesnake():

0 commit comments

Comments
 (0)