dialyxir
dialyxir copied to clipboard
Elixir 1.15 + Umbrella Project + Dialyzer issues
Environment
- Elixir & Erlang/OTP versions (elixir --version):
Elixir 1.15.0 (compiled with Erlang/OTP 25)
- Which version of Dialyxir are you using? (cat mix.lock | grep dialyxir):
"dialyxir": {:hex, :dialyxir, "1.3.0", "fd1672f0922b7648ff9ce7b1b26fcf0ef56dda964a459892ad15f6b4410b5284", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "00b2a4bcd6aa8db9dcb0b38c1225b7277dca9bc370b6438715667071a304696f"},
Current behavior
I have an umbrella project with Phoenix + LiveView that worked well on 1.14 and is broken in 1.15. To reproduce it's pretty easy:
- mix phx.new --umbrella example
- add
{:dialyxir, "~> 1.0", only: [:dev, :test], runtime: false}to the deps mix do deps.get, compilemix dialyzer
Looking up modules in dialyxir_erlang-25.3.2.2_elixir-1.15.0_deps-dev.plt
** (UndefinedFunctionError) function :dialyzer_plt.included_files/1 is undefined (module :dialyzer_plt is not available)
(dialyzer 5.0.5) :dialyzer_plt.included_files(~c"/home/elliott/Code/dialyzer_new_umbrella/_build/dev/dialyxir_erlang-25.3.2.2_elixir-1.15.0_deps-dev.plt")
(dialyzer 5.0.5) dialyzer.erl:228: :dialyzer.plt_info/1
(dialyxir 1.3.0) lib/dialyxir/plt.ex:243: Dialyxir.Plt.plt_files/1
(dialyxir 1.3.0) lib/dialyxir/plt.ex:16: Dialyxir.Plt.find_plts/3
(dialyxir 1.3.0) lib/mix/tasks/dialyzer.ex:254: Mix.Tasks.Dialyzer.check_plt/1
(dialyxir 1.3.0) lib/mix/tasks/dialyzer.ex:174: Mix.Tasks.Dialyzer.run/1
(mix 1.15.0) lib/mix/task.ex:447: anonymous fn/3 in Mix.Task.run_task/5
(mix 1.15.0) lib/mix/cli.ex:92: Mix.CLI.run_task/2
This worked with 1.14. I've put together an example repo: https://github.com/elliottneilclark/dialyzer_new_umbrella that will fail with 1.15.0 and work with the latest 1.14. If you already use nix it should be set up to reproduce. https://github.com/elliottneilclark/dialyzer_new_umbrella/blob/830f9c867a1938af97e6e56357fe7d19f2a6b04b/flake.nix#L38 You can change that line to see it work in 1.14
If I add dialyxir as a dependency to each sub-app, it seems to work, however, it complains LOUDLY about missing deps.
Expected behavior
I would expect to be able to upgrade from 1.14 to 1.15 successfully.
https://gist.github.com/elliottneilclark/33cb21c37be951a38268217a8a2e1f1c
Yeah, I was looking into this error that we had first in the GitHub Action after upgrade our application. 🥴
I'm using Elixir 1.15.0 (OTP 26) installed by ASDF.
Reading about the new elixir release, mention this:
After set this in my mix.exs I was able to run dialyzer in my local and in the CI. Although I got this errors:
I prefer keeping that setting safer. I did find that adding:
{:dialyxir, "~> 1.3", only: [:dev, :test], runtime: false},
into every sub-application worked around everything. See this example commit: https://github.com/elliottneilclark/dialyzer_new_umbrella/commit/aaba7c648ed6de065d424b751526c21ea9873f6a I'm not sure why credo can work when added to the umbrella, but dialyzer fails.
Dialyxir has a runtime dependency on :dialyzer and the dialyxir strategy for umbrella apps is actually to dialyze each application separately, so we have to be sure :dialyzer is included in extra_applications for each child in some way. I'd prefer to address this by changing this design, it would address several other issues. https://github.com/jeremyjh/dialyxir/issues?q=is%3Aissue+is%3Aopen+umbrella
@elliottneilclark Adding to each umbrella app seems to fix the UndefinedFunctionError error, but I still get this big list of "dependency list may be incomplete". Is that what you're seeing as well?
@denvaar Yep that's what I see as well. I think the warnings are from #502
Curious, after add dialyzer as dep in every umbrella app I got same errors
I came here having a similar problem with elixir 1.15.2 and erlang 26.0.2. After reading this issue I tried adding {:dialyxir, "~> 1.3", only: [:dev, :test], runtime: false} to each sub app and that appears to have solved the issue. My error was different though, and I figured I'd share it here in case it's helpful. When I run mix dialyzer from the umbrella root I got this odd error:
$ mix dialyzer
** (UndefinedFunctionError) function Dialyxir.Output.info/1 is undefined (module Dialyxir.Output is not available)
(dialyxir 1.3.0) Dialyxir.Output.info("Finding suitable PLTs")
(dialyxir 1.3.0) lib/mix/tasks/dialyzer.ex:172: Mix.Tasks.Dialyzer.run/1
(mix 1.15.2) lib/mix/task.ex:447: anonymous fn/3 in Mix.Task.run_task/5
(mix 1.15.2) lib/mix/cli.ex:92: Mix.CLI.run_task/2
Error: exit status 1
@Toady00 Did you try adding prune_code_paths: false in your mix.exs? For me, dialyzer works, but have a looooot of warnings and errors
@carlogilmar I didn't want to disable that functionality if I could help it so no, I didn't add that. But it works as expected adding it to every child's mix.exs
After reading this issue I tried adding {:dialyxir, "~> 1.3", only: [:dev, :test], runtime: false} to each sub app and that appears to have solved the issue
Came to comment this also solved the issue for us (umbrella app). Thanks!
This seems to be fixed with Elixir 1.15.6, the workaround is not needed anymore for umbrella projects.
I'm seeing the same
Unknown application :debugger
Unknown application :hex
when running dialyxir on ElixirLS repo. Those apps are explicitly listed in plt_add_apps