Skip to content

Commit 93eb508

Browse files
committed
feat(cli): unifier bcasl run/doctor pour usage serveur
1 parent 9aa3a66 commit 93eb508

3 files changed

Lines changed: 56 additions & 6 deletions

File tree

cli/click_app.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -817,22 +817,30 @@ def bcasl_list(as_json):
817817
sys.exit(_run_bcasl_headless(["list"]))
818818

819819
@bcasl.command("run")
820-
@click.argument("workspace", type=click.Path(exists=False))
820+
@click.argument("workspace", required=False, type=click.Path(exists=False))
821+
@click.option("-w", "--workspace", "workspace_opt", type=click.Path(exists=False))
821822
@click.option("--timeout", type=float, default=0.0)
822-
def bcasl_run(workspace, timeout):
823+
def bcasl_run(workspace, workspace_opt, timeout):
823824
"""Run BCASL pipeline headlessly for one workspace."""
824-
args = ["run", _resolve_workspace_path(workspace) or workspace]
825+
selected_workspace = workspace_opt or workspace
826+
if not selected_workspace:
827+
raise click.ClickException("Missing workspace path for bcasl run")
828+
args = ["run", _resolve_workspace_path(selected_workspace) or selected_workspace]
825829
if timeout:
826830
args.extend(["--timeout", str(timeout)])
827831
sys.exit(_run_bcasl_headless(args))
828832

829833
@bcasl.command("doctor")
830834
@click.argument("workspace", required=False, type=click.Path(exists=False))
835+
@click.option("-w", "--workspace", "workspace_opt", type=click.Path(exists=False))
831836
@click.option("--json", "as_json", is_flag=True)
832837
@click.option("--strict", is_flag=True, help="Exit non-zero when BCASL checks fail")
833-
def bcasl_doctor(workspace, as_json, strict):
838+
def bcasl_doctor(workspace, workspace_opt, as_json, strict):
834839
"""Run BCASL diagnostics and optionally enforce strict mode."""
835-
payload = bcasl_doctor_payload(workspace=_resolve_workspace_path(workspace))
840+
selected_workspace = workspace_opt or workspace
841+
payload = bcasl_doctor_payload(
842+
workspace=_resolve_workspace_path(selected_workspace)
843+
)
836844
if as_json:
837845
if strict and any(not check["ok"] for check in payload.get("checks", [])):
838846
_emit_and_exit(payload, EXIT_PRECHECK_FAILED, as_json=True)

cli/dedicated.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,13 +301,16 @@ def _print_bcasl_help() -> None:
301301
plain(" bcasl list")
302302
plain(" bcasl run <workspace> [--timeout SECONDS]")
303303
plain(" bcasl run -w <workspace> [--timeout SECONDS]")
304+
plain(" bcasl doctor [workspace] [--strict]")
305+
plain(" bcasl doctor -w <workspace> [--strict]")
304306
plain("")
305307
plain("Examples:")
306308
plain(" bcasl")
307309
plain(" bcasl /path/to/workspace")
308310
plain(" bcasl list")
309311
plain(" bcasl run /path/to/workspace")
310312
plain(" bcasl run /path/to/workspace --timeout 30")
313+
plain(" bcasl doctor /path/to/workspace --strict")
311314
plain("")
312315
return
313316

@@ -318,10 +321,12 @@ def _print_bcasl_help() -> None:
318321
table.add_row("bcasl list", "List BCASL plugins")
319322
table.add_row("bcasl run <workspace>", "Run plugins headless")
320323
table.add_row("bcasl run -w <workspace>", "Run plugins headless")
324+
table.add_row("bcasl doctor [workspace]", "Run BCASL diagnostics")
321325
_RICH_CONSOLE.print(table)
322326
_RICH_CONSOLE.print("[bold]Examples[/bold]")
323327
_print_cmdline("bcasl list")
324328
_print_cmdline("bcasl run /path/to/workspace --timeout 30")
329+
_print_cmdline("bcasl doctor /path/to/workspace --strict")
325330

326331

327332
def _run_bcasl_headless(args: list[str]) -> int:
@@ -414,6 +419,41 @@ def _log(msg: str) -> None:
414419
error(f"BCASL run finished with failures: {failed} plugin(s) failed.")
415420
return 1
416421

422+
if sub == "doctor":
423+
workspace: str | None = None
424+
strict = False
425+
i = 1
426+
while i < len(args):
427+
tok = args[i]
428+
if tok in ("-w", "--workspace"):
429+
if i + 1 >= len(args):
430+
error("Missing workspace path after --workspace")
431+
return 2
432+
workspace = _resolve_workspace(args[i + 1])
433+
i += 2
434+
continue
435+
if tok == "--strict":
436+
strict = True
437+
i += 1
438+
continue
439+
if workspace is None and not tok.startswith("-"):
440+
workspace = _resolve_workspace(tok)
441+
i += 1
442+
continue
443+
error(f"Unknown option for bcasl doctor: {tok}")
444+
return 2
445+
446+
from .headless_ops import bcasl_doctor_payload
447+
448+
payload = bcasl_doctor_payload(workspace=workspace)
449+
plain("BCASL Doctor")
450+
for check in payload.get("checks", []):
451+
status = "OK" if check.get("ok") else "FAIL"
452+
plain(f" [{status}] {check.get('name')}: {check.get('message') or ''}")
453+
if strict and not payload.get("ok", False):
454+
return 1
455+
return 0
456+
417457
error(f"Unknown bcasl subcommand: {sub}")
418458
_print_bcasl_help()
419459
return 2

cli/fallback.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
first_positional,
1616
normalize_path,
1717
)
18-
from .dedicated import run_dedicated_cli
18+
from .dedicated import _run_bcasl_headless, run_dedicated_cli
1919
from .headless_commands import (
2020
run_check,
2121
run_config_auto,
@@ -134,6 +134,8 @@ def run(argv: list[str] | None, app_version: str) -> int:
134134
if cmd in ("--unload", "unload"):
135135
return _run_unload()
136136
if cmd == "bcasl":
137+
if rest and rest[0] in ("list", "run", "doctor"):
138+
return _run_bcasl_headless(rest)
137139
return launch_bcasl_gui(normalize_path(first_positional(rest)))
138140
if cmd == "engines":
139141
return _run_engines(rest)

0 commit comments

Comments
 (0)