aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTristan Sloughter <[email protected]>2015-04-28 22:36:44 -0500
committerTristan Sloughter <[email protected]>2015-05-08 11:16:53 -0500
commit88d1f29257869b0de9369881236477163804125a (patch)
treec14b95ae8efdebcf074d314b6b0afb662f3454fb
parenta36609536aaf7d98b5bd5d3364cab739dc6689b5 (diff)
downloadrelx-88d1f29257869b0de9369881236477163804125a.tar.gz
relx-88d1f29257869b0de9369881236477163804125a.tar.bz2
relx-88d1f29257869b0de9369881236477163804125a.zip
use mustache instead of erlydtl for overlays
-rwxr-xr-xpriv/templates/bin (renamed from priv/templates/bin.dtl)0
-rw-r--r--priv/templates/bin_windows (renamed from priv/templates/bin_windows.dtl)0
-rw-r--r--priv/templates/erl_ini (renamed from priv/templates/erl_ini.dtl)0
-rw-r--r--priv/templates/erl_script (renamed from priv/templates/erl_script.dtl)0
-rwxr-xr-xpriv/templates/extended_bin (renamed from priv/templates/extended_bin.dtl)0
-rw-r--r--priv/templates/extended_bin_windows (renamed from priv/templates/extended_bin_windows.dtl)0
-rw-r--r--priv/templates/install_upgrade_escript (renamed from priv/templates/install_upgrade_escript.dtl)0
-rw-r--r--priv/templates/nodetool (renamed from priv/templates/nodetool.dtl)0
-rw-r--r--priv/templates/sys_config (renamed from priv/templates/sys_config.dtl)0
-rw-r--r--priv/templates/vm_args (renamed from priv/templates/vm_args.dtl)0
-rw-r--r--rebar.config16
-rw-r--r--rebar.lock18
-rw-r--r--src/rlx_prv_archive.erl3
-rw-r--r--src/rlx_prv_assembler.erl26
-rw-r--r--src/rlx_prv_overlay.erl208
-rw-r--r--src/rlx_util.erl62
-rw-r--r--test/rlx_release_SUITE.erl64
-rw-r--r--test/rlx_test_utils.erl20
18 files changed, 171 insertions, 246 deletions
diff --git a/priv/templates/bin.dtl b/priv/templates/bin
index dd11707..dd11707 100755
--- a/priv/templates/bin.dtl
+++ b/priv/templates/bin
diff --git a/priv/templates/bin_windows.dtl b/priv/templates/bin_windows
index 3466292..3466292 100644
--- a/priv/templates/bin_windows.dtl
+++ b/priv/templates/bin_windows
diff --git a/priv/templates/erl_ini.dtl b/priv/templates/erl_ini
index b2ce5bc..b2ce5bc 100644
--- a/priv/templates/erl_ini.dtl
+++ b/priv/templates/erl_ini
diff --git a/priv/templates/erl_script.dtl b/priv/templates/erl_script
index 72e93dd..72e93dd 100644
--- a/priv/templates/erl_script.dtl
+++ b/priv/templates/erl_script
diff --git a/priv/templates/extended_bin.dtl b/priv/templates/extended_bin
index 452669c..452669c 100755
--- a/priv/templates/extended_bin.dtl
+++ b/priv/templates/extended_bin
diff --git a/priv/templates/extended_bin_windows.dtl b/priv/templates/extended_bin_windows
index cb9f747..cb9f747 100644
--- a/priv/templates/extended_bin_windows.dtl
+++ b/priv/templates/extended_bin_windows
diff --git a/priv/templates/install_upgrade_escript.dtl b/priv/templates/install_upgrade_escript
index 3fb9d04..3fb9d04 100644
--- a/priv/templates/install_upgrade_escript.dtl
+++ b/priv/templates/install_upgrade_escript
diff --git a/priv/templates/nodetool.dtl b/priv/templates/nodetool
index dee14b4..dee14b4 100644
--- a/priv/templates/nodetool.dtl
+++ b/priv/templates/nodetool
diff --git a/priv/templates/sys_config.dtl b/priv/templates/sys_config
index eda2e75..eda2e75 100644
--- a/priv/templates/sys_config.dtl
+++ b/priv/templates/sys_config
diff --git a/priv/templates/vm_args.dtl b/priv/templates/vm_args
index 558ce39..558ce39 100644
--- a/priv/templates/vm_args.dtl
+++ b/priv/templates/vm_args
diff --git a/rebar.config b/rebar.config
index 74ae226..facbdc8 100644
--- a/rebar.config
+++ b/rebar.config
@@ -6,16 +6,17 @@
{providers, ".*",
{git, "https://github.com/tsloughter/providers.git",
{tag, "v1.3.0"}}},
- {erlydtl, ".*",
- {git, "https://github.com/erlydtl/erlydtl.git",
+ {mustache, ".*",
+ {git, "https://github.com/soranoba/mustache.git",
{branch, "master"}}},
{getopt, "",
{git, "https://github.com/jcomellas/getopt.git",
{branch, "master"}}}]}.
+{escript_incl_extra, [{"priv/templates/*", "."}]}.
{escript_emu_args, "%%! +sbtu +A0 -noinput\n"}.
{escript_incl_apps,
- [getopt, erlware_commons, merl, erlydtl, providers, relx]}.
+ [getopt, erlware_commons, providers, relx]}.
%% Compiler Options ============================================================
{erl_opts,
@@ -28,13 +29,6 @@
{eunit_opts,
[{report, {eunit_surefire, [{dir, "."}]}}]}.
-%% Erlydtl =====================================================================
-{erlydtl_opts, [{doc_root, "priv/templates"},
- force_recompile,
- {compiler_options, [report, return, debug_info]}]}.
-
-{provider_hooks, [{pre, [{compile, {erlydtl, compile}}]}]}.
-
%% Profiles ====================================================================
{profiles, [{dev, [{deps, [{neotoma, ".*",
@@ -43,6 +37,8 @@
]
}]}.
+{overrides, [{override, mustache, [{deps, []}, {plugins, []}]}]}.
+
{ct_opts, [{cover_spec, "cover.spec"},
{cover_enabled, true},
{cover_print_enabled, true}]}.
diff --git a/rebar.lock b/rebar.lock
index 8bfc7c1..0f47b93 100644
--- a/rebar.lock
+++ b/rebar.lock
@@ -2,27 +2,19 @@
{git,"https://github.com/erlware/rebar_vsn_plugin.git",
{ref,"fd40c960c7912193631d948fe962e1162a8d1334"}},
1},
- {<<"merl">>,
- {git,"git://github.com/erlydtl/merl.git",
- {ref,"750b09d44425f435ff579a4d28bf5844bb5b4ef1"}},
- 1},
- {<<"eunit_formatters">>,
- {git,"git://github.com/seancribbs/eunit_formatters",
- {ref,"2c73eb6e46b0863f19507857b386a48a53aaf141"}},
- 1},
{<<"providers">>,
{git,"https://github.com/tsloughter/providers.git",
{ref,"d565693cbbca3457df34d95c53c47e1faa8cde6c"}},
0},
+ {<<"mustache">>,
+ {git,"https://github.com/soranoba/mustache.git",
+ {ref,"5a15c03e0bcc307dd4165208802b1641dbf88b50"}},
+ 0},
{<<"getopt">>,
{git,"https://github.com/jcomellas/getopt.git",
{ref,"626698975e63866156159661d100785d65eab6f9"}},
0},
- {<<"erlydtl">>,
- {git,"https://github.com/erlydtl/erlydtl.git",
- {ref,"de00ccf522be8d3f9b0dcb7cd680f83b4fb7267a"}},
- 0},
{<<"erlware_commons">>,
{git,"https://github.com/erlware/erlware_commons.git",
- {ref,"05b956da26788f30b3cb793fa6ace02b75f481d0"}},
+ {ref,"ef0d252b11c863f9c228af2fe93a4e42fba2f7f3"}},
0}].
diff --git a/src/rlx_prv_archive.erl b/src/rlx_prv_archive.erl
index 3ed34f8..59fbdc2 100644
--- a/src/rlx_prv_archive.erl
+++ b/src/rlx_prv_archive.erl
@@ -144,8 +144,7 @@ overlay_files(_, undefined, _) ->
overlay_files(OverlayVars, Overlay, OutputDir) ->
[begin
To = to(O),
- ToTemplateName = rlx_prv_overlay:make_template_name("rlx_template_to_template", To),
- File = rlx_prv_overlay:render_string(OverlayVars, To, ToTemplateName),
+ File = rlx_prv_overlay:render_string(OverlayVars, To),
{ec_cnv:to_list(File), ec_cnv:to_list(filename:join(OutputDir, File))}
end || O <- Overlay, filter(O)].
diff --git a/src/rlx_prv_assembler.erl b/src/rlx_prv_assembler.erl
index 60cef76..5fa1817 100644
--- a/src/rlx_prv_assembler.erl
+++ b/src/rlx_prv_assembler.erl
@@ -545,20 +545,20 @@ ensure_not_exist(RelConfPath) ->
end.
erl_script(ErtsVsn) ->
- render(erl_script_dtl, [{erts_vsn, ErtsVsn}]).
+ render(erl_script, [{erts_vsn, ErtsVsn}]).
bin_file_contents(OsFamily, RelName, RelVsn, ErtsVsn, ErlOpts) ->
Template = case OsFamily of
- unix -> bin_dtl;
- win32 -> bin_windows_dtl
+ unix -> bin;
+ win32 -> bin_windows
end,
render(Template, [{rel_name, RelName}, {rel_vsn, RelVsn},
{erts_vsn, ErtsVsn}, {erl_opts, ErlOpts}]).
extended_bin_file_contents(OsFamily, RelName, RelVsn, ErtsVsn, ErlOpts) ->
Template = case OsFamily of
- unix -> extended_bin_dtl;
- win32 -> extended_bin_windows_dtl
+ unix -> extended_bin;
+ win32 -> extended_bin_windows
end,
render(Template, [{rel_name, RelName}, {rel_vsn, RelVsn},
{erts_vsn, ErtsVsn}, {erl_opts, ErlOpts}]).
@@ -566,23 +566,25 @@ extended_bin_file_contents(OsFamily, RelName, RelVsn, ErtsVsn, ErlOpts) ->
erl_ini(OutputDir, ErtsVsn) ->
ErtsDirName = string:concat("erts-", ErtsVsn),
BinDir = filename:join([OutputDir, ErtsDirName, bin]),
- render(erl_ini_dtl, [{bin_dir, BinDir}, {output_dir, OutputDir}]).
+ render(erl_ini, [{bin_dir, BinDir}, {output_dir, OutputDir}]).
install_upgrade_escript_contents() ->
- render(install_upgrade_escript_dtl).
+ render(install_upgrade_escript).
nodetool_contents() ->
- render(nodetool_dtl).
+ render(nodetool).
sys_config_file() ->
- render(sys_config_dtl).
+ render(sys_config).
vm_args_file(RelName) ->
- render(vm_args_dtl, [{rel_name, RelName}]).
+ render(vm_args, [{rel_name, RelName}]).
render(Template) ->
render(Template, []).
render(Template, Data) ->
- {ok, Rendered} = Template:render(Data),
- Rendered.
+ Files = rlx_util:template_files(),
+ Tpl = rlx_util:load_file(Files, escript, atom_to_list(Template)),
+ {ok, Content} = rlx_util:render(Tpl, Data),
+ Content.
diff --git a/src/rlx_prv_overlay.erl b/src/rlx_prv_overlay.erl
index d9c409c..6c27b5c 100644
--- a/src/rlx_prv_overlay.erl
+++ b/src/rlx_prv_overlay.erl
@@ -29,13 +29,10 @@
format_error/1]).
-export([generate_overlay_vars/2,
- make_template_name/2,
- render_string/3]).
+ render_string/2]).
-define(DIRECTORY_RE, ".*(\/|\\\\)$").
--define(ERLYDTL_COMPILE_OPTS, [report_warnings, return_errors, {auto_escape, false}, {out_dir, false}]).
-
-include("relx.hrl").
-define(PROVIDER, overlay).
@@ -64,7 +61,8 @@ do(State) ->
{error, Reason} ->
{error, Reason};
OverlayVars ->
- do_overlay(State, OverlayVars)
+ Files = rlx_util:template_files(),
+ do_overlay(State, Files, OverlayVars)
end;
false ->
?RLX_ERROR({unresolved_release, RelName, RelVsn})
@@ -79,6 +77,9 @@ format_error({ec_file_error, AppDir, TargetDir, E}) ->
format_error({unable_to_read_varsfile, FileName, Reason}) ->
io_lib:format("Unable to read vars file (~s) for overlay due to: ~p",
[FileName, Reason]);
+format_error({read_template, FileName, Reason}) ->
+ io_lib:format("Unable to read template file (~s) for overlay due to: ~s",
+ [FileName, file:format_error(Reason)]);
format_error({overlay_failed, Errors}) ->
[[format_error(rlx_util:error_reason(Error)), "\n"] || Error <- Errors];
format_error({dir_render_failed, Dir, Error}) ->
@@ -183,8 +184,16 @@ merge_overlay_vars(State, FileNames) ->
lists:foldl(fun(FileName, Acc) ->
RelativePath = filename:join(RelativeRoot, erlang:iolist_to_binary(FileName)),
case file:consult(RelativePath) of
+ %% {ok, [Terms]} ->
+ %% lists:ukeymerge(1, lists:ukeysort(1, Terms), Acc);
+ %% % the location of the included overlay files will be relative
+ %% %% to the current one being read
+ %% %% OverlayRelativeRoot = filename:dirname(FileName),
+ %% %% NewTerms = check_overlay_inclusion(State, OverlayRelativeRoot, Terms),
+
+ %% %% lists:ukeymerge(1, lists:ukeysort(1, NewTerms), Acc);
{ok, Terms} ->
- % the location of the included overlay files will be relative
+ %% the location of the included overlay files will be relative
%% to the current one being read
OverlayRelativeRoot = filename:dirname(FileName),
NewTerms = check_overlay_inclusion(State, OverlayRelativeRoot, Terms),
@@ -237,26 +246,7 @@ generate_release_vars(Release) ->
{release_erts_version, rlx_release:erts(Release)},
{release_name, rlx_release:name(Release)},
{rel_vsn, rlx_release:vsn(Release)},
- {release_version, rlx_release:vsn(Release)},
- {release_applications, lists:map(fun(App) ->
- rlx_app_info:name(App)
- end, rlx_release:application_details(Release))},
- {release, [generate_app_vars(App)|| App <- rlx_release:application_details(Release)]},
- {release_goals, [if
- erlang:is_list(Constraint) ->
- Constraint;
- true ->
- rlx_depsolver:format_constraint(Constraint)
- end || Constraint <- rlx_release:goals(Release)]}].
-
--spec generate_app_vars(rlx_app_info:t()) -> AppInfo::tuple().
-generate_app_vars(App) ->
- {rlx_app_info:name(App),
- [{version, rlx_app_info:original_vsn(App)},
- {dir, rlx_app_info:dir(App)},
- {active_dependencies, rlx_app_info:active_deps(App)},
- {library_dependencies, rlx_app_info:library_deps(App)},
- {link, rlx_app_info:link(App)}]}.
+ {release_version, rlx_release:vsn(Release)}].
-spec generate_state_vars(rlx_state:t()) -> proplists:proplist().
generate_state_vars(State) ->
@@ -288,16 +278,16 @@ generate_state_vars(State) ->
erlang:atom_to_list(Name1) ++ "-" ++ Vsn1
end}].
--spec do_overlay(rlx_state:t(), proplists:proplist()) ->
+-spec do_overlay(rlx_state:t(), list(), proplists:proplist()) ->
{ok, rlx_state:t()} | relx:error().
-do_overlay(State, OverlayVars) ->
+do_overlay(State, Files, OverlayVars) ->
case rlx_state:get(State, overlay, undefined) of
undefined ->
{ok, State};
Overlays ->
handle_errors(State,
lists:map(fun(Overlay) ->
- do_individual_overlay(State, OverlayVars,
+ do_individual_overlay(State, Files, OverlayVars,
Overlay)
end, Overlays))
end.
@@ -313,61 +303,49 @@ handle_errors(State, Result) ->
{ok, State}
end.
--spec do_individual_overlay(rlx_state:t(), proplists:proplist(),
+-spec do_individual_overlay(rlx_state:t(), list(), proplists:proplist(),
OverlayDirective::term()) ->
{ok, rlx_state:t()} | relx:error().
-do_individual_overlay(State, OverlayVars, {mkdir, Dir}) ->
- ModuleName = make_template_name("rlx_mkdir_template", Dir),
- case erlydtl:compile(erlang:iolist_to_binary(Dir), ModuleName, ?ERLYDTL_COMPILE_OPTS) of
- {ok, ModuleName} ->
- case render(ModuleName, OverlayVars) of
- {ok, IoList} ->
- Absolute = absolutize(State,
- filename:join(rlx_state:output_dir(State),
- erlang:iolist_to_binary(IoList))),
- case rlx_util:mkdir_p(Absolute) of
- {error, Error} ->
- ?RLX_ERROR({unable_to_make_dir, Absolute, Error});
- ok ->
- ok
- end;
+do_individual_overlay(State, _Files, OverlayVars, {mkdir, Dir}) ->
+ case rlx_util:render(erlang:iolist_to_binary(Dir), OverlayVars) of
+ {ok, IoList} ->
+ Absolute = absolutize(State,
+ filename:join(rlx_state:output_dir(State),
+ erlang:iolist_to_binary(IoList))),
+ case rlx_util:mkdir_p(Absolute) of
{error, Error} ->
- ?RLX_ERROR({dir_render_failed, Dir, Error})
+ ?RLX_ERROR({unable_to_make_dir, Absolute, Error});
+ ok ->
+ ok
end;
- {error, Reason, _Warnings} ->
- ?RLX_ERROR({unable_to_compile_template, Dir, Reason})
+ {error, Error} ->
+ ?RLX_ERROR({dir_render_failed, Dir, Error})
end;
-do_individual_overlay(State, OverlayVars, {copy, From, To}) ->
- FromTemplateName = make_template_name("rlx_copy_from_template", From),
- ToTemplateName = make_template_name("rlx_copy_to_template", To),
- file_render_do(OverlayVars, From, FromTemplateName,
+do_individual_overlay(State, _Files, OverlayVars, {copy, From, To}) ->
+ file_render_do(OverlayVars, From,
fun(FromFile) ->
- file_render_do(OverlayVars, To, ToTemplateName,
+ file_render_do(OverlayVars, To,
fun(ToFile) ->
copy_to(State, FromFile, ToFile)
end)
end);
-do_individual_overlay(State, OverlayVars, {link, From, To}) ->
+do_individual_overlay(State, Files, OverlayVars, {link, From, To}) ->
case rlx_state:dev_mode(State) of
false ->
- do_individual_overlay(State, OverlayVars, {copy, From, To});
+ do_individual_overlay(State, Files, OverlayVars, {copy, From, To});
true ->
- FromTemplateName = make_template_name("rlx_copy_from_template", From),
- ToTemplateName = make_template_name("rlx_copy_to_template", To),
- file_render_do(OverlayVars, From, FromTemplateName,
+ file_render_do(OverlayVars, From,
fun(FromFile) ->
- file_render_do(OverlayVars, To, ToTemplateName,
+ file_render_do(OverlayVars, To,
fun(ToFile) ->
link_to(State, FromFile, ToFile)
end)
end)
end;
-do_individual_overlay(State, OverlayVars, {template, From, To}) ->
- FromTemplateName = make_template_name("rlx_template_from_template", From),
- ToTemplateName = make_template_name("rlx_template_to_template", To),
- file_render_do(OverlayVars, From, FromTemplateName,
+do_individual_overlay(State, _Files, OverlayVars, {template, From, To}) ->
+ file_render_do(OverlayVars, From,
fun(FromFile) ->
- file_render_do(OverlayVars, To, ToTemplateName,
+ file_render_do(OverlayVars, To,
fun(ToFile) ->
RelativeRoot = get_relative_root(State),
FromFile0 = absolutize(State,
@@ -465,85 +443,55 @@ is_directory(ToFile0, ToFile1) ->
-spec render_template(proplists:proplist(), iolist()) ->
ok | relx:error().
render_template(OverlayVars, Data) ->
- TemplateName = make_template_name("rlx_template_renderer", Data),
- case erlydtl:compile(Data, TemplateName, ?ERLYDTL_COMPILE_OPTS) of
- Good when Good =:= ok; Good =:= {ok, TemplateName} ->
- case render(TemplateName, OverlayVars) of
- {ok, IoData} ->
- {ok, IoData};
- {error, Reason} ->
- ?RLX_ERROR({unable_to_render_template, Data, Reason})
- end;
- {error, Reason, _Warnings} ->
- ?RLX_ERROR({unable_to_compile_template, Data, Reason})
+ case rlx_util:render(Data, OverlayVars) of
+ {ok, IoData} ->
+ {ok, IoData};
+ {error, Reason} ->
+ ?RLX_ERROR({unable_to_render_template, Data, Reason})
end.
write_template(OverlayVars, FromFile, ToFile) ->
- case render_template(OverlayVars, FromFile) of
- {ok, IoData} ->
- case filelib:ensure_dir(ToFile) of
- ok ->
- case file:write_file(ToFile, IoData) of
+ case file:read_file(FromFile) of
+ {ok, File} ->
+ case render_template(OverlayVars, File) of
+ {ok, IoData} ->
+ case filelib:ensure_dir(ToFile) of
ok ->
- {ok, FileInfo} = file:read_file_info(FromFile),
- ok = file:write_file_info(ToFile, FileInfo),
- ok;
+ case file:write_file(ToFile, IoData) of
+ ok ->
+ {ok, FileInfo} = file:read_file_info(FromFile),
+ ok = file:write_file_info(ToFile, FileInfo),
+ ok;
+ {error, Reason} ->
+ ?RLX_ERROR({unable_to_write, ToFile, Reason})
+ end;
{error, Reason} ->
- ?RLX_ERROR({unable_to_write, ToFile, Reason})
+ ?RLX_ERROR({unable_to_enclosing_dir, ToFile, Reason})
end;
- {error, Reason} ->
- ?RLX_ERROR({unable_to_enclosing_dir, ToFile, Reason})
+ Error ->
+ Error
end;
- Error ->
- Error
+ {error, Error} ->
+ ?RLX_ERROR({read_template, Error})
end.
-render_string(OverlayVars, Data, TemplateName) ->
- case erlydtl:compile(erlang:iolist_to_binary(Data), TemplateName, ?ERLYDTL_COMPILE_OPTS) of
- {ok, TemplateName} ->
- case render(TemplateName, OverlayVars) of
- {ok, IoList} ->
- erlang:iolist_to_binary(IoList);
- {error, Error} ->
- ?RLX_ERROR({render_failed, Data, Error})
- end;
- {error, Reason, _Warnings} ->
- ?RLX_ERROR({unable_to_compile_template, Data, Reason})
+render_string(OverlayVars, Data) ->
+ case rlx_util:render(Data, OverlayVars) of
+ {ok, IoList} ->
+ erlang:iolist_to_binary(IoList);
+ {error, Error} ->
+ ?RLX_ERROR({render_failed, Data, Error})
end.
--spec file_render_do(proplists:proplist(), iolist(), module(),
+-spec file_render_do(proplists:proplist(), iolist(),
fun((term()) -> {ok, rlx_state:t()} | relx:error())) ->
{ok, rlx_state:t()} | relx:error().
-file_render_do(OverlayVars, Data, TemplateName, NextAction) ->
- case erlydtl:compile(erlang:iolist_to_binary(Data), TemplateName, ?ERLYDTL_COMPILE_OPTS) of
- {ok, TemplateName} ->
- case render(TemplateName, OverlayVars) of
- {ok, IoList} ->
- NextAction(IoList);
- {error, Error} ->
- ?RLX_ERROR({render_failed, Data, Error})
- end;
- {error, Reason, _Warnings} ->
- ?RLX_ERROR({unable_to_compile_template, Data, Reason})
- end.
-
--spec make_template_name(string(), term()) -> module().
-make_template_name(Base, Value) ->
- %% Seed so we get different values each time
- random:seed(os:timestamp()),
- Hash = erlang:phash2(Value),
- Ran = random:uniform(10000000),
- erlang:list_to_atom(Base ++ "_" ++
- erlang:integer_to_list(Hash) ++
- "_" ++ erlang:integer_to_list(Ran)).
-
--spec render(module(), proplists:proplist()) -> {ok, iolist()} | {error, Reason::term()}.
-render(ModuleName, OverlayVars) ->
- try
- ModuleName:render(OverlayVars)
- catch
- _:Reason ->
- {error, Reason}
+file_render_do(OverlayVars, File, NextAction) ->
+ case rlx_util:render(File, OverlayVars) of
+ {ok, IoList} ->
+ NextAction(IoList);
+ {error, Error} ->
+ ?RLX_ERROR({render_failed, File, Error})
end.
absolutize(State, FileName) ->
diff --git a/src/rlx_util.erl b/src/rlx_util.erl
index 9c4dcc2..4639ffa 100644
--- a/src/rlx_util.erl
+++ b/src/rlx_util.erl
@@ -32,7 +32,12 @@
error_reason/1,
indent/1,
optional_to_string/1,
- wildcard_paths/1]).
+ wildcard_paths/1,
+ render/1,
+ render/2,
+ load_file/3,
+ template_files/0,
+ escript_foldl/3]).
-define(ONE_LEVEL_INDENT, " ").
%%============================================================================
@@ -147,6 +152,61 @@ wildcard(Path) when is_list(Path) ->
Paths -> Paths
end.
+render(Template) ->
+ render(Template, []).
+
+render(Template, Data) ->
+ {ok, mustache:render(ec_cnv:to_binary(Template), Data)}.
+
+load_file(Files, escript, Name) ->
+ {Name, Bin} = lists:keyfind(Name, 1, Files),
+ Bin;
+load_file(_Files, file, Name) ->
+ {ok, Bin} = file:read_file(Name),
+ Bin.
+
+template_files() ->
+ find_priv_templates() ++ escript_files().
+
+find_priv_templates() ->
+ Files = filelib:wildcard(filename:join([code:priv_dir(relx), "templates", "*"])),
+ lists:map(fun(File) ->
+ {ok, Bin} = file:read_file(File),
+ {filename:basename(File), Bin}
+ end, Files).
+
+%% Scan the current escript for available files
+escript_files() ->
+ try
+ {ok, Files} = escript_foldl(
+ fun(Name, _, GetBin, Acc) ->
+ [{filename:basename(Name), GetBin()} | Acc]
+ end, [], filename:absname(escript:script_name())),
+ Files
+ catch
+ _:_ ->
+ []
+ end.
+
+escript_foldl(Fun, Acc, File) ->
+ case escript:extract(File, [compile_source]) of
+ {ok, [_Shebang, _Comment, _EmuArgs, Body]} ->
+ case Body of
+ {source, BeamCode} ->
+ GetInfo = fun() -> file:read_file_info(File) end,
+ GetBin = fun() -> BeamCode end,
+ {ok, Fun(".", GetInfo, GetBin, Acc)};
+ {beam, BeamCode} ->
+ GetInfo = fun() -> file:read_file_info(File) end,
+ GetBin = fun() -> BeamCode end,
+ {ok, Fun(".", GetInfo, GetBin, Acc)};
+ {archive, ArchiveBin} ->
+ zip:foldl(Fun, Acc, {File, ArchiveBin})
+ end;
+ {error, _} = Error ->
+ Error
+ end.
+
%%%===================================================================
%%% Test Functions
%%%===================================================================
diff --git a/test/rlx_release_SUITE.erl b/test/rlx_release_SUITE.erl
index 766eb40..c4c782b 100644
--- a/test/rlx_release_SUITE.erl
+++ b/test/rlx_release_SUITE.erl
@@ -497,18 +497,17 @@ overlay_release(Config) ->
VarsFile1 = filename:join([LibDir1, "vars1.config"]),
rlx_test_utils:write_config(VarsFile1, [{yahoo, "yahoo"},
- {yahoo2, [{foo, "bar"}]},
- {yahoo3, [{bar, "{{yahoo}}/{{yahoo2.foo}}"}]},
- {foo_dir, "foodir"}]),
+ {yahoo2, [{foo, "bar"}]},
+ {foo_dir, "foodir"}]),
VarsFile2 = filename:join([LibDir1, "vars2.config"]),
rlx_test_utils:write_config(VarsFile2, [{google, "yahoo"},
- {yahoo2, [{foo, "foo"}]},
- OverlayVars3]),
+ {yahoo2, "foo"},
+ OverlayVars3]),
VarsFile3 = filename:join([LibDir1, "vars3.config"]),
rlx_test_utils:write_config(VarsFile3, [{google, "yahoo"},
- {yahoo4, [{foo, "{{yahoo}}/{{yahoo2.foo}}4"}]}]),
+ {yahoo4, "{{yahoo}}/{{yahoo2}}4"}]),
ok = rlx_util:mkdir_p(TestDirFull),
ok = file:write_file(TestFileFull, rlx_test_utils:test_template_contents()),
@@ -557,59 +556,6 @@ overlay_release(Config) ->
proplists:get_value(release_version, TemplateData)),
?assertEqual(foo,
proplists:get_value(release_name, TemplateData)),
- ?assertEqual([kernel,stdlib,lib_dep_1,non_goal_2,non_goal_1,
- goal_app_1,goal_app_2],
- proplists:get_value(release_applications, TemplateData)),
- ?assert(proplists:is_defined(std_version, TemplateData)),
- ?assert(proplists:is_defined(kernel_version, TemplateData)),
- ?assertEqual("0.0.1",
- proplists:get_value(non_goal_1_version, TemplateData)),
- ?assertEqual("0.0.1",
- proplists:get_value(non_goal_2_version, TemplateData)),
- ?assertEqual("0.0.1",
- proplists:get_value(goal_app_1_version, TemplateData)),
- ?assertEqual("0.0.1",
- proplists:get_value(goal_app_2_version, TemplateData)),
- ?assertEqual("0.0.1",
- proplists:get_value(lib_dep_1, TemplateData)),
- ?assert(proplists:is_defined(lib_dep_1_dir, TemplateData)),
- ?assertEqual([stdlib,kernel],
- proplists:get_value(lib_dep_1_active, TemplateData)),
- ?assertEqual([],
- proplists:get_value(lib_dep_1_library, TemplateData)),
- ?assertEqual("false",
- proplists:get_value(lib_dep_1_link, TemplateData)),
- ?assertEqual("(3:debug)",
- proplists:get_value(log, TemplateData)),
- ?assertEqual(filename:join(OutputDir, "foo"),
- proplists:get_value(output_dir, TemplateData)),
- ?assertEqual(filename:join(OutputDir, "foo"),
- proplists:get_value(target_dir, TemplateData)),
- ?assertEqual([],
- proplists:get_value(overridden, TemplateData)),
- ?assertEqual([""],
- proplists:get_value(goals, TemplateData)),
- ?assert(proplists:is_defined(lib_dirs, TemplateData)),
- ?assert(proplists:is_defined(config_file, TemplateData)),
- ?assertEqual([""],
- proplists:get_value(goals, TemplateData)),
- ?assertEqual([],
- proplists:get_value(sys_config, TemplateData)),
- ?assert(proplists:is_defined(root_dir, TemplateData)),
- ?assertEqual(foo,
- proplists:get_value(default_release_name, TemplateData)),
- ?assertEqual("0.0.1",
- proplists:get_value(default_release_version, TemplateData)),
- ?assertEqual("foo-0.0.1",
- proplists:get_value(default_release, TemplateData)),
- ?assertEqual("yahoo",
- proplists:get_value(yahoo, TemplateData)),
- ?assertEqual("foo",
- proplists:get_value(yahoo2_foo, TemplateData)),
- ?assertEqual("foodir",
- proplists:get_value(foo_dir, TemplateData)),
- ?assertEqual("yahoo/foo",
- proplists:get_value(yahoo3, TemplateData)),
?assertEqual("yahoo/foo4",
proplists:get_value(yahoo4, TemplateData)),
?assertEqual("yahoo",
diff --git a/test/rlx_test_utils.erl b/test/rlx_test_utils.erl
index 644c49f..4e0fc0d 100644
--- a/test/rlx_test_utils.erl
+++ b/test/rlx_test_utils.erl
@@ -65,34 +65,16 @@ test_template_contents() ->
"{release_name, {{release_name}}}.\n"
"{rel_vsn, \"{{release_version}}\"}.\n"
"{release_version, \"{{release_version}}\"}.\n"
- "{release_applications, [{{ release_applications|join:\", \" }}]}.\n"
- "{std_version, \"{{release.stdlib.version}}\"}.\n"
- "{kernel_version, \"{{release.kernel.version}}\"}.\n"
- "{non_goal_1_version, \"{{release.non_goal_1.version}}\"}.\n"
- "{non_goal_2_version, \"{{release.non_goal_2.version}}\"}.\n"
- "{goal_app_1_version, \"{{release.goal_app_1.version}}\"}.\n"
- "{goal_app_2_version, \"{{release.goal_app_2.version}}\"}.\n"
- "{lib_dep_1, \"{{release.lib_dep_1.version}}\"}.\n"
- "{lib_dep_1_dir, \"{{release.lib_dep_1.dir}}\"}.\n"
- "{lib_dep_1_active, [{{ release.lib_dep_1.active_dependencies|join:\", \" }}]}.\n"
- "{lib_dep_1_library, [{{ release.lib_dep_1.library_dependencies|join:\", \" }}]}.\n"
- "{lib_dep_1_link, \"{{release.lib_dep_1.link}}\"}.\n"
"{log, \"{{log}}\"}.\n"
"{output_dir, \"{{output_dir}}\"}.\n"
"{target_dir, \"{{target_dir}}\"}.\n"
- "{overridden, [{{ overridden|join:\", \" }}]}.\n"
- "{goals, [\"{{ goals|join:\", \" }}\"]}.\n"
- "{lib_dirs, [\"{{ lib_dirs|join:\", \" }}\"]}.\n"
"{config_file, \"{{ config_file }}\"}.\n"
- "{providers, [{{ providers|join:\", \" }}]}.\n"
"{sys_config, \"{{sys_config}}\"}.\n"
"{root_dir, \"{{root_dir}}\"}.\n"
"{default_release_name, {{default_release_name}}}.\n"
"{default_release_version, \"{{default_release_version}}\"}.\n"
"{default_release, \"{{default_release}}\"}.\n"
+ "{yahoo4, \"{{yahoo4}}\"}.\n"
"{yahoo, \"{{yahoo}}\"}.\n"
- "{yahoo2_foo, \"{{yahoo2.foo}}\"}.\n"
"{foo_dir, \"{{foo_dir}}\"}.\n"
- "{yahoo3, \"{{yahoo3.bar}}\"}.\n"
- "{yahoo4, \"{{yahoo4.foo}}\"}.\n"
"{google, \"{{google}}\"}.\n".