diff options
author | Luke Granger-Brown <git@lukegb.com> | 2021-04-12 18:26:33 +0000 |
---|---|---|
committer | Luke Granger-Brown <git@lukegb.com> | 2021-04-12 18:49:01 +0000 |
commit | 08b22e605bc7d7560ef6ce567caa43f57178715f (patch) | |
tree | eed46af25264ec81b18ba7a216beec55a84f6683 /pkgs/development/beam-modules | |
parent | 82ca81cd62c785b81bf530837c05babcb9cde8a5 (diff) | |
parent | 60daed57149403acbb622e48a003422eacea4c16 (diff) |
Merge remote-tracking branch 'upstream/staging-next' into down-integrate-staging
Diffstat (limited to 'pkgs/development/beam-modules')
-rw-r--r-- | pkgs/development/beam-modules/build-mix.nix | 100 | ||||
-rw-r--r-- | pkgs/development/beam-modules/default.nix | 134 | ||||
-rw-r--r-- | pkgs/development/beam-modules/fetch-mix-deps.nix | 41 | ||||
-rwxr-xr-x | pkgs/development/beam-modules/mix-bootstrap | 108 | ||||
-rw-r--r-- | pkgs/development/beam-modules/mix-release.nix | 106 |
5 files changed, 201 insertions, 288 deletions
diff --git a/pkgs/development/beam-modules/build-mix.nix b/pkgs/development/beam-modules/build-mix.nix deleted file mode 100644 index 45f5e36744211..0000000000000 --- a/pkgs/development/beam-modules/build-mix.nix +++ /dev/null @@ -1,100 +0,0 @@ -{ stdenv, writeText, elixir, erlang, hex, lib }: - -{ name -, version -, src -, setupHook ? null -, buildInputs ? [] -, beamDeps ? [] -, postPatch ? "" -, compilePorts ? false -, installPhase ? null -, buildPhase ? null -, configurePhase ? null -, meta ? {} -, enableDebugInfo ? false -, ... }@attrs: - -with lib; - -let - - debugInfoFlag = lib.optionalString (enableDebugInfo || elixir.debugInfo) "--debug-info"; - - shell = drv: stdenv.mkDerivation { - name = "interactive-shell-${drv.name}"; - buildInputs = [ drv ]; - }; - - bootstrapper = ./mix-bootstrap; - - pkg = self: stdenv.mkDerivation ( attrs // { - name = "${name}-${version}"; - inherit version; - - dontStrip = true; - - inherit src; - - setupHook = if setupHook == null - then writeText "setupHook.sh" '' - addToSearchPath ERL_LIBS "$1/lib/erlang/lib" - '' - else setupHook; - - inherit buildInputs; - propagatedBuildInputs = [ hex elixir ] ++ beamDeps; - - configurePhase = if configurePhase == null - then '' - runHook preConfigure - ${erlang}/bin/escript ${bootstrapper} - runHook postConfigure - '' - else configurePhase ; - - - buildPhase = if buildPhase == null - then '' - runHook preBuild - - export HEX_OFFLINE=1 - export HEX_HOME=`pwd` - export MIX_ENV=prod - export MIX_NO_DEPS=1 - - mix compile ${debugInfoFlag} --no-deps-check - - runHook postBuild - '' - else buildPhase; - - installPhase = if installPhase == null - then '' - runHook preInstall - - MIXENV=prod - - if [ -d "_build/shared" ]; then - MIXENV=shared - fi - - mkdir -p "$out/lib/erlang/lib/${name}-${version}" - for reldir in src ebin priv include; do - fd="_build/$MIXENV/lib/${name}/$reldir" - [ -d "$fd" ] || continue - cp -Hrt "$out/lib/erlang/lib/${name}-${version}" "$fd" - success=1 - done - - runHook postInstall - '' - else installPhase; - - passthru = { - packageName = name; - env = shell self; - inherit beamDeps; - }; -}); -in fix pkg diff --git a/pkgs/development/beam-modules/default.nix b/pkgs/development/beam-modules/default.nix index 02877a954117a..6e6da4fab0376 100644 --- a/pkgs/development/beam-modules/default.nix +++ b/pkgs/development/beam-modules/default.nix @@ -3,7 +3,7 @@ let inherit (lib) makeExtensible; - lib' = pkgs.callPackage ./lib.nix {}; + lib' = pkgs.callPackage ./lib.nix { }; # FIXME: add support for overrideScope callPackageWithScope = scope: drv: args: lib.callPackageWith scope drv args; @@ -14,70 +14,70 @@ let defaultScope = mkScope self; callPackage = drv: args: callPackageWithScope defaultScope drv args; in - rec { - inherit callPackage erlang; - beamPackages = self; - - rebar = callPackage ../tools/build-managers/rebar { }; - rebar3 = callPackage ../tools/build-managers/rebar3 { }; - - # rebar3 port compiler plugin is required by buildRebar3 - pc_1_6_0 = callPackage ./pc {}; - pc = pc_1_6_0; - - fetchHex = callPackage ./fetch-hex.nix { }; - - fetchRebar3Deps = callPackage ./fetch-rebar-deps.nix { }; - rebar3Relx = callPackage ./rebar3-release.nix { }; - - buildRebar3 = callPackage ./build-rebar3.nix {}; - buildHex = callPackage ./build-hex.nix {}; - buildErlangMk = callPackage ./build-erlang-mk.nix {}; - fetchMixDeps = callPackage ./fetch-mix-deps.nix { }; - buildMix = callPackage ./build-mix.nix {}; - - # BEAM-based languages. - elixir = elixir_1_11; - - elixir_1_11 = lib'.callElixir ../interpreters/elixir/1.11.nix { - inherit erlang; - debugInfo = true; - }; - - elixir_1_10 = lib'.callElixir ../interpreters/elixir/1.10.nix { - inherit erlang; - debugInfo = true; - }; - - elixir_1_9 = lib'.callElixir ../interpreters/elixir/1.9.nix { - inherit erlang; - debugInfo = true; - }; - - elixir_1_8 = lib'.callElixir ../interpreters/elixir/1.8.nix { - inherit erlang; - debugInfo = true; - }; - - elixir_1_7 = lib'.callElixir ../interpreters/elixir/1.7.nix { - inherit erlang; - debugInfo = true; - }; - - # Remove old versions of elixir, when the supports fades out: - # https://hexdocs.pm/elixir/compatibility-and-deprecations.html - - lfe = lfe_1_3; - lfe_1_2 = lib'.callLFE ../interpreters/lfe/1.2.nix { inherit erlang buildRebar3 buildHex; }; - lfe_1_3 = lib'.callLFE ../interpreters/lfe/1.3.nix { inherit erlang buildRebar3 buildHex; }; - - # Non hex packages. Examples how to build Rebar/Mix packages with and - # without helper functions buildRebar3 and buildMix. - hex = callPackage ./hex {}; - webdriver = callPackage ./webdriver {}; - relxExe = callPackage ../tools/erlang/relx-exe {}; - - # An example of Erlang/C++ package. - cuter = callPackage ../tools/erlang/cuter {}; + rec { + inherit callPackage erlang; + beamPackages = self; + + rebar = callPackage ../tools/build-managers/rebar { }; + rebar3 = callPackage ../tools/build-managers/rebar3 { }; + + # rebar3 port compiler plugin is required by buildRebar3 + pc = callPackage ./pc { }; + + fetchHex = callPackage ./fetch-hex.nix { }; + + fetchRebar3Deps = callPackage ./fetch-rebar-deps.nix { }; + rebar3Relx = callPackage ./rebar3-release.nix { }; + + buildRebar3 = callPackage ./build-rebar3.nix { }; + buildHex = callPackage ./build-hex.nix { }; + buildErlangMk = callPackage ./build-erlang-mk.nix { }; + fetchMixDeps = callPackage ./fetch-mix-deps.nix { }; + mixRelease = callPackage ./mix-release.nix { }; + + # BEAM-based languages. + elixir = elixir_1_11; + + elixir_1_11 = lib'.callElixir ../interpreters/elixir/1.11.nix { + inherit erlang; + debugInfo = true; }; -in makeExtensible packages + + elixir_1_10 = lib'.callElixir ../interpreters/elixir/1.10.nix { + inherit erlang; + debugInfo = true; + }; + + elixir_1_9 = lib'.callElixir ../interpreters/elixir/1.9.nix { + inherit erlang; + debugInfo = true; + }; + + elixir_1_8 = lib'.callElixir ../interpreters/elixir/1.8.nix { + inherit erlang; + debugInfo = true; + }; + + elixir_1_7 = lib'.callElixir ../interpreters/elixir/1.7.nix { + inherit erlang; + debugInfo = true; + }; + + # Remove old versions of elixir, when the supports fades out: + # https://hexdocs.pm/elixir/compatibility-and-deprecations.html + + lfe = lfe_1_3; + lfe_1_2 = lib'.callLFE ../interpreters/lfe/1.2.nix { inherit erlang buildRebar3 buildHex; }; + lfe_1_3 = lib'.callLFE ../interpreters/lfe/1.3.nix { inherit erlang buildRebar3 buildHex; }; + + # Non hex packages. Examples how to build Rebar/Mix packages with and + # without helper functions buildRebar3 and buildMix. + hex = callPackage ./hex { }; + webdriver = callPackage ./webdriver { }; + relxExe = callPackage ../tools/erlang/relx-exe { }; + + # An example of Erlang/C++ package. + cuter = callPackage ../tools/erlang/cuter { }; + }; +in +makeExtensible packages diff --git a/pkgs/development/beam-modules/fetch-mix-deps.nix b/pkgs/development/beam-modules/fetch-mix-deps.nix index 020a82ad70b74..73365bd1a93e1 100644 --- a/pkgs/development/beam-modules/fetch-mix-deps.nix +++ b/pkgs/development/beam-modules/fetch-mix-deps.nix @@ -1,34 +1,49 @@ { stdenvNoCC, lib, elixir, hex, rebar, rebar3, cacert, git }: -{ name, version, sha256, src, mixEnv ? "prod", debug ? false, meta ? { } }: - -stdenvNoCC.mkDerivation ({ - name = "mix-deps-${name}-${version}"; - +{ pname +, version +, sha256 +, src +, mixEnv ? "prod" +, debug ? false +, meta ? { } +, ... +}@attrs: + +stdenvNoCC.mkDerivation (attrs // { nativeBuildInputs = [ elixir hex cacert git ]; - inherit src; - MIX_ENV = mixEnv; MIX_DEBUG = if debug then 1 else 0; DEBUG = if debug then 1 else 0; # for rebar3 - - configurePhase = '' + # the api with `mix local.rebar rebar path` makes a copy of the binary + MIX_REBAR = "${rebar}/bin/rebar"; + MIX_REBAR3 = "${rebar3}/bin/rebar3"; + # there is a persistent download failure with absinthe 1.6.3 + # those defaults reduce the failure rate + HEX_HTTP_CONCURRENCY = 1; + HEX_HTTP_TIMEOUT = 120; + + configurePhase = attrs.configurePhase or '' + runHook preConfigure export HEX_HOME="$TEMPDIR/.hex"; export MIX_HOME="$TEMPDIR/.mix"; - export MIX_DEPS_PATH="$out"; + export MIX_DEPS_PATH="$TEMPDIR/deps"; # Rebar - mix local.rebar rebar "${rebar}/bin/rebar" - mix local.rebar rebar3 "${rebar3}/bin/rebar3" export REBAR_GLOBAL_CONFIG_DIR="$TMPDIR/rebar3" export REBAR_CACHE_DIR="$TMPDIR/rebar3.cache" + runHook postConfigure ''; dontBuild = true; - installPhase = '' + installPhase = attrs.installPhase or '' + runHook preInstall mix deps.get --only ${mixEnv} + find "$TEMPDIR/deps" -path '*/.git/*' -a ! -name HEAD -exec rm -rf {} + + cp -r --no-preserve=mode,ownership,timestamps $TEMPDIR/deps $out + runHook postInstall ''; outputHashAlgo = "sha256"; diff --git a/pkgs/development/beam-modules/mix-bootstrap b/pkgs/development/beam-modules/mix-bootstrap deleted file mode 100755 index 7e31def71fa82..0000000000000 --- a/pkgs/development/beam-modules/mix-bootstrap +++ /dev/null @@ -1,108 +0,0 @@ -#!/usr/bin/env escript -%% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*- -%%! -smp enable -%%% --------------------------------------------------------------------------- -%%% @doc -%%% The purpose of this command is to prepare a mix project so that mix -%%% understands that the dependencies are all already installed. If you want a -%%% hygienic build on nix then you must run this command before running mix. I -%%% suggest that you add a `Makefile` to your project and have the bootstrap -%%% command be a dependency of the build commands. See the nix documentation for -%%% more information. -%%% -%%% This command designed to have as few dependencies as possible so that it can -%%% be a dependency of root level packages like mix. To that end it does many -%%% things in a fairly simplistic way. That is by design. -%%% -%%% ### Assumptions -%%% -%%% This command makes the following assumptions: -%%% -%%% * It is run in a nix-shell or nix-build environment -%%% * that all dependencies have been added to the ERL_LIBS -%%% Environment Variable - --record(data, {version - , erl_libs - , root - , name}). --define(LOCAL_HEX_REGISTRY, "registry.ets"). - -main(Args) -> - {ok, RequiredData} = gather_required_data_from_the_environment(Args), - ok = bootstrap_libs(RequiredData). - -%% @doc -%% This takes an app name in the standard OTP <name>-<version> format -%% and returns just the app name. Why? Because rebar doesn't -%% respect OTP conventions in some cases. --spec fixup_app_name(file:name()) -> string(). -fixup_app_name(Path) -> - BaseName = filename:basename(Path), - case string:split(BaseName, "-") of - [Name, _Version] -> Name; - Name -> Name - end. - - --spec gather_required_data_from_the_environment([string()]) -> {ok, #data{}}. -gather_required_data_from_the_environment(_) -> - {ok, #data{ version = guard_env("version") - , erl_libs = os:getenv("ERL_LIBS", []) - , root = code:root_dir() - , name = guard_env("name")}}. - --spec guard_env(string()) -> string(). -guard_env(Name) -> - case os:getenv(Name) of - false -> - stderr("Expected Environment variable ~s! Are you sure you are " - "running in a Nix environment? Either a nix-build, " - "nix-shell, etc?~n", [Name]), - erlang:halt(1); - Variable -> - Variable - end. - --spec bootstrap_libs(#data{}) -> ok. -bootstrap_libs(#data{erl_libs = ErlLibs}) -> - io:format("Bootstrapping dependent libraries~n"), - Target = "_build/prod/lib/", - Paths = string:tokens(ErlLibs, ":"), - CopiableFiles = - lists:foldl(fun(Path, Acc) -> - gather_directory_contents(Path) ++ Acc - end, [], Paths), - lists:foreach(fun (Path) -> - ok = link_app(Path, Target) - end, CopiableFiles). - --spec gather_directory_contents(string()) -> [{string(), string()}]. -gather_directory_contents(Path) -> - {ok, Names} = file:list_dir(Path), - lists:map(fun(AppName) -> - {filename:join(Path, AppName), fixup_app_name(AppName)} - end, Names). - -%% @doc -%% Makes a symlink from the directory pointed at by Path to a -%% directory of the same name in Target. So if we had a Path of -%% {`foo/bar/baz/bash`, `baz`} and a Target of `faz/foo/foos`, the symlink -%% would be `faz/foo/foos/baz`. --spec link_app({string(), string()}, string()) -> ok. -link_app({Path, TargetFile}, TargetDir) -> - Target = filename:join(TargetDir, TargetFile), - ok = make_symlink(Path, Target). - --spec make_symlink(string(), string()) -> ok. -make_symlink(Path, TargetFile) -> - file:delete(TargetFile), - ok = filelib:ensure_dir(TargetFile), - io:format("Making symlink from ~s to ~s~n", [Path, TargetFile]), - ok = file:make_symlink(Path, TargetFile). - -%% @doc -%% Write the result of the format string out to stderr. --spec stderr(string(), [term()]) -> ok. -stderr(FormatStr, Args) -> - io:put_chars(standard_error, io_lib:format(FormatStr, Args)). diff --git a/pkgs/development/beam-modules/mix-release.nix b/pkgs/development/beam-modules/mix-release.nix new file mode 100644 index 0000000000000..320fcaa9c9b7c --- /dev/null +++ b/pkgs/development/beam-modules/mix-release.nix @@ -0,0 +1,106 @@ +{ stdenv, lib, elixir, erlang, findutils, hex, rebar, rebar3, fetchMixDeps, makeWrapper, git }: + +{ pname +, version +, src +, nativeBuildInputs ? [ ] +, meta ? { } +, enableDebugInfo ? false +, mixEnv ? "prod" +, compileFlags ? [ ] +, mixDeps ? null +, ... +}@attrs: +let + overridable = builtins.removeAttrs attrs [ "compileFlags" ]; + +in +stdenv.mkDerivation (overridable // { + nativeBuildInputs = nativeBuildInputs ++ [ erlang hex elixir makeWrapper git ]; + + 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_REBAR = "${rebar}/bin/rebar"; + MIX_REBAR3 = "${rebar3}/bin/rebar3"; + + postUnpack = '' + export HEX_HOME="$TEMPDIR/hex" + export MIX_HOME="$TEMPDIR/mix" + # 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" + + # Rebar + export REBAR_GLOBAL_CONFIG_DIR="$TEMPDIR/rebar3" + export REBAR_CACHE_DIR="$TEMPDIR/rebar3.cache" + + ${lib.optionalString (mixDeps != null) '' + cp --no-preserve=mode -R "${mixDeps}" "$MIX_DEPS_PATH" + '' + } + + '' + (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 + # TODO remove the uneeded reference too erlang + # one possible way would be + # for f in $(${findutils}/bin/find $out -name start); do + # substituteInPlace $f \ + # --replace 'ROOTDIR=${erlang}/lib/erlang' 'ROOTDIR=""' + # done + # What is left to do is to check that erlang is not required on + # the host + + patchShebangs $out + runHook postFixup + ''; + # TODO figure out how to do a Fixed Output Derivation and add the output hash + # This doesn't play well at the moment with Phoenix projects + # for example that have frontend dependencies + + # disallowedReferences = [ erlang ]; +}) |