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

Inspect an image's effective filesystem: list files, read a file's bytes, and extract a
best-effort software bill of materials — all over `Stevedore.Layer.merged_view/2`, in memory.

`sbom/2` is a **heuristic**: it reads well-known metadata files (`/etc/os-release`, the dpkg
and apk databases) if present. It does not run a scanner or shell out, and is not a guarantee
of completeness.

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

# `matcher`

```elixir
@type matcher() :: Regex.t() | (String.t() -&gt; boolean())
```

# `files`

```elixir
@spec files(Stevedore.Image.t(), matcher(), keyword()) ::
  {:ok, [Stevedore.Layer.fs_node()]} | {:error, term()}
```

Lists the effective-filesystem nodes whose path matches `matcher` (a `Regex` or a predicate),
sorted by path.

## Examples

    iex> tar = Stevedore.Archive.write!([
    ...>   %{name: "usr/bin/sh", type: :regular, mode: 0o755, size: 1, linkname: nil, content: "x"},
    ...>   %{name: "etc/hosts", type: :regular, mode: 0o644, size: 1, linkname: nil, content: "y"}
    ...> ])
    iex> {:ok, image} = Stevedore.Build.image([tar], %{})
    iex> {:ok, nodes} = Stevedore.Analyze.files(image, ~r{^usr/})
    iex> Enum.map(nodes, & &1.path)
    ["usr/bin/sh"]

# `read_file`

```elixir
@spec read_file(Stevedore.Image.t(), String.t()) ::
  {:ok, binary()} | {:error, :enoent}
```

Reads the bytes of a single regular file from the effective filesystem (the top-most version
across layers). Leading `/` in `path` is optional.

# `sbom`

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

Best-effort SBOM: OS identity from `/etc/os-release` and installed packages from the dpkg
(Debian/Ubuntu) and apk (Alpine) databases, if present.

---

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