Supporting older versions of Elixir

I have once mentioned that Elixir should add to its ExDoc some tool to help us find which version it changed the signature of a function. Right now I am suffering with this :slight_smile: (I proposed some attrs like @since 1.40).

Here is the scenario: I have a library in hex junit-formatter that is being asked to remove the deprecation warnings of recent versions (namely the GenEvent thing). Well, my trouble is this: I NEED to support GenEvent in versions 1.2 and 1.3 but SHOULD use GenServer from version 1.4 and on. Most likely I will NEED to use GenServer in later versions.

I intend to support down to version 1.2 of Elixir. Though many would say this is “ancient”… I feel that as a library maintainer I don’t want to force users to update their whole runtime. Reasons might differ as to why one would like to keep on Elixir 1.2 and I won’t claim they are fools or anything of the like.

Well, with asdf in hands I started drafting a solution. Started looking into the System.build_info() and Version function and module. They also differ from version to version :slight_smile: The one way to find this out was checking each version with asdf.

So here is my question to all you library developers out there: how do YOU tackle this requirement?

I think I will stick a huge if in my ExUnit.Formatter like:

  %{version: version} = System.build_info
  {:ok, current_version} = Version.parse(version)
  {:ok, version_140} = Version.parse("1.4.0")

if Version.compare(current_version, version_140) != :lt do
  # GenServer implementation
else
  # Practically the same implementation for GenEvent
end

If I truly intend to remove all warnings then I will need to do that per major version (there were other functions deprecated like Atom.to_char_list and so on…

This is far away from good code though…

2 Likes

If you are going to write the code to use a GenServer, why can’t the 1.2 and 1.3 code just use the GenServer as well? Also keep in mind that GenEvent is currently deprecated. It has not actually been removed and is still there in 1.5. I’m not sure when it will actually be removed.

That is exactly because GenEvent is deprecated that I am doing all of this. Using a GenServer all the way up to 1.2 is failing tests. So, I thought about keeping GenEvent for older versions and going with GenServer for 1.4+.

Well, you will need to write tests for the GenServer implementation, so instead of maintaining 2 code bases and 2 test suites (one for GenEvent and another for GenServer), you should just scrap the GenEvent code and use GenServer for all versions of Elixir.

This has the benefit of being easier to maintain as well. It is a lower barrier of entry for potential contributors.

The ExUnit.Formatter tests with GenServer passes just fine from version 1.4+ :slight_smile:

I would like to keep a single implementation and I understand your reasoning. But it seems to me here that I will have to keep the GenEvent implementation for 1.2 and 1.3 because of ExUnit.

Here are the docs for the ExUnit.Formatter:

  • 1.2 - GenEvent
  • 1.3 - GenEvent
  • 1.4 - GenServer
  • 1.5 - GenServer

So, I have to keep both. My question is how to do this simply and cleanly here.

@cs-victor-nascimento: Don’t see a good reason to support older Elixir versions in same package release. Any break change will be made in next major Elixir version, so you do not need to care about it.

Upgrading Elixir is not something really important unless there are breaking changes. Developer will only see more warnings during compilation of your library and he can easily switch between multiple Elixir versions using version manager tool like asdf.

You can publish same package in two versions with major number change. Older one will support GenEvent and you can still develop it adding for example security updates. Second version will depend on higher Elixir versions. In that way you do not need any change in code other than change GenEvent to GenServer in next major version.

1 Like

You can use System.version instead of build_info. Regarding the support of older Elixir versions, I would say those users can always grab an older version of junit_formatter too.

And regarding GenEvent, we will support it until Elixir v2.0. So you should not be worried about it being removed anytime soon.

2 Likes