Skip to content

Commit 4dd6c3c

Browse files
committed
Revert "Allow overriding specific dependencies in override (#15193)"
Hex uses the flag in a way that's not visibile to Mix, so we have false positives. Closes #15407. This reverts commit bc7af21.
1 parent 862ff78 commit 4dd6c3c

4 files changed

Lines changed: 62 additions & 229 deletions

File tree

lib/mix/lib/mix/dep.ex

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -343,14 +343,12 @@ defmodule Mix.Dep do
343343
"the dependency compile environment is outdated, please run \"#{mix_env_var()}mix deps.compile\""
344344
end
345345

346-
def format_status(%Mix.Dep{app: app, status: {:divergedreq, vsn, parent, other}} = dep) do
347-
override = if parent, do: [parent], else: true
348-
346+
def format_status(%Mix.Dep{app: app, status: {:divergedreq, vsn, other}} = dep) do
349347
"the dependency #{app} #{vsn}\n" <>
350348
dep_status(dep) <>
351349
"\n does not match the requirement specified\n" <>
352350
dep_status(other) <>
353-
"\n Ensure they match or specify one of the above in your deps and set \"override: #{inspect(override)}\""
351+
"\n Ensure they match or specify one of the above in your deps and set \"override: true\""
354352
end
355353

356354
def format_status(%Mix.Dep{app: app, status: {:divergedonly, other}} = dep) do
@@ -381,16 +379,14 @@ defmodule Mix.Dep do
381379
dep_status(other) <> "\n #{recommendation}"
382380
end
383381

384-
def format_status(%Mix.Dep{app: app, status: {:diverged, parent, other}} = dep) do
382+
def format_status(%Mix.Dep{app: app, status: {:diverged, other}} = dep) do
385383
"different specs were given for the #{app} app:\n" <>
386-
"#{dep_status(dep)}#{dep_status(other)}\n " <>
387-
override_diverge_recommendation(dep, parent, other)
384+
"#{dep_status(dep)}#{dep_status(other)}\n " <> override_diverge_recommendation(dep, other)
388385
end
389386

390-
def format_status(%Mix.Dep{app: app, status: {:overridden, parent, other}} = dep) do
387+
def format_status(%Mix.Dep{app: app, status: {:overridden, other}} = dep) do
391388
"the dependency #{app} in #{Path.relative_to_cwd(dep.from)} is overriding a child dependency:\n" <>
392-
"#{dep_status(dep)}#{dep_status(other)}\n " <>
393-
override_diverge_recommendation(dep, parent, other)
389+
"#{dep_status(dep)}#{dep_status(other)}\n " <> override_diverge_recommendation(dep, other)
394390
end
395391

396392
def format_status(%Mix.Dep{status: {:unavailable, _}, scm: scm}) do
@@ -409,14 +405,11 @@ defmodule Mix.Dep do
409405
"the dependency was built with another SCM, run \"#{mix_env_var()}mix deps.compile\""
410406
end
411407

412-
defp override_diverge_recommendation(dep, parent, other) do
408+
defp override_diverge_recommendation(dep, other) do
413409
if dep.opts[:from_umbrella] || other.opts[:from_umbrella] do
414410
"Please remove the conflicting options from your definition"
415411
else
416-
override = if parent, do: [parent], else: true
417-
418-
"Ensure they match or specify one of the above in your deps " <>
419-
"and set \"override: #{inspect(override)}\""
412+
"Ensure they match or specify one of the above in your deps and set \"override: true\""
420413
end
421414
end
422415

@@ -511,9 +504,9 @@ defmodule Mix.Dep do
511504
@doc """
512505
Checks if a dependency has diverged.
513506
"""
514-
def diverged?(%Mix.Dep{status: {:overridden, _, _}}), do: true
515-
def diverged?(%Mix.Dep{status: {:diverged, _, _}}), do: true
516-
def diverged?(%Mix.Dep{status: {:divergedreq, _, _, _}}), do: true
507+
def diverged?(%Mix.Dep{status: {:overridden, _}}), do: true
508+
def diverged?(%Mix.Dep{status: {:diverged, _}}), do: true
509+
def diverged?(%Mix.Dep{status: {:divergedreq, _, _}}), do: true
517510
def diverged?(%Mix.Dep{status: {:divergedonly, _}}), do: true
518511
def diverged?(%Mix.Dep{status: {:divergedtargets, _}}), do: true
519512
def diverged?(%Mix.Dep{}), do: false

