Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pluggable parsers #207

Open
wants to merge 2 commits into
base: develop-3.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions src/cuttlefish_conf.erl
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
-export([
generate/1,
generate_file/2,
file/1,
files/1,
file/2,
files/2,
is_variable_defined/2,
pretty_datatype/1]).

Expand All @@ -38,11 +38,11 @@
is_variable_defined(VariableDef, Conf) ->
lists:any(fun({X, _}) -> cuttlefish_variable:is_fuzzy_match(X, VariableDef) end, Conf).

-spec files([file:name()]) -> conf() | cuttlefish_error:errorlist().
files(ListOfConfFiles) ->
-spec files([file:name()], atom()) -> conf() | cuttlefish_error:errorlist().
files(ListOfConfFiles, ParserMod) ->
{ValidConf, Errors} = lists:foldl(
fun(ConfFile, {ConfAcc, ErrorAcc}) ->
case cuttlefish_conf:file(ConfFile) of
case cuttlefish_conf:file(ConfFile, ParserMod) of
{errorlist, ErrorList} ->
{ConfAcc, ErrorList ++ ErrorAcc};
Conf ->
Expand All @@ -61,9 +61,9 @@ files(ListOfConfFiles) ->
_ -> {errorlist, Errors}
end.

-spec file(file:name()) -> conf() | cuttlefish_error:errorlist().
file(Filename) ->
case conf_parse:file(Filename) of
-spec file(file:name(), atom()) -> conf() | cuttlefish_error:errorlist().
file(Filename, ParserMod) ->
case ParserMod:file(Filename) of
{error, Reason} ->
%% Reason is an atom via file:open
{errorlist, [{error, {file_open, {Filename, Reason}}}]};
Expand Down
47 changes: 35 additions & 12 deletions src/cuttlefish_escript.erl
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,18 @@
cli_options() ->
%% Option Name, Short Code, Long Code, Argument Spec, Help Message
[
{help, $h, "help", undefined, "Print this usage page"},
{etc_dir, $e, "etc_dir", {string, "/etc"}, "etc dir"},
{dest_dir, $d, "dest_dir", string, "specifies the directory to write the config file to"},
{dest_file, $f, "dest_file", {string, "app"}, "the file name to write"},
{schema_dir, $s, "schema_dir", string, "a directory containing .schema files"},
{schema_file, $i, "schema_file", string, "individual schema file, will be processed in command line order, after -s"},
{conf_file, $c, "conf_file", string, "a cuttlefish conf file, multiple files allowed"},
{app_config, $a, "app_config", string, "the advanced erlangy app.config"},
{log_level, $l, "log_level", {string, "notice"}, "log level for cuttlefish output"},
{print_schema, $p, "print", undefined, "prints schema mappings on stderr"},
{max_history, $m, "max_history", {integer, 3}, "the maximum number of generated config files to keep"}
{help, $h, "help", undefined, "Print this usage page"},
{etc_dir, $e, "etc_dir", {string, "/etc"}, "etc dir"},
{dest_dir, $d, "dest_dir", string, "specifies the directory to write the config file to"},
{dest_file, $f, "dest_file", {string, "app"}, "the file name to write"},
{schema_dir, $s, "schema_dir", string, "a directory containing .schema files"},
{schema_file, $i, "schema_file", string, "individual schema file, will be processed in command line order, after -s"},
{conf_file, $c, "conf_file", string, "a cuttlefish conf file, multiple files allowed"},
{app_config, $a, "app_config", string, "the advanced erlangy app.config"},
{log_level, $l, "log_level", {string, "notice"}, "log level for cuttlefish output"},
{print_schema, $p, "print", undefined, "prints schema mappings on stderr"},
{max_history, $m, "max_history", {integer, 3}, "the maximum number of generated config files to keep"},
{parser, undefined, "parser", atom, "parser module to parse config file"}
].

%% LOL! I wanted this to be halt 0, but honestly, if this escript does anything
Expand Down Expand Up @@ -303,8 +304,13 @@ load_schema(ParsedArgs) ->

load_conf(ParsedArgs) ->
ConfFiles = proplists:get_all_values(conf_file, ParsedArgs),
Parser = proplists:get_value(parser, ParsedArgs),
ParserMod = case Parser of
undefined -> conf_parse;
_ -> ensure_parser(Parser)
end,
lager:debug("ConfFiles: ~p", [ConfFiles]),
case cuttlefish_conf:files(ConfFiles) of
case cuttlefish_conf:files(ConfFiles, ParserMod) of
{errorlist, Errors} ->
_ = [ lager:error(cuttlefish_error:xlate(E)) ||
{error, E} <- Errors],
Expand All @@ -314,6 +320,23 @@ load_conf(ParsedArgs) ->
GoodConf
end.

ensure_parser(Module) ->
case code:ensure_loaded(Module) of
{module, Module} ->
case erlang:function_exported(Module, file, 1) of
true -> Module;
false ->
lager:error("Unable to parse config. No function ~p:file/1 exported", [Module]),
stop_deactivate(),
{error, function_not_exported}

end;
{error, Reason} ->
lager:error("Unable to parse config. Unable to load parser module ~p. Reason: ~p", [Module, Reason]),
stop_deactivate(),
{error, Reason}
end.

-spec writable_destination_path([proplists:property()]) -> file:filename() | error.
writable_destination_path(ParsedArgs) ->
EtcDir = proplists:get_value(etc_dir, ParsedArgs),
Expand Down
9 changes: 9 additions & 0 deletions src/cuttlefish_parse.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
-module(cuttlefish_parse).

-type variable() :: [string()].
-type conf() :: [{variable(), term()}].
-type parse_result() :: {error, term()}
| {conf(), binary(), {{line, integer()}, {column, integer()}}}
| conf().

-callback file(iolist()) -> parse_result().