瀏覽代碼

Fix ordering of overlays and overlay vars in Relx

Specifically, this impacts profiles. It appears that relx as a whole
requires its configuration to be merged in one tuple order (New takes
precedence over Old), whereas the overlays require the opposite (Old
takes precedence over New) since the operation order on disk is
important to work well.

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 #1609)

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

Overlay vars of profiles are also checked to be working fine, along with
a test.

This fixes #1247 and #1609
pull/1610/head
Fred Hebert 7 年之前
父節點
當前提交
bc2f062200
共有 2 個檔案被更改,包括 38 行新增8 行删除
  1. +5
    -1
      src/rebar_opts.erl
  2. +33
    -7
      test/rebar_release_SUITE.erl

+ 5
- 1
src/rebar_opts.erl 查看文件

@ -132,7 +132,11 @@ merge_opt(mib_first_files, Value, Value) ->
merge_opt(mib_first_files, NewValue, OldValue) -> merge_opt(mib_first_files, NewValue, OldValue) ->
OldValue ++ NewValue; OldValue ++ NewValue;
merge_opt(relx, NewValue, OldValue) -> merge_opt(relx, NewValue, OldValue) ->
rebar_utils:tup_umerge(OldValue, NewValue);
Partition = fun(C) -> is_tuple(C) andalso element(1, C) =:= overlay end,
{NewOverlays, NewOther} = lists:partition(Partition, NewValue),
{OldOverlays, OldOther} = lists:partition(Partition, OldValue),
rebar_utils:tup_umerge(NewOverlays, OldOverlays)
++ rebar_utils:tup_umerge(OldOther, NewOther);
merge_opt(Key, NewValue, OldValue) merge_opt(Key, NewValue, OldValue)
when Key == erl_opts; Key == eunit_compile_opts; Key == ct_compile_opts -> when Key == erl_opts; Key == eunit_compile_opts; Key == ct_compile_opts ->
merge_erl_opts(lists:reverse(OldValue), NewValue); merge_erl_opts(lists:reverse(OldValue), NewValue);

+ 33
- 7
test/rebar_release_SUITE.erl 查看文件

@ -200,13 +200,34 @@ profile_overlays(Config) ->
AppDir = ?config(apps, Config), AppDir = ?config(apps, Config),
Name = ?config(name, Config), Name = ?config(name, Config),
Vsn = "1.0.0", 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} = {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]), ReleaseDir = filename:join([AppDir, "./_build/prod/rel/", Name]),
@ -216,7 +237,12 @@ profile_overlays(Config) ->
{ok, [{release, list_to_atom(Name), Vsn, false}, {ok, [{release, list_to_atom(Name), Vsn, false},
{dir, filename:join(ReleaseDir, "otherrandomdir")}, {dir, filename:join(ReleaseDir, "otherrandomdir")},
{dir, filename:join(ReleaseDir, "randomdir")}]} {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) -> profile_overlay_merge (_Config) ->
% when profile and relx overlays both exist, the profile overlays should be % when profile and relx overlays both exist, the profile overlays should be

Loading…
取消
儲存