lib/mix/lib/mix/dep/converger.ex

Lines changed: 42 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -73,31 +73,7 @@ defmodule Mix.Dep.Converger do
7373
def converge(acc, lock, opts, callback) do
7474
{deps, acc, lock} = all(acc, lock, opts, callback)
7575
if remote = Mix.RemoteConverger.get(), do: remote.post_converge()
76-
sorted_deps = topological_sort(deps)
77-
warn_on_unneeded_deps_overrides(sorted_deps)
78-
{sorted_deps, acc, lock}
79-
end
80-
81-
defp warn_on_unneeded_deps_overrides([%{app: app, opts: opts} = dep | rest]) do
82-
override = Keyword.get(opts, :override, false)
83-
84-
if is_list(override) do
85-
Enum.each(override, fn overridden_app ->
86-
# Since we used a topological sort, if someone depends on dep, it will come after dep
87-
with %{deps: deps} <- Enum.find(rest, &(&1.app == overridden_app)),
88-
true <- Enum.any?(deps, &(&1.app == app)) do
89-
:ok
90-
else
91-
_ -> warn_uneeded_override(dep, overridden_app)
92-
end
93-
end)
94-
end
95-
96-
warn_on_unneeded_deps_overrides(rest)
97-
end
98-
99-
defp warn_on_unneeded_deps_overrides([]) do
100-
:ok
76+
{topological_sort(deps), acc, lock}
10177
end
10278

10379
defp all(acc, lock, opts, callback) do
@@ -176,10 +152,11 @@ defmodule Mix.Dep.Converger do
176152

177153
defp init_all(main, apps, rest, lock, callback, locked?, env_target, cache) do
178154
state = %{locked?: locked?, env_target: env_target, cache: cache, callback: callback}
179-
{deps, _kept, _optional, rest, lock} = all(main, nil, [], [], [], apps, [], rest, lock, state)
155+
{deps, _kept, _optional, rest, lock} = all(main, [], [], [], apps, [], rest, lock, state)
156+
deps = Enum.reverse(deps)
180157
# When traversing dependencies, we keep skipped ones to
181158
# find conflicts. We remove them now after traversal.
182-
{deps, _} = deps |> Enum.reverse() |> Mix.Dep.Loader.split_by_env_and_target(env_target)
159+
{deps, _} = Mix.Dep.Loader.split_by_env_and_target(deps, env_target)
183160
{deps, rest, lock}
184161
end
185162

@@ -222,19 +199,19 @@ defmodule Mix.Dep.Converger do
222199
# Now, since "d" was specified in a parent project, no
223200
# exception is going to be raised since d is considered
224201
# to be the authoritative source.
225-
defp all([dep | t], parent, acc, kept, upper, breadths, optional, rest, lock, state) do
226-
case match_deps(parent, acc, upper, dep, state.env_target) do
202+
defp all([dep | t], acc, kept, upper, breadths, optional, rest, lock, state) do
203+
case match_deps(acc, upper, dep, state.env_target) do
227204
{:replace, dep, acc} ->
228-
all([dep | t], parent, acc, kept, upper, breadths, optional, rest, lock, state)
205+
all([dep | t], acc, kept, upper, breadths, optional, rest, lock, state)
229206

230207
{:match, acc} ->
231-
all(t, parent, acc, kept, upper, breadths, optional, rest, lock, state)
208+
all(t, acc, kept, upper, breadths, optional, rest, lock, state)
232209

233210
:skip ->
234211
# We still keep skipped dependencies around to detect conflicts.
235212
# They must be rejected after every all iteration but they are not
236213
# included in the list of kept dependencies.
237-
all(t, parent, [dep | acc], kept, upper, breadths, optional, rest, lock, state)
214+
all(t, [dep | acc], kept, upper, breadths, optional, rest, lock, state)
238215

