Skip to content

Commit cf79748

Browse files
digimangosCopilot
andcommitted
fix(preset): keep update retry usable for option-like IDs
A preset ID starting with a hyphen satisfies manifest validation but Typer parses it as an option, so the printed retry command could not be copy-pasted. Place the source and priority options before a -- separator for such IDs, preserving the existing order for normal ones. Assisted-by: GitHub Copilot (model: claude-opus-5, supervised) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 162466c commit cf79748

2 files changed

Lines changed: 76 additions & 7 deletions

File tree

src/specify_cli/presets/_commands.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -524,12 +524,17 @@ def preset_update(
524524
# reconciliation before add resolves and installs the replacement.
525525
preset_remove(preset_id)
526526

527-
retry_args = ["specify", "preset", "add", preset_id]
528-
if from_url:
529-
retry_args.extend(["--from", from_url])
530-
if dev:
531-
retry_args.extend(["--dev", dev])
532-
retry_args.extend(["--priority", str(priority)])
527+
retry_args = ["specify", "preset", "add"]
528+
retry_options = []
529+
if from_url is not None:
530+
retry_options.extend(["--from", from_url])
531+
if dev is not None:
532+
retry_options.extend(["--dev", dev])
533+
retry_options.extend(["--priority", str(priority)])
534+
if preset_id.startswith("-"):
535+
retry_args.extend([*retry_options, "--", preset_id])
536+
else:
537+
retry_args.extend([preset_id, *retry_options])
533538

534539
def report_add_failure() -> None:
535540
import subprocess

tests/integration/test_preset_update_workflow.py

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ def write_preset(
4141
version: str,
4242
body: str,
4343
extra_file: str | None = None,
44+
preset_id: str = PRESET_ID,
4445
) -> Path:
4546
"""Write a minimal single-template preset under *directory*.
4647
@@ -58,7 +59,7 @@ def write_preset(
5859
{
5960
"schema_version": "1.0",
6061
"preset": {
61-
"id": PRESET_ID,
62+
"id": preset_id,
6263
"name": "Update Workflow Demo",
6364
"version": version,
6465
"description": "Fixture preset for update workflow tests",
@@ -261,3 +262,66 @@ def test_preset_update_failed_replacement_prints_working_retry_command(
261262
assert metadata is not None
262263
assert metadata["version"] == "2.0.0"
263264
assert metadata["priority"] == 7
265+
266+
267+
def test_preset_update_retry_handles_option_like_id(project: Path, tmp_path: Path):
268+
"""The printed retry places a leading-hyphen ID after ``--``."""
269+
runner = CliRunner()
270+
preset_id = "--option-like-preset"
271+
272+
original = write_preset(
273+
tmp_path / "option-v1",
274+
version="1.0.0",
275+
body="# Option-like Version One\n",
276+
preset_id=preset_id,
277+
)
278+
install = runner.invoke(app, ["preset", "add", "--dev", str(original)])
279+
assert install.exit_code == 0, install.output
280+
assert PresetManager(project).registry.is_installed(preset_id)
281+
282+
replacement = tmp_path / "option-replacement"
283+
update = runner.invoke(
284+
app,
285+
[
286+
"preset",
287+
"update",
288+
"--dev",
289+
str(replacement),
290+
"--priority",
291+
"9",
292+
"--",
293+
preset_id,
294+
],
295+
)
296+
assert update.exit_code == 1, update.output
297+
assert not PresetManager(project).registry.is_installed(preset_id)
298+
299+
rendered = retry_command_from(update.output)
300+
assert rendered == render_command(
301+
[
302+
"specify",
303+
"preset",
304+
"add",
305+
"--dev",
306+
str(replacement),
307+
"--priority",
308+
"9",
309+
"--",
310+
preset_id,
311+
]
312+
)
313+
314+
write_preset(
315+
replacement,
316+
version="2.0.0",
317+
body="# Option-like Version Two\n",
318+
preset_id=preset_id,
319+
)
320+
retry_args = parse_command(rendered)
321+
retry = runner.invoke(app, retry_args[1:])
322+
323+
assert retry.exit_code == 0, retry.output
324+
metadata = PresetManager(project).registry.get(preset_id)
325+
assert metadata is not None
326+
assert metadata["version"] == "2.0.0"
327+
assert metadata["priority"] == 9

0 commit comments

Comments
 (0)