about summary refs log tree commit diff
path: root/nixpkgs/pkgs/development/beam-modules
diff options
context:
space:
mode:
Diffstat (limited to 'nixpkgs/pkgs/development/beam-modules')
-rw-r--r--nixpkgs/pkgs/development/beam-modules/build-erlang-mk.nix108
-rw-r--r--nixpkgs/pkgs/development/beam-modules/build-hex.nix18
-rw-r--r--nixpkgs/pkgs/development/beam-modules/build-mix.nix93
-rw-r--r--nixpkgs/pkgs/development/beam-modules/build-rebar3.nix86
-rw-r--r--nixpkgs/pkgs/development/beam-modules/default.nix92
-rw-r--r--nixpkgs/pkgs/development/beam-modules/elixir-ls/default.nix76
-rw-r--r--nixpkgs/pkgs/development/beam-modules/elvis-erlang/default.nix47
-rw-r--r--nixpkgs/pkgs/development/beam-modules/elvis-erlang/rebar-deps.nix168
-rw-r--r--nixpkgs/pkgs/development/beam-modules/erlang-ls/default.nix79
-rw-r--r--nixpkgs/pkgs/development/beam-modules/erlang-ls/rebar-deps.nix221
-rw-r--r--nixpkgs/pkgs/development/beam-modules/erlfmt/default.nix20
-rw-r--r--nixpkgs/pkgs/development/beam-modules/fetch-hex.nix45
-rw-r--r--nixpkgs/pkgs/development/beam-modules/fetch-mix-deps.nix65
-rw-r--r--nixpkgs/pkgs/development/beam-modules/fetch-rebar-deps.nix41
-rw-r--r--nixpkgs/pkgs/development/beam-modules/hex/default.nix57
-rw-r--r--nixpkgs/pkgs/development/beam-modules/lib.nix82
-rwxr-xr-xnixpkgs/pkgs/development/beam-modules/mix-configure-hook.sh18
-rw-r--r--nixpkgs/pkgs/development/beam-modules/mix-release.nix141
-rw-r--r--nixpkgs/pkgs/development/beam-modules/pc/default.nix13
-rw-r--r--nixpkgs/pkgs/development/beam-modules/pgsql/default.nix34
-rw-r--r--nixpkgs/pkgs/development/beam-modules/rebar3-nix/default.nix18
-rw-r--r--nixpkgs/pkgs/development/beam-modules/rebar3-proper/default.nix13
-rw-r--r--nixpkgs/pkgs/development/beam-modules/rebar3-release.nix106
-rw-r--r--nixpkgs/pkgs/development/beam-modules/webdriver/default.nix40
24 files changed, 1681 insertions, 0 deletions
diff --git a/nixpkgs/pkgs/development/beam-modules/build-erlang-mk.nix b/nixpkgs/pkgs/development/beam-modules/build-erlang-mk.nix
new file mode 100644
index 000000000000..eb70517c82ec
--- /dev/null
+++ b/nixpkgs/pkgs/development/beam-modules/build-erlang-mk.nix
@@ -0,0 +1,108 @@
+{ stdenv, writeText, erlang, perl, which, gitMinimal, wget, lib }:
+
+{ name
+, version
+, src
+, setupHook ? null
+, buildInputs ? [ ]
+, beamDeps ? [ ]
+, postPatch ? ""
+, compilePorts ? false
+, installPhase ? null
+, buildPhase ? null
+, configurePhase ? null
+, meta ? { }
+, enableDebugInfo ? false
+, buildFlags ? [ ]
+, ...
+}@attrs:
+
+let
+  debugInfoFlag = lib.optionalString (enableDebugInfo || erlang.debugInfo) "+debug_info";
+
+  shell = drv: stdenv.mkDerivation {
+    name = "interactive-shell-${drv.name}";
+    buildInputs = [ drv ];
+  };
+
+  pkg = self: stdenv.mkDerivation (attrs // {
+    app_name = name;
+    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;
+
+    buildInputs = buildInputs ++ [ erlang perl which gitMinimal wget ];
+    propagatedBuildInputs = beamDeps;
+
+    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
+
+        runHook postConfigure
+      ''
+      else configurePhase;
+
+    buildPhase =
+      if buildPhase == null
+      then ''
+        runHook preBuild
+
+        make $buildFlags "''${buildFlagsArray[@]}"
+
+        runHook postBuild
+      ''
+      else buildPhase;
+
+    installPhase =
+      if installPhase == null
+      then ''
+        runHook preInstall
+
+        mkdir -p $out/lib/erlang/lib/${name}
+        cp -r ebin $out/lib/erlang/lib/${name}/
+        cp -r src $out/lib/erlang/lib/${name}/
+
+        if [ -d include ]; then
+          cp -r include $out/lib/erlang/lib/${name}/
+        fi
+
+        if [ -d priv ]; then
+          cp -r priv $out/lib/erlang/lib/${name}/
+        fi
+
+        if [ -d doc ]; then
+          cp -r doc $out/lib/erlang/lib/${name}/
+        fi
+
+        runHook postInstall
+      ''
+      else installPhase;
+
+    passthru = {
+      packageName = name;
+      env = shell self;
+      inherit beamDeps;
+    };
+  });
+in
+lib.fix pkg
diff --git a/nixpkgs/pkgs/development/beam-modules/build-hex.nix b/nixpkgs/pkgs/development/beam-modules/build-hex.nix
new file mode 100644
index 000000000000..b5d20fa97783
--- /dev/null
+++ b/nixpkgs/pkgs/development/beam-modules/build-hex.nix
@@ -0,0 +1,18 @@
+{ lib, buildRebar3, fetchHex }:
+
+{ name, version, sha256
+, builder ? buildRebar3
+, hexPkg ? name
+, ... }@attrs:
+
+let
+  pkg = self: builder (attrs // {
+
+    src = fetchHex {
+      pkg = hexPkg;
+      inherit version;
+      inherit sha256;
+    };
+  });
+in
+  lib.fix pkg
diff --git a/nixpkgs/pkgs/development/beam-modules/build-mix.nix b/nixpkgs/pkgs/development/beam-modules/build-mix.nix
new file mode 100644
index 000000000000..081d4988bace
--- /dev/null
+++ b/nixpkgs/pkgs/development/beam-modules/build-mix.nix
@@ -0,0 +1,93 @@
+{ stdenv, writeText, elixir, erlang, hex, lib }:
+
+{ name
+, version
+, src
+, buildInputs ? [ ]
+, nativeBuildInputs ? [ ]
+, beamDeps ? [ ]
+, propagatedBuildInputs ? [ ]
+, postPatch ? ""
+, compilePorts ? false
+, meta ? { }
+, enableDebugInfo ? false
+, mixEnv ? "prod"
+, ...
+}@attrs:
+
+let
+  shell = drv: stdenv.mkDerivation {
+    name = "interactive-shell-${drv.name}";
+    buildInputs = [ drv ];
+  };
+
+  pkg = self: stdenv.mkDerivation (attrs // {
+    name = "${name}-${version}";
+    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;
+
+    configurePhase = attrs.configurePhase or ''
+      runHook preConfigure
+
+      ${./mix-configure-hook.sh}
+
+      runHook postConfigure
+    '';
+
+    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
+
+      runHook postInstall
+    '';
+
+    # 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
+lib.fix pkg
+
diff --git a/nixpkgs/pkgs/development/beam-modules/build-rebar3.nix b/nixpkgs/pkgs/development/beam-modules/build-rebar3.nix
new file mode 100644
index 000000000000..43d613d072ee
--- /dev/null
+++ b/nixpkgs/pkgs/development/beam-modules/build-rebar3.nix
@@ -0,0 +1,86 @@
+{ stdenv, writeText, erlang, rebar3WithPlugins, openssl, libyaml, lib }:
+
+{ name
+, version
+, src
+, setupHook ? null
+, buildInputs ? [ ]
+, beamDeps ? [ ]
+, buildPlugins ? [ ]
+, postPatch ? ""
+, installPhase ? null
+, buildPhase ? null
+, configurePhase ? null
+, meta ? { }
+, enableDebugInfo ? false
+, ...
+}@attrs:
+
+let
+  debugInfoFlag = lib.optionalString (enableDebugInfo || erlang.debugInfo) "debug-info";
+
+  rebar3 = rebar3WithPlugins {
+    plugins = buildPlugins;
+  };
+
+  shell = drv: stdenv.mkDerivation {
+    name = "interactive-shell-${drv.name}";
+    buildInputs = [ drv ];
+  };
+
+  customPhases = lib.filterAttrs
+    (_: v: v != null)
+    { inherit setupHook configurePhase buildPhase installPhase; };
+
+  pkg = self: stdenv.mkDerivation (attrs // {
+
+    name = "${name}-${version}";
+    inherit version;
+
+    buildInputs = buildInputs ++ [ erlang rebar3 openssl libyaml ];
+    propagatedBuildInputs = lib.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/"
+    '';
+
+    postPatch = ''
+      rm -f rebar rebar3
+    '' + postPatch;
+
+    buildPhase = ''
+      runHook preBuild
+      HOME=. rebar3 bare compile -path ""
+      runHook postBuild
+    '';
+
+    installPhase = ''
+      runHook preInstall
+      mkdir -p "$out/lib/erlang/lib/${name}-${version}"
+      for reldir in src ebin priv include; do
+        [ -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
+    '';
+
+    meta = {
+      inherit (erlang.meta) platforms;
+    } // meta;
+
+    passthru = {
+      packageName = name;
+      env = shell self;
+      inherit beamDeps;
+    };
+  } // customPhases);
+in
+lib.fix pkg
diff --git a/nixpkgs/pkgs/development/beam-modules/default.nix b/nixpkgs/pkgs/development/beam-modules/default.nix
new file mode 100644
index 000000000000..421d5f7ffbc0
--- /dev/null
+++ b/nixpkgs/pkgs/development/beam-modules/default.nix
@@ -0,0 +1,92 @@
+{ lib, __splicedPackages, erlang }:
+
+let
+  pkgs = __splicedPackages;
+  inherit (lib) makeExtensible;
+
+  lib' = pkgs.callPackage ./lib.nix { };
+
+  # FIXME: add support for overrideScope
+  callPackageWithScope = scope: drv: args: lib.callPackageWith scope drv args;
+  mkScope = scope: pkgs // scope;
+
+  packages = self:
+    let
+      defaultScope = mkScope self;
+      callPackage = drv: args: callPackageWithScope defaultScope drv args;
+    in
+    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_14;
+
+      elixir_1_15 = lib'.callElixir ../interpreters/elixir/1.15.nix {
+        inherit erlang;
+        debugInfo = true;
+      };
+
+      elixir_1_14 = lib'.callElixir ../interpreters/elixir/1.14.nix {
+        inherit erlang;
+        debugInfo = true;
+      };
+
+      elixir_1_13 = lib'.callElixir ../interpreters/elixir/1.13.nix {
+        inherit erlang;
+        debugInfo = true;
+      };
+
+      elixir_1_12 = lib'.callElixir ../interpreters/elixir/1.12.nix {
+        inherit erlang;
+        debugInfo = true;
+      };
+
+      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;
+      };
+
+      # Remove old versions of elixir, when the supports fades out:
+      # https://hexdocs.pm/elixir/compatibility-and-deprecations.html
+
+      elixir-ls = callPackage ./elixir-ls { inherit elixir fetchMixDeps mixRelease; };
+
+      lfe = lfe_2_1;
+      lfe_2_1 = lib'.callLFE ../interpreters/lfe/2.1.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/nixpkgs/pkgs/development/beam-modules/elixir-ls/default.nix b/nixpkgs/pkgs/development/beam-modules/elixir-ls/default.nix
new file mode 100644
index 000000000000..037aba684819
--- /dev/null
+++ b/nixpkgs/pkgs/development/beam-modules/elixir-ls/default.nix
@@ -0,0 +1,76 @@
+{ lib, elixir, fetchFromGitHub, fetchMixDeps, mixRelease, nix-update-script }:
+# Based on the work of Hauleth
+# None of this would have happened without him
+
+let
+  pname = "elixir-ls";
+  version = "0.15.1";
+  src = fetchFromGitHub {
+    owner = "elixir-lsp";
+    repo = "elixir-ls";
+    rev = "v${version}";
+    hash = "sha256-bWR5wKOVE9qPQyFjiaBumsWwG7vv9pFCVvXO4N8a3HA=";
+    fetchSubmodules = true;
+  };
+in
+mixRelease  {
+  inherit pname version src elixir;
+
+  stripDebug = true;
+
+  mixFodDeps = fetchMixDeps {
+    pname = "mix-deps-${pname}";
+    inherit src version elixir;
+    hash = "sha256-7AE6RUD7DLo5uTxPMiUDm9MIBYcrNatrIuILK9jinNk=";
+  };
+
+  # 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;
+  };
+  passthru.updateScript = nix-update-script { };
+}
diff --git a/nixpkgs/pkgs/development/beam-modules/elvis-erlang/default.nix b/nixpkgs/pkgs/development/beam-modules/elvis-erlang/default.nix
new file mode 100644
index 000000000000..7b1454554196
--- /dev/null
+++ b/nixpkgs/pkgs/development/beam-modules/elvis-erlang/default.nix
@@ -0,0 +1,47 @@
+{ 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.1.0";
+  src = fetchFromGitHub {
+    inherit owner repo;
+    sha256 = "6vNxr3AYpFuXaIVH9bWw7K5KiF1swfI+CSI43RoMQEA=";
+    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 | 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 ];
+    mainProgram = "elvis";
+  };
+}
diff --git a/nixpkgs/pkgs/development/beam-modules/elvis-erlang/rebar-deps.nix b/nixpkgs/pkgs/development/beam-modules/elvis-erlang/rebar-deps.nix
new file mode 100644
index 000000000000..6c5e429b24d0
--- /dev/null
+++ b/nixpkgs/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.1";
+      src = fetchHex {
+        pkg = "parse_trans";
+        version = "3.4.1";
+        sha256 = "sha256-YgpAbOddragnuC5FPBnPBndr4mb1pnz/NOHvLLtg5Jo=";
+      };
+      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.8.0";
+      src = fetchHex {
+        pkg = "certifi";
+        version = "2.8.0";
+        sha256 = "sha256-asfvwcb4YAsI1iUpLUu/WE4UhHzhtrXETZg9Jz4Ql+o=";
+      };
+      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.3.1";
+      src = fetchHex {
+        pkg = "elvis_core";
+        version = "1.3.1";
+        sha256 = "sha256-eoiQv4GFoyUs1OvYJv5fita5MCTt+IV26yeunl3BnWk=";
+      };
+      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/nixpkgs/pkgs/development/beam-modules/erlang-ls/default.nix b/nixpkgs/pkgs/development/beam-modules/erlang-ls/default.nix
new file mode 100644
index 000000000000..04d6fc36176f
--- /dev/null
+++ b/nixpkgs/pkgs/development/beam-modules/erlang-ls/default.nix
@@ -0,0 +1,79 @@
+{ fetchFromGitHub, fetchgit, fetchHex, rebar3Relx, buildRebar3, rebar3-proper
+, stdenv, writeScript, lib, erlang }:
+let
+  version = "0.48.0";
+  owner = "erlang-ls";
+  repo = "erlang_ls";
+  deps = import ./rebar-deps.nix {
+    inherit fetchHex fetchFromGitHub fetchgit;
+    builder = buildRebar3;
+    overrides = (self: super: {
+      proper = super.proper.overrideAttrs (_: {
+        configurePhase = "true";
+      });
+      redbug = super.redbug.overrideAttrs (_: {
+        patchPhase = ''
+          substituteInPlace rebar.config --replace ", warnings_as_errors" ""
+          '';
+      });
+    });
+  };
+in
+rebar3Relx {
+  pname = "erlang-ls";
+  inherit version;
+  src = fetchFromGitHub {
+    inherit owner repo;
+    sha256 = "sha256-QwsN/P2FBuhIS/vRlrdvokQS6G77kkZ2Rg5rwNc36Jg=";
+    rev = version;
+  };
+  releaseType = "escript";
+  beamDeps = builtins.attrValues deps;
+
+  # https://github.com/erlang-ls/erlang_ls/issues/1429
+  postPatch =  ''
+    rm apps/els_lsp/test/els_diagnostics_SUITE.erl
+  '';
+
+  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
+  '';
+  # tests seem to be a bit flaky on darwin, skip them for now
+  doCheck = !stdenv.isDarwin;
+  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;
+    mainProgram = "erlang_ls";
+  };
+  passthru.updateScript = writeScript "update.sh" ''
+    #!/usr/bin/env nix-shell
+    #! nix-shell -i bash -p common-updater-scripts coreutils git gnused gnutar gzip "rebar3WithPlugins { globalPlugins = [ beamPackages.rebar3-nix ]; }"
+
+    set -ox errexit
+    latest=$(list-git-tags | sed -n '/[\d\.]\+/p' | sort -V | tail -1)
+    if [[ "$latest" != "${version}" ]]; then
+      nixpkgs="$(git rev-parse --show-toplevel)"
+      nix_path="$nixpkgs/pkgs/development/beam-modules/erlang-ls"
+      update-source-version erlang-ls "$latest" --version-key=version --print-changes --file="$nix_path/default.nix"
+      tmpdir=$(mktemp -d)
+      cp -R $(nix-build $nixpkgs --no-out-link -A erlang-ls.src)/* "$tmpdir"
+      DEBUG=1
+      (cd "$tmpdir" && HOME=. rebar3 as test nix lock -o "$nix_path/rebar-deps.nix")
+    else
+      echo "erlang-ls is already up-to-date"
+    fi
+  '';
+}
diff --git a/nixpkgs/pkgs/development/beam-modules/erlang-ls/rebar-deps.nix b/nixpkgs/pkgs/development/beam-modules/erlang-ls/rebar-deps.nix
new file mode 100644
index 000000000000..afdf4767843b
--- /dev/null
+++ b/nixpkgs/pkgs/development/beam-modules/erlang-ls/rebar-deps.nix
@@ -0,0 +1,221 @@
+# 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; {
+    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 = "git";
+      src = fetchFromGitHub {
+        owner = "erlang-ls";
+        repo = "yamerl";
+        rev = "9a9f7a2e84554992f2e8e08a8060bfe97776a5b7";
+        sha256 = "1gb44v27paxwxm443m5f554wiziqi2kd300hgjjdg6fyvy3mvhss";
+      };
+      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 ];
+    };
+    jsx = builder {
+      name = "jsx";
+      version = "3.0.0";
+      src = fetchHex {
+        pkg = "jsx";
+        version = "3.0.0";
+        sha256 = "sha256-N77KBDX1yoovRfdqRiEedkGPvvgMNvA2HCSfx1BZ3G0=";
+      };
+      beamDeps = [ ];
+    };
+    gradualizer = builder {
+      name = "gradualizer";
+      version = "git";
+      src = fetchFromGitHub {
+        owner = "josefs";
+        repo = "gradualizer";
+        rev = "3021d29d82741399d131e3be38d2a8db79d146d4";
+        sha256 = "052f8x9x93yy00pbkl1745ffnwj3blcm39j12i4k166y1zbnwy00";
+      };
+      beamDeps = [ ];
+    };
+    erlfmt = builder {
+      name = "erlfmt";
+      version = "git";
+      src = fetchFromGitHub {
+        owner = "gomoripeti";
+        repo = "erlfmt";
+        rev = "d4422d1fd79a73ef534c2bcbe5b5da4da5338833";
+        sha256 = "07jp4g6a41w7318lh8ndsvgivkj0ahz3spnrsnx4cqkdb97yjaid";
+      };
+      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.3.1";
+      src = fetchHex {
+        pkg = "elvis_core";
+        version = "1.3.1";
+        sha256 = "sha256-eoiQv4GFoyUs1OvYJv5fita5MCTt+IV26yeunl3BnWk=";
+      };
+      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/nixpkgs/pkgs/development/beam-modules/erlfmt/default.nix b/nixpkgs/pkgs/development/beam-modules/erlfmt/default.nix
new file mode 100644
index 000000000000..8c1d3f72c7e0
--- /dev/null
+++ b/nixpkgs/pkgs/development/beam-modules/erlfmt/default.nix
@@ -0,0 +1,20 @@
+{ fetchFromGitHub, rebar3Relx, lib }:
+
+rebar3Relx rec {
+  pname = "erlfmt";
+  version = "1.2.0";
+  releaseType = "escript";
+  src = fetchFromGitHub {
+    owner = "WhatsApp";
+    repo = "erlfmt";
+    sha256 = "sha256-mma4QH6GlayTG5I9hW9wNZph/IJcCXjiY7Ft3hfxaPg=";
+    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/nixpkgs/pkgs/development/beam-modules/fetch-hex.nix b/nixpkgs/pkgs/development/beam-modules/fetch-hex.nix
new file mode 100644
index 000000000000..2d1fa623745a
--- /dev/null
+++ b/nixpkgs/pkgs/development/beam-modules/fetch-hex.nix
@@ -0,0 +1,45 @@
+{ lib, stdenv, fetchurl }:
+
+{ pkg
+, version
+, sha256
+, meta ? { }
+}:
+
+stdenv.mkDerivation ({
+  pname = "hex-source-${pkg}";
+  inherit version;
+  dontBuild = true;
+  dontConfigure = true;
+  dontFixup = true;
+
+  src = fetchurl {
+    url = "https://repo.hex.pm/tarballs/${pkg}-${version}.tar";
+    inherit sha256;
+  };
+
+  unpackCmd = ''
+    tar -xf $curSrc contents.tar.gz CHECKSUM metadata.config
+    mkdir contents
+    tar -C contents -xzf contents.tar.gz
+    mv metadata.config contents/hex_metadata.config
+
+    # To make the extracted hex tarballs appear legitimate to mix, we need to
+    # make sure they contain not just the contents of contents.tar.gz but also
+    # a .hex file with some lock metadata.
+    # We use an old version of .hex file per hex's mix_task_test.exs since it
+    # is just plain-text instead of an encoded format.
+    # See: https://github.com/hexpm/hex/blob/main/test/hex/mix_task_test.exs#L410
+    echo -n "${pkg},${version},$(cat CHECKSUM | tr '[:upper:]' '[:lower:]'),hexpm" > contents/.hex
+  '';
+
+  installPhase = ''
+    runHook preInstall
+    mkdir "$out"
+    cp -Hrt "$out" .
+    success=1
+    runHook postInstall
+  '';
+
+  inherit meta;
+})
diff --git a/nixpkgs/pkgs/development/beam-modules/fetch-mix-deps.nix b/nixpkgs/pkgs/development/beam-modules/fetch-mix-deps.nix
new file mode 100644
index 000000000000..b9a1add3c7d1
--- /dev/null
+++ b/nixpkgs/pkgs/development/beam-modules/fetch-mix-deps.nix
@@ -0,0 +1,65 @@
+{ stdenvNoCC, lib, elixir, hex, rebar, rebar3, cacert, git }@inputs:
+
+{ pname
+, version
+, hash ? ""
+, sha256 ? ""
+, src
+, mixEnv ? "prod"
+, debug ? false
+, meta ? { }
+, patches ? []
+, elixir ? inputs.elixir
+, hex ? inputs.hex.override { inherit elixir; }
+, ...
+}@attrs:
+
+let
+  hash_ =
+    if hash != "" then { outputHashAlgo = null; outputHash = hash; }
+    else if sha256 != "" then { outputHashAlgo = "sha256"; outputHash = sha256; }
+    else { outputHashAlgo = "sha256"; outputHash = lib.fakeSha256; };
+in
+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 ''${MIX_ENV:+--only $MIX_ENV}
+    find "$TEMPDIR/deps" -path '*/.git/*' -a ! -name HEAD -exec rm -rf {} +
+    cp -r --no-preserve=mode,ownership,timestamps $TEMPDIR/deps $out
+    runHook postInstall
+  '';
+
+  outputHashMode = "recursive";
+
+  impureEnvVars = lib.fetchers.proxyImpureEnvVars;
+  inherit meta;
+} // hash_)
diff --git a/nixpkgs/pkgs/development/beam-modules/fetch-rebar-deps.nix b/nixpkgs/pkgs/development/beam-modules/fetch-rebar-deps.nix
new file mode 100644
index 000000000000..b253e16761ba
--- /dev/null
+++ b/nixpkgs/pkgs/development/beam-modules/fetch-rebar-deps.nix
@@ -0,0 +1,41 @@
+{ lib, stdenv, rebar3 }:
+
+{ name
+, version
+, sha256
+, src
+, meta ? { }
+}:
+
+stdenv.mkDerivation ({
+  pname = "rebar-deps-${name}";
+  inherit version;
+
+  dontUnpack = true;
+  dontConfigure = true;
+  dontFixup = true;
+
+  buildPhase = ''
+    cp -r ${src} src
+    chmod -R u+w src
+    cd src
+    HOME='.' DEBUG=1 ${rebar3}/bin/rebar3 get-deps
+  '';
+
+  installPhase = ''
+    runHook preInstall
+    mkdir -p "$out/_checkouts"
+    for i in ./_build/default/lib/* ; do
+       echo "$i"
+       cp -R "$i" "$out/_checkouts"
+    done
+    runHook postInstall
+  '';
+
+  outputHashAlgo = "sha256";
+  outputHashMode = "recursive";
+  outputHash = sha256;
+
+  impureEnvVars = lib.fetchers.proxyImpureEnvVars;
+  inherit meta;
+})
diff --git a/nixpkgs/pkgs/development/beam-modules/hex/default.nix b/nixpkgs/pkgs/development/beam-modules/hex/default.nix
new file mode 100644
index 000000000000..32628886f11f
--- /dev/null
+++ b/nixpkgs/pkgs/development/beam-modules/hex/default.nix
@@ -0,0 +1,57 @@
+{ lib, stdenv, fetchFromGitHub, writeText, elixir }:
+
+let
+  shell = drv: stdenv.mkDerivation {
+    name = "interactive-shell-${drv.name}";
+    buildInputs = [ drv ];
+  };
+
+  pkg = self: stdenv.mkDerivation rec {
+    pname = "hex";
+    version = "2.0.6";
+
+    src = fetchFromGitHub {
+      owner = "hexpm";
+      repo = "hex";
+      rev = "v${version}";
+      sha256 = "sha256-fSADQDrqh5U/TdhaHXsMiLMk1wtQ0gEiTqEclJ2w2nY=";
+    };
+
+    setupHook = writeText "setupHook.sh" ''
+       addToSearchPath ERL_LIBS "$1/lib/erlang/lib/"
+    '';
+
+    dontStrip = true;
+
+    buildInputs = [ elixir ];
+
+    buildPhase = ''
+      runHook preBuild
+      export HEX_OFFLINE=1
+      export HEX_HOME=./
+      export MIX_ENV=prod
+      mix compile
+      runHook postBuild
+    '';
+
+    installPhase = ''
+      runHook preInstall
+
+      mkdir -p $out/lib/erlang/lib
+      cp -r ./_build/prod/lib/hex $out/lib/erlang/lib/
+
+      runHook postInstall
+    '';
+
+    meta = {
+      description = "Package manager for the Erlang VM https://hex.pm";
+      license = lib.licenses.mit;
+      homepage = "https://github.com/hexpm/hex";
+      maintainers = with lib.maintainers; [ ericbmerritt ];
+    };
+
+    passthru = {
+      env = shell self;
+    };
+};
+in lib.fix pkg
diff --git a/nixpkgs/pkgs/development/beam-modules/lib.nix b/nixpkgs/pkgs/development/beam-modules/lib.nix
new file mode 100644
index 000000000000..2d93b28cda6b
--- /dev/null
+++ b/nixpkgs/pkgs/development/beam-modules/lib.nix
@@ -0,0 +1,82 @@
+{ __splicedPackages, lib }:
+
+let
+  pkgs = __splicedPackages;
+in
+rec {
+
+  /* Similar to callPackageWith/callPackage, but without makeOverridable
+  */
+  callPackageWith = autoArgs: fn: args:
+    let
+      f = if pkgs.lib.isFunction fn then fn else import fn;
+      auto = builtins.intersectAttrs (lib.functionArgs f) autoArgs;
+    in f (auto // args);
+
+  callPackage = callPackageWith pkgs;
+
+  /* Uses generic-builder to evaluate provided drv containing OTP-version
+  specific data.
+
+  drv: package containing version-specific args;
+  builder: generic builder for all Erlang versions;
+  args: arguments merged into version-specific args, used mostly to customize
+        dependencies;
+
+  Arguments passed to the generic-builder are overridable, used to
+  enable/disable high-level OTP features, like ODBC or WX support;
+
+  Please note that "mkDerivation" defined here is the one called from R16.nix
+  and similar files.
+  */
+  callErlang = drv: args:
+    let
+      builder = callPackage ../../development/interpreters/erlang/generic-builder.nix args;
+    in
+      callPackage drv {
+        mkDerivation = pkgs.makeOverridable builder;
+      };
+
+  /* Uses generic-builder to evaluate provided drv containing Elixir version
+  specific data.
+
+  drv: package containing version-specific args;
+  builder: generic builder for all Erlang versions;
+  args: arguments merged into version-specific args, used mostly to customize
+        dependencies;
+
+  Arguments passed to the generic-builder are overridable.
+
+  Please note that "mkDerivation" defined here is the one called from 1.4.nix
+  and similar files.
+  */
+  callElixir = drv: args:
+    let
+      builder = callPackage ../interpreters/elixir/generic-builder.nix args;
+    in
+      callPackage drv {
+        mkDerivation = pkgs.makeOverridable builder;
+      };
+
+  /* Uses generic-builder to evaluate provided drv containing Elixir version
+  specific data.
+
+  drv: package containing version-specific args;
+  builder: generic builder for all Erlang versions;
+  args: arguments merged into version-specific args, used mostly to customize
+        dependencies;
+
+  Arguments passed to the generic-builder are overridable.
+
+  Please note that "mkDerivation" defined here is the one called from 1.2.nix
+  and similar files.
+  */
+  callLFE = drv: args:
+    let
+      builder = callPackage ../interpreters/lfe/generic-builder.nix args;
+    in
+      callPackage drv {
+        mkDerivation = pkgs.makeOverridable builder;
+      };
+
+}
diff --git a/nixpkgs/pkgs/development/beam-modules/mix-configure-hook.sh b/nixpkgs/pkgs/development/beam-modules/mix-configure-hook.sh
new file mode 100755
index 000000000000..f8b4f3d159fe
--- /dev/null
+++ b/nixpkgs/pkgs/development/beam-modules/mix-configure-hook.sh
@@ -0,0 +1,18 @@
+# shellcheck shell=bash
+# this hook will symlink all dependencies found in ERL_LIBS
+# since Elixir 1.12.2 elixir does not look into ERL_LIBS for
+# elixir depencencies anymore, so those have to be symlinked to the _build directory
+mkdir -p _build/"$MIX_ENV"/lib
+while read -r -d ':' lib; do
+    for dir in "$lib"/*; do
+    # Strip version number for directory name if it exists, so naming of
+    # all libs matches what mix's expectation.
+    dest=$(basename "$dir" | cut -d '-' -f1)
+    build_dir="_build/$MIX_ENV/lib/$dest"
+    ((MIX_DEBUG == 1)) && echo "Linking $dir to $build_dir"
+    # Symlink libs to _build so that mix can find them when compiling.
+    # This is what allows mix to compile the package without searching
+    # for dependencies over the network.
+    ln -s "$dir" "$build_dir"
+    done
+done <<< "$ERL_LIBS:"
diff --git a/nixpkgs/pkgs/development/beam-modules/mix-release.nix b/nixpkgs/pkgs/development/beam-modules/mix-release.nix
new file mode 100644
index 000000000000..1d40da27ecba
--- /dev/null
+++ b/nixpkgs/pkgs/development/beam-modules/mix-release.nix
@@ -0,0 +1,141 @@
+{ stdenv, lib, elixir, erlang, findutils, hex, rebar, rebar3, fetchMixDeps, makeWrapper, git, ripgrep }@inputs:
+
+{ pname
+, version
+, src
+, nativeBuildInputs ? [ ]
+, buildInputs ? [ ]
+, 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 ? { }
+
+, elixir ? inputs.elixir
+, hex ? inputs.hex.override { inherit elixir; }
+
+# This reduces closure size, but can lead to some hard to understand runtime
+# errors, so use with caution. See e.g.
+# https://github.com/whitfin/cachex/issues/205
+# https://framagit.org/framasoft/mobilizon/-/issues/1169
+, stripDebug ? false
+
+, ...
+}@attrs:
+let
+  # remove non standard attributes that cannot be coerced to strings
+  overridable = builtins.removeAttrs attrs [ "compileFlags" "mixNixDeps" ];
+in
+assert mixNixDeps != { } -> mixFodDeps == null;
+assert stripDebug -> !enableDebugInfo;
+
+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 = 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
+
+    ${./mix-configure-hook.sh}
+    # 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
+      # TODO:
+      # sometimes there are links in dependencies like bcrypt compiled binaries
+      # at the moment those are not removed since substituteInPlace will
+      # error on binaries
+      for file in $(rg "${erlang}/lib/erlang" "$out" --files-with-matches); do
+        echo "removing reference to erlang in $file"
+        substituteInPlace "$file" --replace "${erlang}/lib/erlang" "$out"
+      done
+    fi
+  '' + lib.optionalString stripDebug ''
+    # strip debug symbols to avoid hardreferences to "foreign" closures actually
+    # not needed at runtime, while at the same time reduce size of BEAM files.
+    erl -noinput -eval 'lists:foreach(fun(F) -> io:format("Stripping ~p.~n", [F]), beam_lib:strip(F) end, filelib:wildcard("'"$out"'/**/*.beam"))' -s init stop
+  '';
+
+  # TODO investigate why the resulting closure still has
+  # a reference to erlang.
+  # uncommenting the following will fail the build
+  # disallowedReferences = [ erlang ];
+})
diff --git a/nixpkgs/pkgs/development/beam-modules/pc/default.nix b/nixpkgs/pkgs/development/beam-modules/pc/default.nix
new file mode 100644
index 000000000000..2896a325e0e1
--- /dev/null
+++ b/nixpkgs/pkgs/development/beam-modules/pc/default.nix
@@ -0,0 +1,13 @@
+{ lib, buildHex }:
+
+buildHex {
+  name = "pc";
+  version = "1.12.0";
+  sha256 = "1gdvixy4j560qjdiv5qjgnl5wl3rrn231dv1m4vdq4b9l4g4p27x";
+
+  meta = {
+    description = "a rebar3 port compiler for native code";
+    license = lib.licenses.mit;
+    homepage = "https://github.com/blt/port_compiler";
+  };
+}
diff --git a/nixpkgs/pkgs/development/beam-modules/pgsql/default.nix b/nixpkgs/pkgs/development/beam-modules/pgsql/default.nix
new file mode 100644
index 000000000000..df6561b7cf18
--- /dev/null
+++ b/nixpkgs/pkgs/development/beam-modules/pgsql/default.nix
@@ -0,0 +1,34 @@
+{ lib, stdenv, fetchFromGitHub, buildRebar3 }:
+
+let
+  shell = drv: stdenv.mkDerivation {
+          name = "interactive-shell-${drv.name}";
+          buildInputs = [ drv ];
+    };
+
+  pkg = self: buildRebar3 {
+    name = "pgsql";
+    version = "25+beta.2";
+
+    src = fetchFromGitHub {
+        owner = "semiocast";
+        repo = "pgsql";
+        rev = "14f632bc89e464d82ce3ef12a67ed8c2adb5b60c";
+        sha256 = "17dcahiwlw61zhy8aq9rn46lwb35fb9q3372s4wmz01czm8c348w";
+    };
+
+    dontStrip = true;
+
+    meta = {
+      description = "Erlang PostgreSQL Driver";
+      license = lib.licenses.mit;
+      homepage = "https://github.com/semiocast/pgsql";
+      maintainers = with lib.maintainers; [ ericbmerritt ];
+    };
+
+    passthru = {
+      env = shell self;
+    };
+
+};
+in lib.fix pkg
diff --git a/nixpkgs/pkgs/development/beam-modules/rebar3-nix/default.nix b/nixpkgs/pkgs/development/beam-modules/rebar3-nix/default.nix
new file mode 100644
index 000000000000..50bd29658354
--- /dev/null
+++ b/nixpkgs/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/nixpkgs/pkgs/development/beam-modules/rebar3-proper/default.nix b/nixpkgs/pkgs/development/beam-modules/rebar3-proper/default.nix
new file mode 100644
index 000000000000..2955beeeb5b5
--- /dev/null
+++ b/nixpkgs/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/nixpkgs/pkgs/development/beam-modules/rebar3-release.nix b/nixpkgs/pkgs/development/beam-modules/rebar3-release.nix
new file mode 100644
index 000000000000..b884809505f3
--- /dev/null
+++ b/nixpkgs/pkgs/development/beam-modules/rebar3-release.nix
@@ -0,0 +1,106 @@
+{ stdenv
+, erlang
+, rebar3WithPlugins
+, openssl
+, lib
+}:
+
+{ pname
+, version
+, src
+, beamDeps ? [ ]
+, buildPlugins ? [ ]
+, checkouts ? null
+, releaseType
+, buildInputs ? [ ]
+, setupHook ? null
+, profile ? "default"
+, installPhase ? null
+, buildPhase ? null
+, configurePhase ? null
+, meta ? { }
+, ...
+}@attrs:
+
+let
+  shell = drv: stdenv.mkDerivation {
+    name = "interactive-shell-${drv.pname}";
+    buildInputs = [ drv ];
+  };
+
+  customPhases = lib.filterAttrs
+    (_: v: v != null)
+    { inherit setupHook configurePhase buildPhase installPhase; };
+
+  # 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
+lib.fix pkg
diff --git a/nixpkgs/pkgs/development/beam-modules/webdriver/default.nix b/nixpkgs/pkgs/development/beam-modules/webdriver/default.nix
new file mode 100644
index 000000000000..131fd03d86dc
--- /dev/null
+++ b/nixpkgs/pkgs/development/beam-modules/webdriver/default.nix
@@ -0,0 +1,40 @@
+{ lib, stdenv, fetchFromGitHub, writeText, erlang }:
+
+let
+  shell = drv: stdenv.mkDerivation {
+    name = "interactive-shell-${drv.name}";
+    buildInputs = [ drv ];
+  };
+
+  pkg = self: stdenv.mkDerivation {
+    pname = "webdriver";
+    version = "0.pre+unstable=2015-02-08";
+
+    src = fetchFromGitHub {
+      owner = "Quviq";
+      repo = "webdrv";
+      rev = "7ceaf1f67d834e841ca0133b4bf899a9fa2db6bb";
+      sha256 = "1pq6pmlr6xb4hv2fvmlrvzd8c70kdcidlgjv4p8n9pwvkif0cb87";
+    };
+
+    setupHook = writeText "setupHook.sh" ''
+       addToSearchPath ERL_LIBS "$1/lib/erlang/lib/"
+    '';
+
+    buildInputs = [ erlang ];
+
+    installFlags = [ "PREFIX=$(out)/lib/erlang/lib" ];
+
+    meta = {
+      description = "WebDriver implementation in Erlang";
+      license = lib.licenses.mit;
+      homepage = "https://github.com/Quviq/webdrv";
+      maintainers = with lib.maintainers; [ ericbmerritt ];
+    };
+
+    passthru = {
+      env = shell self;
+    };
+
+  };
+in lib.fix pkg