.elixir-version File Proposal

suggestion
#1

.elixir-version File Proposal

When it comes to version management Elixir has quite a few options. The official site lists asdf, exenv, and kiex for Elixir, and kerl for Erlang. One thing Elixir version managers still lack is a common version file supported by all of them. In Ruby there is the .ruby-version file and all the major version managers support it. It would be nice to have a version file for Elixir that is version manager agnostic too. This has previously been proposed on the kiex issue tracker - https://github.com/taylor/kiex/issues/53, https://github.com/taylor/kiex/pull/54

The proposal on the kiex issue tracker seems like generally a good solution. To outline the specifics about my proposal for an .elixir-version file:

  • It would be a flat file named .elixir-version.
  • The file would contain a full Elixir version. No wildcards or partial versions. Think of it as the version manager equivalent of a mix.lock file, not a mix.exs file.
  • The could be used by any version manager but it would not enforce any specific behavior on the version manager. It’s simply indicates the Elixir version that should be used.

Note that we can’t use the version specified in mix.exs because there is no good way to get that version without already having a version of Elixir installed and available. We could use grep/sed/awk to extract the version, but it’s not required to be a full Elixir version, and manually extracting it from a mix.exs file seems a bit hacky.

What would it take to implement this? We are already pretty close.

  • exenv appears to already have support for an .elixir-version file that matches what I’ve described here. It’s likely no changes to exenv would be needed.
  • kiex would need some work done, but there is already a PR out to add support for this (https://github.com/taylor/kiex/pull/54).
  • asdf-elixir doesn’t have support for an .elixir-version file, but with legacy file support it would be trivial to add (I’m a maintainer of asdf).

I want to hear everyone’s thoughts on this. Specifically:

  • Is this something worth doing? If everyone is happy with the current state of things, there is no need trying to define a convention and then get it implemented.
  • Do you think this is a good approach? Maybe we shouldn’t have a separate file for specifying the full Elixir version?
  • Do you think there is anything my .elixir-version proposal that should be different or could be improved?
5 Likes
#2

This could improve the experience of newcomers, simplifying the Elixir versioning history, what is a good thing.

#3

My personal preference would be that version managers learn to read .tool-versions instead. I find when I want a specific Elixir version, I also want a specific Erlang version. In a phoenix project it’s useful to have node as well. If a particular tool only handles one of those, it should ignore the others.

I’ll also say, I’ve not had a problem with this sort of thing like I have in other languages. Everyone I know who writes Elixir uses asdf, even if they don’t use it for other languages.

20 Likes
#4

I think I like .tool-versions better. This elixir version file could be supported too with asdf but as a legacy method.

How would using mix.exs for the version know which OTP version we want Elixir compiled with, and what erts to use?

As far as I know you have to have both Elixir and Erlang to run Elixir projects, so it doesn’t make sense to me to have a file that only specified Elixir’s version.

2 Likes
#5

This is going to be another vote for .tool-versions for the reason that yuo generally want to lock Elixir projects not to just Elixir, but to Elixir and Erlang. And possibly node if you use it.

So, for Elxiir project I definitely always specify .tool-versions with erlang and elixir lines in it. Specifying just Elixir version is half of the solution.

Moreover, .tool-versions is already understood by version managers like asdf so is a good base to build upon.

4 Likes
#6

We do not know each other yet, but nice to meet you.


Now you know people who do not use asdf and instead I use Nix.

3 Likes
#7

Which again, at least I understand it, could as well fetch the versions needed from the .tool-versions file, assuming. You need to script it as I understand it, but it is possible…

#8

Yes it would be possible, but AFAIK it would be a little problematic to use with all Elixir versions as OOtB Nix supports only minor versions, not down to patch. But for sure it would be possible.

#9

It needs to have the OTP version specified too, Elixir gets some conditional new features depending on the OTP version plus the OTP API changes.

Ditto honestly.

Precisely.

That’s why nix is insufficient here, I not only specify precise elixir versions with otp versions but often grab master or another specific commit too.

1 Like
#10

Agree with tool versions as well. Elixir + Erlang + sometimes Node. Just makes more sense.

I can see an elixir versions file as long as the format includes both elixir and Erlang.

#11

Disclaimer: I’m the person that originally added support for multiple Elixir versions within Nix.

I wouldn’t say insufficient. Like @hauleth said, out of the box we only provide down to the minor version. I think that is fine for 90+% of people. If you want to do something more fine grained than that, we provide a nice little builder script where you can get any version of Elixir you wanted.

With that said, nix would (likely) never read the .tool-versions file itself. It would be up to a tool that converts your project into a nix file to do that. Be it rebar32nix (self plug), bundix, cabal2nix, etc.

1 Like
What kind of learning resources would you like to see made?
#12

Does it support per-directory versions with such a script? I have some old projects that broke upon Elixir 1.7 or so because of backwards incompatible change Elixir made to its macro syntax system (for I still have no clue what reason, but there’s still no defined elixir spec so I can’t point to why or why not it was good or bad) so I use versioning very specifically… ^.^;

Is nix able to convert a combined elixir/node/rust/c project into a nix setup with specific versions?

#13

Yes. Each project is meant to be reproducible (not necessarily down to the binary, but I believe there is work being done for that). So you define what a project looks like using the nix configuration language, and you can even specify the specific version of nixpkgs, even down to the commit, so that your project (assuming hardware isn’t an issue) will always be able to build and run.

Again, this would be down to the tool used to create the nix file. Though, there is nothing stopping you from doing it by hand. As an example, my own rebar32nix tool only cares about Erlang. I was going to do a similar tool for Elixir mix2nix, which would care about Elixir as well as the given OTP version you want to compile/run against. Then it may also be useful to either build into mix2nix or make a separate tool that would run against common tools built with Elixir. Most notably would be Phoenix, which would need to add nodejs support for building assets.

TL;DR: Yes. You can use Nix to build / bundle multiple languages and runtimes in a single project. It can be done by hand, or a tool can be written to do the work for you.

3 Likes
#14

Doc links for how to do the above? ^.^
I’d be happy to replace asdf if something is at least equally powerful and at least equally easy to use but it supports a lot more ‘things’. :slight_smile:

Right now I’m using asdf for everything from, let me grab my list, version handling for: clojure, cmake, crystal, dotnet-core, elixir, erlang, golang, gradle, java, kotlin, lfe, nim, nodejs, and ocaml (just to get opam really).

#15

I think we are getting a little away from the topic at hand (sorry everyone!). I will post a new thread in the next day or two with information on Nix. Or, if anyone else wants to start it, I will chime in where I can.

3 Likes
#16

That would be awesome! We need this well documented somewhere. I think that’s why asdf is so used is because it is so easy to use and so well documented. :slight_smile:

#17

I use Common Lisp’s ASDF, but I have no idea why anyone would use it for an Elixir project :sweat_smile:

(go for .tool-versions)

#18

This is going to be my last post on Nix in this thread (truly sorry for hijaking). But if anyone interested in Nix would like to PM me some questions that I can cover when I start that Nix thread, it could help with some content for it.

2 Likes
#19

we are talking about this asdf https://github.com/asdf-vm/asdf

edit: just noticed your emoji and that maybe you were joking :thinking: :slight_smile:

1 Like
#20

I think this pretty much settles it. I wasn’t thinking about the need to specify the OTP version as well. All Elixir projects need an Elixir version and an Erlang version. Some projects can get away with an implicit Erlang version, but ideally a version file should specify both.

Based on what I’ve heard here we should probably try to standardize on the .tool-versions file. Currently it’s only used by asdf, but nothing prevents other version managers from also using it. I’ll try to write something up in the coming weeks specifying how other version managers ought to use .tool-versions.

Going forward with asdf-elixir I may decide to add support for .elixir-version, but only for backwards compatibility with exenv. Although given what I’ve observed almost nobody is using it so I may not even do that. We can always revisit this later if the need arises.

3 Likes