A pure tar reader/writer plus gzip helpers.
OCI layers are tar archives (optionally gzip- or zstd-compressed). This reads and writes them
without shelling out to tar: the writer emits POSIX ustar headers; the reader also
understands GNU long-name (L) and PAX extended-header (x) records, which real registry
images use for paths longer than 100 bytes. zstd is added in a later phase (optional NIF);
gzip is native via Erlang's :zlib.
Spec: POSIX pax/ustar format.
Summary
Functions
Decompresses gzip data, returning {:error, :gzip} on malformed input.
Gzip-compresses data (RFC 1952).
Reads a tar archive into a list of entries, in archive order.
Decompresses zstd data. Raises a clear error if the optional :ezstd NIF isn't available.
Writes entries to a tar archive, returning {:ok, binary} or an error tuple.
Writes entries to a tar archive (ustar). Raises Stevedore.Archive.Error on an unencodable
entry (e.g. a path too long for ustar headers).
Zstd-compresses data. Raises a clear error if the optional :ezstd NIF isn't available.
Whether zstd support is available — i.e. the optional :ezstd NIF is loaded. gzip is always
available natively; zstd requires adding {:ezstd, "~> 1.1"} to your deps.
Types
@type entry() :: %{ name: String.t(), type: :regular | :directory | :symlink | :hardlink, mode: non_neg_integer(), size: non_neg_integer(), linkname: String.t() | nil, content: binary() | nil }
Functions
Decompresses gzip data, returning {:error, :gzip} on malformed input.
Gzip-compresses data (RFC 1952).
Examples
iex> Stevedore.Archive.gunzip(Stevedore.Archive.gzip("payload"))
{:ok, "payload"}
@spec read(binary()) :: {:ok, [entry()]} | {:error, Stevedore.Archive.Error.t()}
Reads a tar archive into a list of entries, in archive order.
Examples
iex> tar = Stevedore.Archive.write!([%{name: "a.txt", type: :regular, mode: 0o644, size: 2, linkname: nil, content: "hi"}])
iex> {:ok, [entry]} = Stevedore.Archive.read(tar)
iex> {entry.name, entry.content}
{"a.txt", "hi"}
Decompresses zstd data. Raises a clear error if the optional :ezstd NIF isn't available.
@spec write([entry()]) :: {:ok, binary()} | {:error, Stevedore.Archive.Error.t()}
Writes entries to a tar archive, returning {:ok, binary} or an error tuple.
Examples
iex> {:ok, tar} = Stevedore.Archive.write([%{name: "a", type: :regular, mode: 0o644, size: 0, linkname: nil, content: ""}])
iex> is_binary(tar)
true
Writes entries to a tar archive (ustar). Raises Stevedore.Archive.Error on an unencodable
entry (e.g. a path too long for ustar headers).
Examples
iex> tar = Stevedore.Archive.write!([%{name: "d", type: :directory, mode: 0o755, size: 0, linkname: nil, content: nil}])
iex> {:ok, [entry]} = Stevedore.Archive.read(tar)
iex> entry.type
:directory
Zstd-compresses data. Raises a clear error if the optional :ezstd NIF isn't available.
@spec zstd_available?() :: boolean()
Whether zstd support is available — i.e. the optional :ezstd NIF is loaded. gzip is always
available natively; zstd requires adding {:ezstd, "~> 1.1"} to your deps.