nixpkgs/pkgs/development/beam-modules/mix-release.nix

114 lines
3.5 KiB
Nix
Raw Normal View History

2021-06-05 23:43:29 +00:00
{ stdenv, lib, elixir, erlang, findutils, hex, rebar3, fetchMixDeps, makeWrapper, git }:
2021-04-08 11:54:48 +00:00
{ pname
, version
, src
, nativeBuildInputs ? [ ]
, meta ? { }
, enableDebugInfo ? false
, mixEnv ? "prod"
, compileFlags ? [ ]
2021-05-19 04:59:52 +00:00
# mix fixed output derivation dependencies
, mixFodDeps ? null
# mix dependencies generated by mix2nix
# this assumes each dependency is built by buildMix or buildRebar3
# each dependency needs to have a setup hook to add the lib path to $ERL_LIBS
# this is how mix will find dependencies
, mixNixDeps ? { }
2021-04-08 11:54:48 +00:00
, ...
}@attrs:
let
2021-05-19 04:59:52 +00:00
# remove non standard attributes that cannot be coerced to strings
overridable = builtins.removeAttrs attrs [ "compileFlags" "mixNixDeps" ];
2021-04-08 11:54:48 +00:00
in
2021-05-19 04:59:52 +00:00
assert mixNixDeps != { } -> mixFodDeps == null;
2021-04-08 11:54:48 +00:00
stdenv.mkDerivation (overridable // {
nativeBuildInputs = nativeBuildInputs ++ [ erlang hex elixir makeWrapper git ];
2021-05-19 04:59:52 +00:00
buildInputs = builtins.attrValues mixNixDeps;
2021-04-08 11:54:48 +00:00
MIX_ENV = mixEnv;
MIX_DEBUG = if enableDebugInfo then 1 else 0;
HEX_OFFLINE = 1;
DEBUG = if enableDebugInfo then 1 else 0; # for Rebar3 compilation
# the api with `mix local.rebar rebar path` makes a copy of the binary
MIX_REBAR3 = "${rebar3}/bin/rebar3";
postUnpack = ''
export HEX_HOME="$TEMPDIR/hex"
export MIX_HOME="$TEMPDIR/mix"
# Rebar
export REBAR_GLOBAL_CONFIG_DIR="$TEMPDIR/rebar3"
export REBAR_CACHE_DIR="$TEMPDIR/rebar3.cache"
2021-05-19 04:59:52 +00:00
${lib.optionalString (mixFodDeps != null) ''
# compilation of the dependencies will require
# that the dependency path is writable
# thus a copy to the TEMPDIR is inevitable here
export MIX_DEPS_PATH="$TEMPDIR/deps"
cp --no-preserve=mode -R "${mixFodDeps}" "$MIX_DEPS_PATH"
2021-04-08 11:54:48 +00:00
''
}
'' + (attrs.postUnpack or "");
configurePhase = attrs.configurePhase or ''
runHook preConfigure
# this is needed for projects that have a specific compile step
# the dependency needs to be compiled in order for the task
# to be available
# Phoenix projects for example will need compile.phoenix
mix deps.compile --no-deps-check --skip-umbrella-children
runHook postConfigure
'';
buildPhase = attrs.buildPhase or ''
runHook preBuild
mix compile --no-deps-check ${lib.concatStringsSep " " compileFlags}
runHook postBuild
'';
installPhase = attrs.installPhase or ''
runHook preInstall
mix release --no-deps-check --path "$out"
runHook postInstall
'';
fixupPhase = ''
runHook preFixup
if [ -e "$out/bin/${pname}.bat" ]; then # absent in special cases, i.e. elixir-ls
rm "$out/bin/${pname}.bat" # windows file
fi
# contains secrets and should not be in the nix store
# TODO document how to handle RELEASE_COOKIE
# secrets should not be in the nix store.
# This is only used for connecting multiple nodes
if [ -e $out/releases/COOKIE ]; then # absent in special cases, i.e. elixir-ls
rm $out/releases/COOKIE
fi
# removing unused erlang reference from resulting derivation to reduce
# closure size
if [ -e $out/erts-* ]; then
echo "ERTS found in $dir - removing references to erlang to reduce closure size"
for file in $out/erts-*/bin/{erl,start}; do
substituteInPlace "$file" --replace "${erlang}/lib/erlang" "$out"
done
fi
2021-04-08 11:54:48 +00:00
patchShebangs $out
runHook postFixup
'';
# TODO investigate why the resulting closure still has
# a reference to erlang.
# uncommenting the following will fail the build
2021-04-08 11:54:48 +00:00
# disallowedReferences = [ erlang ];
})