Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 4 additions & 9 deletions lib/mix/lib/mix/dep.ex
Original file line number Diff line number Diff line change
Expand Up @@ -131,18 +131,13 @@ defmodule Mix.Dep do
for dep <- deps,
dep.app == app,
child <- dep.deps,
do: {child.app, Keyword.get(child.opts, :optional, false)},
do: {child.app, true},
into: %{}

Enum.map(children, fn %{app: app, opts: opts} = dep ->
# optional only matters at the top level. Any non-top level dependency
# that is optional and is still available means it has been fulfilled.
Enum.map(children, fn %{app: app} = dep ->
case top_level do
%{^app => optional} ->
%{dep | top_level: true, opts: Keyword.put(opts, :optional, optional)}

%{} ->
%{dep | top_level: false, opts: Keyword.delete(opts, :optional)}
%{^app => _} -> %{dep | top_level: true}
%{} -> %{dep | top_level: false}
end
end)
end
Expand Down
7 changes: 3 additions & 4 deletions lib/mix/lib/mix/tasks/compile.app.ex
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ defmodule Mix.Tasks.Compile.App do
apps =
properties
|> Keyword.get(:applications)
|> Kernel.||(apps_from_prod_non_optional_deps(properties, config))
|> Kernel.||(apps_from_prod_deps(properties, config))
|> normalize_apps(extra, config)

Keyword.put(properties, :applications, apps)
Expand Down Expand Up @@ -313,12 +313,11 @@ defmodule Mix.Tasks.Compile.App do
end)
end

defp apps_from_prod_non_optional_deps(properties, config) do
defp apps_from_prod_deps(properties, config) do
included_applications = Keyword.get(properties, :included_applications, [])
non_runtime_deps = non_runtime_deps(config)

for %{app: app, opts: opts, top_level: true} <- Mix.Dep.cached(),
not Keyword.get(opts, :optional, false),
for %{app: app, top_level: true} <- Mix.Dep.cached(),
not Map.has_key?(non_runtime_deps, app),
app not in included_applications,
do: app
Expand Down
25 changes: 0 additions & 25 deletions lib/mix/test/mix/dep_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -525,31 +525,6 @@ defmodule Mix.DepTest do
end)
end

test "nested deps with optional matching" do
Process.put(:custom_deps_git_repo_opts, optional: true)

# deps_repo brings git_repo but it is optional
deps = [
{:deps_repo, "0.1.0", path: "custom/deps_repo"},
{:git_repo, "0.1.0", git: MixTest.Case.fixture_path("git_repo")}
]

with_deps(deps, fn ->
in_fixture("deps_status", fn ->
File.mkdir_p!("custom/deps_repo/lib")

File.write!("custom/deps_repo/lib/a.ex", """
# Check that the child dependency is top_level and optional
[%Mix.Dep{app: :git_repo, top_level: true, opts: opts}] = Mix.Dep.cached()
true = Keyword.fetch!(opts, :optional)
""")

Mix.Tasks.Deps.Get.run([])
Mix.Tasks.Deps.Compile.run([])
end)
end)
end

test "nested deps considers runtime from current app" do
Process.put(:custom_deps_git_repo_opts, runtime: false)

Expand Down
2 changes: 1 addition & 1 deletion lib/mix/test/mix/tasks/compile.app_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ defmodule Mix.Tasks.Compile.AppTest do
properties = parse_resource_file(:custom_deps)

assert properties[:applications] ==
[:kernel, :stdlib, :elixir, :logger, :ok1, :ok3, :ok4, :ok7]
[:kernel, :stdlib, :elixir, :logger, :ok1, :ok3, :ok4, :ok6, :ok7]
end)
end

Expand Down