Skip to content

Commit 80b9f6f

Browse files
committed
feat(cli): unifier workspace apply/select et workflow headless
1 parent 73f1b82 commit 80b9f6f

7 files changed

Lines changed: 577 additions & 64 deletions

cli/click_workspace_commands.py

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
from typing import Any, Callable
99

1010
from .contracts import EXIT_PRECHECK_FAILED, EXIT_WORKSPACE_INVALID
11+
from .headless_commands import run_workspace_apply
1112
from .output import plain
13+
from .workspace_apply_args import build_workspace_apply_args
1214

1315

1416
def register_workspace_commands(
@@ -85,6 +87,84 @@ def workspace_files(path, as_json):
8587
for item in result["python_files_preview"]:
8688
plain(f" - {item}")
8789

90+
@workspace.command("apply")
91+
@click.argument("path", required=False, type=click.Path(exists=False))
92+
@click.option("--json", "as_json", is_flag=True)
93+
@click.option("--with-venv", is_flag=True, help="Create or reuse a local workspace venv")
94+
@click.option("--entrypoint", type=str, help="Override detected entrypoint")
95+
@click.option("--no-auto-config", is_flag=True, help="Skip auto configuration pass")
96+
@click.option("--no-inspect-files", is_flag=True, help="Skip recursive python file scan")
97+
@click.option("--no-apply-venv-pref", is_flag=True, help="Skip workspace venv preference application")
98+
@click.option("--no-apply-engine-configs", is_flag=True, help="Skip loading workspace engine configs")
99+
@click.option("--strict", is_flag=True, help="Fail when required checks are missing")
100+
@click.option("--require-entrypoint", is_flag=True, help="Require a resolved entrypoint")
101+
def workspace_apply(
102+
path,
103+
as_json,
104+
with_venv,
105+
entrypoint,
106+
no_auto_config,
107+
no_inspect_files,
108+
no_apply_venv_pref,
109+
no_apply_engine_configs,
110+
strict,
111+
require_entrypoint,
112+
):
113+
args = build_workspace_apply_args(
114+
path=path,
115+
as_json=bool(as_json),
116+
with_venv=bool(with_venv),
117+
entrypoint=entrypoint,
118+
no_auto_config=bool(no_auto_config),
119+
no_inspect_files=bool(no_inspect_files),
120+
no_apply_venv_pref=bool(no_apply_venv_pref),
121+
no_apply_engine_configs=bool(no_apply_engine_configs),
122+
strict=bool(strict),
123+
require_entrypoint=bool(require_entrypoint),
124+
)
125+
code = run_workspace_apply(args)
126+
if code:
127+
raise click.exceptions.Exit(code)
128+
129+
@workspace.command("select")
130+
@click.argument("path", required=False, type=click.Path(exists=False))
131+
@click.option("--json", "as_json", is_flag=True)
132+
@click.option("--with-venv", is_flag=True, help="Create or reuse a local workspace venv")
133+
@click.option("--entrypoint", type=str, help="Override detected entrypoint")
134+
@click.option("--no-auto-config", is_flag=True, help="Skip auto configuration pass")
135+
@click.option("--no-inspect-files", is_flag=True, help="Skip recursive python file scan")
136+
@click.option("--no-apply-venv-pref", is_flag=True, help="Skip workspace venv preference application")
137+
@click.option("--no-apply-engine-configs", is_flag=True, help="Skip loading workspace engine configs")
138+
@click.option("--strict", is_flag=True, help="Fail when required checks are missing")
139+
@click.option("--require-entrypoint", is_flag=True, help="Require a resolved entrypoint")
140+
def workspace_select(
141+
path,
142+
as_json,
143+
with_venv,
144+
entrypoint,
145+
no_auto_config,
146+
no_inspect_files,
147+
no_apply_venv_pref,
148+
no_apply_engine_configs,
149+
strict,
150+
require_entrypoint,
151+
):
152+
args = build_workspace_apply_args(
153+
path=path,
154+
as_json=bool(as_json),
155+
with_venv=bool(with_venv),
156+
entrypoint=entrypoint,
157+
no_auto_config=bool(no_auto_config),
158+
no_inspect_files=bool(no_inspect_files),
159+
no_apply_venv_pref=bool(no_apply_venv_pref),
160+
no_apply_engine_configs=bool(no_apply_engine_configs),
161+
strict=bool(strict),
162+
require_entrypoint=bool(require_entrypoint),
163+
)
164+
code = run_workspace_apply(args)
165+
if code:
166+
raise click.exceptions.Exit(code)
167+
88168
@cli.command("init")
89169
@click.argument("workspace", required=False, type=click.Path(exists=False))
90170
@click.option("--json", "as_json", is_flag=True)
@@ -140,3 +220,81 @@ def ws_config_auto_cmd(workspace, entrypoint, as_json):
140220
entrypoint=entrypoint,
141221
as_json=as_json,
142222
)
223+
224+
@ws.command("apply")
225+
@click.argument("workspace", required=False, type=click.Path(exists=False))
226+
@click.option("--json", "as_json", is_flag=True)
227+
@click.option("--with-venv", is_flag=True, help="Create or reuse a local workspace venv")
228+
@click.option("--entrypoint", type=str, help="Override detected entrypoint")
229+
@click.option("--no-auto-config", is_flag=True, help="Skip auto configuration pass")
230+
@click.option("--no-inspect-files", is_flag=True, help="Skip recursive python file scan")
231+
@click.option("--no-apply-venv-pref", is_flag=True, help="Skip workspace venv preference application")
232+
@click.option("--no-apply-engine-configs", is_flag=True, help="Skip loading workspace engine configs")
233+
@click.option("--strict", is_flag=True, help="Fail when required checks are missing")
234+
@click.option("--require-entrypoint", is_flag=True, help="Require a resolved entrypoint")
235+
def ws_apply_cmd(
236+
workspace,
237+
as_json,
238+
with_venv,
239+
entrypoint,
240+
no_auto_config,
241+
no_inspect_files,
242+
no_apply_venv_pref,
243+
no_apply_engine_configs,
244+
strict,
245+
require_entrypoint,
246+
):
247+
args = build_workspace_apply_args(
248+
path=workspace,
249+
as_json=bool(as_json),
250+
with_venv=bool(with_venv),
251+
entrypoint=entrypoint,
252+
no_auto_config=bool(no_auto_config),
253+
no_inspect_files=bool(no_inspect_files),
254+
no_apply_venv_pref=bool(no_apply_venv_pref),
255+
no_apply_engine_configs=bool(no_apply_engine_configs),
256+
strict=bool(strict),
257+
require_entrypoint=bool(require_entrypoint),
258+
)
259+
code = run_workspace_apply(args)
260+
if code:
261+
raise click.exceptions.Exit(code)
262+
263+
@ws.command("select")
264+
@click.argument("workspace", required=False, type=click.Path(exists=False))
265+
@click.option("--json", "as_json", is_flag=True)
266+
@click.option("--with-venv", is_flag=True, help="Create or reuse a local workspace venv")
267+
@click.option("--entrypoint", type=str, help="Override detected entrypoint")
268+
@click.option("--no-auto-config", is_flag=True, help="Skip auto configuration pass")
269+
@click.option("--no-inspect-files", is_flag=True, help="Skip recursive python file scan")
270+
@click.option("--no-apply-venv-pref", is_flag=True, help="Skip workspace venv preference application")
271+
@click.option("--no-apply-engine-configs", is_flag=True, help="Skip loading workspace engine configs")
272+
@click.option("--strict", is_flag=True, help="Fail when required checks are missing")
273+
@click.option("--require-entrypoint", is_flag=True, help="Require a resolved entrypoint")
274+
def ws_select_cmd(
275+
workspace,
276+
as_json,
277+
with_venv,
278+
entrypoint,
279+
no_auto_config,
280+
no_inspect_files,
281+
no_apply_venv_pref,
282+
no_apply_engine_configs,
283+
strict,
284+
require_entrypoint,
285+
):
286+
args = build_workspace_apply_args(
287+
path=workspace,
288+
as_json=bool(as_json),
289+
with_venv=bool(with_venv),
290+
entrypoint=entrypoint,
291+
no_auto_config=bool(no_auto_config),
292+
no_inspect_files=bool(no_inspect_files),
293+
no_apply_venv_pref=bool(no_apply_venv_pref),
294+
no_apply_engine_configs=bool(no_apply_engine_configs),
295+
strict=bool(strict),
296+
require_entrypoint=bool(require_entrypoint),
297+
)
298+
code = run_workspace_apply(args)
299+
if code:
300+
raise click.exceptions.Exit(code)

