Skip to content

Commit

Permalink
Merge pull request #48 from soranoba/bbmustache-cmd
Browse files Browse the repository at this point in the history
command-line script
  • Loading branch information
soranoba authored May 16, 2020
2 parents 636815b + bb8700f commit 9cf055a
Show file tree
Hide file tree
Showing 25 changed files with 393 additions and 9 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ _build
.rebar3
_checkouts
benchmarks/.tmp
/bbmustache
21 changes: 15 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
CWD=$(shell pwd)

.PHONY: ct
all: compile eunit ct xref dialyze edoc
all: compile escriptize eunit ct xref dialyze edoc

compile:
@./rebar3 as dev compile

xref:
@./rebar3 xref
@./rebar3 as dev xref

clean:
@./rebar3 clean

ct:
@./rebar3 ct
ct: escriptize
@CMD_TOOL=$(CWD)/bbmustache ./rebar3 ct

cover:
@./rebar3 cover
Expand All @@ -20,15 +22,22 @@ eunit:
@./rebar3 eunit

edoc:
@./rebar3 as dev edoc
@./rebar3 as doc edoc

start:
@./rebar3 as dev shell

dialyze:
@./rebar3 dialyzer
@./rebar3 as dev dialyzer

bench:
@./rebar3 as test compile
@./rebar3 as bench compile
@./benchmarks/bench.escript

escriptize:
@./rebar3 as dev escriptize
@cp _build/dev/bin/bbmustache .

install: escriptize
cp bbmustache /usr/local/bin
16 changes: 14 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,19 @@ Associative array
<<"hoge">>
```
### Use as a command-line tool
```bash
make escriptize
echo '{"name", "hoge"}.' > vars.config
echo '{{name}}' > template.mustache
./bbmustache -d vars.config template.mustache
hoge
```
Data files (-d) support a single assoc list, a single map, and [consult](https://erlang.org/doc/man/file.html#consult-1) format.<br>
Note: the behind term has a high priority in all cases. it is a result of supporting to allow for embedding relative file paths as in [config](http://erlang.org/doc/man/config.html).
### More information
- For the alias of mustache, Please refer to [ManPage](http://mustache.github.io/mustache.5.html) and [Specification](https://github.com/mustache/spec)
- For the options of this library, please see [doc](doc)
Expand Down Expand Up @@ -144,11 +157,10 @@ ok
3> bbmustache:render(<<"<h1>{{{title}}}</h1>">>, #{<<"title">> => #{<<"nested">> => <<"value">>}}, [{key_type, binary}, {value_serializer, fun(X) -> jsone:encode(X) end}]).
<<"<h1>{\"nested\": \"value\"}</h1>">>
4> bbmustache:render(<<"<h1>{{title}}</h1>">>, #{<<"title">> => #{<<"nested">> => <<"value">>}}, [{key_type, binary}, {value_serializer, fun(X) -> jsone:encode(X) end}]).
4> bbmustache:render(<<"<h1>{{title}}</h1>">>, #{<<"title">> => #{<<"nested">> => <<"value">>}}, [{key_type, binary}, {value_serializer, fun(X) -> jsone:encode(X) end}]).
<<"<h1>{&quot;nested&quot;:&quot;value&quot;}</h1>">>
```
## Attention
- Lambda expression is included wasted processing.
- Because it is optimized to `parse_binary/1` + `compile/2`.
Expand Down
144 changes: 144 additions & 0 deletions ct/bbmustache_escript_SUITE.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
%% @copyright 2020 Hinagiku Soranoba All Rights Reserved.

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

%%----------------------------------------------------------------------------------------------------------------------
%% 'common_test' Callback API
%%----------------------------------------------------------------------------------------------------------------------

all() ->
[
{group, long},
{group, short},
{group, with_args},

help, all_key_and_format_type, multiple_data_files, enoent
].

groups() ->
[
{long, [version, help, key_type]},
{short, [version, help, key_type]},
{with_args, [version, help]}
].

init_per_suite(Config) ->
Escript = case os:getenv("CMD_TOOL") of
Path when is_list(Path) -> Path
end,
[{escript, Escript} | Config].

end_per_suite(_) ->
ok.

init_per_testcase(TestCase, Config) ->
Args = case {group_name(Config), TestCase} of
{long, version} -> ["--version"];
{short, version} -> ["-v"];
{with_args, version} -> ["-v", "file"];

{long, help} -> ["--help"];
{short, help} -> ["-h"];
{with_args, help} -> ["-h", "file"];
{undefined, help} -> [];

