Tinfoil.NifCheck (tinfoil v0.2.22)

Copy Markdown View Source

Heuristic detection of dependencies that may not cross-compile cleanly under Burrito's Zig toolchain.

Burrito handles pure-Erlang/Elixir deps without ceremony, but deps that carry NIFs -- Rustler crates, elixir_make C extensions, raw c_src/ sources -- often need per-target native tooling that Zig can't always synthesize. This module surfaces those deps at plan time so a broken release doesn't silently ship.

It reads files from disk but never shells out or runs a build; the heuristics look at each dep's top-level mix.exs, Makefile, and well-known source directories. The detection is a warning, not a gate -- Burrito + Zig often does cross-compile these cleanly, and rustler_precompiled deps ship prebuilts that sidestep the issue entirely when coverage matches your targets.

Summary

Functions

Inspect a list of {name, path} dep tuples and return a list of warnings, one entry per dep that matched at least one NIF signal.

Human-readable sentence for a reason atom.

Resolve the dep set to scan: the deps that will actually be present in the release build.

Types

reason()

@type reason() :: :rustler | :rustler_precompiled | :elixir_make | :c_sources

warning()

@type warning() :: %{name: atom(), path: Path.t(), reasons: [reason()]}

Functions

check(deps)

@spec check([{atom(), Path.t()}]) :: [warning()]

Inspect a list of {name, path} dep tuples and return a list of warnings, one entry per dep that matched at least one NIF signal.

Order of reasons within a warning is stable (see @reason_order/0). Order of warnings follows the input order.

describe(atom)

@spec describe(reason()) :: String.t()

Human-readable sentence for a reason atom.

release_deps(env \\ :prod)

@spec release_deps(atom()) :: [{atom(), Path.t()}]

Resolve the dep set to scan: the deps that will actually be present in the release build.

mix tinfoil.plan normally runs under MIX_ENV=dev, but the generated workflow builds under MIX_ENV=prod. Scanning the dev set reports NIFs in deps that can never reach the artifact -- credo pulls in file_system, which carries a c_src/ directory but is only: [:dev, :test] and so is absent from the release.

Two filters are applied:

  • environment -- deps are resolved as env sees them, so only: restrictions that exclude a dep from the build drop it here too
  • runtime: false -- top-level deps marked compile-time-only are excluded from the release's :applications, so a NIF in one cannot affect the built binary

Returns {name, path} tuples suitable for check/1. The list is empty when mix deps.get hasn't been run, in which case callers should stay silent rather than emit spurious warnings.