diff --git a/src/rebar_opts.erl b/src/rebar_opts.erl index 8195a775..8b157e60 100644 --- a/src/rebar_opts.erl +++ b/src/rebar_opts.erl @@ -151,10 +151,10 @@ add_opt(Opts1, Opts2) -> del_opt(Opts1, Opts2) -> lists:foldl(fun({deps, Value}, OptsAcc) -> OldValue = ?MODULE:get(OptsAcc, {deps,default}, []), - set(OptsAcc, {deps,default}, OldValue--Value); + set(OptsAcc, {deps,default}, del_dep(OldValue, Value)); ({Key, Value}, OptsAcc) -> OldValue = ?MODULE:get(OptsAcc, Key, []), - set(OptsAcc, Key, OldValue--Value) + set(OptsAcc, Key, del_dep(OldValue, Value)) end, Opts2, Opts1). override_opt(Opts1, Opts2) -> @@ -164,6 +164,25 @@ override_opt(Opts1, Opts2) -> set(OptsAcc, Key, Value) end, Opts2, Opts1). +%% @private +del_dep(OldValue, [Value]) when is_atom(Value) -> + NewValue = lists:keydelete(atom_to_binary(Value, utf8), 1, OldValue), + del_dep(NewValue, OldValue, [Value]); +del_dep(OldValue, [{Value, _Version, _Source}]) -> + NewValue = lists:keydelete(atom_to_binary(Value, utf8), 1, OldValue), + del_dep(NewValue, OldValue, [{Value, _Version, _Source}]); +del_dep(OldValue, [Value|Values]) -> + NewValue = del_dep(del_dep(OldValue, [Value]), OldValue, [Value]), + del_dep(NewValue, Values). + +%% @private +%% If the initial deletion did not work remove it as always +%% to ensure rebar3 at least maintains its old behaviour. +del_dep(OldValue, OldValue, Value) -> + OldValue--Value; +del_dep(NewValue, _OldValue, _Value) -> + NewValue. + %% %% Function for dict:merge/3 (in merge_opts/2) to merge options by priority. %% diff --git a/test/rebar_compile_SUITE.erl b/test/rebar_compile_SUITE.erl index ed05bf48..36ee8b2f 100644 --- a/test/rebar_compile_SUITE.erl +++ b/test/rebar_compile_SUITE.erl @@ -28,7 +28,7 @@ all() -> umbrella_mib_first_test, only_default_transitive_deps, clean_all, clean_specific, profile_deps, deps_build_in_prod, only_deps, override_deps, git_subdir_deps, override_add_deps, override_del_deps, - override_opts, override_add_opts, override_del_opts, + override_del_pkg_deps, override_opts, override_add_opts, override_del_opts, apply_overrides_exactly_once, override_only_deps, profile_override_deps, profile_override_add_deps, profile_override_del_deps, profile_override_opts, profile_override_add_opts, profile_override_del_opts, @@ -1608,6 +1608,28 @@ override_del_deps(Config) -> {dep, "dep_d"}]} ). +override_del_pkg_deps(Config) -> + Deps = rebar_test_utils:expand_deps(pkg, [{"some_dep", "0.0.1", [{"other_dep", "0.0.1", []}]}]), + TopDeps = rebar_test_utils:top_level_deps(Deps), + + {_, PkgDeps} = rebar_test_utils:flat_deps(Deps), + mock_pkg_resource:mock([{pkgdeps, PkgDeps}]), + + RebarConfig = [ + {deps, TopDeps}, + {overrides, [ + {del, some_dep, [ + {deps, [other_dep]} + ]} + ]} + ], + + rebar_test_utils:run_and_check( + Config, RebarConfig, ["compile"], + {ok, [{dep, "some_dep"}, + {dep_not_exist, "other_dep"}]} + ). + override_opts(Config) -> AppsDir = ?config(apps, Config),