{long, key_type} -> ["--key-type", "atom",
"--data-file", data_file_name(atom, basic, Config),
?config(data_dir, Config) ++ "template.mustache"];
{short, key_type} -> ["-k", "atom",
"-d", data_file_name(atom, basic, Config),
?config(data_dir, Config) ++ "template.mustache"];
_ -> []
end,
[{args, Args} | Config].

end_per_testcase(_, _) ->
ok.

%%----------------------------------------------------------------------------------------------------------------------
%% Common Test Functions
%%----------------------------------------------------------------------------------------------------------------------

version(Config) ->
Got = run(Config),
?assertMatch({match, _}, re:run(Got, "bbmustache v[0-9]\.[0-9]\.[0-9].*")).

help(Config) ->
Got = run(Config),
?assertMatch({match, _}, re:run(Got, "Usage: .*")).

key_type(Config) ->
Got = run(Config),
Expect = read_file("template.result", Config),
?assertEqual(Expect, Got).

all_key_and_format_type(Config) ->
KeyTypes = [atom, string, binary, undefined],
FormatTypes = [basic, assoc, maps],
Expect = read_file("template.result", Config),
TempalteFile = ?config(data_dir, Config) ++ "template.mustache",
ok = lists:foreach(fun({KeyType, FormatType}) ->
ct:log("KeyType = ~p, FormatType = ~p", [KeyType, FormatType]),
Got = run(Config, options(KeyType, FormatType, Config) ++ [TempalteFile]),
?assertEqual(Expect, Got)
end, [{K, F} || K <- KeyTypes, F <- FormatTypes]).

multiple_data_files(Config) ->
KeyTypes = [atom, string, binary, undefined],
FormatTypes = [basic, assoc, maps],
Expect = read_file("template.overlay.result", Config),
TempalteFile = ?config(data_dir, Config) ++ "template.mustache",
ok = lists:foreach(fun({KeyType, FormatType}) ->
ct:log("KeyType = ~p, FormatType = ~p", [KeyType, FormatType]),
Got = run(Config, options(KeyType, FormatType, Config)
++ ["-d", data_file_name(KeyType, overlays, Config)] ++ [TempalteFile]),
?assertEqual(Expect, Got)
end, [{K, F} || K <- KeyTypes, F <- FormatTypes]).

enoent(Config) ->
Got0 = run(Config, ["-d", "no_file", ?config(data_dir, Config) ++ "template.mustache"]),
?assertEqual(<<"ERROR: no_file is unable to read. (enoent)\n">>, Got0),

Got1 = run(Config, ["no_file"]),
?assertEqual(<<"ERROR: no_file is unable to read.\n">>, Got1).

%%----------------------------------------------------------------------------------------------------------------------
%% Internal Functions
%%----------------------------------------------------------------------------------------------------------------------

-spec group_name([term()]) -> atom().
group_name(Config) ->
proplists:get_value(name, ?config(tc_group_properties, Config)).

-spec run([term()]) -> binary().
run(Config) ->
run(Config, []).

-spec run([term()], [string()]) -> binary().
run(Config, Args) ->
Cmd = ?config(escript, Config) ++ " " ++ string:join(?config(args, Config) ++ Args, " "),
ct:log("$ ~s", [Cmd]),
Ret = os:cmd(Cmd),
ct:log("~s", [Ret]),
list_to_binary(Ret).

-spec read_file(file:filename_all(), [term()]) -> binary().
read_file(FileName, Config) ->
{ok, File} = file:read_file(filename:join([?config(data_dir, Config), FileName])),
File.

-spec data_file_name(atom(), atom(), [term()]) -> string().
data_file_name(undefined, FormatType, Config) ->
data_file_name(string, FormatType, Config);
data_file_name(KeyType, FormatType, Config) ->
?config(data_dir, Config) ++ atom_to_list(KeyType) ++ "." ++ atom_to_list(FormatType).

-spec options(atom(), atom(), [term()]) -> [string()].
options(undefined, FormatType, Config) ->
["-d", data_file_name(string, FormatType, Config)];
options(KeyType, FormatType, Config) ->
["-k", atom_to_list(KeyType),
"-d", data_file_name(KeyType, FormatType, Config)].

8 changes: 8 additions & 0 deletions ct/bbmustache_escript_SUITE_data/atom.assoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[
{name, "mustache"},
"atom.include",
{data, [
"a",
"b"
]}
].
8 changes: 8 additions & 0 deletions ct/bbmustache_escript_SUITE_data/atom.basic
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{name, "mustache"}.