239216
:nomatch ->
240217
{%{app: app, deps: deps, opts: opts} = dep, rest, lock} =
@@ -257,21 +234,19 @@ defmodule Mix.Dep.Converger do
257234
# no longer a dependency. Add it back for traversal.
258235
{no_longer_optional, optional} = Enum.split_with(optional, &(&1.app == app))
259236
t = no_longer_optional ++ t
260-
acc = [dep | acc]
261237

262238
{acc, kept, optional, rest, lock} =
263-
all(t, parent, acc, [dep.app | kept], upper, breadths, optional, rest, lock, state)
239+
all(t, [dep | acc], [dep.app | kept], upper, breadths, optional, rest, lock, state)
264240

265241
# Now traverse all parent dependencies and see if we have any optional dependency.
266242
{discarded, deps} = split_non_fulfilled_optional(deps, kept, opts[:from_umbrella])
267243

268244
new_breadths = Enum.map(deps, & &1.app) ++ breadths
269-
new_optional = discarded ++ optional
270-
all(deps, app, acc, kept, breadths, new_breadths, new_optional, rest, lock, state)
245+
all(deps, acc, kept, breadths, new_breadths, discarded ++ optional, rest, lock, state)
271246
end
272247
end
273248

274-
defp all([], _parent, acc, kept, _upper, _current, optional, rest, lock, _state) do
249+
defp all([], acc, kept, _upper, _current, optional, rest, lock, _state) do
275250
{acc, kept, optional, rest, lock}
276251
end
277252

@@ -289,7 +264,7 @@ defmodule Mix.Dep.Converger do
289264
# diverges is in the upper breadth, in those cases we
290265
# also check for the override option and mark the dependency
291266
# as overridden instead of diverged.
292-
defp match_deps(parent, list, upper_breadths, %Mix.Dep{app: app} = dep, env_target) do
267+
defp match_deps(list, upper_breadths, %Mix.Dep{app: app} = dep, env_target) do
293268
case Enum.split_while(list, &(&1.app != app)) do
294269
{_, []} ->
295270
if Mix.Dep.Loader.skip?(dep, env_target) do
@@ -308,84 +283,51 @@ defmodule Mix.Dep.Converger do
308283
)
309284
end
310285

311-
override = Keyword.get(other_opts, :override, false)
312-
313286
cond do
314-
in_upper? && override == true ->
287+
in_upper? && other_opts[:override] ->
315288
{:match, list}
316289

317290
not converge?(other, dep) ->
318-
if parent_overriden?(override, parent) do
319-
{:match, list}
320-
else
321-
tag = if in_upper?, do: :overridden, else: :diverged
322-
other = %{other | status: {tag, parent, dep}}
323-
{:match, pre ++ [other | pos]}
324-
end
291+
tag = if in_upper?, do: :overridden, else: :diverged
292+
other = %{other | status: {tag, dep}}
293+
{:match, pre ++ [other | pos]}
325294

326295
vsn = req_mismatch(other, dep) ->
327-
if parent_overriden?(override, parent) do
328-
{:match, list}
329-
else
330-
other = %{other | status: {:divergedreq, vsn, parent, dep}}
331-
{:match, pre ++ [other | pos]}
332-
end
296+
other = %{other | status: {:divergedreq, vsn, dep}}
297+
{:match, pre ++ [other | pos]}
333298

334299
not in_upper? and Mix.Dep.Loader.skip?(other, env_target) and
335300
not Mix.Dep.Loader.skip?(dep, env_target) ->
336-
dep
337-
|> merge_manager(other, in_upper?)
338-
|> with_matching_only_and_targets(other, in_upper?, override, parent, list, fn dep ->
339-
{:replace, dep, pre ++ pos}
340-
end)
301+
dep =
302+
dep
303+
|> with_matching_only_and_targets(other, in_upper?)
304+
|> merge_manager(other, in_upper?)
305+
306+
{:replace, dep, pre ++ pos}
341307