cli/dedicated.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
launch_main_gui,
1616
unload_all_engines,
1717
)
18-
from .headless_commands import run_check, run_config_auto, run_init
18+
from .headless_commands import run_check, run_config_auto, run_init, run_workspace_apply
1919
from .output import error, info, plain, success, warn
2020
from .system_info import print_system_info
2121

@@ -194,6 +194,7 @@ def _print_help() -> None:
194194
plain(" cfg-auto [workspace] Alias for config-auto")
195195
plain(" ws init [workspace] Alias for init")
196196
plain(" ws config-auto [workspace] Alias for config-auto")
197+
plain(" ws apply [workspace] Full workspace apply workflow")
197198
plain(" engines --dry-run List available engines")
198199
plain(" unload Unload all registered engines")
199200
plain(" exit | quit Close dedicated CLI")
@@ -223,6 +224,7 @@ def _print_help() -> None:
223224
table.add_row("cfg-auto [workspace]", "Alias for config-auto")
224225
table.add_row("ws init [workspace]", "Alias for init")
225226
table.add_row("ws config-auto [workspace]", "Alias for config-auto")
227+
table.add_row("ws apply [workspace]", "Apply full workspace workflow")
226228
table.add_row("unload", "Unload all registered engines")
227229
table.add_row("exit | quit", "Close dedicated CLI")
228230
_RICH_CONSOLE.print(table)
@@ -678,6 +680,9 @@ def run_dedicated_cli(app_version: str) -> int:
678680
"ws",
679681
"ws init",
680682
"ws config-auto",
683+
"ws apply",
684+
"workspace apply",
685+
"workspace select",
681686
"unload",
682687
"exit",
683688
"quit",
@@ -805,7 +810,7 @@ def run_dedicated_cli(app_version: str) -> int:
805810
continue
806811
if cmd == "ws":
807812
if not args:
808-
warn("Usage: ws <init|config-auto|cfg-auto> [workspace]")
813+
warn("Usage: ws <init|config-auto|cfg-auto|apply|select> [workspace]")
809814
continue
810815
sub = args[0].lower()
811816
ws_args = args[1:]
@@ -815,8 +820,21 @@ def run_dedicated_cli(app_version: str) -> int:
815820
if sub in ("config-auto", "cfg-auto"):
816821
run_config_auto(ws_args)
817822
continue
823+
if sub in ("apply", "select"):
824+
run_workspace_apply(ws_args)
825+
continue
818826
warn(f"Unknown ws subcommand: {sub}")
819827
continue
828+
if cmd == "workspace":
829+
if not args:
830+
warn("Usage: workspace <apply|select> [workspace]")
831+
continue
832+
sub = args[0].lower()
833+
if sub in ("apply", "select"):
834+
run_workspace_apply(args[1:])
835+
continue
836+
warn(f"Unknown workspace subcommand: {sub}")
837+
continue
820838
if cmd == "unload":
821839
_run_unload()
822840
continue

