cli.run¶
otto run subcommand: decorator and Typer app for user-defined run instructions.
- class otto.cli.run.InstructionEntry(name: str, sub_app: Typer, module: str)¶
Bases:
objectOne registered instruction: its Typer sub-app + defining module.
- otto.cli.run.list_instructions_callback(value: bool) None¶
Print all available run instructions (one panel per repo) and exit when the flag is set.
- otto.cli.run.main(ctx: ~typer.models.Context, list_instructions: ~typing.Annotated[bool, <typer.models.OptionInfo object at 0x73017964bac0>] = False) None¶
Handle the eager
--list-instructionsflag; real work runs in the leaf preamble.Output-dir creation and the reservation gate moved to the shared leaf-invoke
command_preamble(), so a subcommand--help(which exits before invoke) can never create a spurious dir.
-
otto.cli.run.instruction(*args: Any, options: type | None =
None, **kwargs: Any) Callable[[...], Any]¶ Register an async function as an
otto runsubcommand.When options is a dataclass, the decorator expands its fields (including inherited ones) into individual CLI flags — exactly like
OttoSuite’s auto-registration does for suite options. The original function must declare a parameter annotated with the options class; the decorator replaces it with the expanded fields and, at call time, constructs the populated dataclass instance before forwarding it to the function.If the function declares a parameter annotated as
OttoContext, that parameter is stripped from the CLI signature and injected at call time from the active context (DI-friendly, additive — existing handlers are unaffected).Usage without options (unchanged from before):
@instruction() async def deploy(debug: Annotated[bool, typer.Option()] = False): ...Usage with an options dataclass:
@dataclass class _Opts(RepoOptions): debug: Annotated[bool, typer.Option()] = False @instruction(options=_Opts) async def deploy(opts: _Opts): print(opts.debug)Usage with OttoContext injection:
@instruction() async def status(ctx: OttoContext) -> CommandResult: host = ctx.get_host("router") ...The same dataclass may be inherited by a suite’s inner
Optionsclass, giving bothotto testandotto runsubcommands a uniform set of repo-wide flags.