Skip to content
v0.1.3

Docs Command API Reference

This section documents the internals of the docs command in Bijux CLI.

bijux_cli.commands.docs

Docs command for the Bijux CLI.

Generates a machine-readable specification of the entire CLI, outputting it as JSON or YAML. This command is designed for automation, enabling integration with external documentation tools or APIs. It supports outputting to stdout or a file and ensures all text is ASCII-safe.

Output Contract
  • Success (file): {"status": "written", "file": "<path>"}
  • Success (stdout): The raw specification string is printed directly.
  • Spec fields: {"version": str, "commands": list, ...}
  • Verbose: Adds {"python": str, "platform": str} to the spec.
  • Error: {"error": str, "code": int}
Exit Codes
  • 0: Success.
  • 1: Fatal or internal error.
  • 2: CLI argument, flag, or format error.
  • 3: ASCII or encoding error.

docs

docs(
    ctx: Context,
    out: Path | None = OUT_OPTION,
    quiet: bool = Option(
        False, "-q", "--quiet", help=HELP_QUIET
    ),
    verbose: bool = Option(
        False, "-v", "--verbose", help=HELP_VERBOSE
    ),
    fmt: str = Option(
        "json", "-f", "--format", help=HELP_FORMAT
    ),
    pretty: bool = Option(
        True, "--pretty/--no-pretty", help=HELP_NO_PRETTY
    ),
    debug: bool = Option(
        False, "-d", "--debug", help=HELP_DEBUG
    ),
) -> None

Defines the entrypoint and logic for the bijux docs command.

This function orchestrates the entire specification generation process. It validates CLI flags, checks for ASCII-safe environment variables, resolves the output destination, builds the specification payload, and writes the result to a file or stdout. All errors are handled and emitted in a structured format before exiting with a specific code.

Parameters:

  • ctx (Context) –

    The Typer context, used for managing command state.

  • out (Path | None, default: OUT_OPTION ) –

    The output destination: a file path, a directory, or '-' to signify stdout.

  • quiet (bool, default: Option(False, '-q', '--quiet', help=HELP_QUIET) ) –

    If True, suppresses all output except for errors.

  • verbose (bool, default: Option(False, '-v', '--verbose', help=HELP_VERBOSE) ) –

    If True, includes Python and platform metadata in the spec.

  • fmt (str, default: Option('json', '-f', '--format', help=HELP_FORMAT) ) –

    The output format, either "json" or "yaml". Defaults to "json".

  • pretty (bool, default: Option(True, '--pretty/--no-pretty', help=HELP_NO_PRETTY) ) –

    If True, pretty-prints the output for human readability.

  • debug (bool, default: Option(False, '-d', '--debug', help=HELP_DEBUG) ) –

    If True, enables debug diagnostics, implying verbose and pretty.

Returns:

  • None ( None ) –

Raises:

  • SystemExit

    Exits the application with a contract-compliant status code and payload upon any error, including argument validation, ASCII violations, serialization failures, or I/O issues.