cli/fallback.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,12 @@
1616
normalize_path,
1717
)
1818
from .dedicated import run_dedicated_cli
19-
from .headless_commands import run_check, run_config_auto, run_init
19+
from .headless_commands import (
20+
run_check,
21+
run_config_auto,
22+
run_init,
23+
run_workspace_apply,
24+
)
2025
from .lazy_ops import (
2126
available_engine_ids,
2227
launch_bcasl_gui,
@@ -47,6 +52,7 @@
4752
python -m pycompiler_ark check [workspace] # CI/CD strict checks
4853
python -m pycompiler_ark init [workspace] # Init workspace config
4954
python -m pycompiler_ark config-auto [workspace] # Auto configure workspace
55+
python -m pycompiler_ark ws apply [workspace] # Full workspace apply workflow
5056
"""
5157

5258

@@ -137,17 +143,28 @@ def run(argv: list[str] | None, app_version: str) -> int:
137143
return run_init(rest)
138144
if cmd in ("config-auto", "cfg-auto"):
139145
return run_config_auto(rest)
146+
if cmd == "workspace":
147+
if not rest:
148+
error("Usage: workspace <apply|select> [workspace]")
149+
return EXIT_USAGE_ERROR
150+
sub = rest[0]
151+
if sub in ("apply", "select"):
152+
return run_workspace_apply(rest[1:])
153+
error(f"Unknown workspace subcommand: {sub}")
154+
return EXIT_USAGE_ERROR
140155
# Alias workspace: garde les habitudes courtes (`ws ...`) en fallback.
141156
if cmd == "ws":
142157
if not rest:
143-
error("Usage: ws <init|config-auto|cfg-auto> [workspace]")
158+
error("Usage: ws <init|config-auto|cfg-auto|apply|select> [workspace]")
144159
return EXIT_USAGE_ERROR
145160
ws_cmd = rest[0]
146161
ws_args = rest[1:]
147162
if ws_cmd == "init":
148163
return run_init(ws_args)
149164
if ws_cmd in ("config-auto", "cfg-auto"):
150165
return run_config_auto(ws_args)
166+
if ws_cmd in ("apply", "select"):
167+
return run_workspace_apply(ws_args)
151168
error(f"Unknown ws subcommand: {ws_cmd}")
152169
return EXIT_USAGE_ERROR
153170

0 commit comments

Comments
 (0)