summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFred Hebert <mononcqc@ferd.ca>2014-11-11 00:28:05 +0000
committerFred Hebert <mononcqc@ferd.ca>2014-11-11 00:31:20 +0000
commit4ed1c4ef581cb780a4b6e2da7cb4e8243b20a370 (patch)
treecd775fb6d8c28a127e8626793c6dd355a95da0e9 /src
parentc832b567dba73ddbed961b265f2018b3f2cb45ae (diff)
Allow to forcibly overwrite files with templates
Diffstat (limited to 'src')
-rw-r--r--src/rebar_prv_new.erl29
-rw-r--r--src/rebar_templater.erl48
2 files changed, 44 insertions, 33 deletions
diff --git a/src/rebar_prv_new.erl b/src/rebar_prv_new.erl
index e22625c..93adeb4 100644
--- a/src/rebar_prv_new.erl
+++ b/src/rebar_prv_new.erl
@@ -17,14 +17,17 @@
-spec init(rebar_state:t()) -> {ok, rebar_state:t()}.
init(State) ->
- State1 = rebar_state:add_provider(State, providers:create([{name, ?PROVIDER},
- {module, ?MODULE},
- {bare, false},
- {deps, ?DEPS},
- {example, "rebar new <template>"},
- {short_desc, "Create new project from templates."},
- {desc, info()},
- {opts, []}])),
+ Provider = providers:create([
+ {name, ?PROVIDER},
+ {module, ?MODULE},
+ {bare, false},
+ {deps, ?DEPS},
+ {example, "rebar new <template>"},
+ {short_desc, "Create new project from templates."},
+ {desc, info()},
+ {opts, [{force, $f, "force", undefined, "overwrite existing files"}]}
+ ]),
+ State1 = rebar_state:add_provider(State, Provider),
{ok, State1}.
-spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}.
@@ -37,7 +40,8 @@ do(State) ->
end,
{ok, State};
[TemplateName | Opts] ->
- ok = rebar_templater:new(TemplateName, parse_opts(Opts), State),
+ Force = is_forced(State),
+ ok = rebar_templater:new(TemplateName, parse_opts(Opts), Force, State),
{ok, State};
[] ->
show_short_templates(rebar_templater:list_templates(State)),
@@ -59,6 +63,13 @@ info() ->
"Valid command line options:~n"
" template= [var=foo,...]~n", []).
+is_forced(State) ->
+ {Args, _} = rebar_state:command_parsed_args(State),
+ case proplists:get_value(force, Args) of
+ undefined -> false;
+ _ -> true
+ end.
+
parse_opts([]) -> [];
parse_opts([Opt|Opts]) -> [parse_opt(Opt, "") | parse_opts(Opts)].
diff --git a/src/rebar_templater.erl b/src/rebar_templater.erl
index 57915f4..40f3165 100644
--- a/src/rebar_templater.erl
+++ b/src/rebar_templater.erl
@@ -26,7 +26,7 @@
%% -------------------------------------------------------------------
-module(rebar_templater).
--export([new/3,
+-export([new/4,
list_templates/1]).
%% API for other utilities that need templating functionality
@@ -43,12 +43,12 @@
%% ===================================================================
%% Apply a template
-new(Template, Vars, State) ->
+new(Template, Vars, Force, State) ->
{AvailTemplates, Files} = find_templates(State),
?DEBUG("Looking for ~p~n", [Template]),
case lists:keyfind(Template, 1, AvailTemplates) of
false -> {not_found, Template};
- TemplateTup -> create(TemplateTup, Files, Vars)
+ TemplateTup -> create(TemplateTup, Files, Vars, Force)
end.
%% Give a list of templates with their expanded content
@@ -157,24 +157,24 @@ drop_var_docs([{K,V}|Rest]) -> [{K,V} | drop_var_docs(Rest)].
%% Load the template index, resolve all variables, and then execute
%% the template.
-create({Template, Type, File}, Files, UserVars) ->
+create({Template, Type, File}, Files, UserVars, Force) ->
TemplateTerms = consult(load_file(Files, Type, File)),
Vars = drop_var_docs(override_vars(UserVars, get_template_vars(TemplateTerms))),
TemplateCwd = filename:dirname(File),
- execute_template(TemplateTerms, Files, {Template, Type, TemplateCwd}, Vars).
+ execute_template(TemplateTerms, Files, {Template, Type, TemplateCwd}, Vars, Force).
%% Run template instructions one at a time.
-execute_template([], _, {Template,_,_}, _) ->
+execute_template([], _, {Template,_,_}, _, _) ->
?DEBUG("Template ~s applied~n", [Template]),
ok;
%% We can't execute the description
-execute_template([{description, _} | Terms], Files, Template, Vars) ->
- execute_template(Terms, Files, Template, Vars);
+execute_template([{description, _} | Terms], Files, Template, Vars, Force) ->
+ execute_template(Terms, Files, Template, Vars, Force);
%% We can't execute variables
-execute_template([{variables, _} | Terms], Files, Template, Vars) ->
- execute_template(Terms, Files, Template, Vars);
+execute_template([{variables, _} | Terms], Files, Template, Vars, Force) ->
+ execute_template(Terms, Files, Template, Vars, Force);
%% Create a directory
-execute_template([{dir, Path} | Terms], Files, Template, Vars) ->
+execute_template([{dir, Path} | Terms], Files, Template, Vars, Force) ->
?DEBUG("Creating directory ~p~n", [Path]),
case ec_file:mkdir_p(expand_path(Path, Vars)) of
ok ->
@@ -183,45 +183,45 @@ execute_template([{dir, Path} | Terms], Files, Template, Vars) ->
?ABORT("Failed while processing template instruction "
"{dir, ~p}: ~p~n", [Path, Reason])
end,
- execute_template(Terms, Files, Template, Vars);
+ execute_template(Terms, Files, Template, Vars, Force);
%% Change permissions on a file
-execute_template([{chmod, File, Perm} | Terms], Files, Template, Vars) ->
+execute_template([{chmod, File, Perm} | Terms], Files, Template, Vars, Force) ->
Path = expand_path(File, Vars),
case file:change_mode(Path, Perm) of
ok ->
- execute_template(Terms, Files, Template, Vars);
+ execute_template(Terms, Files, Template, Vars, Force);
{error, Reason} ->
?ABORT("Failed while processing template instruction "
"{chmod, ~.8#, ~p}: ~p~n", [Perm, File, Reason])
end;
%% Create a raw untemplated file
-execute_template([{file, From, To} | Terms], Files, {Template, Type, Cwd}, Vars) ->
+execute_template([{file, From, To} | Terms], Files, {Template, Type, Cwd}, Vars, Force) ->
?DEBUG("Creating file ~p~n", [To]),
Data = load_file(Files, Type, filename:join(Cwd, From)),
Out = expand_path(To,Vars),
- case write_file(Out, Data, false) of
+ case write_file(Out, Data, Force) of
ok -> ok;
{error, exists} -> ?INFO("File ~p already exists.~n", [Out])
end,
- execute_template(Terms, Files, {Template, Type, Cwd}, Vars);
+ execute_template(Terms, Files, {Template, Type, Cwd}, Vars, Force);
%% Operate on a django template
-execute_template([{template, From, To} | Terms], Files, {Template, Type, Cwd}, Vars) ->
+execute_template([{template, From, To} | Terms], Files, {Template, Type, Cwd}, Vars, Force) ->
?DEBUG("Executing template file ~p~n", [From]),
Out = expand_path(To, Vars),
Tpl = load_file(Files, Type, filename:join(Cwd, From)),
TplName = make_template_name("rebar_template", Out),
{ok, Mod} = erlydtl:compile_template(Tpl, TplName, ?ERLYDTL_COMPILE_OPTS),
{ok, Output} = Mod:render(Vars),
- case write_file(Out, Output, false) of
+ case write_file(Out, Output, Force) of
ok -> ok;
{error, exists} -> ?INFO("File ~p already exists~n", [Out])
end,
- execute_template(Terms, Files, {Template, Type, Cwd}, Vars);
+ execute_template(Terms, Files, {Template, Type, Cwd}, Vars, Force);
%% Unknown
-execute_template([Instruction|Terms], Files, Tpl={Template,_,_}, Vars) ->
+execute_template([Instruction|Terms], Files, Tpl={Template,_,_}, Vars, Force) ->
?WARN("Unknown template instruction ~p in template ~s",
[Instruction, Template]),
- execute_template(Terms, Files, Tpl, Vars).
+ execute_template(Terms, Files, Tpl, Vars, Force).
%% Workaround to allow variable substitution in path names without going
%% through the ErlyDTL compilation step. Parse the string and replace
@@ -346,11 +346,11 @@ write_file(Output, Data, Force) ->
%% perform the function if we're allowed,
%% otherwise just process the next template
- case Force =:= "1" orelse FileExists =:= false of
+ case Force orelse FileExists =:= false of
true ->
ok = filelib:ensure_dir(Output),
case {Force, FileExists} of
- {"1", true} ->
+ {true, true} ->
?INFO("Writing ~s (forcibly overwriting)",
[Output]);
_ ->