Maybe improve Mix.Utils.extract_files?

26 views
Skip to first unread message

Vanja Radovanović

unread,
Oct 1, 2019, 6:08:39 AM10/1/19
to elixir-lang-core
In the project I'm working on, we have a bunch of tests that could share code among them, e.g. to build common test data, some validations, setup etc.

As per https://stackoverflow.com/questions/30652439/importing-test-code-in-elixir-unit-test, a simple way of doing that was to require such files explicitly, in test modules.
But that soon became too much repetition and manual stitching.

The most common ones could easily go to `test/support` and we did so initially, making them available in tests via
defp elixirc_paths(env) when env in [:test, :ci], do: ["lib", "test/support"]
in `mix.exs`. We noticed that while doing work inside a context, the shared test code actually belongs to that context only.
So putting all such shared code in one big bucket wasn't a nice solution.

A simple fix was to just do 
defp elixirc_paths(env) when env in [:test, :ci], do: ["lib", "test"]
which would find all the files to compile for tests, regardless of their nested path.
And this is fine as well, but has a bit of a downside, there's no convention for putting such shared code, which may be a good or a bad thing :)

In any case, what we aimed for was to have something like this:
defp elixirc_paths(env) when env in [:test, :ci], do: ["lib", "test/**/support"]
which would have the added convention of putting such files in support folder for each context in tests.
That unfortunately doesn't work.

Due to usage of `:elixir_utils.read_file_type(path)` it wasn't able to parse the glob pattern given in the mix.exs.

A simple fix would be:
  def extract_files(paths, pattern) do
    paths
   
|> Enum.filter(& &1 && &1 != "")
   
|> Enum.flat_map(&Path.wildcard(&1))
   
|> Enum.flat_map(fn path ->
     
case :elixir_utils.read_file_type(path) do
       
{:ok, :directory} -> Path.wildcard("#{path}/**/#{pattern}")
       
{:ok, :regular} -> [path]
        _
-> []
     
end
   
end)
   
|> Enum.uniq()
 
end

I even have the related tests ready to make the PR.
But, was just wondering, is it something that makes sense to support?

Kind regards,
Vanja


José Valim

unread,
Oct 1, 2019, 6:12:08 AM10/1/19
to elixir-l...@googlegroups.com
extract_files is used in many places so we would need to carefully assess the impact of said change. That said, couldn't you write it as:

defp elixirc_paths(env) when env in [:test, :ci], do: ["lib"] ++ Path.wildcard("test/**/support")

It would work today and there would be no need to change Elixir.

José Valim
Skype: jv.ptec
Founder and Director of R&D


--
You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/da4d5e91-4a9c-44d9-9768-8b5638af4c96%40googlegroups.com.

Vanja Radovanović

unread,
Oct 1, 2019, 6:23:48 AM10/1/19
to elixir-lang-core
Indeed, works as advertised :-)
Yep, that would solve the immediate problem!

As for supporting glob in elixirc_paths, if you decide it makes sense at one point, I'm open for lending a hand.
Thank you!
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-l...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages