# `Stevedore.Build`
[🔗](https://github.com/oshlabs/stevedore/blob/v0.2.0/lib/stevedore/build.ex#L1)

Assemble images **declaratively** from layers + a config — the crane-style create surface.

Stevedore builds images as data; it never *runs* build steps (no Dockerfile `RUN`). For each
layer it computes both digests the spec requires and keeps them straight:

  * the **diff_id** — `sha256` of the *uncompressed* tar (goes in the config's `rootfs.diff_ids`)
  * the **descriptor digest** — `sha256` of the *compressed* bytes (goes in the manifest)

The default compression is gzip; output is OCI media types (or Docker `v2s2` via
`format: :docker`). Builds are deterministic: layer compression and tar headers carry no
timestamps, so the same inputs yield the same digests.

Spec: [OCI image-spec, config](https://github.com/opencontainers/image-spec/blob/main/config.md)
and [layer](https://github.com/opencontainers/image-spec/blob/main/layer.md); crane semantics.

# `layer_input`

```elixir
@type layer_input() :: binary() | [Stevedore.Archive.entry()] | {Path.t(), keyword()}
```

A layer source: an uncompressed tar binary, a list of `t:Stevedore.Archive.entry/0`, or a
`{path, opts}` pointing at an uncompressed tar file.

# `append`

```elixir
@spec append(Stevedore.Image.t(), layer_input(), keyword()) ::
  {:ok, Stevedore.Image.t()} | {:error, term()}
```

Appends a layer to an image, adding a matching history entry and recomputing the manifest.

# `from_dir`

```elixir
@spec from_dir(Path.t(), map() | Stevedore.Config.t(), keyword()) ::
  {:ok, Stevedore.Image.t()} | {:error, term()}
```

Builds a single-layer image from a directory tree.

The tree is tarred with deterministic ordering and zeroed timestamps, so the same tree always
produces the same digest.

# `image`

```elixir
@spec image([layer_input()], map() | Stevedore.Config.t(), keyword()) ::
  {:ok, Stevedore.Image.t()} | {:error, term()}
```

Builds an image from a list of layer inputs and a config.

`config` is the runtime config — a map of `:entrypoint`/`:cmd`/`:env`/`:user`/`:working_dir`/
`:labels`, or a `t:Stevedore.Config.t/0`. Options: `:platform` (`"os/arch"` or a keyword),
`:format` (`:oci`/`:docker`), `:compression` (`:gzip`/`:none`/`:zstd`).

## Examples

    iex> tar = Stevedore.Archive.write!([%{name: "f", type: :regular, mode: 0o644, size: 2, linkname: nil, content: "hi"}])
    iex> {:ok, image} = Stevedore.Build.image([tar], %{entrypoint: ["/f"]})
    iex> length(image.layers)
    1

---

*Consult [api-reference.md](api-reference.md) for complete listing*
