-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Description
Environment
- Elixir version (elixir -v):
Erlang/OTP 18 [erts-7.2.1] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]
Elixir 1.3.0-rc.1 (9eb4781)
- Operating system:
El Capitan
Current behavior
There's an example app for this in josevalim/umbrella_sample#6.
Running against that branch, if I use a :path
dependency (set via the BAR_DEP
env var) and run mix test
, everything passes:
$ export BAR_DEP=path && elixir -v && rm -rf _build && mix test
Erlang/OTP 18 [erts-7.2.1] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]
Elixir 1.3.0-rc.1 (9eb4781)
"/Users/myron/code/umbrella_sample/apps/bar"
"/Users/myron/code/umbrella_sample/apps/bar"
"/Users/myron/code/umbrella_sample/apps/bar"
==> bar
Compiling 2 files (.ex)
Generated bar app
"/Users/myron/code/umbrella_sample/apps/bar"
==> foo
Compiling 1 file (.ex)
Generated foo app
==> bar
"/Users/myron/code/umbrella_sample/apps/bar"
.
Finished in 0.04 seconds
1 test, 0 failures
Randomized with seed 220497
"/Users/myron/code/umbrella_sample/apps/bar"
==> foo
.
Finished in 0.03 seconds
1 test, 0 failures
Randomized with seed 300412
(BTW, you can ignore the printed "/Users/myron/code/umbrella_sample/apps/bar"
bits: I added that to confirm that the path was in fact correct regardless of which directory is the current working dir).
But, if I use a :path
dependency, cd into apps/foo
, and run mix test
, if fails -- a module defined in the dependency's test/support
directory (which has been added to elixirc_paths
), it fails:
$ export BAR_DEP=path && elixir -v && rm -rf _build && (cd apps/foo && mix test)
Erlang/OTP 18 [erts-7.2.1] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]
Elixir 1.3.0-rc.1 (9eb4781)
"/Users/myron/code/umbrella_sample/apps/bar"
"/Users/myron/code/umbrella_sample/apps/bar"
==> bar
Compiling 1 file (.ex)
Generated bar app
==> foo
Compiling 1 file (.ex)
Generated foo app
** (CompileError) test/foo_test.exs:3: module Bar.TestHelper is not loaded and could not be found
(stdlib) erl_eval.erl:669: :erl_eval.do_apply/6
(elixir) lib/code.ex:363: Code.require_file/2
(elixir) lib/kernel/parallel_require.ex:56: anonymous fn/2 in Kernel.ParallelRequire.spawn_requires/5
If I instead use in_umbrella: true
for the bar
dependency, it works in both cases:
$ export BAR_DEP=umbrella && elixir -v && rm -rf _build && mix test
Erlang/OTP 18 [erts-7.2.1] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]
Elixir 1.3.0-rc.1 (9eb4781)
==> bar
Compiling 2 files (.ex)
Generated bar app
==> foo
Compiling 1 file (.ex)
Generated foo app
==> bar
.
Finished in 0.05 seconds
1 test, 0 failures
Randomized with seed 709339
==> foo
.
Finished in 0.02 seconds
1 test, 0 failures
Randomized with seed 792854
$ export BAR_DEP=umbrella && elixir -v && rm -rf _build && (cd apps/foo && mix test)
Erlang/OTP 18 [erts-7.2.1] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]
Elixir 1.3.0-rc.1 (9eb4781)
==> bar
Compiling 2 files (.ex)
Generated bar app
==> foo
Compiling 1 file (.ex)
Generated foo app
.
Finished in 0.02 seconds
1 test, 0 failures
Randomized with seed 590057
On 1.2, the same behavior I've described exists:
$ export BAR_DEP=path && elixir -v && rm -rf _build && mix test
Erlang/OTP 18 [erts-7.2.1] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]
Elixir 1.2.1
"/Users/myron/code/umbrella_sample/apps/bar"
"/Users/myron/code/umbrella_sample/apps/bar"
"/Users/myron/code/umbrella_sample/apps/bar"
==> bar
Compiled test/support/bar_helper.ex
Compiled lib/bar.ex
Generated bar app
"/Users/myron/code/umbrella_sample/apps/bar"
==> foo
Compiled lib/foo.ex
Generated foo app
Consolidated List.Chars
Consolidated Collectable
Consolidated String.Chars
Consolidated Enumerable
Consolidated IEx.Info
Consolidated Inspect
==> bar
"/Users/myron/code/umbrella_sample/apps/bar"
.
Finished in 0.07 seconds (0.07s on load, 0.00s on tests)
1 test, 0 failures
Randomized with seed 767345
"/Users/myron/code/umbrella_sample/apps/bar"
==> foo
.
Finished in 0.00 seconds
1 test, 0 failures
Randomized with seed 803551
$ export BAR_DEP=path && elixir -v && rm -rf _build && (cd apps/foo && mix test)
Erlang/OTP 18 [erts-7.2.1] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]
Elixir 1.2.1
"/Users/myron/code/umbrella_sample/apps/bar"
"/Users/myron/code/umbrella_sample/apps/bar"
==> bar
Compiled lib/bar.ex
Generated bar app
==> foo
Compiled lib/foo.ex
Generated foo app
Consolidated List.Chars
Consolidated Collectable
Consolidated String.Chars
Consolidated Enumerable
Consolidated IEx.Info
Consolidated Inspect
** (CompileError) test/foo_test.exs:3: module Bar.TestHelper is not loaded and could not be found
$ export BAR_DEP=umbrella && elixir -v && rm -rf _build && mix test
Erlang/OTP 18 [erts-7.2.1] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]
Elixir 1.2.1
==> bar
Compiled test/support/bar_helper.ex
Compiled lib/bar.ex
Generated bar app
==> foo
Compiled lib/foo.ex
Generated foo app
Consolidated List.Chars
Consolidated Collectable
Consolidated String.Chars
Consolidated Enumerable
Consolidated IEx.Info
Consolidated Inspect
==> bar
.
Finished in 0.06 seconds (0.06s on load, 0.00s on tests)
1 test, 0 failures
Randomized with seed 170481
==> foo
.
Finished in 0.00 seconds
1 test, 0 failures
Randomized with seed 205215
$ export BAR_DEP=umbrella && elixir -v && rm -rf _build && (cd apps/foo && mix test)
Erlang/OTP 18 [erts-7.2.1] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]
Elixir 1.2.1
==> bar
Compiled test/support/bar_helper.ex
Compiled lib/bar.ex
Generated bar app
==> foo
Compiled lib/foo.ex
Generated foo app
Consolidated List.Chars
Consolidated String.Chars
Consolidated Collectable
Consolidated Enumerable
Consolidated IEx.Info
Consolidated Inspect
.
Finished in 0.05 seconds (0.05s on load, 0.00s on tests)
1 test, 0 failures
Randomized with seed 953446
However, there is a noticeable difference in behavior between 1.2 and 1.3. In 1.2, if you do mix test
and then do cd apps/foo && mix test
, it works:
xport BAR_DEP=path && elixir -v && rm -rf _build && mix test && (cd apps/foo && mix test)
Erlang/OTP 18 [erts-7.2.1] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]
Elixir 1.2.1
"/Users/myron/code/umbrella_sample/apps/bar"
"/Users/myron/code/umbrella_sample/apps/bar"
"/Users/myron/code/umbrella_sample/apps/bar"
==> bar
Compiled test/support/bar_helper.ex
Compiled lib/bar.ex
Generated bar app
"/Users/myron/code/umbrella_sample/apps/bar"
==> foo
Compiled lib/foo.ex
Generated foo app
Consolidated List.Chars
Consolidated String.Chars
Consolidated Collectable
Consolidated Enumerable
Consolidated IEx.Info
Consolidated Inspect
==> bar
"/Users/myron/code/umbrella_sample/apps/bar"
.
Finished in 0.07 seconds (0.07s on load, 0.00s on tests)
1 test, 0 failures
Randomized with seed 576670
"/Users/myron/code/umbrella_sample/apps/bar"
==> foo
.
Finished in 0.00 seconds
1 test, 0 failures
Randomized with seed 608613
"/Users/myron/code/umbrella_sample/apps/bar"
"/Users/myron/code/umbrella_sample/apps/bar"
Compiled lib/foo.ex
Generated foo app
Consolidated List.Chars
Consolidated Collectable
Consolidated String.Chars
Consolidated Enumerable
Consolidated IEx.Info
Consolidated Inspect
.
Finished in 0.05 seconds (0.05s on load, 0.00s on tests)
1 test, 0 failures
Randomized with seed 525439
...so the act of first running mix test
at the umbrella root fixes it. But when I do that on 1.3, it still does not work when I'm in the child app directory:
$ export BAR_DEP=path && elixir -v && rm -rf _build && mix test && (cd apps/foo && mix test)
Erlang/OTP 18 [erts-7.2.1] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]
Elixir 1.3.0-rc.1 (9eb4781)
"/Users/myron/code/umbrella_sample/apps/bar"
"/Users/myron/code/umbrella_sample/apps/bar"
"/Users/myron/code/umbrella_sample/apps/bar"
==> bar
Compiling 2 files (.ex)
Generated bar app
"/Users/myron/code/umbrella_sample/apps/bar"
==> foo
Compiling 1 file (.ex)
Generated foo app
==> bar
"/Users/myron/code/umbrella_sample/apps/bar"
.
Finished in 0.04 seconds
1 test, 0 failures
Randomized with seed 886356
"/Users/myron/code/umbrella_sample/apps/bar"
==> foo
.
Finished in 0.02 seconds
1 test, 0 failures
Randomized with seed 951032
"/Users/myron/code/umbrella_sample/apps/bar"
"/Users/myron/code/umbrella_sample/apps/bar"
==> bar
Generated bar app
==> foo
** (CompileError) test/foo_test.exs:3: module Bar.TestHelper is not loaded and could not be found
(stdlib) erl_eval.erl:669: :erl_eval.do_apply/6
(elixir) lib/code.ex:363: Code.require_file/2
(elixir) lib/kernel/parallel_require.ex:56: anonymous fn/2 in Kernel.ParallelRequire.spawn_ruires/5
Sorry if that's too much detail; I spent many hours trimming my large umbrella project into something small and reproducible here, and only figured out that our use of :path
dependencies was causing the problem. As it so happens, we're only using :path
as a way to work around an issue with :in_umbrella
that I brought up on the mailing list and that, from what I understand, is fixed in Elixir 1.3, so we should be able to switch back to :in_umbrella
to work around this problem.
Still, the behavior of :path
dependencies is surprising; it seems like :elixirc_paths
in them should work fine.
Expected behavior
The :elixirc_paths
option should work on dependencies regardless of if the dependency is specified as an :in_umbrella
dependency or a :path
dependency. It should work both from the root project directory and from the directory of one of the child apps.