342308
true ->
343-
other
344-
|> merge_manager(dep, in_upper?)
345-
|> with_matching_only_and_targets(dep, in_upper?, override, parent, list, fn other ->
346-
{:match, pre ++ [other | pos]}
347-
end)
309+
other =
310+
other
311+
|> with_matching_only_and_targets(dep, in_upper?)
312+
|> merge_manager(dep, in_upper?)
313+
314+
{:match, pre ++ [other | pos]}
348315
end
349316
end
350317
end
351318

352-
defp parent_overriden?(list, app) when is_list(list), do: app in list
353-
defp parent_overriden?(_list, _app), do: false
354-
355-
defp with_matching_only_and_targets(other, dep, in_upper?, override, parent, list, callback) do
319+
defp with_matching_only_and_targets(other, dep, in_upper?) do
356320
%{opts: opts} = dep
357321

358322
if opts[:optional] do
359-
maybe_warn_uneeded_override(dep, override, parent)
360-
callback.(other)
323+
other
361324
else
362-
with {:ok, other} <- with_matching(other, :only, dep, opts, in_upper?),
363-
{:ok, other} <- with_matching(other, :targets, dep, opts, in_upper?) do
364-
maybe_warn_uneeded_override(dep, override, parent)
365-
callback.(other)
366-
else
367-
{:error, other} ->
368-
if parent_overriden?(override, parent) do
369-
{:match, list}
370-
else
371-
callback.(other)
372-
end
373-
end
374-
end
375-
end
376-
377-
defp maybe_warn_uneeded_override(dep, override, parent) do
378-
if parent_overriden?(override, parent) do
379-
warn_uneeded_override(dep, parent)
325+
other
326+
|> with_matching(:only, dep, opts, in_upper?)
327+
|> with_matching(:targets, dep, opts, in_upper?)
380328
end
381329
end
382330

383-
defp warn_uneeded_override(dep, parent) do
384-
Mix.shell().error(
385-
"Dependency #{Mix.Dep.format_dep(dep)} no longer requires :override on #{inspect(parent)}"
386-
)
387-
end
388-
389331
# When in_upper is true
390332
#
391333
# When a parent dependency specifies :only/:targets that is a
@@ -403,16 +345,16 @@ defmodule Mix.Dep.Converger do
403345
case Keyword.fetch(opts, key) do
404346
{:ok, value} ->
405347
case List.wrap(value) -- List.wrap(other_value) do
406-
[] -> {:ok, other}
407-
_ -> {:error, %{other | status: {:"diverged#{key}", dep}}}
348+
[] -> other
349+
_ -> %{other | status: {:"diverged#{key}", dep}}
408350
end
409351

410352
:error ->
411-
{:error, %{other | status: {:"diverged#{key}", dep}}}
353+
%{other | status: {:"diverged#{key}", dep}}
412354
end
413355

414356
:error ->
415-
{:ok, other}
357+
other
416358
end
417359
end
418360

@@ -427,9 +369,9 @@ defmodule Mix.Dep.Converger do
427369
value = Keyword.get(opts, key)
428370

429371
if other_value && value do
430-
{:ok, put_in(other.opts[key], Enum.uniq(List.wrap(other_value) ++ List.wrap(value)))}
372+
put_in(other.opts[key], Enum.uniq(List.wrap(other_value) ++ List.wrap(value)))
431373
else
432-
{:ok, %{other | opts: Keyword.delete(other_opts, key)}}
374+
%{other | opts: Keyword.delete(other_opts, key)}
433375
end
434376
end
435377

lib/mix/lib/mix/tasks/deps.ex

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,7 @@ defmodule Mix.Tasks.Deps do
9999
targets (like `[:host, :rpi3]`)
100100
101101
* `:override` - if set to `true` the dependency will override any other
102-
definitions of itself by other dependencies. From Elixir v1.20.0,
103-
this option can also be a list of dependency names, which allows you to
104-
override the definition of specific dependencies. If a dependency is not
105-
included in the list and an override is required, it will still fail.
106-
If a dependency is in the list and no longer necessary, then an error is emitted
102+
definitions of itself by other dependencies
107103
108104
* `:manager` - Mix can also compile Rebar3 and makefile projects
109105
and can fetch sub dependencies of Rebar3 projects. Mix will

0 commit comments

Comments
 (0)