Source code in src/bijux_cli/commands/docs.py
@docs_app.callback(invoke_without_command=True)
def docs(
    ctx: typer.Context,
    out: Path | None = OUT_OPTION,
    quiet: bool = typer.Option(False, "-q", "--quiet", help=HELP_QUIET),
    verbose: bool = typer.Option(False, "-v", "--verbose", help=HELP_VERBOSE),
    fmt: str = typer.Option("json", "-f", "--format", help=HELP_FORMAT),
    pretty: bool = typer.Option(True, "--pretty/--no-pretty", help=HELP_NO_PRETTY),
    debug: bool = typer.Option(False, "-d", "--debug", help=HELP_DEBUG),
) -> None:
    """Defines the entrypoint and logic for the `bijux docs` command.

    This function orchestrates the entire specification generation process. It
    validates CLI flags, checks for ASCII-safe environment variables, resolves
    the output destination, builds the specification payload, and writes the
    result to a file or stdout. All errors are handled and emitted in a
    structured format before exiting with a specific code.

    Args:
        ctx (typer.Context): The Typer context, used for managing command state.
        out (Path | None): The output destination: a file path, a directory, or
            '-' to signify stdout.
        quiet (bool): If True, suppresses all output except for errors.
        verbose (bool): If True, includes Python and platform metadata in the spec.
        fmt (str): The output format, either "json" or "yaml". Defaults to "json".
        pretty (bool): If True, pretty-prints the output for human readability.
        debug (bool): If True, enables debug diagnostics, implying `verbose`
            and `pretty`.

    Returns:
        None:

    Raises:
        SystemExit: Exits the application with a contract-compliant status code
            and payload upon any error, including argument validation, ASCII
            violations, serialization failures, or I/O issues.
    """
    from bijux_cli.commands.utilities import normalize_format
    from bijux_cli.infra.serializer import OrjsonSerializer, PyYAMLSerializer
    from bijux_cli.infra.telemetry import NullTelemetry

    command = "docs"
    effective_include_runtime = (verbose or debug) and not quiet
    effective_pretty = True if (debug and not quiet) else pretty

    fmt_lower = normalize_format(fmt)

    if ctx.args:
        stray = ctx.args[0]
        msg = (
            f"No such option: {stray}"
            if stray.startswith("-")
            else f"Too many arguments: {' '.join(ctx.args)}"
        )
        emit_error_and_exit(
            msg,
            code=2,
            failure="args",
            command=command,
            fmt=fmt_lower,
            quiet=quiet,
            include_runtime=effective_include_runtime,
            debug=debug,
        )

    validate_common_flags(
        fmt,
        command,
        quiet,
        include_runtime=effective_include_runtime,
    )

    if contains_non_ascii_env():
        emit_error_and_exit(
            "Non-ASCII characters in environment variables",
            code=3,
            failure="ascii_env",
            command=command,
            fmt=fmt_lower,
            quiet=quiet,
            include_runtime=effective_include_runtime,
            debug=debug,
        )

    out_env = os.environ.get("BIJUXCLI_DOCS_OUT")
    if out is None and out_env:
        out = Path(out_env)

    target, path = _resolve_output_target(out, fmt_lower)

    try:
        spec = _build_spec_payload(effective_include_runtime)
    except ValueError as exc:
        emit_error_and_exit(
            str(exc),
            code=3,
            failure="ascii",
            command=command,
            fmt=fmt_lower,
            quiet=quiet,
            include_runtime=effective_include_runtime,
            debug=debug,
        )

    output_format = OutputFormat.YAML if fmt_lower == "yaml" else OutputFormat.JSON
    serializer = (
        PyYAMLSerializer(NullTelemetry())
        if output_format is OutputFormat.YAML
        else OrjsonSerializer(NullTelemetry())
    )
    try:
        content = serializer.dumps(spec, fmt=output_format, pretty=effective_pretty)
    except Exception as exc:
        emit_error_and_exit(
            f"Serialization failed: {exc}",
            code=1,
            failure="serialize",
            command=command,
            fmt=fmt_lower,
            quiet=quiet,
            include_runtime=effective_include_runtime,
            debug=debug,
        )

    if os.environ.get("BIJUXCLI_TEST_IO_FAIL") == "1":
        emit_error_and_exit(
            "Simulated I/O failure for test",
            code=1,
            failure="io_fail",
            command=command,
            fmt=fmt_lower,
            quiet=quiet,
            include_runtime=effective_include_runtime,
            debug=debug,
        )

    if target == "-":
        if not quiet:
            typer.echo(content)
        raise typer.Exit(0)

    if path is None:
        emit_error_and_exit(
            "Internal error: expected non-null output path",
            code=1,
            failure="internal",
            command=command,
            fmt=fmt_lower,
            quiet=quiet,
            include_runtime=effective_include_runtime,
            debug=debug,
        )

    parent = path.parent
    if not parent.exists():
        emit_error_and_exit(
            f"Output directory does not exist: {parent}",
            code=2,
            failure="output_dir",
            command=command,
            fmt=fmt_lower,
            quiet=quiet,
            include_runtime=effective_include_runtime,
            debug=debug,
        )

    try:
        path.write_text(content, encoding="utf-8")
    except Exception as exc:
        emit_error_and_exit(
            f"Failed to write spec: {exc}",
            code=2,
            failure="write",
            command=command,
            fmt=fmt_lower,
            quiet=quiet,
            include_runtime=effective_include_runtime,
            debug=debug,
        )

    emit_and_exit(
        {"status": "written", "file": str(path)},
        output_format,
        effective_pretty,
        verbose,
        debug,
        quiet,
        command,
    )