summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rebar.config2
-rw-r--r--src/rebar_core.erl2
-rw-r--r--src/rebar_prv_erlydtl_compiler.erl143
-rw-r--r--src/rebar_prv_escriptize.erl1
-rw-r--r--test/rebar_erlydtl_SUITE.erl72
-rw-r--r--test/rebar_test_utils.erl3
6 files changed, 133 insertions, 90 deletions
diff --git a/rebar.config b/rebar.config
index 649de05..3997d8d 100644
--- a/rebar.config
+++ b/rebar.config
@@ -24,7 +24,7 @@
{branch, "master"}}},
{providers, "",
{git, "https://github.com/tsloughter/providers.git",
- {branch, "hooks"}}},
+ {tag, "v1.3.0"}}},
{erlydtl, ".*",
{git, "https://github.com/erlydtl/erlydtl.git",
{tag, "0.10.0"}}},
diff --git a/src/rebar_core.erl b/src/rebar_core.erl
index ab90961..12cd1fc 100644
--- a/src/rebar_core.erl
+++ b/src/rebar_core.erl
@@ -84,7 +84,7 @@ process_command(State, Command) ->
%% to have both $REBAR_PROFILE set and use 'as' in a command
case rebar_state:current_profiles(State) of
[default] ->
- do([{default, hd(TargetProviders)} | tl(TargetProviders)], State);
+ do(TargetProviders, State);
_ ->
{error, "Namespace 'as' is forbidden"}
end;
diff --git a/src/rebar_prv_erlydtl_compiler.erl b/src/rebar_prv_erlydtl_compiler.erl
index f4b4eb0..db4dde2 100644
--- a/src/rebar_prv_erlydtl_compiler.erl
+++ b/src/rebar_prv_erlydtl_compiler.erl
@@ -100,13 +100,11 @@
do/1,
format_error/1]).
-%% for internal use only
--export([info/2]).
-
-include("rebar.hrl").
+-include_lib("providers/include/providers.hrl").
-define(PROVIDER, compile).
--define(DEPS, []).
+-define(DEPS, [{default, compile}]).
%% ===================================================================
%% Public API
@@ -125,27 +123,44 @@ init(State) ->
{opts, []}])),
{ok, State1}.
-do(Config) ->
+do(State) ->
?INFO("Running erlydtl...", []),
- MultiDtlOpts = erlydtl_opts(Config),
+ DtlOpts = proplists:unfold(rebar_state:get(State, erlydtl_opts, [])),
+
+ %% We need a project app to store the results under in _build
+ %% If there is more than 1 project app, check for an app config
+ %% if that doesn't exist, error out.
+ App1 = case rebar_state:project_apps(State) of
+ [App] ->
+ App;
+ Apps ->
+ case option(app, DtlOpts) of
+ undefined ->
+ ?PRV_ERROR(no_main_app);
+ Name ->
+ rebar_app_utils:find(Name, Apps)
+ end
+ end,
- Result = lists:foldl(fun(DtlOpts, _) ->
- file:make_dir(option(out_dir, DtlOpts)),
- rebar_base_compiler:run(Config, [],
- option(doc_root, DtlOpts),
- option(source_ext, DtlOpts),
- option(out_dir, DtlOpts),
- option(module_ext, DtlOpts) ++ ".beam",
- fun(S, T, C) ->
- compile_dtl(C, S, T, DtlOpts)
- end,
- [{check_last_mod, false},
- {recursive, option(recursive, DtlOpts)}])
- end, ok, MultiDtlOpts),
+ Dir = rebar_app_info:dir(App1),
+ OutDir = rebar_app_info:ebin_dir(App1),
+ rebar_base_compiler:run(State,
+ [],
+ filename:join(Dir, option(doc_root, DtlOpts)),
+ option(source_ext, DtlOpts),
+ OutDir,
+ option(module_ext, DtlOpts) ++ ".beam",
+ fun(S, T, C) ->
+ compile_dtl(C, S, T, DtlOpts, Dir, OutDir)
+ end,
+ [{check_last_mod, false},
+ {recursive, option(recursive, DtlOpts)}]),
- {Result, Config}.
+ {ok, State}.
-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]).
@@ -153,41 +168,11 @@ format_error(Reason) ->
%% Internal functions
%% ===================================================================
-info(help, compile) ->
- ?CONSOLE(
- "Build ErlyDtl (*.dtl) sources.~n"
- "~n"
- "Valid rebar.config options:~n"
- " ~p",
- [
- {erlydtl_opts, [{doc_root, "templates"},
- {out_dir, "ebin"},
- {source_ext, ".dtl"},
- {module_ext, "_dtl"},
- {recursive, true}]}
- ]).
-
-erlydtl_opts(Config) ->
- Opts = rebar_state:get(Config, erlydtl_opts, []),
- Tuples = [{K,V} || {K,V} <- Opts],
- case [L || L <- Opts, is_list(L), not io_lib:printable_list(L)] of
- [] ->
- [lists:keysort(1, Tuples)];
- Lists ->
- lists:map(
- fun(L) ->
- lists:keysort(1,
- lists:foldl(
- fun({K,T}, Acc) ->
- lists:keystore(K, 1, Acc, {K, T})
- end, Tuples, L))
- end, Lists)
- end.
-
option(Opt, DtlOpts) ->
proplists:get_value(Opt, DtlOpts, default(Opt)).
-default(doc_root) -> "templates";
+default(app) -> undefined;
+default(doc_root) -> "priv/templates";
default(out_dir) -> "ebin";
default(source_ext) -> ".dtl";
default(module_ext) -> "_dtl";
@@ -195,62 +180,44 @@ default(custom_tags_dir) -> "";
default(compiler_options) -> [return];
default(recursive) -> true.
-compile_dtl(Config, Source, Target, DtlOpts) ->
- case code:which(erlydtl) of
- non_existing ->
- ?ERROR("~n===============================================~n"
- " You need to install erlydtl to compile DTL templates~n"
- " Download the latest tarball release from github~n"
- " https://github.com/erlydtl/erlydtl/releases~n"
- " and install it into your erlang library dir~n"
- "===============================================~n", []),
- ?FAIL;
- _ ->
- case needs_compile(Source, Target, DtlOpts) of
- true ->
- do_compile(Config, Source, Target, DtlOpts);
- false ->
- skipped
- end
+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(Config, Source, Target, DtlOpts) ->
- %% TODO: Check last mod on target and referenced DTLs here..
-
- %% erlydtl >= 0.8.1 does not use the extra indirection using the
- %% compiler_options. Kept for backward compatibility with older
- %% versions of erlydtl.
+do_compile(State, Source, Target, DtlOpts, Dir, OutDir) ->
CompilerOptions = option(compiler_options, DtlOpts),
Sorted = proplists:unfold(
lists:sort(
- [{out_dir, option(out_dir, DtlOpts)},
- {doc_root, option(doc_root, DtlOpts)},
+ [{out_dir, OutDir},
+ {doc_root, filename:join(Dir, option(doc_root, DtlOpts))},
{custom_tags_dir, option(custom_tags_dir, DtlOpts)},
- {compiler_options, CompilerOptions}
- |CompilerOptions])),
+ {compiler_options, CompilerOptions}])),
%% ensure that doc_root and out_dir are defined,
%% using defaults if necessary
Opts = lists:ukeymerge(1, DtlOpts, Sorted),
- ?INFO("Compiling \"~s\" -> \"~s\" with options:~n ~s",
- [Source, Target, io_lib:format("~p", [Opts])]),
+ ?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
+ list_to_atom(module_name(Target)),
+ Opts) of
{ok, _Mod} ->
ok;
{ok, _Mod, Ws} ->
- rebar_base_compiler:ok_tuple(Config, Source, Ws);
+ rebar_base_compiler:ok_tuple(State, Source, Ws);
error ->
- rebar_base_compiler:error_tuple(Config, Source, [], [], Opts);
+ rebar_base_compiler:error_tuple(State, Source, [], [], Opts);
{error, Es, Ws} ->
- rebar_base_compiler:error_tuple(Config, Source, Es, Ws, Opts)
+ rebar_base_compiler:error_tuple(State, Source, Es, Ws, Opts)
end.
module_name(Target) ->
- F = filename:basename(Target),
- string:substr(F, 1, length(F)-length(".beam")).
+ filename:rootname(filename:basename(Target), ".beam").
needs_compile(Source, Target, DtlOpts) ->
LM = filelib:last_modified(Target),
diff --git a/src/rebar_prv_escriptize.erl b/src/rebar_prv_escriptize.erl
index ad58281..d5708c5 100644
--- a/src/rebar_prv_escriptize.erl
+++ b/src/rebar_prv_escriptize.erl
@@ -61,6 +61,7 @@ desc() ->
"the project's and its dependencies' BEAM files.".
do(State) ->
+ ?INFO("Building escript...", []),
escriptize(State).
escriptize(State0) ->
diff --git a/test/rebar_erlydtl_SUITE.erl b/test/rebar_erlydtl_SUITE.erl
new file mode 100644
index 0000000..c9054fd
--- /dev/null
+++ b/test/rebar_erlydtl_SUITE.erl
@@ -0,0 +1,72 @@
+%% -*- 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() ->
+ ["[]"].
diff --git a/test/rebar_test_utils.erl b/test/rebar_test_utils.erl
index 157c2df..8d999b4 100644
--- a/test/rebar_test_utils.erl
+++ b/test/rebar_test_utils.erl
@@ -236,6 +236,9 @@ check_results(AppDir, Expected) ->
ct:pal("Tarball: ~s-~s", [Name, Vsn]),
Tarball = filename:join([AppDir, "_build", "rel", Name, Name++"-"++Vsn++".tar.gz"]),
?assertNotEqual([], filelib:is_file(Tarball))
+ ; ({file, Filename}) ->
+ ct:pal("Filename: ~s", [Filename]),
+ ?assert(filelib:is_file(Filename))
end, Expected).
write_src_file(Dir, Name) ->