Skip to content

CommandContext

The CommandContext captures the output of shell commands. It can be created using the capsula.CommandContext.builder method or the capsula.CommandContext.__init__ method.

capsula.CommandContext.builder classmethod

builder(
    command: str,
    *,
    cwd: Path | str | None = None,
    check: bool = True,
    abort_on_error: bool = True,
    cwd_relative_to_project_root: bool = False,
    shell: bool = True
) -> Callable[[CapsuleParams], CommandContext]
PARAMETER DESCRIPTION
command

Command to run

TYPE: str

cwd

Working directory for the command, passed to the cwd argument of subprocess.run

TYPE: Path | str | None DEFAULT: None

check

Whether to raise an exception if the command returns a non-zero exit code, passed to the check argument of `subprocess.run

TYPE: bool DEFAULT: True

abort_on_error

Whether to abort the encapsulation if the command returns a non-zero exit code

TYPE: bool DEFAULT: True

cwd_relative_to_project_root

Whether cwd argument is relative to the project root. Will be ignored if cwd is None or absolute. If True, it will be interpreted as relative to the project root. If False, cwd will be interpreted as relative to the current working directory. It is recommended to set this to True in the configuration file.

TYPE: bool DEFAULT: False

shell

Whether to run the command using the shell. If True, the command will be run using the shell. If False, the command will be run directly. For more information, see the shell argument of subprocess.run.

TYPE: bool DEFAULT: True

Source code in capsula/_context/_command.py
@classmethod
def builder(
    cls,
    command: Annotated[str, Doc("Command to run")],
    *,
    cwd: Annotated[
        Path | str | None,
        Doc("Working directory for the command, passed to the `cwd` argument of `subprocess.run`"),
    ] = None,
    check: Annotated[
        bool,
        Doc(
            "Whether to raise an exception if the command returns a non-zero exit code, passed to the `check` "
            "argument of `subprocess.run",
        ),
    ] = True,
    abort_on_error: Annotated[
        bool,
        Doc("Whether to abort the encapsulation if the command returns a non-zero exit code"),
    ] = True,
    cwd_relative_to_project_root: Annotated[
        bool,
        Doc(
            "Whether `cwd` argument is relative to the project root. Will be ignored if `cwd` is None or absolute. "
            "If True, it will be interpreted as relative to the project root. "
            "If False, `cwd` will be interpreted as relative to the current working directory. "
            "It is recommended to set this to True in the configuration file.",
        ),
    ] = False,
    shell: Annotated[
        bool,
        Doc(
            "Whether to run the command using the shell. If True, the command will be run using the shell. "
            "If False, the command will be run directly. "
            "For more information, see the `shell` argument of `subprocess.run`. ",
        ),
    ] = True,
) -> Callable[[CapsuleParams], CommandContext]:
    def build(params: CapsuleParams) -> CommandContext:
        if cwd_relative_to_project_root and cwd is not None and not Path(cwd).is_absolute():
            cwd_path: Path | None = params.project_root / cwd
        elif cwd_relative_to_project_root and cwd is None:
            cwd_path = params.project_root
        else:
            cwd_path = Path(cwd) if cwd is not None else None

        return cls(
            command,
            cwd=cwd_path,
            check=check,
            abort_on_error=abort_on_error,
            shell=shell,
        )

    return build

capsula.CommandContext.__init__

__init__(
    command: str,
    *,
    cwd: Path | None = None,
    check: bool = True,
    abort_on_error: bool = True,
    shell: bool = True
)

Initialize the command context.

PARAMETER DESCRIPTION
command

TYPE: str

cwd

TYPE: Path | None DEFAULT: None

check

TYPE: bool DEFAULT: True

abort_on_error

TYPE: bool DEFAULT: True

shell

TYPE: bool DEFAULT: True

Source code in capsula/_context/_command.py
def __init__(
    self,
    command: str,
    *,
    cwd: Path | None = None,
    check: bool = True,
    abort_on_error: bool = True,
    shell: bool = True,
) -> None:
    """Initialize the command context."""
    self._command = command
    self._cwd = cwd
    self._check = check
    self._abort_on_error = abort_on_error
    self._shell = shell

Configuration example

Via capsula.toml

[pre-run]
contexts = [
  { type = "CommandContext", command = "uv lock --locked", cwd = ".", cwd_relative_to_project_root = true },
]

Via @capsula.context decorator

import capsula
PROJECT_ROOT = capsula.search_for_project_root(__file__)

@capsula.run()
@capsula.context(capsula.CommandContext("uv lock --locked", cwd=PROJECT_ROOT), mode="pre")
def func(): ...

Output example

The following is an example of the output of the CommandContext, reported by the JsonDumpReporter:

"uv lock --locked": {
  "command": "uv lock --locked",
  "cwd": "/Users/nomura/ghq/github.com/shunichironomura/capsula",
  "returncode": 0,
  "stdout": "",
  "stderr": "Resolved 73 packages in 0.35ms\n"
}