## The run builder


## RunBuilder


Accumulates shell commands into a single `RUN` instruction.


Usage

``` python
RunBuilder(
    apt_updated=False,
    apt_dirty=True,
    stage,
    commands=list(),
)
```


Obtained from [Stage.run](stage-authoring.md#docker_dsl.Stage.run) used as a `with` block. Any attribute you access becomes a shell binary: `r.git("clone", url)` emits `git clone <url>`, with keyword arguments turned into flags by [CmdInvoker](the-run-builder.md#docker_dsl.CmdInvoker). The shipped `builder.pyi` type stub gives editors completions for the common binaries. Use [__call__](the-run-builder.md#docker_dsl.RunBuilder.__call__) for a raw command line, and the apt helpers from [AptMixin](the-run-builder.md#docker_dsl.AptMixin) for package installs.

On block exit, the accumulated commands join with `&&` into one `RUN`; nothing is emitted if the block raises or stays empty.


#### Parameter Attributes


`apt_updated: bool = ``False`  

`apt_dirty: bool = ``True`  

`stage: `<a href="stage-authoring.html#docker_dsl.Stage" class="gdls-link gdls-code"><code>Stage</code></a>  

`commands: list[ShellCommand] = list()`    


#### Example

``` python
>>> with s.run() as r:
...     r.git("clone", "https://example.com/repo.git", ".")
...     r.make("-j$(nproc)")
```


#### Methods

| Name | Description |
|----|----|
| [__call__()](#docker_dsl.RunBuilder.__call__) | Append a raw command line, for anything the dispatch can't express. |
| [echo()](#docker_dsl.RunBuilder.echo) | Build an [echo](the-run-builder.md#docker_dsl.RunBuilder.echo) whose output you redirect to a file. |
| [cd()](#docker_dsl.RunBuilder.cd) | Change directory, as a statement or a scoped `with` block. |
| [curl_bash()](#docker_dsl.RunBuilder.curl_bash) | Pipe a remote install script into `bash` over a pinned-TLS curl. |
| [install()](#docker_dsl.RunBuilder.install) | Download a tarball and extract it into a directory. |
| [fetch_file()](#docker_dsl.RunBuilder.fetch_file) | Download a single file, creating its parent directory first. |


##### \_\_call\_\_()


Append a raw command line, for anything the dispatch can't express.


Usage

``` python
__call__(raw, *, env=None)
```


##### Parameters


`raw: str`  
The verbatim shell command.

`env: dict[str, str] | None = None`  
Environment variables prefixed onto the command.


##### echo()


Build an [echo](the-run-builder.md#docker_dsl.RunBuilder.echo) whose output you redirect to a file.


Usage

``` python
echo(text)
```


Apply `>>` to append or `>` to truncate, with the destination path on the right (see [RedirectableCmd](the-run-builder.md#docker_dsl.RedirectableCmd)).


##### Parameters


`text: str`  
The text to echo. It is quoted for you.


##### Returns


<a href="the-run-builder.html#docker_dsl.RedirectableCmd" class="gdls-link gdls-code"><code>RedirectableCmd</code></a>  
A [RedirectableCmd](the-run-builder.md#docker_dsl.RedirectableCmd) awaiting a `>>` or `>` redirect.


##### Example

``` python
>>> r.echo("deb ... main") >> "/etc/apt/sources.list.d/extra.list"
```


##### cd()


Change directory, as a statement or a scoped `with` block.


Usage

``` python
cd(path)
```


As a bare call, later commands run from `path`. As a `with` block, the directory is restored with `cd -` on exit (see [CdScope](the-run-builder.md#docker_dsl.CdScope)).


##### Parameters


`path: str`  
Directory to change into.


##### Returns


<a href="the-run-builder.html#docker_dsl.CdScope" class="gdls-link gdls-code"><code>CdScope</code></a>  
A [CdScope](the-run-builder.md#docker_dsl.CdScope), usable as a statement or a `with` block.


##### Example

``` python
>>> with r.cd("/src"):
...     r.make("install")
```


##### curl_bash()


Pipe a remote install script into `bash` over a pinned-TLS curl.


Usage

``` python
curl_bash(url, *, args=())
```


##### Parameters


`url: str`  
Script URL, fetched with `--proto '=https' --tlsv1.2`.

`args: tuple[str, …] = ()`    
Arguments passed to the script after `-s --`.


##### install()


Download a tarball and extract it into a directory.


Usage

``` python
install(url, *, target="/usr/local/bin", strip=1)
```


##### Parameters


`url: str`  
Tarball URL.

`target: str = ``"/usr/local/bin"`  
Directory to extract into.

`strip: int = ``1`  
Leading path components to strip (`tar --strip-components`).


##### fetch_file()


Download a single file, creating its parent directory first.


Usage

``` python
fetch_file(url, dest)
```


##### Parameters


`url: str`  
File URL.

`dest: str`  
Destination path; its parent directory is created.


## AptMixin


AptMixin(\*, apt_updated: 'bool' = False, apt_dirty: 'bool' = True)


Usage

``` python
AptMixin(*, apt_updated=False, apt_dirty=True)
```


#### Parameter Attributes


`apt_updated: bool = ``False`  

`apt_dirty: bool = ``True`  


#### Methods

| Name | Description |
|----|----|
| [apt_install()](#docker_dsl.AptMixin.apt_install) | Install apt packages, inserting `apt-get update` only when stale. |
| [add_apt_ppa()](#docker_dsl.AptMixin.add_apt_ppa) | Add a PPA and mark the package lists stale. |
| [add_apt_repo()](#docker_dsl.AptMixin.add_apt_repo) | Add a third-party apt repository with its signing key. |


##### apt_install()


Install apt packages, inserting `apt-get update` only when stale.


Usage

``` python
apt_install(*packages, fast=False)
```


An update runs before the first install and again after anything that dirties the package lists ([add_apt_ppa](the-run-builder.md#docker_dsl.AptMixin.add_apt_ppa), [add_apt_repo](the-run-builder.md#docker_dsl.AptMixin.add_apt_repo)), so you never write `apt-get update` by hand and never run it redundantly.


##### Parameters


`*packages: str`  
Package names to install.

`fast: bool = ``False`  
Install with `apt-fast` instead of `apt-get` (requires apt-fast to be installed first).


##### add_apt_ppa()


Add a PPA and mark the package lists stale.


Usage

``` python
add_apt_ppa(ppa)
```


The next [apt_install](the-run-builder.md#docker_dsl.AptMixin.apt_install) re-runs `apt-get update` so the PPA's packages are visible.


##### Parameters


`ppa: str`  
PPA spec, e.g. `ppa:apt-fast/stable`.


##### add_apt_repo()


Add a third-party apt repository with its signing key.


Usage

``` python
add_apt_repo(key_url, repo_url, *, name)
```


Fetches the GPG key, dearmors it into `/usr/share/keyrings`, writes a `signed-by` source list, and marks the package lists stale so the next [apt_install](the-run-builder.md#docker_dsl.AptMixin.apt_install) re-runs `apt-get update`.


##### Parameters


`key_url: str`  
URL of the repository's GPG key.

`repo_url: str`  
The `deb` line's repository and components, e.g. `https://example.com/apt stable main`.

`name: str`  
Basename for the keyring and source-list files.


## RedirectableCmd


A pending [echo](the-run-builder.md#docker_dsl.RunBuilder.echo) awaiting a redirect target.


Usage

``` python
RedirectableCmd(builder, text)
```


Returned by [RunBuilder.echo](the-run-builder.md#docker_dsl.RunBuilder.echo). Apply `>>` to append to a file or `>` to truncate it, with the path on the right. The echoed text is quoted for you.


#### Parameter Attributes


`builder: `<a href="the-run-builder.html#docker_dsl.RunBuilder" class="gdls-link gdls-code"><code>RunBuilder</code></a>  

`text: str`  


#### Example

``` python
>>> r.echo("pillow>=11") >> "/root/overrides.txt"   # append
>>> r.echo("numpy<3") > "/etc/pip/constraint.txt"    # truncate
```


## CdScope


A [cd](the-run-builder.md#docker_dsl.RunBuilder.cd) that optionally restores the previous directory.


Usage

``` python
CdScope(builder, path)
```


Returned by [RunBuilder.cd](the-run-builder.md#docker_dsl.RunBuilder.cd). As a bare statement it just changes directory. As a `with` block it appends `cd -` on exit, so later commands resume where they were.


#### Parameter Attributes


`builder: `<a href="the-run-builder.html#docker_dsl.RunBuilder" class="gdls-link gdls-code"><code>RunBuilder</code></a>  

`path: str`  


#### Example

``` python
>>> with r.cd("/src/build"):
...     r.make("install")
... # cd /src/build && make install && cd -
```


## CmdInvoker


A bound shell binary, produced by [RunBuilder](the-run-builder.md#docker_dsl.RunBuilder)'s attribute dispatch.


Usage

``` python
CmdInvoker(builder, binary)
```


Accessing `r.<name>` yields one of these for `<name>`; calling it appends the command. Positional arguments pass through verbatim. Keyword arguments become flags: `depth="1"` adds `--depth 1`, `verbose=True` adds `--verbose`, and a `False` value is dropped. Underscores in names become hyphens.


#### Parameter Attributes


`builder: `<a href="the-run-builder.html#docker_dsl.RunBuilder" class="gdls-link gdls-code"><code>RunBuilder</code></a>  

`binary: str`  


#### Example

``` python
>>> r.git("clone", url, depth="1", recurse_submodules=True)
... # git clone <url> --depth 1 --recurse-submodules
```
