Only fetch deps compatible for a specific version of Elixir

I’m testing a library with multiple versions of Elixir on my CI. One of my dependencies is specified as a range.

{:poison, ">= 3.1.0 and < 5.0.0", optional: true}

Poison 4.0 is compatible with Elixir 1.6+ while Poison 3.1 is compatible with Elixir 1.3+. When my CI attempts to test in an Elixir 1.3 environment it fails because it’s trying to fetch Poison 4.0.

Is there any way to get around this?

I do fear you have to do it like this:

{:poison, cond do           
  Version.match?(System.version, "~> 1.6") -> ">= 3.1.0 and < 5.0.0"
  Version.match?(System.version, "~> 1.3") -> ">= 3.1.0 and < 4.0.0"
end, optional: true}

Any idea how would handle reporting this?

Plug uses a different lock file to test with older dependencies:

defmodule Plug.MixProject do
  use Mix.Project

  # ...
  def project do
      # ...
      lockfile: lockfile(),
      # ...

  defp lockfile() do
    case System.get_env("COWBOY_VERSION") do
      "1" <> _ -> "mix-cowboy1.lock"
      _ -> "mix.lock"

Are you able to build a different lockfile using mix or will I have to handle it manually?

I would update mix.exs and then run mix deps.get to generate the lock file: {:poison, ">= 3.1.0 and < 4.0.0", optional: true}

Then I can rename the lock file, and revert changes on mix.lock and mix.exs.

Got it figured out! Thanks @NobbZ and @danschultzer for your help! Went with a combination of your two approaches.

For reference:


Hmmm, I wonder if we could add this as tip for library maintainers. I’m not sure what the best place for that would be. Does anyone know?

1 Like

This is where I’ve seen library guidelines before: