Remove erlydtl and replace with mustachepull/381/head
@ -1,2 +1,2 @@ | |||
{description, "Makefile for building C/C++ in c_src"}. | |||
{template, "Makefile.dtl", "c_src/Makefile"}. | |||
{template, "Makefile", "c_src/Makefile"}. |
@ -0,0 +1,230 @@ | |||
%% The MIT License | |||
%% | |||
%% Copyright (c) 2009 Tom Preston-Werner <tom@mojombo.com> | |||
%% | |||
%% Permission is hereby granted, free of charge, to any person obtaining a copy | |||
%% of this software and associated documentation files (the "Software"), to deal | |||
%% in the Software without restriction, including without limitation the rights | |||
%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||
%% copies of the Software, and to permit persons to whom the Software is | |||
%% furnished to do so, subject to the following conditions: | |||
%% | |||
%% The above copyright notice and this permission notice shall be included in | |||
%% all copies or substantial portions of the Software. | |||
%% | |||
%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||
%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||
%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |||
%% THE SOFTWARE. | |||
%% See the README at http://github.com/mojombo/mustache.erl for additional | |||
%% documentation and usage examples. | |||
-module(rebar_mustache). %% v0.1.0 | |||
-author("Tom Preston-Werner"). | |||
-export([compile/1, compile/2, render/1, render/2, render/3, get/2, get/3, escape/1, start/1]). | |||
-record(mstate, {mod = undefined, | |||
section_re = undefined, | |||
tag_re = undefined}). | |||
-define(MUSTACHE_STR, "rebar_mustache"). | |||
compile(Body) when is_list(Body) -> | |||
State = #mstate{}, | |||
CompiledTemplate = pre_compile(Body, State), | |||
% io:format("~p~n~n", [CompiledTemplate]), | |||
% io:format(CompiledTemplate ++ "~n", []), | |||
{ok, Tokens, _} = erl_scan:string(CompiledTemplate), | |||
{ok, [Form]} = erl_parse:parse_exprs(Tokens), | |||
Bindings = erl_eval:new_bindings(), | |||
{value, Fun, _} = erl_eval:expr(Form, Bindings), | |||
Fun; | |||
compile(Mod) -> | |||
TemplatePath = template_path(Mod), | |||
compile(Mod, TemplatePath). | |||
compile(Mod, File) -> | |||
code:purge(Mod), | |||
{module, _} = code:load_file(Mod), | |||
{ok, TemplateBin} = file:read_file(File), | |||
Template = re:replace(TemplateBin, "\"", "\\\\\"", [global, {return,list}]), | |||
State = #mstate{mod = Mod}, | |||
CompiledTemplate = pre_compile(Template, State), | |||
% io:format("~p~n~n", [CompiledTemplate]), | |||
% io:format(CompiledTemplate ++ "~n", []), | |||
{ok, Tokens, _} = erl_scan:string(CompiledTemplate), | |||
{ok, [Form]} = erl_parse:parse_exprs(Tokens), | |||
Bindings = erl_eval:new_bindings(), | |||
{value, Fun, _} = erl_eval:expr(Form, Bindings), | |||
Fun. | |||
render(Mod) -> | |||
TemplatePath = template_path(Mod), | |||
render(Mod, TemplatePath). | |||
render(Body, Ctx) when is_list(Body) -> | |||
TFun = compile(Body), | |||
render(undefined, TFun, Ctx); | |||
render(Mod, File) when is_list(File) -> | |||
render(Mod, File, dict:new()); | |||
render(Mod, CompiledTemplate) -> | |||
render(Mod, CompiledTemplate, dict:new()). | |||
render(Mod, File, Ctx) when is_list(File) -> | |||
CompiledTemplate = compile(Mod, File), | |||
render(Mod, CompiledTemplate, Ctx); | |||
render(Mod, CompiledTemplate, Ctx) -> | |||
Ctx2 = dict:store('__mod__', Mod, Ctx), | |||
lists:flatten(CompiledTemplate(Ctx2)). | |||
pre_compile(T, State) -> | |||
SectionRE = "\{\{\#([^\}]*)}}\s*(.+?){{\/\\1\}\}\s*", | |||
{ok, CompiledSectionRE} = re:compile(SectionRE, [dotall]), | |||
TagRE = "\{\{(#|=|!|<|>|\{)?(.+?)\\1?\}\}+", | |||
{ok, CompiledTagRE} = re:compile(TagRE, [dotall]), | |||
State2 = State#mstate{section_re = CompiledSectionRE, tag_re = CompiledTagRE}, | |||
"fun(Ctx) -> " ++ | |||
"CFun = fun(A, B) -> A end, " ++ | |||
compiler(T, State2) ++ " end.". | |||
compiler(T, State) -> | |||
Res = re:run(T, State#mstate.section_re), | |||
case Res of | |||
{match, [{M0, M1}, {N0, N1}, {C0, C1}]} -> | |||
Front = string:substr(T, 1, M0), | |||
Back = string:substr(T, M0 + M1 + 1), | |||
Name = string:substr(T, N0 + 1, N1), | |||
Content = string:substr(T, C0 + 1, C1), | |||
"[" ++ compile_tags(Front, State) ++ | |||
" | [" ++ compile_section(Name, Content, State) ++ | |||
" | [" ++ compiler(Back, State) ++ "]]]"; | |||
nomatch -> | |||
compile_tags(T, State) | |||
end. | |||
compile_section(Name, Content, State) -> | |||
Mod = State#mstate.mod, | |||
Result = compiler(Content, State), | |||
"fun() -> " ++ | |||
"case " ++ ?MUSTACHE_STR ++ ":get(" ++ Name ++ ", Ctx, " ++ atom_to_list(Mod) ++ ") of " ++ | |||
"\"true\" -> " ++ | |||
Result ++ "; " ++ | |||
"\"false\" -> " ++ | |||
"[]; " ++ | |||
"List when is_list(List) -> " ++ | |||
"[fun(Ctx) -> " ++ Result ++ " end(dict:merge(CFun, SubCtx, Ctx)) || SubCtx <- List]; " ++ | |||
"Else -> " ++ | |||
"throw({template, io_lib:format(\"Bad context for ~p: ~p\", [" ++ Name ++ ", Else])}) " ++ | |||
"end " ++ | |||
"end()". | |||
compile_tags(T, State) -> | |||
Res = re:run(T, State#mstate.tag_re), | |||
case Res of | |||
{match, [{M0, M1}, K, {C0, C1}]} -> | |||
Front = string:substr(T, 1, M0), | |||
Back = string:substr(T, M0 + M1 + 1), | |||
Content = string:substr(T, C0 + 1, C1), | |||
Kind = tag_kind(T, K), | |||
Result = compile_tag(Kind, Content, State), | |||
"[\"" ++ Front ++ | |||
"\" | [" ++ Result ++ | |||
" | " ++ compile_tags(Back, State) ++ "]]"; | |||
nomatch -> | |||
"[\"" ++ T ++ "\"]" | |||
end. | |||
tag_kind(_T, {-1, 0}) -> | |||
none; | |||
tag_kind(T, {K0, K1}) -> | |||
string:substr(T, K0 + 1, K1). | |||
compile_tag(none, Content, State) -> | |||
Mod = State#mstate.mod, | |||
?MUSTACHE_STR ++ ":escape(" ++ ?MUSTACHE_STR ++ ":get(" ++ Content ++ ", Ctx, " ++ atom_to_list(Mod) ++ "))"; | |||
compile_tag("{", Content, State) -> | |||
Mod = State#mstate.mod, | |||
?MUSTACHE_STR ++ ":get(" ++ Content ++ ", Ctx, " ++ atom_to_list(Mod) ++ ")"; | |||
compile_tag("!", _Content, _State) -> | |||
"[]". | |||
template_dir(Mod) -> | |||
DefaultDirPath = filename:dirname(code:which(Mod)), | |||
case application:get_env(mustache, templates_dir) of | |||
{ok, DirPath} when is_list(DirPath) -> | |||
case filelib:ensure_dir(DirPath) of | |||
ok -> DirPath; | |||
_ -> DefaultDirPath | |||
end; | |||
_ -> | |||
DefaultDirPath | |||
end. | |||
template_path(Mod) -> | |||
DirPath = template_dir(Mod), | |||
Basename = atom_to_list(Mod), | |||
filename:join(DirPath, Basename ++ ".mustache"). | |||
get(Key, Ctx) when is_list(Key) -> | |||
{ok, Mod} = dict:find('__mod__', Ctx), | |||
get(list_to_atom(Key), Ctx, Mod); | |||
get(Key, Ctx) -> | |||
{ok, Mod} = dict:find('__mod__', Ctx), | |||
get(Key, Ctx, Mod). | |||
get(Key, Ctx, Mod) when is_list(Key) -> | |||
get(list_to_atom(Key), Ctx, Mod); | |||
get(Key, Ctx, Mod) -> | |||
case dict:find(Key, Ctx) of | |||
{ok, Val} -> | |||
% io:format("From Ctx {~p, ~p}~n", [Key, Val]), | |||
to_s(Val); | |||
error -> | |||
case erlang:function_exported(Mod, Key, 1) of | |||
true -> | |||
Val = to_s(Mod:Key(Ctx)), | |||
% io:format("From Mod/1 {~p, ~p}~n", [Key, Val]), | |||
Val; | |||
false -> | |||
case erlang:function_exported(Mod, Key, 0) of | |||
true -> | |||
Val = to_s(Mod:Key()), | |||
% io:format("From Mod/0 {~p, ~p}~n", [Key, Val]), | |||
Val; | |||
false -> | |||
[] | |||
end | |||
end | |||
end. | |||
to_s(Val) when is_integer(Val) -> | |||
integer_to_list(Val); | |||
to_s(Val) when is_float(Val) -> | |||
io_lib:format("~.2f", [Val]); | |||
to_s(Val) when is_atom(Val) -> | |||
atom_to_list(Val); | |||
to_s(Val) -> | |||
Val. | |||
escape(HTML) -> | |||
escape(HTML, []). | |||
escape([], Acc) -> | |||
lists:reverse(Acc); | |||
escape(["<" | Rest], Acc) -> | |||
escape(Rest, lists:reverse("<", Acc)); | |||
escape([">" | Rest], Acc) -> | |||
escape(Rest, lists:reverse(">", Acc)); | |||
escape(["&" | Rest], Acc) -> | |||
escape(Rest, lists:reverse("&", Acc)); | |||
escape([X | Rest], Acc) -> | |||
escape(Rest, [X | Acc]). | |||
%%--------------------------------------------------------------------------- | |||
start([T]) -> | |||
Out = render(list_to_atom(T)), | |||
io:format(Out ++ "~n", []). |
@ -1,270 +0,0 @@ | |||
%% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*- | |||
%% ex: ts=4 sw=4 et | |||
%% ------------------------------------------------------------------- | |||
%% | |||
%% rebar: Erlang Build Tools | |||
%% | |||
%% Copyright (c) 2009 Dave Smith (dizzyd@dizzyd.com), | |||
%% Bryan Fink (bryan@basho.com) | |||
%% | |||
%% Permission is hereby granted, free of charge, to any person obtaining a copy | |||
%% of this software and associated documentation files (the "Software"), to deal | |||
%% in the Software without restriction, including without limitation the rights | |||
%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||
%% copies of the Software, and to permit persons to whom the Software is | |||
%% furnished to do so, subject to the following conditions: | |||
%% | |||
%% The above copyright notice and this permission notice shall be included in | |||
%% all copies or substantial portions of the Software. | |||
%% | |||
%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||
%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||
%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |||
%% THE SOFTWARE. | |||
%% ------------------------------------------------------------------- | |||
%% The rebar_erlydtl_compiler module is a plugin for rebar that compiles | |||
%% ErlyDTL templates. By default, it compiles all templates/*.dtl | |||
%% to ebin/*_dtl.beam. | |||
%% | |||
%% Configuration options should be placed in rebar.config under | |||
%% 'erlydtl_opts'. It can be a list of name-value tuples or a list of | |||
%% lists of name-value tuples if you have multiple template directories | |||
%% that need to have different settings (see example below). | |||
%% | |||
%% Available options include: | |||
%% | |||
%% doc_root: where to find templates to compile | |||
%% "templates" by default | |||
%% | |||
%% out_dir: where to put compiled template beam files | |||
%% "ebin" by default | |||
%% | |||
%% source_ext: the file extension the template sources have | |||
%% ".dtl" by default | |||
%% | |||
%% module_ext: characters to append to the template's module name | |||
%% "_dtl" by default | |||
%% | |||
%% recursive: boolean that determines if doc_root(s) need to be | |||
%% scanned recursively for matching template file names | |||
%% (default: true). | |||
%% For example, if you had: | |||
%% /t_src/ | |||
%% base.html | |||
%% foo.html | |||
%% | |||
%% And you wanted them compiled to: | |||
%% /priv/ | |||
%% base.beam | |||
%% foo.beam | |||
%% | |||
%% You would add to your rebar.config: | |||
%% {erlydtl_opts, [ | |||
%% {doc_root, "t_src"}, | |||
%% {out_dir, "priv"}, | |||
%% {source_ext, ".html"}, | |||
%% {module_ext, ""} | |||
%% ]}. | |||
%% | |||
%% The default settings are the equivalent of: | |||
%% {erlydtl_opts, [ | |||
%% {doc_root, "templates"}, | |||
%% {out_dir, "ebin"}, | |||
%% {source_ext, ".dtl"}, | |||
%% {module_ext, "_dtl"} | |||
%% ]}. | |||
%% | |||
%% The following example will compile the following templates: | |||
%% "src/*.dtl" files into "ebin/*_dtl.beam" and | |||
%% "templates/*.html" into "ebin/*.beam". Note that any tuple option | |||
%% (such as 'out_dir') in the outer list is added to each inner list: | |||
%% {erlydtl_opts, [ | |||
%% {out_dir, "ebin"}, | |||
%% {recursive, false}, | |||
%% [ | |||
%% {doc_root, "src"}, {module_ext, "_dtl"} | |||
%% ], | |||
%% [ | |||
%% {doc_root, "templates"}, {module_ext, ""}, {source_ext, ".html"} | |||
%% ] | |||
%% ]}. | |||
-module(rebar_prv_erlydtl_compiler). | |||
-behaviour(provider). | |||
-export([init/1, | |||
do/1, | |||
format_error/1]). | |||
-include("rebar.hrl"). | |||
-include_lib("providers/include/providers.hrl"). | |||
-define(PROVIDER, compile). | |||
-define(DEPS, [{default, compile}]). | |||
%% =================================================================== | |||
%% Public API | |||
%% =================================================================== | |||
-spec init(rebar_state:t()) -> {ok, rebar_state:t()}. | |||
init(State) -> | |||
State1 = rebar_state:add_provider(State, providers:create([{name, ?PROVIDER}, | |||
{module, ?MODULE}, | |||
{namespace, erlydtl}, | |||
{bare, false}, | |||
{deps, ?DEPS}, | |||
{example, "rebar3 erlydtl compile"}, | |||
{short_desc, "Compile erlydtl templates."}, | |||
{desc, "Compile erlydtl templates."}, | |||
{opts, []}])), | |||
{ok, State1}. | |||
do(State) -> | |||
?INFO("Running erlydtl...", []), | |||
case rebar_state:get(State, escript_main_app, undefined) of | |||
undefined -> | |||
Dir = rebar_state:dir(State), | |||
case rebar_app_discover:find_app(Dir, all) of | |||
{true, AppInfo} -> | |||
AllApps = rebar_state:project_apps(State) ++ rebar_state:all_deps(State), | |||
case rebar_app_utils:find(rebar_app_info:name(AppInfo), AllApps) of | |||
{ok, AppInfo1} -> | |||
%% Use the existing app info instead of newly created one | |||
run_erlydtl(AppInfo1, State); | |||
_ -> | |||
run_erlydtl(AppInfo, State) | |||
end, | |||
{ok, State}; | |||
_ -> | |||
?PRV_ERROR(no_main_app) | |||
end; | |||
Name -> | |||
AllApps = rebar_state:project_apps(State) ++ rebar_state:all_deps(State), | |||
{ok, App} = rebar_app_utils:find(Name, AllApps), | |||
run_erlydtl(App, State), | |||
{ok, State} | |||
end. | |||
run_erlydtl(App, State) -> | |||
Dir = rebar_state:dir(State), | |||
DtlOpts = proplists:unfold(rebar_state:get(State, erlydtl_opts, [])), | |||
TemplateDir = filename:join(Dir, option(doc_root, DtlOpts)), | |||
DtlOpts2 = [{doc_root, TemplateDir} | proplists:delete(doc_root, DtlOpts)], | |||
OutDir = rebar_app_info:ebin_dir(App), | |||
filelib:ensure_dir(filename:join(OutDir, "dummy.beam")), | |||
rebar_base_compiler:run(State, | |||
[], | |||
TemplateDir, | |||
option(source_ext, DtlOpts2), | |||
OutDir, | |||
option(module_ext, DtlOpts2) ++ ".beam", | |||
fun(S, T, C) -> | |||
compile_dtl(C, S, T, DtlOpts2, Dir, OutDir) | |||
end, | |||
[{check_last_mod, false}, | |||
{recursive, option(recursive, DtlOpts2)}]). | |||
-spec format_error(any()) -> iolist(). | |||
format_error(no_main_app) -> | |||
"Erlydtl Error: Multiple project apps found and no {app, atom()} option found in erlydtl_opts."; | |||
format_error(Reason) -> | |||
io_lib:format("~p", [Reason]). | |||
%% =================================================================== | |||
%% Internal functions | |||
%% =================================================================== | |||
option(Opt, DtlOpts) -> | |||
proplists:get_value(Opt, DtlOpts, default(Opt)). | |||
default(app) -> undefined; | |||
default(doc_root) -> "priv/templates"; | |||
default(source_ext) -> ".dtl"; | |||
default(module_ext) -> "_dtl"; | |||
default(custom_tags_dir) -> ""; | |||
default(compiler_options) -> [return]; | |||
default(recursive) -> true. | |||
compile_dtl(State, Source, Target, DtlOpts, Dir, OutDir) -> | |||
case needs_compile(Source, Target, DtlOpts) of | |||
true -> | |||
do_compile(State, Source, Target, DtlOpts, Dir, OutDir); | |||
false -> | |||
skipped | |||
end. | |||
do_compile(State, Source, Target, DtlOpts, Dir, OutDir) -> | |||
CompilerOptions = option(compiler_options, DtlOpts), | |||
Sorted = proplists:unfold( | |||
lists:sort( | |||
[{out_dir, OutDir}, | |||
{doc_root, filename:join(Dir, option(doc_root, DtlOpts))}, | |||
{custom_tags_dir, option(custom_tags_dir, DtlOpts)}, | |||
{compiler_options, CompilerOptions}])), | |||
%% ensure that doc_root and out_dir are defined, | |||
%% using defaults if necessary | |||
Opts = lists:ukeymerge(1, DtlOpts, Sorted), | |||
?DEBUG("Compiling \"~s\" -> \"~s\" with options:~n ~s", | |||
[Source, Target, io_lib:format("~p", [Opts])]), | |||
case erlydtl:compile_file(ec_cnv:to_list(Source), | |||
list_to_atom(module_name(Target)), | |||
Opts) of | |||
{ok, _Mod} -> | |||
ok; | |||
{ok, _Mod, Ws} -> | |||
rebar_base_compiler:ok_tuple(State, Source, Ws); | |||
error -> | |||
rebar_base_compiler:error_tuple(State, Source, [], [], Opts); | |||
{error, Es, Ws} -> | |||
rebar_base_compiler:error_tuple(State, Source, Es, Ws, Opts) | |||
end. | |||
module_name(Target) -> | |||
filename:rootname(filename:basename(Target), ".beam"). | |||
needs_compile(Source, Target, DtlOpts) -> | |||
LM = filelib:last_modified(Target), | |||
LM < filelib:last_modified(Source) orelse | |||
lists:any(fun(D) -> LM < filelib:last_modified(D) end, | |||
referenced_dtls(Source, DtlOpts)). | |||
referenced_dtls(Source, DtlOpts) -> | |||
DtlOpts1 = lists:keyreplace(doc_root, 1, DtlOpts, | |||
{doc_root, filename:dirname(Source)}), | |||
Set = referenced_dtls1([Source], DtlOpts1, | |||
sets:add_element(Source, sets:new())), | |||
sets:to_list(sets:del_element(Source, Set)). | |||
referenced_dtls1(Step, DtlOpts, Seen) -> | |||
ExtMatch = re:replace(option(source_ext, DtlOpts), "\.", "\\\\\\\\.", | |||
[{return, list}]), | |||
ShOpts = [{use_stdout, false}, return_on_error], | |||
AllRefs = | |||
lists:append( | |||
[begin | |||
Cmd = lists:flatten(["grep -o [^\\\"]*\\", | |||
ExtMatch, "[^\\\"]* ", F]), | |||
case rebar_utils:sh(Cmd, ShOpts) of | |||
{ok, Res} -> | |||
string:tokens(Res, "\n"); | |||
{error, _} -> | |||
"" | |||
end | |||
end || F <- Step]), | |||
DocRoot = option(doc_root, DtlOpts), | |||
WithPaths = [ filename:join([DocRoot, F]) || F <- AllRefs ], | |||
?DEBUG("All deps: ~p\n", [WithPaths]), | |||
Existing = [F || F <- WithPaths, filelib:is_regular(F)], | |||
New = sets:subtract(sets:from_list(Existing), Seen), | |||
case sets:size(New) of | |||
0 -> Seen; | |||
_ -> referenced_dtls1(sets:to_list(New), DtlOpts, | |||
sets:union(New, Seen)) | |||
end. |
@ -1,72 +0,0 @@ | |||
%% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*- | |||
%% ex: ts=4 sw=4 et | |||
-module(rebar_erlydtl_SUITE). | |||
-export([suite/0, | |||
init_per_suite/1, | |||
end_per_suite/1, | |||
init_per_testcase/2, | |||
end_per_testcase/2, | |||
all/0, | |||
compile/1]). | |||
-include_lib("common_test/include/ct.hrl"). | |||
-include_lib("eunit/include/eunit.hrl"). | |||
-include_lib("kernel/include/file.hrl"). | |||
%% =================================================================== | |||
%% common_test callbacks | |||
%% =================================================================== | |||
suite() -> | |||
[]. | |||
init_per_suite(Config) -> | |||
Config. | |||
end_per_suite(_Config) -> | |||
ok. | |||
init_per_testcase(_, Config) -> | |||
UpdConfig = rebar_test_utils:init_rebar_state(Config), | |||
AppDir = ?config(apps, UpdConfig), | |||
Name = rebar_test_utils:create_random_name("erlydtlapp_"), | |||
Vsn = rebar_test_utils:create_random_vsn(), | |||
rebar_test_utils:create_app(AppDir, Name, Vsn, [kernel, stdlib]), | |||
write_dtl_file(AppDir, Name), | |||
RebarConfig = [{erl_opts, [debug_info]}, | |||
{erlydtl_opts, []}], | |||
[{app_name, Name}, | |||
{rebar_config, RebarConfig} | UpdConfig]. | |||
end_per_testcase(_, _Config) -> | |||
ok. | |||
all() -> | |||
[compile]. | |||
compile(Config) -> | |||
AppDir = ?config(apps, Config), | |||
AppName = ?config(app_name, Config), | |||
RebarConfig = ?config(rebar_config, Config), | |||
Beam = beam_file(AppDir, AppName), | |||
rebar_test_utils:run_and_check( | |||
Config, RebarConfig, ["erlydtl", "compile"], | |||
{ok, [{file, Beam}]} | |||
). | |||
beam_file(AppDir, AppName) -> | |||
filename:join([AppDir, "_build", "default", "lib", | |||
AppName, "ebin", AppName++"_template_dtl.beam"]). | |||
write_dtl_file(Dir, AppName) -> | |||
Erl = filename:join([Dir, "priv", "templates", AppName++"_template.dtl"]), | |||
ok = filelib:ensure_dir(Erl), | |||
ok = ec_file:write(Erl, get_body()). | |||
get_body() -> | |||
["[]"]. |