Skip to content

Commit

Permalink
add encoding specifier support for template.
Browse files Browse the repository at this point in the history
  • Loading branch information
AoiMoe committed Feb 18, 2020
1 parent c0d016d commit 8c8819b
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 3 deletions.
10 changes: 9 additions & 1 deletion src/rebar_string.erl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
%% Compatibility exports
-export([join/2, split/2, lexemes/2, trim/1, trim/3, uppercase/1, lowercase/1, chr/2]).
%% Util exports
-export([consult/1]).
-export([consult/1, consult/2]).

-ifdef(unicode_str).

Expand Down Expand Up @@ -59,6 +59,14 @@ chr(Str, Char) -> string:chr(Str, Char).
consult(Str) ->
consult([], unicode:characters_to_list(Str), []).

%% @doc
%% Given a string or binary and its encoding,
%% parse it into a list of terms, ala file:consult/1
-spec consult(unicode:chardata(), unicode:encoding())
-> {error, term()} | [term()].
consult(Str, Encoding) ->
consult([], unicode:characters_to_list(Str, Encoding), []).

consult(Cont, Str, Acc) ->
case erl_scan:tokens(Cont, Str, 0) of
{done, Result, Remaining} ->
Expand Down
16 changes: 14 additions & 2 deletions src/rebar_templater.erl
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
-export([new/4,
list_templates/1,
render/2]).
-ifdef(TEST).
-export([consult_template/3]).
-endif.


-include("rebar.hrl").
Expand Down Expand Up @@ -59,7 +62,7 @@ list_templates(State) ->

%% Expand a single template's value
list_template(Files, {Name, Type, File}, State) ->
case rebar_string:consult(binary_to_list(load_file(Files, Type, File))) of
case consult_template(Files, Type, File) of
{error, Reason} ->
{error, {consult, File, Reason}};
TemplateTerms ->
Expand Down Expand Up @@ -158,7 +161,7 @@ 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, Force, State) ->
TemplateTerms = rebar_string:consult(binary_to_list(load_file(Files, Type, File))),
TemplateTerms = consult_template(Files, Type, File),
Vars = drop_var_docs(override_vars(UserVars, get_template_vars(TemplateTerms, State))),
maybe_warn_about_name(Vars),
TemplateCwd = filename:dirname(File),
Expand Down Expand Up @@ -439,3 +442,12 @@ render(Bin, Context) ->
[{key_type, atom},
{escape_fun, fun(X) -> X end}] % disable HTML-style escaping
).

consult_template(Files, Type, File) ->
TemplateBin = load_file(Files, Type, File),
Encoding =
case epp:read_encoding_from_binary(TemplateBin) of
none -> epp:default_encoding();
X -> X
end,
rebar_string:consult(TemplateBin, Encoding).
39 changes: 39 additions & 0 deletions test/rebar_string_SUITE.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
%% coding:utf-8

-module(rebar_string_SUITE).
-compile(export_all).

-include_lib("common_test/include/ct.hrl").
-include_lib("eunit/include/eunit.hrl").

all() ->
[
consult_2_latin1_test,
consult_2_utf8_test
].

init_per_suite(Config) -> Config.
end_per_suite(_Config) -> ok.

init_per_testcase(_Case, Config) -> Config.
end_per_testcase(_Case, _Config) -> ok.

consult_2_test_common(Encoding) ->
%% Generate UCS string containing all printable characters of latin-1 area.
String = lists:seq(16#A1, 16#AC) ++ lists:seq(16#AE, 16#FE),
Expected = [{test, String}],
Sample = "{test, \"" ++ String ++ "\"}.",
SampleBin = unicode:characters_to_binary(Sample, utf8, Encoding),
Result = rebar_string:consult(SampleBin, Encoding),
?assertEqual(Expected, Result),
ok.

consult_2_latin1_test() ->
[{doc, "consult latin1 binary"}].
consult_2_latin1_test(_Config) ->
consult_2_test_common(latin1).

consult_2_utf8_test() ->
[{doc, "consult utf8 binary"}].
consult_2_utf8_test(_Config) ->
consult_2_test_common(utf8).
63 changes: 63 additions & 0 deletions test/rebar_templater_SUITE.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
%% coding:utf-8

-module(rebar_templater_SUITE).
-compile(export_all).

-include_lib("common_test/include/ct.hrl").
-include_lib("eunit/include/eunit.hrl").

all() ->
[
consult_template_latin1_test,
consult_template_utf8_test
].

init_per_suite(Config) -> Config.
end_per_suite(_Config) -> ok.

init_per_testcase(Case, Config)
when Case =:= consult_template_latin1_test;
Case =:= consult_template_utf8_test ->
%% Generate UCS string containing all printable characters of latin-1 area.
Description = lists:seq(16#A1, 16#AC) ++ lists:seq(16#AE, 16#FE),
Expected = [{description, Description}],
SampleTemplate = "{description, \"" ++ Description ++ "\"}.\n",
Path = generate_sample_template_file(Case, SampleTemplate, Config),
[{template_file_path, Path}, {expected, Expected} | Config];
init_per_testcase(_Case, Config) -> Config.

end_per_testcase(_Case, _Config) -> ok.

generate_sample_template_file(Case, Content, Config) ->
CaseName = atom_to_list(Case),
{Encoding, EncodingName} =
case string:str(CaseName, "latin1") of
0 -> {utf8, "utf-8"};
_ -> {latin1, "latin-1"}
end,
PrivDir = ?config(priv_dir, Config),
Path = filename:join([PrivDir, CaseName ++ ".template"]),
{ok, FH} = file:open(Path, [write, {encoding, Encoding}]),
try
io:format(FH, "%% coding:~s~n~s", [EncodingName, Content])
after
file:close(FH)
end,
Path.

consult_template_test_common(Config) ->
Expected = ?config(expected, Config),
Path = ?config(template_file_path, Config),
Result = rebar_templater:consult_template([], file, Path),
?assertEqual(Expected, Result),
ok.

consult_template_latin1_test() ->
[{doc, "parse test for latin1 template file"}].
consult_template_latin1_test(Config) ->
consult_template_test_common(Config).

consult_template_utf8_test() ->
[{doc, "parse test for utf8 template file"}].
consult_template_utf8_test(Config) ->
consult_template_test_common(Config).

0 comments on commit 8c8819b

Please sign in to comment.