summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFred Hebert <mononcqc@ferd.ca>2015-12-18 22:44:20 -0500
committerFred Hebert <mononcqc@ferd.ca>2015-12-19 20:16:49 -0500
commit44a30ca52f3c74d19007fd0433f6192fa4ccca79 (patch)
tree12e5be5a54ff9d3bcb692bad3800505f2abe7bae /src
parentddc64cd66b2d6e4e2315ee281b9eabb8bc2e8868 (diff)
Plugin templates enabled
This lets a plugin define templates to be loaded: $ rebar3 new ... proper (plugin): A basic PropEr suite for an OTP application ... $ rebar3 new help proper proper: plugin template (...) Description: A basic PropEr suite for an OTP application Variables: name="suite" (...) ... → rebar3 new proper fakesuite ===> Writing test/prop_fakesuite.erl In this case, proper is a fake template file I've put by hand in _build/default/plugins/rebar3_proper/priv/<somename>/, meaning it will only work as far as it's called from the project's root. The priority order of plugins is now .config > plugin > built-in, such that someone could ensure plugins do not crush their own private templates, but also that custom or plugin templates do overtake built-in ones. It used to be Built-in > .config only. Templates are searched for recursively in the priv/ directory of plugins.
Diffstat (limited to 'src')
-rw-r--r--src/rebar_app_info.erl5
-rw-r--r--src/rebar_prv_new.erl3
-rw-r--r--src/rebar_templater.erl34
3 files changed, 35 insertions, 7 deletions
diff --git a/src/rebar_app_info.erl b/src/rebar_app_info.erl
index 95b4624..9fee4e0 100644
--- a/src/rebar_app_info.erl
+++ b/src/rebar_app_info.erl
@@ -23,6 +23,7 @@
original_vsn/1,
original_vsn/2,
ebin_dir/1,
+ priv_dir/1,
applications/1,
applications/2,
profiles/1,
@@ -361,6 +362,10 @@ out_dir(AppInfo=#app_info_t{}, OutDir) ->
ebin_dir(#app_info_t{out_dir=OutDir}) ->
ec_cnv:to_list(filename:join(OutDir, "ebin")).
+-spec priv_dir(t()) -> file:name().
+priv_dir(#app_info_t{out_dir=OutDir}) ->
+ ec_cnv:to_list(filename:join(OutDir, "priv")).
+
-spec resource_type(t(), pkg | src) -> t().
resource_type(AppInfo=#app_info_t{}, Type) ->
AppInfo#app_info_t{resource_type=Type}.
diff --git a/src/rebar_prv_new.erl b/src/rebar_prv_new.erl
index 71560d5..064315e 100644
--- a/src/rebar_prv_new.erl
+++ b/src/rebar_prv_new.erl
@@ -132,10 +132,13 @@ show_template({Name, Type, Location, Description, Vars}) ->
format_vars(Vars)]).
format_type(escript) -> "built-in";
+format_type(plugin) -> "plugin";
format_type(file) -> "custom".
format_type(escript, _) ->
"built-in template";
+format_type(plugin, Loc) ->
+ io_lib:format("plugin template (~s)", [Loc]);
format_type(file, Loc) ->
io_lib:format("custom template (~s)", [Loc]).
diff --git a/src/rebar_templater.erl b/src/rebar_templater.erl
index f0b2ce8..f687637 100644
--- a/src/rebar_templater.erl
+++ b/src/rebar_templater.erl
@@ -239,6 +239,7 @@ replace_var([H|T], Acc, Vars) ->
%% Load a list of all the files in the escript and on disk
find_templates(State) ->
DiskTemplates = find_disk_templates(State),
+ PluginTemplates = find_plugin_templates(State),
{MainTemplates, Files} =
case rebar_state:escript_path(State) of
undefined ->
@@ -249,19 +250,23 @@ find_templates(State) ->
F = cache_escript_files(State),
{find_escript_templates(F), F}
end,
- AvailTemplates = find_available_templates(DiskTemplates,
- MainTemplates),
+ AvailTemplates = find_available_templates([MainTemplates,
+ PluginTemplates,
+ DiskTemplates]),
?DEBUG("Available templates: ~p\n", [AvailTemplates]),
{AvailTemplates, Files}.
-find_available_templates(TemplateList1, TemplateList2) ->
- AvailTemplates = prioritize_templates(
- tag_names(TemplateList1),
- tag_names(TemplateList2)),
-
+find_available_templates(TemplateListList) ->
+ AvailTemplates = prioritize_templates(TemplateListList),
?DEBUG("Available templates: ~p\n", [AvailTemplates]),
AvailTemplates.
+prioritize_templates([TemplateList]) ->
+ tag_names(TemplateList);
+prioritize_templates([TemplateList | TemplateListList]) ->
+ prioritize_templates(tag_names(TemplateList),
+ prioritize_templates(TemplateListList)).
+
%% Scan the current escript for available files
cache_escript_files(State) ->
{ok, Files} = rebar_utils:escript_foldl(
@@ -299,6 +304,14 @@ find_other_templates(State) ->
rebar_utils:find_files(TemplateDir, ?TEMPLATE_RE)
end.
+%% Fetch template indexes that sit on disk in plugins
+find_plugin_templates(State) ->
+ [{plugin, File}
+ || App <- rebar_state:all_plugin_deps(State),
+ Priv <- [rebar_app_info:priv_dir(App)],
+ Priv =/= undefined,
+ File <- rebar_utils:find_files(Priv, ?TEMPLATE_RE)].
+
%% Take an existing list of templates and tag them by name the way
%% the user would enter it from the CLI
tag_names(List) ->
@@ -316,6 +329,10 @@ prioritize_templates([{Name, Type, File} | Rest], Valid) ->
?DEBUG("Skipping template ~p, due to presence of a built-in "
"template with the same name", [Name]),
prioritize_templates(Rest, Valid);
+ {_, plugin, _} ->
+ ?DEBUG("Skipping template ~p, due to presence of a plugin "
+ "template with the same name", [Name]),
+ prioritize_templates(Rest, Valid);
{_, file, _} ->
?DEBUG("Skipping template ~p, due to presence of a custom "
"template at ~s", [Name, File]),
@@ -327,6 +344,9 @@ prioritize_templates([{Name, Type, File} | Rest], Valid) ->
load_file(Files, escript, Name) ->
{Name, Bin} = lists:keyfind(Name, 1, Files),
Bin;
+load_file(_Files, plugin, Name) ->
+ {ok, Bin} = file:read_file(Name),
+ Bin;
load_file(_Files, file, Name) ->
{ok, Bin} = file:read_file(Name),
Bin.