elixirc_paths and deps including test libs separate from prod builds

20 views
Skip to first unread message

Brandon Gillespie

unread,
Mar 16, 2023, 4:03:35 PM3/16/23
to elixir-lang-core

Need:

  • I want to provide factories using ex_machina in my library projects that come into other projects as deps
  • I want to use ex_machina, (so please, don't recommend not using it, I've heard that many times)
  • I don't want ex_machina to appear as a dependency to production
  • I want to do this with umbrella apps

I've bumped into this several times where I'd like to have a separate section of library/code available in a dep, which is only in-scope for :test builds, not :prod.

But deps are always compiled in :prod scope, so it doesn't matter what else you do.

The general consensus from what I've found and observed in other libs is to just put test modules into the production code tree. This is ... not great.

The typical other response is "don't make your factories use ex_machina, build them yourself" which is a myopic response, and dismisses the actual problem, covering it up with a band-aid.

As I've hunted this out I tried playing around with elixirc_paths from the parent project (the outer project including the dep), but it doesn't want relative directories, and doesn't like things within the deps folder? (In an umbrella I have to do ../../deps/..., which then errors out — I saw this ticket: https://github.com/elixir-lang/elixir/issues/10016).

I wonder, however, why deps aren't recompiled for test using :test elixirc_paths? I presume there's a really good reason for not doing it — probably everything would break because few deps include the test folders in the package.

Thus, separately, is there a way for me to spec a dep's folder in-scope for the parent application?

Specific scenario:


dep-application:
  lib/std-prod-code.ex
  test/lib/factory-code.ex

umbrella-application
  apps/child-application/mix.exs


In `elixirc_paths(:test)` of the umbrella-application, is there a syntax/pathing/something that will allow me to bring dep-application/test/lib into scope for test compiles?

Because its an umbrella application "deps/dep-application/test/lib" doesn't bring anything in scope. If I do a relative path "../../deps/dep-application/test/lib" then I get the error:

** (Mix) Could not find source for "/home/git/umbrella-app/src/deps/rivet_ident/test/lib/ident_factory.ex". Make sure the :elixirc_paths configuration is a list of relative paths to the current project or absolute paths to external directories

What makes this curious is it gave a legitimate path to the file. If I vi that path, I edit the file. So I'm not sure why it effectively said "this thing I'm holding doesn't exist."

Is there a way to make this work without a bunch of hackery?

My fallback is to just manually copy the deps in, or add a symlink to the deps from the parent project, which is also kindof hacky.

-Brandon



José Valim

unread,
Mar 16, 2023, 7:00:44 PM3/16/23
to elixir-l...@googlegroups.com
You shouldn't need to bundle test code into your production code.

1. Deps are compiled in prod but in_umbrella deps are compiled in the same environment as the current project. You can achieve this by specifying the env option to the dependency, such as "env: Mix.env()", and it works for any dependency

2. You can also specify a dependency as only: :test

> So I'm not sure why it effectively said "this thing I'm holding doesn't exist."

That's now what it says. It says that it must be either relative from the current dir or absolute to anywhere. :)


--
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/55c8853f-8917-f464-756a-1fbde892d346%40cold.org.

Brandon Gillespie

unread,
Mar 17, 2023, 3:26:18 PM3/17/23
to elixir-l...@googlegroups.com
On 3/16/23 5:00 PM, José Valim wrote:

> You shouldn't need to bundle test code into your production code.
>
> 1. Deps are compiled in prod but in_umbrella deps are compiled in the
> same environment as the current project. You can achieve this by
> specifying the env option to the dependency, such as "env: Mix.env()",
> and it works for any dependency


Even when this is a library? So "your production code" becomes muddied.
I create a library, I post it to hex.pm, then another app uses this
library—how can it use the library's ex_machina test factories?


> > So I'm not sure why it effectively said "this thing I'm holding
> doesn't exist."
>
> That's now what it says. It says that it must be either relative from
> the current dir or absolute to anywhere. :)


But it is relative and that's my confusion :)

I gave it the path "../../deps/rivet_ident/test/lib" and it found the
actual factory, it then gave the absolute path to that factory as part
of the error, and the absolute path was correct, yet it said it couldn't
use it. This is what confused me.


-Brandon

José Valim

unread,
Mar 17, 2023, 3:47:23 PM3/17/23
to elixir-l...@googlegroups.com
Yes, even another library. You can run it in test while you are in test.

And the error message says it must be a relative path pointing inside the current directory, IIRC.

--
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.
Reply all
Reply to author
Forward
0 new messages