Skip to content

Commit 87e2b86

Browse files
lebriceclaude
andcommitted
Remove --no-sync from cluv submit: always sync before submitting
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 986fb06 commit 87e2b86

3 files changed

Lines changed: 8 additions & 62 deletions

File tree

cluv/cli/submit.py

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
from pathlib import Path
88

99
import rich_argparse
10-
from milatools.utils.remote_v2 import RemoteV2
11-
1210
from cluv.cli.sync import sync
1311
from cluv.config import find_pyproject, get_config
1412
from cluv.utils import console
@@ -22,7 +20,7 @@ def add_submit_args(
2220
"submit",
2321
help="Submit a SLURM job on a remote cluster.",
2422
formatter_class=rich_argparse.RichHelpFormatter,
25-
usage="cluv submit <cluster> <job.sh> [--no-sync] [sbatch-args...] [-- program-args...]",
23+
usage="cluv submit <cluster> <job.sh> [sbatch-args...] [-- program-args...]",
2624
)
2725
submit_parser.add_argument(
2826
"cluster",
@@ -35,12 +33,6 @@ def add_submit_args(
3533
metavar="<job.sh>",
3634
help="Path to the sbatch job script (relative to project root).",
3735
)
38-
submit_parser.add_argument(
39-
"--no-sync",
40-
action="store_true",
41-
default=False,
42-
help="Skip syncing the project to the cluster before submitting.",
43-
)
4436
submit_parser.add_argument(
4537
"rest",
4638
nargs=argparse.REMAINDER,
@@ -54,14 +46,13 @@ def add_submit_args(
5446
async def submit(
5547
cluster: str,
5648
job_script: str,
57-
no_sync: bool,
5849
rest: list[str],
5950
):
6051
"""Submit a SLURM job on a remote cluster.
6152
62-
Enforces a clean git state, sets GIT_COMMIT and any SBATCH_* env vars
63-
configured in [tool.cluv.slurm] / [tool.cluv.clusters.<name>], then calls
64-
sbatch on the remote.
53+
Enforces a clean git state, syncs the project, sets GIT_COMMIT and any
54+
SBATCH_* env vars configured in [tool.cluv.slurm] / [tool.cluv.clusters.<name>],
55+
then calls sbatch on the remote.
6556
6657
Any arguments before -- are forwarded to sbatch as flags; arguments after --
6758
are passed to the job script as program arguments.
@@ -91,12 +82,9 @@ async def submit(
9182
["git", "rev-parse", "HEAD"], text=True
9283
).strip()
9384

94-
# 3. Sync (or just connect).
95-
if not no_sync:
96-
remotes = await sync(clusters=[cluster])
97-
remote = remotes[0]
98-
else:
99-
remote = await RemoteV2.connect(cluster)
85+
# 3. Sync.
86+
remotes = await sync(clusters=[cluster])
87+
remote = remotes[0]
10088

10189
config = get_config()
10290

tests/test_integration.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,6 @@ async def test_submit_rorqual_builds_correct_command():
217217
await submit_module.submit(
218218
cluster="rorqual",
219219
job_script="scripts/job.sh",
220-
no_sync=False, # uses the mocked sync, which returns our patched remote
221220
rest=["--", "echo", "hello"],
222221
)
223222

tests/test_submit.py

Lines changed: 1 addition & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ async def test_dirty_git_aborts(tmp_path):
5959
await submit_module.submit(
6060
cluster="rorqual",
6161
job_script="scripts/job.sh",
62-
no_sync=False,
6362
rest=[],
6463
)
6564
assert exc_info.value.code == 1
@@ -87,7 +86,6 @@ async def test_submit_builds_correct_remote_command(tmp_path):
8786
await submit_module.submit(
8887
cluster="rorqual",
8988
job_script="scripts/job.sh",
90-
no_sync=False,
9189
rest=["--", "python", "train.py"],
9290
)
9391

@@ -120,7 +118,6 @@ async def test_sbatch_flags_forwarded(tmp_path):
120118
await submit_module.submit(
121119
cluster="rorqual",
122120
job_script="scripts/job.sh",
123-
no_sync=False,
124121
rest=["--partition=gpu", "--mem=40G", "--", "python", "train.py"],
125122
)
126123

@@ -153,7 +150,6 @@ async def test_rest_without_separator_treated_as_sbatch_flags(tmp_path):
153150
await submit_module.submit(
154151
cluster="rorqual",
155152
job_script="scripts/job.sh",
156-
no_sync=False,
157153
rest=["--gres=gpu:1"],
158154
)
159155

@@ -184,7 +180,6 @@ async def test_submit_includes_global_slurm_vars(tmp_path):
184180
await submit_module.submit(
185181
cluster="rorqual",
186182
job_script="scripts/job.sh",
187-
no_sync=False,
188183
rest=["--", "python", "train.py"],
189184
)
190185

@@ -213,7 +208,6 @@ async def test_submit_per_cluster_vars_override_globals(tmp_path):
213208
await submit_module.submit(
214209
cluster="rorqual",
215210
job_script="scripts/job.sh",
216-
no_sync=False,
217211
rest=["--", "python", "train.py"],
218212
)
219213

@@ -224,40 +218,7 @@ async def test_submit_per_cluster_vars_override_globals(tmp_path):
224218
assert "SBATCH_TIME=1:00:00" in cmd
225219

226220

227-
# ---------------------------------------------------------------------------
228-
# --no-sync skips sync and calls RemoteV2.connect instead
229-
# ---------------------------------------------------------------------------
230-
231-
232-
async def test_no_sync_skips_sync(tmp_path):
233-
fake_remote = AsyncMock()
234-
pyproject = tmp_path / "proj" / "pyproject.toml"
235-
(tmp_path / "proj").mkdir()
236-
237-
mock_connect = AsyncMock(return_value=fake_remote)
238-
mock_sync = AsyncMock(return_value=[fake_remote])
239-
240-
with (
241-
patch.object(submit_module.subprocess, "run", side_effect=_git_clean_run),
242-
patch.object(submit_module.subprocess, "check_output", return_value=FAKE_COMMIT),
243-
patch.object(submit_module, "sync", mock_sync),
244-
patch.object(submit_module.RemoteV2, "connect", mock_connect),
245-
patch.object(submit_module, "get_config", return_value=_make_config()),
246-
patch.object(submit_module, "find_pyproject", return_value=pyproject),
247-
patch.object(Path, "home", return_value=tmp_path),
248-
):
249-
await submit_module.submit(
250-
cluster="rorqual",
251-
job_script="scripts/job.sh",
252-
no_sync=True,
253-
rest=[],
254-
)
255-
256-
mock_sync.assert_not_called()
257-
mock_connect.assert_called_once_with("rorqual")
258-
259-
260-
async def test_sync_called_by_default(tmp_path):
221+
async def test_always_syncs(tmp_path):
261222
fake_remote = AsyncMock()
262223
pyproject = tmp_path / "proj" / "pyproject.toml"
263224
(tmp_path / "proj").mkdir()
@@ -275,7 +236,6 @@ async def test_sync_called_by_default(tmp_path):
275236
await submit_module.submit(
276237
cluster="rorqual",
277238
job_script="scripts/job.sh",
278-
no_sync=False,
279239
rest=[],
280240
)
281241

@@ -303,7 +263,6 @@ async def test_git_commit_always_injected(tmp_path):
303263
await submit_module.submit(
304264
cluster="rorqual",
305265
job_script="scripts/job.sh",
306-
no_sync=False,
307266
rest=[],
308267
)
309268

0 commit comments

Comments
 (0)