cli.main¶
Top-level otto CLI: callback, subcommand dispatch, and eager option handlers.
- otto.cli.main.version_callback(version: bool) None¶
Print the otto version string and exit when
--versionis passed.
- otto.cli.main.clear_autocomplete_cache_callback(value: bool) None¶
Delete the shell-completion cache file and exit when the flag is set.
- otto.cli.main.list_labs_callback(value: bool) None¶
Print all available lab names (one panel per repo) and exit when the flag is set.
- otto.cli.main.log_level_callback(value: str) str¶
Normalise the
--log-levelvalue to upper-case before Typer stores it.
- otto.cli.main.main(ctx: ~typer.models.Context, labs: ~types.Annotated[list[str] | None, <typer.models.OptionInfo object at 0x730179a1f100>] | None = None, xdir: ~pathlib.Annotated[~pathlib.Path, <typer.models.OptionInfo object at 0x730179a1e1a0>] = PosixPath('.'), debug: ~typing.Annotated[bool, <typer.models.OptionInfo object at 0x730179a1df90>] = False, log_days: ~typing.Annotated[int, <typer.models.OptionInfo object at 0x730179a1f6a0>] = 30, log_level: ~typing.Annotated[str, <typer.models.OptionInfo object at 0x730179a1dc60>] = 'INFO', rich_log_file: ~typing.Annotated[bool, <typer.models.OptionInfo object at 0x730179a1cf10>] = False, show_time: ~typing.Annotated[bool, <typer.models.OptionInfo object at 0x730179a1e050>] = False, lab_depth: ~typing.Annotated[int, <typer.models.OptionInfo object at 0x730179a1e170>] = 3, list_labs: ~typing.Annotated[bool, <typer.models.OptionInfo object at 0x730179a1ea10>] = False, show_lab: ~typing.Annotated[bool, <typer.models.OptionInfo object at 0x730179a1f970>] = False, list_hosts: ~typing.Annotated[bool, <typer.models.OptionInfo object at 0x730179a1da80>] = False, dry_run: ~typing.Annotated[bool, <typer.models.OptionInfo object at 0x730179a1fb20>] = False, version: ~types.Annotated[bool | None, <typer.models.OptionInfo object at 0x730179a1fca0>] | None = None, clear_autocomplete_cache: ~typing.Annotated[bool, <typer.models.OptionInfo object at 0x730179a1edd0>] = False, as_user: ~types.Annotated[str | None, <typer.models.OptionInfo object at 0x730179a1ee30>] | None = None, skip_reservation_check: ~typing.Annotated[bool, <typer.models.OptionInfo object at 0x730179a1d1e0>] = False) None¶
Record root options for lazy lab loading; handle inline root-flag actions.
This is the Typer root callback executed before every
ottosubcommand. It no longer loads the lab or initialises logging: it stashes the root options onctx.metaand returns. The real work (lab load, session setup, output dir, reservation gate) runs lazily in the leaf-invokecommand_preamble(), so--help/ discovery paths are structurally incapable of touching host state. The only exceptions are--show-lab/--list-hosts, which inspect live lab state and so load it inline here before printing and exiting.
- otto.cli.main.entry() None¶
Console-script entry: composition root, then the Typer app.
Completion invocations take the cache fast path (zero user code); everything else runs
otto.bootstrap.bootstrap()before argv parsing so registered third-party commands exist when the root group is consulted. Contained user-code failures print one framed warning line each; real command dispatch fails loud in the invoke preamble.