Skip to content

Generate sandbox buildable Nix expression from Mix lock file

License

Notifications You must be signed in to change notification settings

serokell/mix-to-nix

Repository files navigation

Overview

Nix function that reads mix.lock file and builds a Mix project. Works inside the Nix sandbox.

To try it out, create the following default.nix in your Mix project:

with import <nixpkgs> {};

let
  inherit (callPackage (fetchGit {
    url = https://gitlab.com/transumption/mix-to-nix;
    rev = "b70cb8f7fca80d0c5f7539dbfec497535e07d75c";
  }) {}) mixToNix;
in

mixToNix { src = ./.; }

Run nix-build.

OTP apps

To start an OTP app, run:

$ cd result
$ MIX_ENV=prod \
  mix run -c /path/to/config.exs --no-deps-check --no-halt

Escripts

To build an escript, override postBuild and installPhase:

(mixToNix { src = ./.; }).overrideAttrs (super: {
  postBuild = ''
    mix escript.build --no-deps-check
  '';

  installPhase = "install -Dt $out/bin ${super.pname}";
})

Distillery

(mixToNix { src = ./.; }).overrideAttrs (super: {
  buildPhase = ''
    mix do deps.loadpaths --no-deps-check, release --env=prod
  '';
  
  installPhase = ''
    mkdir $out
    find _build -name \*.tar.gz | xargs cat | tar zxf - -C $out
  '';
})

Details

If src is a path, it is filtered against lib.cleanSource, _build/, and deps/.

elixir-to-json evaluates Elixir term in mix.lock and marshals it to JSON. Tuples are represented as lists.

Then, Nix imports that JSON via lib.importJSON. Each mix.lock key corresponds to a deps/ path. Two types of deps are supported, :git and :hexpm.

:git fetches given rev from HEAD. It doesn't support other branches just yet, see NixOS/nix#2409.

:hexpm fetches package from Hex.pm. It comes with a SHA-256 hash of catenation of Mix archive version, package metadata, and .tar.gz source code archive. Nix can only carry that catenation into the sandbox, so binwalk finds where the source code archive starts and extracts that part, ignoring archive version and metadata.

Mix, Rebar3 and ErlangMk deps are supported.

fake-hex-registry creates a fake Hex v1 registry with dependencies for Rebar3 projects. Rebar3 needs registry to function.

Every dependency is built and cached individually via Nixpkgs buildMix and buildRebar3.

Quirks

:git dependencies are flat, so they are assumed to depend on every non-Git entry in mix.lock. If this is undesirable, or if you want to make Git deps depend on each other, you can override beamDeps via overlay.

If you have dependencies that require Rebar3 plugins (such as pc or rebar3_hex), add them to mix.exs deps. These are normally unpinned and non-sandboxable. You will also need to set buildPlugins via overlay. See tests/02-fast-yaml for example.

Releases

No releases published

Packages

No packages published