Is it possible to test the version of Elixir being used? How to support both use Mix.Config and import Config?

I recently submitted a PR for an open source Elixir project and the tests failed for older versions of Elixir because I (prematurely) changed the config files to use import Config instead of the older form use Mix.Config.

Elsewhere I have seen code that tests the version of Erlang:

    if System.otp_release() >= "22" do
        # do something
      # do something the old way

but is there something similar to testing the version of Elixir being used? Or is there some better way to write config files so they can run on older and newer versions of Elixir? The following results in a compile error when I use it inside config/config.exs:

if System.version() >= "1.9.0" do
  import Config
  use Mix.Config

You aware of the version module?


I noticed that, but I don’t think it solves for this case where I need to use Mix.Config or import Config based on the version.

Well. you cannot compare Elixir versions like that. It works for OTP versions because it is just the string represetntation of an integer. Look at that when using Semver2 versions

iex> "1.9.0" >= "1.13.0"

I wonder why you get a compile error.

Best way to check if a module is available is to do this IMO:

iex> Code.ensure_loaded(Config)
{:module, Config}

iex> function_exported? Config, :__info__, 1          

or you can just rely on the result of the first function call.

1 Like

if Code.ensure_loaded?(Config), do: ...

1 Like

There you go!

Unfortunately, this doesn’t work in config/config.exs:

if Code.ensure_loaded?(Config), do: import(Config)
if Code.ensure_loaded?(Mix.Config), do: use(Mix.Config)

results in:

** (CompileError) config/config.exs:39: undefined function config/2 (there is no such import)

I suspect this is because this is inside the config.exs and the app is bootstrapping…

I guess the easy answer is to pin the old version of the app to a tag and get on with life using newer versions…

1 Like

I thinking the error is actually because import is lexical, so in order for it to work you’d have to duplicate your entire config (which I wouldn’t recommend)

I forgot about this.

I have asked a very similar question not long ago.