diff options
author | Fred Hebert <mononcqc@ferd.ca> | 2014-11-11 00:28:05 +0000 |
---|---|---|
committer | Fred Hebert <mononcqc@ferd.ca> | 2014-11-11 00:31:20 +0000 |
commit | 4ed1c4ef581cb780a4b6e2da7cb4e8243b20a370 (patch) | |
tree | cd775fb6d8c28a127e8626793c6dd355a95da0e9 | |
parent | c832b567dba73ddbed961b265f2018b3f2cb45ae (diff) |
Allow to forcibly overwrite files with templates
-rw-r--r-- | src/rebar_prv_new.erl | 29 | ||||
-rw-r--r-- | src/rebar_templater.erl | 48 |
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]); _ -> |