瀏覽代碼

Allow to forcibly overwrite files with templates

pull/3/head
Fred Hebert 10 年之前
父節點
當前提交
4ed1c4ef58
共有 2 個檔案被更改,包括 44 行新增33 行删除
  1. +20
    -9
      src/rebar_prv_new.erl
  2. +24
    -24
      src/rebar_templater.erl

+ 20
- 9
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)].

+ 24
- 24
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]);
_ ->

Loading…
取消
儲存