diff options
Diffstat (limited to 'pkgs/development/beam-modules')
24 files changed, 1111 insertions, 417 deletions
diff --git a/pkgs/development/beam-modules/build-erlang-mk.nix b/pkgs/development/beam-modules/build-erlang-mk.nix index 4dedf782b75..d1afa55387d 100644 --- a/pkgs/development/beam-modules/build-erlang-mk.nix +++ b/pkgs/development/beam-modules/build-erlang-mk.nix @@ -1,30 +1,33 @@ { stdenv, writeText, erlang, perl, which, gitMinimal, wget, lib }: -{ name, version +{ name +, version , src , setupHook ? null -, buildInputs ? [] -, beamDeps ? [] +, buildInputs ? [ ] +, beamDeps ? [ ] , postPatch ? "" , compilePorts ? false , installPhase ? null , buildPhase ? null , configurePhase ? null -, meta ? {} +, meta ? { } , enableDebugInfo ? false -, ... }@attrs: +, buildFlags ? [ ] +, ... +}@attrs: -with stdenv.lib; +with lib; let debugInfoFlag = lib.optionalString (enableDebugInfo || erlang.debugInfo) "+debug_info"; shell = drv: stdenv.mkDerivation { - name = "interactive-shell-${drv.name}"; - buildInputs = [ drv ]; - }; + name = "interactive-shell-${drv.name}"; + buildInputs = [ drv ]; + }; - pkg = self: stdenv.mkDerivation ( attrs // { + pkg = self: stdenv.mkDerivation (attrs // { app_name = name; name = "${name}-${version}"; inherit version; @@ -33,39 +36,48 @@ let inherit src; - setupHook = if setupHook == null - then writeText "setupHook.sh" '' - addToSearchPath ERL_LIBS "$1/lib/erlang/lib" - '' - else setupHook; + setupHook = + if setupHook == null + then + writeText "setupHook.sh" '' + addToSearchPath ERL_LIBS "$1/lib/erlang/lib" + '' + else setupHook; - buildInputs = [ erlang perl which gitMinimal wget ]; + buildInputs = buildInputs ++ [ erlang perl which gitMinimal wget ]; propagatedBuildInputs = beamDeps; - configurePhase = if configurePhase == null - then '' - runHook preConfigure + buildFlags = [ "SKIP_DEPS=1" ] + ++ lib.optional (enableDebugInfo || erlang.debugInfo) ''ERL_OPTS="$ERL_OPTS +debug_info"'' + ++ buildFlags; + + configurePhase = + if configurePhase == null + then '' + runHook preConfigure - # We shouldnt need to do this, but it seems at times there is a *.app in - # the repo/package. This ensures we start from a clean slate - make SKIP_DEPS=1 clean + # We shouldnt need to do this, but it seems at times there is a *.app in + # the repo/package. This ensures we start from a clean slate + make SKIP_DEPS=1 clean - runHook postConfigure - '' - else configurePhase; + runHook postConfigure + '' + else configurePhase; - buildPhase = if buildPhase == null - then '' + buildPhase = + if buildPhase == null + then '' runHook preBuild - make SKIP_DEPS=1 ERL_OPTS="$ERL_OPTS ${debugInfoFlag}" + make $buildFlags "''${buildFlagsArray[@]}" runHook postBuild - '' - else buildPhase; + '' + else buildPhase; - installPhase = if installPhase == null - then '' + installPhase = + if installPhase == null + then '' runHook preInstall mkdir -p $out/lib/erlang/lib/${name} @@ -85,13 +97,14 @@ let fi runHook postInstall - '' - else installPhase; + '' + else installPhase; passthru = { packageName = name; env = shell self; inherit beamDeps; }; -}); -in fix pkg + }); +in +fix pkg diff --git a/pkgs/development/beam-modules/build-hex.nix b/pkgs/development/beam-modules/build-hex.nix index 27ce64582f3..1ebe3760ec8 100644 --- a/pkgs/development/beam-modules/build-hex.nix +++ b/pkgs/development/beam-modules/build-hex.nix @@ -1,11 +1,11 @@ -{ stdenv, buildRebar3, fetchHex }: +{ lib, buildRebar3, fetchHex }: { name, version, sha256 , builder ? buildRebar3 , hexPkg ? name , ... }@attrs: -with stdenv.lib; +with lib; let pkg = self: builder (attrs // { diff --git a/pkgs/development/beam-modules/build-mix.nix b/pkgs/development/beam-modules/build-mix.nix index 9aebad2dabf..728d249c97d 100644 --- a/pkgs/development/beam-modules/build-mix.nix +++ b/pkgs/development/beam-modules/build-mix.nix @@ -3,98 +3,83 @@ { name , version , src -, setupHook ? null -, buildInputs ? [] -, beamDeps ? [] +, buildInputs ? [ ] +, nativeBuildInputs ? [ ] +, beamDeps ? [ ] +, propagatedBuildInputs ? [ ] , postPatch ? "" , compilePorts ? false -, installPhase ? null -, buildPhase ? null -, configurePhase ? null -, meta ? {} +, meta ? { } , enableDebugInfo ? false -, ... }@attrs: - -with stdenv.lib; +, mixEnv ? "prod" +, ... +}@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; + name = "interactive-shell-${drv.name}"; + buildInputs = [ drv ]; + }; - pkg = self: stdenv.mkDerivation ( attrs // { + 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 + inherit version src; + + MIX_ENV = mixEnv; + MIX_DEBUG = if enableDebugInfo then 1 else 0; + HEX_OFFLINE = 1; + + # add to ERL_LIBS so other modules can find at runtime. + # http://erlang.org/doc/man/code.html#code-path + # Mix also searches the code path when compiling with the --no-deps-check flag + setupHook = attrs.setupHook or + writeText "setupHook.sh" '' + addToSearchPath ERL_LIBS "$1/lib/erlang/lib" + ''; + + buildInputs = buildInputs ++ [ ]; + nativeBuildInputs = nativeBuildInputs ++ [ elixir hex ]; + propagatedBuildInputs = propagatedBuildInputs ++ beamDeps; + + buildPhase = attrs.buildPhase or '' + runHook preBuild + export HEX_HOME="$TEMPDIR/hex" + export MIX_HOME="$TEMPDIR/mix" + mix compile --no-deps-check + runHook postBuild + ''; + + installPhase = attrs.installPhase or '' + runHook preInstall + + # This uses the install path convention established by nixpkgs maintainers + # for all beam packages. Changing this will break compatibility with other + # builder functions like buildRebar3 and buildErlangMk. + mkdir -p "$out/lib/erlang/lib/${name}-${version}" + + # Some packages like db_connection will use _build/shared instead of + # honoring the $MIX_ENV variable. + for reldir in _build/{$MIX_ENV,shared}/lib/${name}/{src,ebin,priv,include} ; do + if test -d $reldir ; then + # Some builds produce symlinks (eg: phoenix priv dircetory). They must + # be followed with -H flag. + cp -Hrt "$out/lib/erlang/lib/${name}-${version}" "$reldir" fi + done - 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 + ''; - runHook postInstall - '' - else installPhase; + # stripping does not have any effect on beam files + # it is however needed for dependencies with NIFs like bcrypt for example + dontStrip = false; passthru = { packageName = name; env = shell self; inherit beamDeps; }; -}); -in fix pkg + }); +in +fix pkg diff --git a/pkgs/development/beam-modules/build-rebar3.nix b/pkgs/development/beam-modules/build-rebar3.nix index 224d111026a..0dfd68f0993 100644 --- a/pkgs/development/beam-modules/build-rebar3.nix +++ b/pkgs/development/beam-modules/build-rebar3.nix @@ -1,30 +1,34 @@ -{ stdenv, writeText, erlang, rebar3, openssl, libyaml, - pc, lib }: +{ stdenv, writeText, erlang, rebar3WithPlugins, openssl, libyaml, lib }: -{ name, version +{ name +, version , src , setupHook ? null -, buildInputs ? [], beamDeps ? [], buildPlugins ? [] +, buildInputs ? [ ] +, beamDeps ? [ ] +, buildPlugins ? [ ] , postPatch ? "" -, compilePorts ? false , installPhase ? null , buildPhase ? null , configurePhase ? null -, meta ? {} +, meta ? { } , enableDebugInfo ? false -, ... }@attrs: +, ... +}@attrs: -with stdenv.lib; +with lib; let debugInfoFlag = lib.optionalString (enableDebugInfo || erlang.debugInfo) "debug-info"; - ownPlugins = buildPlugins ++ (if compilePorts then [pc] else []); + rebar3 = rebar3WithPlugins { + plugins = buildPlugins; + }; shell = drv: stdenv.mkDerivation { - name = "interactive-shell-${drv.name}"; - buildInputs = [ drv ]; - }; + name = "interactive-shell-${drv.name}"; + buildInputs = [ drv ]; + }; customPhases = filterAttrs (_: v: v != null) @@ -36,35 +40,26 @@ let inherit version; buildInputs = buildInputs ++ [ erlang rebar3 openssl libyaml ]; - propagatedBuildInputs = unique (beamDeps ++ ownPlugins); - - dontStrip = true; - # The following are used by rebar3-nix-bootstrap - inherit compilePorts; - buildPlugins = ownPlugins; + propagatedBuildInputs = unique beamDeps; inherit src; + # stripping does not have any effect on beam files + # it is however needed for dependencies with NIFs + # false is the default but we keep this for readability + dontStrip = false; + setupHook = writeText "setupHook.sh" '' - addToSearchPath ERL_LIBS "$1/lib/erlang/lib/" + addToSearchPath ERL_LIBS "$1/lib/erlang/lib/" ''; postPatch = '' rm -f rebar rebar3 '' + postPatch; - configurePhase = '' - runHook preConfigure - ${erlang}/bin/escript ${rebar3.bootstrapper} ${debugInfoFlag} - runHook postConfigure - ''; - buildPhase = '' runHook preBuild - HOME=. rebar3 compile - ${if compilePorts then '' - HOME=. rebar3 pc compile - '' else ''''} + HOME=. rebar3 bare compile -path "" runHook postBuild ''; @@ -72,10 +67,9 @@ let runHook preInstall mkdir -p "$out/lib/erlang/lib/${name}-${version}" for reldir in src ebin priv include; do - fd="_build/default/lib/${name}/$reldir" - [ -d "$fd" ] || continue - cp -Hrt "$out/lib/erlang/lib/${name}-${version}" "$fd" - success=1 + [ -d "$reldir" ] || continue + # $out/lib/erlang/lib is a convention used in nixpkgs for compiled BEAM packages + cp -Hrt "$out/lib/erlang/lib/${name}-${version}" "$reldir" done runHook postInstall ''; @@ -91,4 +85,4 @@ let }; } // customPhases); in - fix pkg +fix pkg diff --git a/pkgs/development/beam-modules/default.nix b/pkgs/development/beam-modules/default.nix index efd68988c9b..b6be8c3e7fb 100644 --- a/pkgs/development/beam-modules/default.nix +++ b/pkgs/development/beam-modules/default.nix @@ -1,12 +1,12 @@ -{ stdenv, pkgs, erlang }: +{ lib, pkgs, erlang }: let - inherit (stdenv.lib) makeExtensible; + inherit (lib) makeExtensible; - lib = pkgs.callPackage ./lib.nix {}; + lib' = pkgs.callPackage ./lib.nix { }; # FIXME: add support for overrideScope - callPackageWithScope = scope: drv: args: stdenv.lib.callPackageWith scope drv args; + callPackageWithScope = scope: drv: args: lib.callPackageWith scope drv args; mkScope = scope: pkgs // scope; packages = self: @@ -14,69 +14,77 @@ 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 {}; - buildMix = callPackage ./build-mix.nix {}; - - # BEAM-based languages. - elixir = elixir_1_10; - - elixir_1_10 = lib.callElixir ../interpreters/elixir/1.10.nix { - inherit rebar erlang; - debugInfo = true; - }; - - elixir_1_9 = lib.callElixir ../interpreters/elixir/1.9.nix { - inherit rebar erlang; - debugInfo = true; - }; - - elixir_1_8 = lib.callElixir ../interpreters/elixir/1.8.nix { - inherit rebar erlang; - debugInfo = true; - }; - - elixir_1_7 = lib.callElixir ../interpreters/elixir/1.7.nix { - inherit rebar erlang; - debugInfo = true; - }; - - elixir_1_6 = lib.callElixir ../interpreters/elixir/1.6.nix { - inherit rebar 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; + + inherit (callPackage ../tools/build-managers/rebar3 { }) rebar3 rebar3WithPlugins; + rebar = callPackage ../tools/build-managers/rebar { }; + + pc = callPackage ./pc { }; + rebar3-proper = callPackage ./rebar3-proper { }; + rebar3-nix = callPackage ./rebar3-nix { }; + + 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 { }; + buildMix = callPackage ./build-mix.nix { }; + fetchMixDeps = callPackage ./fetch-mix-deps.nix { }; + mixRelease = callPackage ./mix-release.nix { }; + + erlang-ls = callPackage ./erlang-ls { }; + erlfmt = callPackage ./erlfmt { }; + elvis-erlang = callPackage ./elvis-erlang { }; + + # BEAM-based languages. + elixir = elixir_1_12; + + elixir_1_12 = lib'.callElixir ../interpreters/elixir/1.12.nix { + inherit erlang; + debugInfo = true; }; -in makeExtensible packages + + 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 { + erlang = pkgs.beam.interpreters.erlangR23; + debugInfo = true; + }; + + # Remove old versions of elixir, when the supports fades out: + # https://hexdocs.pm/elixir/compatibility-and-deprecations.html + elixir_1_7 = lib'.callElixir ../interpreters/elixir/1.7.nix { + inherit erlang; + debugInfo = true; + }; + + elixir_ls = callPackage ./elixir_ls.nix { inherit elixir fetchMixDeps mixRelease; }; + + lfe = lfe_1_3; + 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 { }; + }; +in +makeExtensible packages diff --git a/pkgs/development/beam-modules/elixir_ls.nix b/pkgs/development/beam-modules/elixir_ls.nix new file mode 100644 index 00000000000..5afab0e1bab --- /dev/null +++ b/pkgs/development/beam-modules/elixir_ls.nix @@ -0,0 +1,71 @@ +{ lib, elixir, fetchFromGitHub, fetchMixDeps, mixRelease }: +# Based on the work of Hauleth +# None of this would have happened without him + +mixRelease rec { + pname = "elixir-ls"; + version = "0.7.0"; + + src = fetchFromGitHub { + owner = "elixir-lsp"; + repo = "elixir-ls"; + rev = "v${version}"; + sha256 = "0d0hqc35hfjkpm88vz21mnm2a9rxiqfrdi83whhhh6d2ba216b7s"; + fetchSubmodules = true; + }; + + mixFodDeps = fetchMixDeps { + pname = "mix-deps-${pname}"; + inherit src version; + sha256 = "0r9x223imq4j9pn9niskyaybvk7jmq8dxcyzk7kwfsi128qig1a1"; + }; + + # elixir_ls is an umbrella app + # override configurePhase to not skip umbrella children + configurePhase = '' + runHook preConfigure + mix deps.compile --no-deps-check + runHook postConfigure + ''; + + # elixir_ls require a special step for release + # compile and release need to be performed together because + # of the no-deps-check requirement + buildPhase = '' + runHook preBuild + mix do compile --no-deps-check, elixir_ls.release + runHook postBuild + ''; + + installPhase = '' + runHook preInstall + mkdir -p $out/bin + cp -Rv release $out/lib + # Prepare the wrapper script + substitute release/language_server.sh $out/bin/elixir-ls \ + --replace 'exec "''${dir}/launch.sh"' "exec $out/lib/launch.sh" + chmod +x $out/bin/elixir-ls + # prepare the launcher + substituteInPlace $out/lib/launch.sh \ + --replace "ERL_LIBS=\"\$SCRIPTPATH:\$ERL_LIBS\"" \ + "ERL_LIBS=$out/lib:\$ERL_LIBS" \ + --replace "exec elixir" "exec ${elixir}/bin/elixir" + runHook postInstall + ''; + + meta = with lib; { + homepage = "https://github.com/elixir-lsp/elixir-ls"; + description = '' + A frontend-independent IDE "smartness" server for Elixir. + Implements the "Language Server Protocol" standard and provides debugger support via the "Debug Adapter Protocol" + ''; + longDescription = '' + The Elixir Language Server provides a server that runs in the background, providing IDEs, editors, and other tools with information about Elixir Mix projects. + It adheres to the Language Server Protocol, a standard for frontend-independent IDE support. + Debugger integration is accomplished through the similar VS Code Debug Protocol. + ''; + license = licenses.asl20; + platforms = platforms.unix; + maintainers = teams.beam.members; + }; +} diff --git a/pkgs/development/beam-modules/elvis-erlang/default.nix b/pkgs/development/beam-modules/elvis-erlang/default.nix new file mode 100644 index 00000000000..81888bdde21 --- /dev/null +++ b/pkgs/development/beam-modules/elvis-erlang/default.nix @@ -0,0 +1,46 @@ +{ fetchFromGitHub, fetchgit, fetchHex, rebar3WithPlugins, rebar3-nix, rebar3Relx +, buildRebar3, writeScript, lib }: + +let + owner = "inaka"; + repo = "elvis"; +in rebar3Relx rec { + releaseType = "escript"; + # The package name "elvis" is already taken + pname = "elvis-erlang"; + version = "1.0.1"; + src = fetchFromGitHub { + inherit owner repo; + sha256 = "139mgd4cwc0vazxfnssyym61jd9g45wn1nc53mjfzx5dkrrn4dc5"; + rev = version; + }; + beamDeps = builtins.attrValues (import ./rebar-deps.nix { + inherit fetchHex fetchgit fetchFromGitHub; + builder = buildRebar3; + }); + passthru.updateScript = writeScript "update.sh" '' + #!/usr/bin/env nix-shell + #!nix-shell -i bash -p bash common-updater-scripts git nix-prefetch-git gnutar gzip "rebar3WithPlugins {globalPlugins = [beamPackages.rebar3-nix];}" + + set -euo pipefail + + latest=$(list-git-tags https://github.com/${owner}/${repo}.git | sort -V | tail -1) + if [ "$latest" != "${version}" ]; then + nixpkgs="$(git rev-parse --show-toplevel)" + nix_path="$nixpkgs/pkgs/development/beam-modules/elvis-erlang" + update-source-version elvis-erlang "$latest" --version-key=version --print-changes --file="$nix_path/default.nix" + tmpdir=$(mktemp -d) + cp -R $(nix-build $nixpkgs --no-out-link -A elvis-erlang.src)/* "$tmpdir" + (cd "$tmpdir" && HOME=. rebar3 nix lock -o "$nix_path/rebar-deps.nix") + else + echo "${repo} is already up-to-date" + fi + ''; + meta = with lib; { + homepage = "https://github.com/inaka/elvis"; + description = "Erlang Style Reviewer"; + platforms = platforms.unix; + license = licenses.asl20; + maintainers = with lib.maintainers; [ dlesl ]; + }; +} diff --git a/pkgs/development/beam-modules/elvis-erlang/rebar-deps.nix b/pkgs/development/beam-modules/elvis-erlang/rebar-deps.nix new file mode 100644 index 00000000000..93c3db16eb9 --- /dev/null +++ b/pkgs/development/beam-modules/elvis-erlang/rebar-deps.nix @@ -0,0 +1,168 @@ +# Generated by rebar3_nix +let fetchOnly = { src, ... }: src; +in { builder ? fetchOnly, fetchHex, fetchgit, fetchFromGitHub, overrides ? (x: y: { }) }: +let + self = packages // (overrides self packages); + packages = with self; { + unicode_util_compat = builder { + name = "unicode_util_compat"; + version = "0.7.0"; + src = fetchHex { + pkg = "unicode_util_compat"; + version = "0.7.0"; + sha256 = "sha256-Je7m1n32GWDPanlCOVZlmbCeF+Zo03ACR7xJhjgVJSE="; + }; + beamDeps = [ ]; + }; + ssl_verify_fun = builder { + name = "ssl_verify_fun"; + version = "1.1.6"; + src = fetchHex { + pkg = "ssl_verify_fun"; + version = "1.1.6"; + sha256 = "sha256-vbDSRx9FPIj/OQjnaG+G+b4yfQZcwewW+kVAGX6gRoA="; + }; + beamDeps = [ ]; + }; + parse_trans = builder { + name = "parse_trans"; + version = "3.4.0"; + src = fetchHex { + pkg = "parse_trans"; + version = "3.4.0"; + sha256 = "sha256-+Z42iDC+pEVSIk434ElDpUh08IuFkEhd6NE4MrY6LcM="; + }; + beamDeps = [ ]; + }; + mimerl = builder { + name = "mimerl"; + version = "1.2.0"; + src = fetchHex { + pkg = "mimerl"; + version = "1.2.0"; + sha256 = "sha256-8nhYVlCqWBmGJkY46/aY+LsZ3yl/Zq2RsYkQ38bhkyM="; + }; + beamDeps = [ ]; + }; + metrics = builder { + name = "metrics"; + version = "1.0.1"; + src = fetchHex { + pkg = "metrics"; + version = "1.0.1"; + sha256 = "sha256-abCa3dxPdKQHFq5U0UD5O+sPuJeNhjbq3tDDG28JnxY="; + }; + beamDeps = [ ]; + }; + idna = builder { + name = "idna"; + version = "6.1.1"; + src = fetchHex { + pkg = "idna"; + version = "6.1.1"; + sha256 = "sha256-kjdut4lEEu0ZrEdeSob3tBPBufu1vRbczVeTQVeUTOo="; + }; + beamDeps = [ unicode_util_compat ]; + }; + certifi = builder { + name = "certifi"; + version = "2.6.1"; + src = fetchHex { + pkg = "certifi"; + version = "2.6.1"; + sha256 = "sha256-UkyXtJkbOEndXBemMSI4licsawr0RneLpGdaHf9Tu34="; + }; + beamDeps = [ ]; + }; + zipper = builder { + name = "zipper"; + version = "1.0.1"; + src = fetchHex { + pkg = "zipper"; + version = "1.0.1"; + sha256 = "sha256-ah/T4fDMHR31ZCyaDOIXgDZBGwpclkKFHR2idr1zfC0="; + }; + beamDeps = [ ]; + }; + lager = builder { + name = "lager"; + version = "3.9.1"; + src = fetchHex { + pkg = "lager"; + version = "3.9.1"; + sha256 = "sha256-P1m6daBKmeXxi/kcifRtzlNvg8bLQV/ibm51pivvN9w="; + }; + beamDeps = [ goldrush ]; + }; + katana_code = builder { + name = "katana_code"; + version = "1.1.2"; + src = fetchHex { + pkg = "katana_code"; + version = "1.1.2"; + sha256 = "sha256-5+YWKkToJqA/aLUDt9kpgbiUv4NMHvDmR3g/fWaIAhw="; + }; + beamDeps = [ ]; + }; + jsx = builder { + name = "jsx"; + version = "2.10.0"; + src = fetchHex { + pkg = "jsx"; + version = "2.10.0"; + sha256 = "sha256-moPjcEgHKYAWlo21Bvn60PAn3jdUbrg4s64QZMOgrWI="; + }; + beamDeps = [ ]; + }; + hackney = builder { + name = "hackney"; + version = "1.17.1"; + src = fetchHex { + pkg = "hackney"; + version = "1.17.1"; + sha256 = "sha256-0sup48gQOtAyBiPp8cM+jTeKFeqr4u6K5EGJjz01oYw="; + }; + beamDeps = [ certifi idna metrics mimerl parse_trans ssl_verify_fun unicode_util_compat ]; + }; + goldrush = builder { + name = "goldrush"; + version = "0.1.9"; + src = fetchHex { + pkg = "goldrush"; + version = "0.1.9"; + sha256 = "sha256-mctBKM/8syJ1geXU2APVQT+mQ/TrllI/d9nmk32ZTOs="; + }; + beamDeps = [ ]; + }; + getopt = builder { + name = "getopt"; + version = "1.0.2"; + src = fetchHex { + pkg = "getopt"; + version = "1.0.2"; + sha256 = "sha256-oAKa6kMi+4KmH2h2ptnGbcmHi2y2H6oT3zGHOE/U6iY="; + }; + beamDeps = [ ]; + }; + elvis_core = builder { + name = "elvis_core"; + version = "1.1.2"; + src = fetchHex { + pkg = "elvis_core"; + version = "1.1.2"; + sha256 = "sha256-xO5Cp6fC/FZ/Pqa1FQFkzWgpDxEA6bGaTPiG2Kocpzw="; + }; + beamDeps = [ katana_code zipper ]; + }; + egithub = builder { + name = "egithub"; + version = "0.7.0"; + src = fetchHex { + pkg = "egithub"; + version = "0.7.0"; + sha256 = "sha256-4AnOEe/YAI0PntWdnEiOPpq+MCoPLNbWY+TMJnVvzEw="; + }; + beamDeps = [ goldrush hackney jsx lager ]; + }; + }; +in self diff --git a/pkgs/development/beam-modules/erlang-ls/default.nix b/pkgs/development/beam-modules/erlang-ls/default.nix new file mode 100644 index 00000000000..7635e46237b --- /dev/null +++ b/pkgs/development/beam-modules/erlang-ls/default.nix @@ -0,0 +1,47 @@ +{ fetchFromGitHub, fetchHex, rebar3Relx, buildRebar3, rebar3-proper, lib }: +let + version = "0.17.0"; + owner = "erlang-ls"; + repo = "erlang_ls"; + deps = import ./rebar-deps.nix { + inherit fetchHex fetchFromGitHub; + builder = buildRebar3; + overrides = (self: super: { + proper = super.proper.overrideAttrs (_: { + configurePhase = "true"; + }); + }); + }; +in +rebar3Relx { + pname = "erlang-ls"; + inherit version; + src = fetchFromGitHub { + inherit owner repo; + sha256 = "0szg9hx436cvy80sh94dzmf2rainnw3fjc84bv3hlzjwwzmxj9aw"; + rev = version; + }; + releaseType = "escript"; + beamDeps = builtins.attrValues deps; + buildPlugins = [ rebar3-proper ]; + buildPhase = "HOME=. make"; + # based on https://github.com/erlang-ls/erlang_ls/blob/main/.github/workflows/build.yml + # these tests are excessively long and we should probably skip them + checkPhase = '' + HOME=. epmd -daemon + HOME=. rebar3 ct + HOME=. rebar3 proper --constraint_tries 100 + ''; + doCheck = true; + installPhase = '' + mkdir -p $out/bin + cp _build/default/bin/erlang_ls $out/bin/ + cp _build/dap/bin/els_dap $out/bin/ + ''; + meta = with lib; { + homepage = "https://github.com/erlang-ls/erlang_ls"; + description = "The Erlang Language Server"; + platforms = platforms.unix; + license = licenses.asl20; + }; +} diff --git a/pkgs/development/beam-modules/erlang-ls/rebar-deps.nix b/pkgs/development/beam-modules/erlang-ls/rebar-deps.nix new file mode 100644 index 00000000000..5d55ce0c523 --- /dev/null +++ b/pkgs/development/beam-modules/erlang-ls/rebar-deps.nix @@ -0,0 +1,219 @@ +# Generated by rebar3_nix +let fetchOnly = { src, ... }: src; +in { builder ? fetchOnly, fetchHex, fetchFromGitHub, overrides ? (x: y: { }) }: +let + self = packages // (overrides self packages); + packages = with self; { + getopt = builder { + name = "getopt"; + version = "1.0.1"; + src = fetchHex { + pkg = "getopt"; + version = "1.0.1"; + sha256 = "sha256-U+Grg7nOtlyWctPno1uAkum9ybPugHIUcaFhwQxZlZw="; + }; + beamDeps = [ ]; + }; + zipper = builder { + name = "zipper"; + version = "1.0.1"; + src = fetchHex { + pkg = "zipper"; + version = "1.0.1"; + sha256 = "sha256-ah/T4fDMHR31ZCyaDOIXgDZBGwpclkKFHR2idr1zfC0="; + }; + beamDeps = [ ]; + }; + quickrand = builder { + name = "quickrand"; + version = "2.0.1"; + src = fetchHex { + pkg = "quickrand"; + version = "2.0.1"; + sha256 = "sha256-FNtn1K72uIFYEOyfPM714yS3O1bK42h/mddSuFvdTJY="; + }; + beamDeps = [ ]; + }; + providers = builder { + name = "providers"; + version = "1.8.1"; + src = fetchHex { + pkg = "providers"; + version = "1.8.1"; + sha256 = "sha256-5FdFrenEdqmkaeoIQOQYqxk2DcRPAaIzME4RikRIa6A="; + }; + beamDeps = [ getopt ]; + }; + katana_code = builder { + name = "katana_code"; + version = "0.2.1"; + src = fetchHex { + pkg = "katana_code"; + version = "0.2.1"; + sha256 = "sha256-hEitP1bZgU+YoovmUPcZG91QZXXjRcwW1YZmCxD26ZI="; + }; + beamDeps = [ ]; + }; + bucs = builder { + name = "bucs"; + version = "1.0.16"; + src = fetchHex { + pkg = "bucs"; + version = "1.0.16"; + sha256 = "sha256-/2pccqUArXrsHuO6FkrjxFDq3uiYsNFR4frKGKyNDWI="; + }; + beamDeps = [ ]; + }; + yamerl = builder { + name = "yamerl"; + version = "0.8.1"; + src = fetchHex { + pkg = "yamerl"; + version = "0.8.1"; + sha256 = "sha256-lssw+dZDRP7Q74qS6fFvIH3mwE3/9PNmdSynn1vOsj8="; + }; + beamDeps = [ ]; + }; + uuid = builder { + name = "uuid"; + version = "2.0.1"; + src = fetchHex { + pkg = "uuid_erl"; + version = "2.0.1"; + sha256 = "sha256-q1fKzNUfFwAR5fREzoZfhLQWBeSDqe/MRowa+uyHVTs="; + }; + beamDeps = [ quickrand ]; + }; + tdiff = builder { + name = "tdiff"; + version = "0.1.2"; + src = fetchHex { + pkg = "tdiff"; + version = "0.1.2"; + sha256 = "sha256-4MLhaPmSUqWIl2jVyPHmUQoYRZLUz6BrIneKGNM9eHU="; + }; + beamDeps = [ ]; + }; + redbug = builder { + name = "redbug"; + version = "2.0.6"; + src = fetchHex { + pkg = "redbug"; + version = "2.0.6"; + sha256 = "sha256-qtlJhnH0q5HqylCZ/oWmFhgVimNuYoaJLE989K8XHQQ="; + }; + beamDeps = [ ]; + }; + rebar3_format = builder { + name = "rebar3_format"; + version = "0.8.2"; + src = fetchHex { + pkg = "rebar3_format"; + version = "0.8.2"; + sha256 = "sha256-yo/ydjjCFpWT0USdrL6IlWNBk+0zNOkGtU/JfwgfUhM="; + }; + beamDeps = [ katana_code ]; + }; + ranch = builder { + name = "ranch"; + version = "2.0.0"; + src = fetchHex { + pkg = "ranch"; + version = "2.0.0"; + sha256 = "sha256-wgpIQMfWYjwZgS06fIKLLxvRU+8PEky2nFT+UdikKuA="; + }; + beamDeps = [ ]; + }; + jsx = builder { + name = "jsx"; + version = "3.0.0"; + src = fetchHex { + pkg = "jsx"; + version = "3.0.0"; + sha256 = "sha256-N77KBDX1yoovRfdqRiEedkGPvvgMNvA2HCSfx1BZ3G0="; + }; + beamDeps = [ ]; + }; + erlfmt = builder { + name = "erlfmt"; + version = "git"; + src = fetchFromGitHub { + owner = "whatsapp"; + repo = "erlfmt"; + rev = "2e93fc4a646111357642b0179a2a63151868d890"; + sha256 = "0n7kygycn05aqdp5dyj192mja89l4nxv2wg16qg2c0bmw9s7j2mr"; + }; + beamDeps = [ ]; + }; + ephemeral = builder { + name = "ephemeral"; + version = "2.0.4"; + src = fetchHex { + pkg = "ephemeral"; + version = "2.0.4"; + sha256 = "sha256-Syk9gPdfnEV1/0ucjoiaVoAvQLAYv1fnTxlkTv7myFA="; + }; + beamDeps = [ bucs ]; + }; + elvis_core = builder { + name = "elvis_core"; + version = "1.1.1"; + src = fetchHex { + pkg = "elvis_core"; + version = "1.1.1"; + sha256 = "sha256-ORyVuqSfJxjX+0mLzwgEbd/CAs8Kq2Oy5DknFIXJ3EI="; + }; + beamDeps = [ katana_code zipper ]; + }; + docsh = builder { + name = "docsh"; + version = "0.7.2"; + src = fetchHex { + pkg = "docsh"; + version = "0.7.2"; + sha256 = "sha256-Tn20YbsHVA0rw9NmuFE/AZdxLQSVu4V0TzZ9OBUHYTQ="; + }; + beamDeps = [ providers ]; + }; + proper_contrib = builder { + name = "proper_contrib"; + version = "0.2.0"; + src = fetchHex { + pkg = "proper_contrib"; + version = "0.2.0"; + sha256 = "sha256-jFRRL1zr9JKaG1eqMDfcKk2xe93uOrXUenB14icVCBU="; + }; + beamDeps = [ proper ]; + }; + proper = builder { + name = "proper"; + version = "1.3.0"; + src = fetchHex { + pkg = "proper"; + version = "1.3.0"; + sha256 = "sha256-SqGS/M3dA/2+UP72IL6dTS+SY1tU9V+4OuwYWZRAPLw="; + }; + beamDeps = [ ]; + }; + meck = builder { + name = "meck"; + version = "0.9.0"; + src = fetchHex { + pkg = "meck"; + version = "0.9.0"; + sha256 = "sha256-+BPpDdC4myUWoCAaNV6EsavHi1dRqgy/ZpqdhagQrGM="; + }; + beamDeps = [ ]; + }; + coveralls = builder { + name = "coveralls"; + version = "2.2.0"; + src = fetchHex { + pkg = "coveralls"; + version = "2.2.0"; + sha256 = "sha256-zVTbCqjGS1OSgBicVhns7hOkaiiw8ct3RUTdzBZiBKM="; + }; + beamDeps = [ jsx ]; + }; + }; +in self diff --git a/pkgs/development/beam-modules/erlfmt/default.nix b/pkgs/development/beam-modules/erlfmt/default.nix new file mode 100644 index 00000000000..da577f2264c --- /dev/null +++ b/pkgs/development/beam-modules/erlfmt/default.nix @@ -0,0 +1,20 @@ +{ fetchFromGitHub, rebar3Relx, lib }: + +rebar3Relx rec { + pname = "erlfmt"; + version = "1.0.0"; + releaseType = "escript"; + src = fetchFromGitHub { + owner = "WhatsApp"; + repo = "erlfmt"; + sha256 = "19apbs9xr4j8qjb3sv9ilknqjw4a7bvp8jvwrjiwvwnxzzm2kjm6"; + rev = "v${version}"; + }; + meta = with lib; { + homepage = "https://github.com/WhatsApp/erlfmt"; + description = "An automated code formatter for Erlang"; + platforms = platforms.unix; + license = licenses.asl20; + maintainers = with lib.maintainers; [ dlesl ]; + }; +} diff --git a/pkgs/development/beam-modules/fetch-hex.nix b/pkgs/development/beam-modules/fetch-hex.nix index c55a7a80ff3..7f84e236070 100644 --- a/pkgs/development/beam-modules/fetch-hex.nix +++ b/pkgs/development/beam-modules/fetch-hex.nix @@ -1,10 +1,10 @@ -{ stdenv, fetchurl }: +{ lib, stdenv, fetchurl }: { pkg, version, sha256 , meta ? {} }: -with stdenv.lib; +with lib; stdenv.mkDerivation ({ name = "hex-source-${pkg}-${version}"; diff --git a/pkgs/development/beam-modules/fetch-mix-deps.nix b/pkgs/development/beam-modules/fetch-mix-deps.nix new file mode 100644 index 00000000000..0c6f4e35a90 --- /dev/null +++ b/pkgs/development/beam-modules/fetch-mix-deps.nix @@ -0,0 +1,58 @@ +{ stdenvNoCC, lib, elixir, hex, rebar, rebar3, cacert, git }: + +{ pname +, version +, sha256 +, src +, mixEnv ? "prod" +, debug ? false +, meta ? { } +, patches ? [] +, ... +}@attrs: + +stdenvNoCC.mkDerivation (attrs // { + nativeBuildInputs = [ elixir hex cacert git ]; + + MIX_ENV = mixEnv; + MIX_DEBUG = if debug then 1 else 0; + DEBUG = if debug then 1 else 0; # for rebar3 + # 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="$TEMPDIR/deps"; + + # Rebar + export REBAR_GLOBAL_CONFIG_DIR="$TMPDIR/rebar3" + export REBAR_CACHE_DIR="$TMPDIR/rebar3.cache" + runHook postConfigure + ''; + + inherit patches; + + dontBuild = true; + + 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"; + outputHashMode = "recursive"; + outputHash = sha256; + + impureEnvVars = lib.fetchers.proxyImpureEnvVars; + inherit meta; +}) diff --git a/pkgs/development/beam-modules/fetch-rebar-deps.nix b/pkgs/development/beam-modules/fetch-rebar-deps.nix index 389e07beca6..d858b3d81af 100644 --- a/pkgs/development/beam-modules/fetch-rebar-deps.nix +++ b/pkgs/development/beam-modules/fetch-rebar-deps.nix @@ -1,10 +1,10 @@ -{ stdenv, rebar3 }: +{ lib, stdenv, rebar3 }: { name, version, sha256, src , meta ? {} }: -with stdenv.lib; +with lib; stdenv.mkDerivation ({ name = "rebar-deps-${name}-${version}"; @@ -28,6 +28,6 @@ stdenv.mkDerivation ({ outputHashMode = "recursive"; outputHash = sha256; - impureEnvVars = stdenv.lib.fetchers.proxyImpureEnvVars; + impureEnvVars = lib.fetchers.proxyImpureEnvVars; inherit meta; }) diff --git a/pkgs/development/beam-modules/hex/default.nix b/pkgs/development/beam-modules/hex/default.nix index 26070ce73bf..836740a7933 100644 --- a/pkgs/development/beam-modules/hex/default.nix +++ b/pkgs/development/beam-modules/hex/default.nix @@ -1,4 +1,4 @@ -{ stdenv, fetchFromGitHub, writeText, elixir }: +{ lib, stdenv, fetchFromGitHub, writeText, elixir }: let shell = drv: stdenv.mkDerivation { @@ -8,13 +8,13 @@ let pkg = self: stdenv.mkDerivation rec { pname = "hex"; - version = "0.20.5"; + version = "0.21.2"; src = fetchFromGitHub { owner = "hexpm"; repo = "hex"; rev = "v${version}"; - sha256 = "1wz6n4qrmsb4kkww6lrdbs99xzwp4dyjjmr8m4drcwn3sd2k9ba6"; + sha256 = "18vwrc5b7pyi3nifmx5hd5wbz8fy3h6sfvkmskjg5acmz66fys0g"; }; setupHook = writeText "setupHook.sh" '' @@ -45,13 +45,13 @@ let meta = { description = "Package manager for the Erlang VM https://hex.pm"; - license = stdenv.lib.licenses.mit; + license = lib.licenses.mit; homepage = "https://github.com/hexpm/hex"; - maintainers = with stdenv.lib.maintainers; [ ericbmerritt ]; + maintainers = with lib.maintainers; [ ericbmerritt ]; }; passthru = { env = shell self; }; }; -in stdenv.lib.fix pkg +in lib.fix pkg diff --git a/pkgs/development/beam-modules/lib.nix b/pkgs/development/beam-modules/lib.nix index db40c47794f..1b021cf9347 100644 --- a/pkgs/development/beam-modules/lib.nix +++ b/pkgs/development/beam-modules/lib.nix @@ -1,4 +1,4 @@ -{ pkgs, stdenv }: +{ pkgs, lib }: rec { @@ -7,7 +7,7 @@ rec { callPackageWith = autoArgs: fn: args: let f = if pkgs.lib.isFunction fn then fn else import fn; - auto = builtins.intersectAttrs (stdenv.lib.functionArgs f) autoArgs; + auto = builtins.intersectAttrs (lib.functionArgs f) autoArgs; in f (auto // args); callPackage = callPackageWith pkgs; diff --git a/pkgs/development/beam-modules/mix-bootstrap b/pkgs/development/beam-modules/mix-bootstrap deleted file mode 100755 index 7e31def71fa..00000000000 --- 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 00000000000..80e8721302e --- /dev/null +++ b/pkgs/development/beam-modules/mix-release.nix @@ -0,0 +1,117 @@ +{ stdenv, lib, elixir, erlang, findutils, hex, rebar, rebar3, fetchMixDeps, makeWrapper, git, ripgrep }: + +{ pname +, version +, src +, nativeBuildInputs ? [ ] +, meta ? { } +, enableDebugInfo ? false +, mixEnv ? "prod" +, compileFlags ? [ ] + # 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 ? { } +, ... +}@attrs: +let + # remove non standard attributes that cannot be coerced to strings + overridable = builtins.removeAttrs attrs [ "compileFlags" "mixNixDeps" ]; +in +assert mixNixDeps != { } -> mixFodDeps == null; +stdenv.mkDerivation (overridable // { + # rg is used as a better grep to search for erlang references in the final release + nativeBuildInputs = nativeBuildInputs ++ [ erlang hex elixir makeWrapper git ripgrep ]; + buildInputs = builtins.attrValues mixNixDeps; + + 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 + # some older dependencies still use rebar + MIX_REBAR = "${rebar}/bin/rebar"; + 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" + + ${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" + '' + } + + '' + (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 + ''; + + # Stripping of the binary is intentional + # even though it does not affect beam files + # it is necessary for NIFs binaries + postFixup = '' + 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 $out - removing references to erlang to reduce closure size" + # there is a link in $out/erts-*/bin/start always + # sometimes there are links in dependencies like bcrypt compiled binaries + for file in $(rg "${erlang}/lib/erlang" "$out" --text --files-with-matches); do + substituteInPlace "$file" --replace "${erlang}/lib/erlang" "$out" + done + fi + ''; + + # TODO investigate why the resulting closure still has + # a reference to erlang. + # uncommenting the following will fail the build + # disallowedReferences = [ erlang ]; +}) diff --git a/pkgs/development/beam-modules/pc/default.nix b/pkgs/development/beam-modules/pc/default.nix index d30b0fbdbd2..2896a325e0e 100644 --- a/pkgs/development/beam-modules/pc/default.nix +++ b/pkgs/development/beam-modules/pc/default.nix @@ -1,13 +1,13 @@ -{ stdenv, buildHex }: +{ lib, buildHex }: buildHex { name = "pc"; - version = "1.6.0"; - sha256 = "0xq411ig5ny3iilkkkqa4vm3w3dgjc9cfzkqwk8pm13dw9mcm8h0"; + version = "1.12.0"; + sha256 = "1gdvixy4j560qjdiv5qjgnl5wl3rrn231dv1m4vdq4b9l4g4p27x"; meta = { - description = ''a rebar3 port compiler for native code''; - license = stdenv.lib.licenses.mit; + description = "a rebar3 port compiler for native code"; + license = lib.licenses.mit; homepage = "https://github.com/blt/port_compiler"; }; } diff --git a/pkgs/development/beam-modules/pgsql/default.nix b/pkgs/development/beam-modules/pgsql/default.nix index c7e7aee1001..df6561b7cf1 100644 --- a/pkgs/development/beam-modules/pgsql/default.nix +++ b/pkgs/development/beam-modules/pgsql/default.nix @@ -1,4 +1,4 @@ -{stdenv, fetchFromGitHub, buildRebar3 }: +{ lib, stdenv, fetchFromGitHub, buildRebar3 }: let shell = drv: stdenv.mkDerivation { @@ -21,9 +21,9 @@ let meta = { description = "Erlang PostgreSQL Driver"; - license = stdenv.lib.licenses.mit; + license = lib.licenses.mit; homepage = "https://github.com/semiocast/pgsql"; - maintainers = with stdenv.lib.maintainers; [ ericbmerritt ]; + maintainers = with lib.maintainers; [ ericbmerritt ]; }; passthru = { @@ -31,4 +31,4 @@ let }; }; -in stdenv.lib.fix pkg +in lib.fix pkg diff --git a/pkgs/development/beam-modules/rebar3-nix/default.nix b/pkgs/development/beam-modules/rebar3-nix/default.nix new file mode 100644 index 00000000000..50bd2965835 --- /dev/null +++ b/pkgs/development/beam-modules/rebar3-nix/default.nix @@ -0,0 +1,18 @@ +{ lib, buildRebar3, fetchFromGitHub }: +buildRebar3 rec { + name = "rebar3_nix"; + version = "0.1.1"; + src = fetchFromGitHub { + owner = "erlang-nix"; + repo = name; + rev = "v${version}"; + sha256 = "10ijc06qvv5hqv0qy3w7mbv9pshdb8bvy0f3phr1vd5hksbk731y"; + }; + + meta = { + description = "nix integration for rebar3"; + license = lib.licenses.bsd3; + homepage = "https://github.com/erlang-nix/rebar3_nix"; + maintainers = with lib.maintainers; [ dlesl gleber ]; + }; +} diff --git a/pkgs/development/beam-modules/rebar3-proper/default.nix b/pkgs/development/beam-modules/rebar3-proper/default.nix new file mode 100644 index 00000000000..2955beeeb5b --- /dev/null +++ b/pkgs/development/beam-modules/rebar3-proper/default.nix @@ -0,0 +1,13 @@ +{ lib, buildHex }: + +buildHex { + name = "rebar3_proper"; + version = "0.12.1"; + sha256 = "1f174fb6h2071wr7qbw9aqqvnglzsjlylmyi8215fhrmi38w94b6"; + + meta = { + description = "rebar3 proper plugin"; + license = lib.licenses.bsd3; + homepage = "https://github.com/ferd/rebar3_proper"; + }; +} diff --git a/pkgs/development/beam-modules/rebar3-release.nix b/pkgs/development/beam-modules/rebar3-release.nix index 1ec9f244d6c..59771c34029 100644 --- a/pkgs/development/beam-modules/rebar3-release.nix +++ b/pkgs/development/beam-modules/rebar3-release.nix @@ -1,83 +1,108 @@ -{ stdenv, writeText, erlang, rebar3, openssl, - lib }: +{ stdenv +, erlang +, rebar3WithPlugins +, openssl +, lib +}: -{ name, version +{ pname +, version , src +, beamDeps ? [ ] +, buildPlugins ? [ ] , checkouts ? null , releaseType -, buildInputs ? [] +, buildInputs ? [ ] , setupHook ? null , profile ? "default" , installPhase ? null , buildPhase ? null , configurePhase ? null -, meta ? {} -, enableDebugInfo ? false -, ... }@attrs: +, meta ? { } +, ... +}@attrs: -with stdenv.lib; +with lib; let shell = drv: stdenv.mkDerivation { - name = "interactive-shell-${drv.name}"; - buildInputs = [ drv ]; - }; + name = "interactive-shell-${drv.pname}"; + buildInputs = [ drv ]; + }; customPhases = filterAttrs (_: v: v != null) { inherit setupHook configurePhase buildPhase installPhase; }; - pkg = self: stdenv.mkDerivation (attrs // { - - name = "${name}-${version}"; - inherit version; - - buildInputs = buildInputs ++ [ erlang rebar3 openssl ]; - propagatedBuildInputs = [checkouts]; - - dontStrip = true; - - inherit src; - - setupHook = writeText "setupHook.sh" '' - addToSearchPath ERL_LIBS "$1/lib/erlang/lib/" - ''; - - configurePhase = '' - runHook preConfigure - ${if checkouts != null then - ''cp --no-preserve=all -R ${checkouts}/_checkouts .'' - else - ''''} - runHook postConfigure - ''; - - buildPhase = '' - runHook preBuild - HOME=. DEBUG=1 rebar3 as ${profile} ${if releaseType == "escript" - then '' escriptize'' - else '' release''} - runHook postBuild - ''; - - installPhase = '' - runHook preInstall - dir=${if releaseType == "escript" - then ''bin'' - else ''rel''} - mkdir -p "$out/$dir" - cp -R --preserve=mode "_build/${profile}/$dir" "$out" - runHook postInstall - ''; - - meta = { - inherit (erlang.meta) platforms; - } // meta; - - passthru = { - packageName = name; - env = shell self; - }; - } // customPhases); + # When using the `beamDeps` argument, it is important that we use + # `rebar3WithPlugins` here even when there are no plugins. The vanilla + # `rebar3` package is an escript archive with bundled dependencies which can + # interfere with those in the app we are trying to build. `rebar3WithPlugins` + # doesn't have this issue since it puts its own deps last on the code path. + rebar3 = rebar3WithPlugins { + plugins = buildPlugins; + }; + + pkg = + assert beamDeps != [ ] -> checkouts == null; + self: stdenv.mkDerivation (attrs // { + + name = "${pname}-${version}"; + inherit version pname; + + buildInputs = buildInputs ++ [ erlang rebar3 openssl ] ++ beamDeps; + + # ensure we strip any native binaries (eg. NIFs, ports) + stripDebugList = lib.optional (releaseType == "release") "rel"; + + inherit src; + + REBAR_IGNORE_DEPS = beamDeps != [ ]; + + configurePhase = '' + runHook preConfigure + ${lib.optionalString (checkouts != null) + "cp --no-preserve=all -R ${checkouts}/_checkouts ."} + runHook postConfigure + ''; + + buildPhase = '' + runHook preBuild + HOME=. DEBUG=1 rebar3 as ${profile} ${if releaseType == "escript" + then "escriptize" + else "release"} + runHook postBuild + ''; + + installPhase = '' + runHook preInstall + dir=${if releaseType == "escript" + then "bin" + else "rel"} + mkdir -p "$out/$dir" "$out/bin" + cp -R --preserve=mode "_build/${profile}/$dir" "$out" + ${lib.optionalString (releaseType == "release") + "find $out/rel/*/bin -type f -executable -exec ln -s -t $out/bin {} \\;"} + runHook postInstall + ''; + + postInstall = '' + for dir in $out/rel/*/erts-*; do + echo "ERTS found in $dir - removing references to erlang to reduce closure size" + for f in $dir/bin/{erl,start}; do + substituteInPlace "$f" --replace "${erlang}/lib/erlang" "''${dir/\/erts-*/}" + done + done + ''; + + meta = { + inherit (erlang.meta) platforms; + } // meta; + + passthru = ({ + packageName = pname; + env = shell self; + } // (if attrs ? passthru then attrs.passthru else { })); + } // customPhases); in - fix pkg +fix pkg diff --git a/pkgs/development/beam-modules/webdriver/default.nix b/pkgs/development/beam-modules/webdriver/default.nix index 8f06f8ed7a8..1255ec59c3a 100644 --- a/pkgs/development/beam-modules/webdriver/default.nix +++ b/pkgs/development/beam-modules/webdriver/default.nix @@ -1,4 +1,4 @@ -{stdenv, fetchFromGitHub, writeText, erlang }: +{ lib, stdenv, fetchFromGitHub, writeText, erlang }: let shell = drv: stdenv.mkDerivation { @@ -27,9 +27,9 @@ let meta = { description = "WebDriver implementation in Erlang"; - license = stdenv.lib.licenses.mit; + license = lib.licenses.mit; homepage = "https://github.com/Quviq/webdrv"; - maintainers = with stdenv.lib.maintainers; [ ericbmerritt ]; + maintainers = with lib.maintainers; [ ericbmerritt ]; }; passthru = { @@ -37,4 +37,4 @@ let }; }; -in stdenv.lib.fix pkg +in lib.fix pkg |