Git Product home page Git Product logo

nix-rebar3's Introduction

nix-rebar3

This is a Nix library aiming to be an alternative to rebar3_nix that does not require code generation, similar to mix-to-nix but for rebar3 instead of Mix.

Usage

(callPackage nix-rebar3 {}).buildRebar3 {
  root = ./.;
  pname = "myapp";
  version = "1.0.0";
  releaseType = "release";
  profile = "prod";
}

Note that for running a built release with dynamic configuration you either need to first copy the files out of the read-only Nix store, or set the RELX_OUT_FILE_PATH environment variable to a suitable location, since the extended start script generated by relx by default will write files under the release root directory.

The parameters of buildRebar3 are:

Attribute Description
pname The name of the derivation.
version The version number.
root Path to the directory of the rebar3 project.
releaseType One of: app to build OTP applications; release to assemble relx releases; or escriptize to generate an escript executable. (Default: app)
profile The profile to run rebar3 tasks in. (Default: default)
checkouts Attribute set where the keys are dependency names and values are paths to their sources.
This is for overriding dependencies or providing the transitive closure of dependencies such as plugins or those not in the default profile, e.g. test dependencies. The latter is made necessary by such dependencies not being stored in the rebar3 lock file. (Default: {})
singleStep Whether to skip compiling the dependencies in an intermediate derivation first. Enabling reduces the incrementality of builds. (Default: false)

All other arguments are passed through to the resulting stdenv.mkDerivation call.

Background

This section summarizes the existing support for packaging rebar3 projects in Nixpkgs. Apart from the regular nixpkgs.rebar3 attribute, which is adequate for interactive usage, there is also a patched version that makes it possible to provide paths to pre-built rebar3 plugins to include with

nixpkgs.rebar3WithPlugins { plugins = [ ... ] }

(which passes them through an internal REBAR_GLOBAL_PLUGINS environment variable) to avoid rebar3 choking on trying to download missing plugins during sandboxed builds. When using rebar3WithPlugins, in addition to manually specified plugins, a custom rebar_ignore_deps is always included, that, when the environment variable REBAR_IGNORE_DEPS is non-empty, overrides the install_deps rebar3 provider to instead proceed with the build as if there were no declared dependencies.

There are choices that can be made when packaging rebar3 projects with Nix in general regarding library Erlang application dependencies. They may be built en masse in a separate derivation, or individually with one derivation each. To prevent Rebar3 from managing and downloading the dependencies, one can either: Copy them into the _checkouts top-level directory; or reference built library dependencies in the ERL_LIBS environment variable, and use the bare compile rebar3 provider instead of compile (which skips trying to build dependencies,) or set REBAR_IGNORE_DEPS to true (see above.) Note that it is not possible to include multiple versions of the same application in Erlang/rebar3; the lock file in the top level project is authoritative, with an algorithm for determining the versions to fetch, see Source Dependencies; and rebar3 plugins may technically interfere when building other dependencies; and therefore building libraries individually can produce unexpected results.

With that said, the available rebar3 builders in Nixpkgs are:

  • buildRebar3: Builds Erlang applications using rebar3 bare compile.

    The built package will export a setup hook that adds the built applications to ERL_LIBS. All dependencies have to be built similarly and passed in the beamDeps argument, which due to the setup hooks is here just an alias for propagatedBuildInputs.

  • rebar3Relx: Builds relx releases or escript executables.

    Dependencies should be provided with beamDeps like above, at which point REBAR_IGNORE_DEPS is set.

  • fetchRebar3Deps: Produces a fixed-output derivation (FOD) with the output of rebar3 get-deps.

    The result can be used as the checkouts argument to rebar3Relx.

  • fetchHex: Fetches a package tarball from Hex the Erlang package manager/repository.

    buildHex is a shorthand for using fetchHex for the source to any other builder such as buildRebar3.

rebar3_nix is a tool that generates a deps.nix file you are intended to check in to version control, which evaluates to an attribute set containing all dependencies for some rebar3 project. Rebar3 lock files are limited to the default profile, and do not include plugin dependencies nor the precise subdependencies of some dependency, but, being a rebar3 plugin, rebar3_nix has access to that information and for any combination of profiles.

This library instead reads the rebar3 lock file with a pure Nix parser, with the big upside of not requiring any additional generated files. The downsides are that compiled dependencies are not shared between different projects built with Nix, and that plugins and dependencies not listed in the default profile, such as test dependencies, and their transitive dependencies, have to be specified manually.

nix-rebar3's People

Contributors

axelf4 avatar rskew avatar zwilias avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

zwilias

nix-rebar3's Issues

Builds fail with nixpkgs/nixos-22.11

Hello, thanks for nix-rebar3!

When moving from "nixpkgs/nixos-22.05" to "nixpkgs/nixos-22.11" my build started failing during installPhase with consumeEntire(): ERROR: Input null bytes, won't process, due to $out/rel/*/erts-*/bin/erl now being a binary file (crashing substituteInPlace here https://github.com/axelf4/nix-rebar3/blob/master/default.nix#L147).

Not running substituteInPlace for binary files fixes the problem:

                if [ -z "$(file $f -b --mime | grep 'charset=binary')" ]; then
                  substituteInPlace "$f" --replace ${erlang}/lib/erlang "''${f%/erts-*/bin/*}"
                fi

however this feels clunky, there's probably a more appropriate solution that I'm not seeing due to my lack of understanding of erlang releases and nix-rebar3 (or maybe my project is mis-configured in some other way).

I haven't managed to find how/why the file is now binary rather than ascii. With nixos-22.11, rebar3 version 3.20.0 is used, whereas nixos 22.05 uses rebar3 3.18.0. Both nixos 22.11 and 22.05 use Erlang/OTP 24 and Erts 12.3.2.5.

I've created a small reproducible example here https://github.com/rskew/nix-rebar3-bug-demo

Cheers :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.