Getting `Mix.Project` to tell me about the test environment

How do I arrange for Mix.Project to use the test environment for functions like in_project or compile_path?


I’m writing a Phoenix dashboard that summarizes structures defined in “.ex” (not “.exs”) files under <project>/test. Those structures are used to support tests.

The dashboard tracks changes to such structures in the usual way (if the source changes, the app notices, provokes a mix compile and then loads the resulting “.beam” files).

From reading the exsync code, which is nice, I see how to do those things for the default (“dev”) environment. But I want to point to a project directory and ask Mix modules to tell me where the “test” environment “.beam” files live.

That is, I want some way to make something like this:

iex(30)> Mix.Project.in_project(:exsync, 
     "/Users/bem/src/watched_app", 
      fn _ -> Mix.Project.compile_path end)
"/Users/bem/src/watched_app/_build/dev/lib/exsync/ebin"

… provide _build/test/... instead of _build/dev/...

Similarly, I want to ask Mix for a directory to watch for changes and get “/Users/bem/watched_app/test” instead of “/Users/bem/watched_app/lib”.

2 Likes

Are the files in a particular directory? If they were, you could accomplish what you’re describing by adding them to elixirc_paths in your mix.exs:

  defp elixirc_paths(:test), do: ["lib", "test/support", "test/something"]
  defp elixirc_paths(:dev), do: ["lib", "test/something"]
  defp elixirc_paths(_), do: ["lib"]
1 Like

The answer is Mix.env/1:

iex(6)> Mix.Project.compile_path
"/Users/bem/src/dsl_dashboard/_build/dev/lib/dsl_dashboard/ebin"
iex(7)> Mix.env(:test)
:ok
iex(8)> Mix.Project.compile_path
"/Users/bem/src/dsl_dashboard/_build/test/lib/dsl_dashboard/ebin"

Note, however, the warnings.

I think that might work, if I ran my :dsl_dashboard app with MIX_ENV=test mix phx.server. But I’m thinking that this might be Mother Nature’s way of saying “That thing you’re wanting to do with Mix? You don’t want to use Mix for that.”

(The underlying issue is that I what to track “.beam” files from under another project’s _build/test directory, load them, and then call a known function in certain of the updated modules. That’s just not what the Mix modules are about.)

Just a very blind shot in the dark but have you looked at Phoenix’s live reload functionality? Maybe it has good pointers.

I have. It’s more complicated than exsync. Exsync tells me what I need to do. I just need to override its use of Mix for configuration. Thanks.