"atom.include".

{data, [
"a",
"b"
]}.
1 change: 1 addition & 0 deletions ct/bbmustache_escript_SUITE_data/atom.include
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{name, "bbmustache"}.
7 changes: 7 additions & 0 deletions ct/bbmustache_escript_SUITE_data/atom.maps
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#{
name => "bbmustache",
data => [
"a",
"b"
]
}.
1 change: 1 addition & 0 deletions ct/bbmustache_escript_SUITE_data/atom.overlays
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{name, "overlays"}.
8 changes: 8 additions & 0 deletions ct/bbmustache_escript_SUITE_data/binary.assoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[
{<<"name">>, "mustache"},
"binary.include",
{<<"data">>, [
"a",
"b"
]}
].
6 changes: 6 additions & 0 deletions ct/bbmustache_escript_SUITE_data/binary.basic
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{<<"name">>, "mustache"}.
"binary.include".
{<<"data">>, [
"a",
"b"
]}.
1 change: 1 addition & 0 deletions ct/bbmustache_escript_SUITE_data/binary.include
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{<<"name">>, "bbmustache"}.
7 changes: 7 additions & 0 deletions ct/bbmustache_escript_SUITE_data/binary.maps
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#{
<<"name">> => "bbmustache",
<<"data">> => [
"a",
"b"
]
}.
1 change: 1 addition & 0 deletions ct/bbmustache_escript_SUITE_data/binary.overlays
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{<<"name">>, "overlays"}.
1 change: 1 addition & 0 deletions ct/bbmustache_escript_SUITE_data/partial.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{name}} is Binary pattern match Based Mustache template engine for Erlang/OTP.
8 changes: 8 additions & 0 deletions ct/bbmustache_escript_SUITE_data/string.assoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[
{"name", "mustache"},
"string.include",
{"data", [
"a",
"b"
]}
].
6 changes: 6 additions & 0 deletions ct/bbmustache_escript_SUITE_data/string.basic
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{"name", "mustache"}.
"string.include".
{"data", [
"a",
"b"
]}.
1 change: 1 addition & 0 deletions ct/bbmustache_escript_SUITE_data/string.include
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"name", "bbmustache"}.
7 changes: 7 additions & 0 deletions ct/bbmustache_escript_SUITE_data/string.maps
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#{
"name" => "bbmustache",
"data" => [
"a",
"b"
]
}.
1 change: 1 addition & 0 deletions ct/bbmustache_escript_SUITE_data/string.overlays
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"name", "overlays"}.
8 changes: 8 additions & 0 deletions ct/bbmustache_escript_SUITE_data/template.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
The engine name ie {{name}}.
It can also resolve relative paths.
{{> partial}}

data:
{{# data}}
- {{.}}
{{/ data}}
7 changes: 7 additions & 0 deletions ct/bbmustache_escript_SUITE_data/template.overlay.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
The engine name ie overlays.
It can also resolve relative paths.
overlays is Binary pattern match Based Mustache template engine for Erlang/OTP.

data:
- a
- b
7 changes: 7 additions & 0 deletions ct/bbmustache_escript_SUITE_data/template.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
The engine name ie bbmustache.
It can also resolve relative paths.
bbmustache is Binary pattern match Based Mustache template engine for Erlang/OTP.

data:
- a
- b
18 changes: 17 additions & 1 deletion rebar.config
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@

{ct_opts, [{dir, "ct"}]}.

{git_vsn, [{env_key, git_vsn},
{describe_opt, "--tags --abbrev=10"},
{separate, true}]}.

{escript_name, bbmustache}.
{escript_incl_apps, [getopt]}.
{escript_comment, "%% https://github.com/soranoba/bbmustache \n"}.

{profiles, [{test, [{erl_opts, [export_all]},
{deps,
[
Expand All @@ -34,7 +42,15 @@
]},
{plugins, [rebar3_raw_deps]}
]},
{dev, [{deps,
{dev, [{erl_opts, [{d, bbmustache_escriptize}]},
{deps,
[
{getopt, "1.0.1"}
]},
{plugins, [rebar3_git_vsn]},
{provider_hooks, [{post, [{compile, git_vsn}]}]}
]},
{doc, [{deps,
[
{edown, ".*", {git, "git://github.com/uwiger/edown.git", {branch, "master"}}}
]}
Expand Down
Loading

0 comments on commit 9cf055a

Please sign in to comment.