Question about packaging ElixirLS

Hello, I’m trying to package ElixirLS. As it described in the Building and running section, it has to be built with the mix elixir_ls.release command, which builds language server components as a bunch of .ez archives and adds shell/Bat scripts to run them.

I have come up with a working derivation:

{ stdenv, elixir, erlang, git, cacert
}:
stdenv.mkDerivation rec {
  name = "elixir-ls-${version}";
  version = "0.2.26";
  src = builtins.fetchGit {
    url = https://github.com/elixir-lsp/elixir-ls;
    rev = "ba1c9cb86545298c487cf77a166c203fc44ce8dd";
  };
  buildInputs = [elixir erlang git cacert];
  buildPhase = ''
    mkdir -p $PWD/.hex
    export HOME=$PWD/.hex

    mix local.hex --force
    mix local.rebar --force

    mix deps.get
    mix compile
  '';
  installPhase = ''
    mkdir -p $out/bin

    mix elixir_ls.release --destination $out/bin
  '';
}

While it works, I have a question about the approach used here. Is mkDerivation the right tool for the job? Nixpkgs manual mentions buildHex and buildMix. I cannot use buildHex because ElixirLS is not published in Hex, and it seems like buildMix is intended to use for “library” packages.

Also, it fails if I don’t override HOME in buildPhase, because mix local.hex tries to write to $HOME, which is not writable:

these derivations will be built:
  /nix/store/fc3660sa7ifmj3ng7xlx3jxqjb7bc2jz-elixir-ls-0.2.26.drv
building '/nix/store/fc3660sa7ifmj3ng7xlx3jxqjb7bc2jz-elixir-ls-0.2.26.drv'...
unpacking sources
unpacking source archive /nix/store/0ylyd74314yvzwxwshnss1ywqnn02cgf-source
source root is source
patching sources
configuring
no configure script, doing nothing
building
** (File.Error) could not make directory (with -p) "/homeless-shelter/.mix/archives/hex-0.20.1": no such file or directory
    (elixir) lib/file.ex:314: File.mkdir_p!/1
    (mix) lib/mix/tasks/archive.install.ex:113: Mix.Tasks.Archive.Install.install/3
    (mix) lib/mix/local/installer.ex:107: Mix.Local.Installer.local_install/3
    (mix) lib/mix/task.ex:331: Mix.Task.run_task/3
    (mix) lib/mix/cli.ex:79: Mix.CLI.run_task/2
builder for '/nix/store/fc3660sa7ifmj3ng7xlx3jxqjb7bc2jz-elixir-ls-0.2.26.drv' failed with exit code 1
error: build of '/nix/store/fc3660sa7ifmj3ng7xlx3jxqjb7bc2jz-elixir-ls-0.2.26.drv' failed
direnv: error ../.envrc is blocked. Run `direnv allow` to approve its content.

This feels like a hack, is there any better way to do it?

Thanks!

Hello. Just a heads up to tell you that i see this. There is work in progress to clean up a bit the state of the beam ecosystem.

For now i would say that this is an acceptable solution. We need to provide a better solution for how to build, but what you have is probably the best solution so far.

1 Like