Skip to content

Commit

Permalink
Fix ordering of overlays and overlay vars in Relx
Browse files Browse the repository at this point in the history
This patch reorders overlay values such that the overlay of a profile
takes place *after* the basic overlay, ensuring that the profile actions
take place after the basic ones; this allows profiles to properly
overwrite files as expected (see erlang#1609)

This is done while adequately maintaining the order of operations that
were required as part of erlang#1563

Overlay vars of profiles are also checked to be taking the same profile
order, along with a test.

This fixes erlang#1247 and erlang#1609
  • Loading branch information
ferd committed Aug 15, 2017
1 parent 9c4e40d commit e6f0227
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 9 deletions.
2 changes: 1 addition & 1 deletion src/rebar_opts.erl
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ merge_opt(mib_first_files, Value, Value) ->
merge_opt(mib_first_files, NewValue, OldValue) ->
OldValue ++ NewValue;
merge_opt(relx, NewValue, OldValue) ->
rebar_utils:tup_umerge(OldValue, NewValue);
rebar_utils:tup_umerge(NewValue, OldValue);
merge_opt(Key, NewValue, OldValue)
when Key == erl_opts; Key == eunit_compile_opts; Key == ct_compile_opts ->
merge_erl_opts(lists:reverse(OldValue), NewValue);
Expand Down
7 changes: 6 additions & 1 deletion src/rebar_relx.erl
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ merge_overlays(Config) ->
lists:partition(fun(C) when element(1, C) =:= overlay -> true;
(_) -> false
end, Config),
{OverlayVars, NonOverlay} =
lists:partition(fun(C) when element(1, C) =:= overlay_vars -> true;
(_) -> false
end, Others),
%% Have profile overlay entries come before others to match how profiles work elsewhere
NewOverlay = lists:flatmap(fun({overlay, Overlay}) -> Overlay end, lists:reverse(Overlays)),
[{overlay, NewOverlay} | Others].
%% Prioritize older profile overlay_vars so that the newest ones are active
[{overlay, NewOverlay} | lists:reverse(OverlayVars, NonOverlay)].
40 changes: 33 additions & 7 deletions test/rebar_release_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -200,13 +200,34 @@ profile_overlays(Config) ->
AppDir = ?config(apps, Config),
Name = ?config(name, Config),
Vsn = "1.0.0",
file:write_file(filename:join(AppDir, "dev.file"), "dev.\n"),
file:write_file(filename:join(AppDir, "prod.file"), "prod.\n"),
file:write_file(filename:join(AppDir, "dev.vars"), "{env, \"dev\"}.\n"),
file:write_file(filename:join(AppDir, "prod.vars"), "{env, \"prod\"}.\n"),
{ok, RebarConfig} =
file:consult(rebar_test_utils:create_config(AppDir,
[{relx, [{release, {list_to_atom(Name), Vsn},
[list_to_atom(Name)]},
{overlay, [{mkdir, "randomdir"}]},
{lib_dirs, [AppDir]}]},
{profiles, [{prod, [{relx, [{overlay, [{mkdir, "otherrandomdir"}]}]}]}]}])),
file:consult(rebar_test_utils:create_config(AppDir,
%% Paths are relative, but to cwd in relx, not the project root as
%% seen by rebar3 (in non-test cases, they're the same).
%% Work around by being explicit.
[{relx, [{release, {list_to_atom(Name), Vsn},
[list_to_atom(Name)]},
{overlay_vars, filename:join(AppDir, "dev.vars")},
{overlay, [{mkdir, "randomdir"},
{copy, filename:join(AppDir,"./dev.file"), "profile.file"},
{copy, filename:join(AppDir,"./dev.file"), "{{env}}.file"},
{chmod, 8#00770, "profile.file"}]},
{lib_dirs, [AppDir]}]},
{profiles, [{prod,
[{relx, [
{overlay_vars, filename:join(AppDir, "prod.vars")},
{overlay, [{mkdir, "otherrandomdir"},
{copy, filename:join(AppDir, "./prod.file"), "{{env}}.file"},
{copy, filename:join(AppDir, "./prod.file"), "profile.file"},
{chmod, 8#00770, "profile.file"}]}

]}]
}]}
])),

ReleaseDir = filename:join([AppDir, "./_build/prod/rel/", Name]),

Expand All @@ -216,7 +237,12 @@ profile_overlays(Config) ->
{ok, [{release, list_to_atom(Name), Vsn, false},
{dir, filename:join(ReleaseDir, "otherrandomdir")},
{dir, filename:join(ReleaseDir, "randomdir")}]}
).
),
?assertMatch({ok,[prod]},
file:consult(filename:join(ReleaseDir, "profile.file"))),
?assertMatch({ok,[prod]},
file:consult(filename:join(ReleaseDir, "prod.file"))),
ok.

profile_overlay_merge (_Config) ->
% when profile and relx overlays both exist, the profile overlays should be
Expand Down

0 comments on commit e6f0227

Please sign in to comment.