Skip to content

Commit

Permalink
Add compile option overrides (#18)
Browse files Browse the repository at this point in the history
One can now specify a list of tuples with some file-pattern and the
overrides it should do for that file-pattern. Use {file, Filename} for
overriding specific files, and {re, Regex} to override for all files with
full path matching the regex.

Fixes #8
  • Loading branch information
sebastiw authored Jun 21, 2023
1 parent f866d26 commit 2ade47c
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 9 deletions.
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,10 @@ The options are as follows:
tuple-element is one of `wildcard` | `file` | `dir` and the second
the filename in string format. Defaults to
`[{wildcard, \"**/*.asn1\"}]`.

* `--overrides -O` An Erlang term consisting of a tuple-list of the
compile options that will override the options per file. The first
tuple-element is one of `file` | `re` and the second the filename
or match pattern in string format.

Example:
```
Expand All @@ -119,7 +122,10 @@ As mentioned, these options can be put in your `rebar.config` file:
```
{asn1_args, [{encoding, per},
{verbose, true},
{compile_opts, [der, compact_bit_string]}]}.
{compile_opts, [der, compact_bit_string]},
{overrides, [{{file, "CAP_PHASE1.set.asn1"}, [{encoding, [ber]},
{compile_opts, [{i, "asn1-lib/"}]}]},
{{re, "/uper/"}, [{encoding, uper}]}]}]}.
```

Options in `rebar.config` will be overridden by command-line options.
56 changes: 49 additions & 7 deletions src/provider_asn1_compile.erl
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ init(State) ->
"An Erlang term consisting of a tuple-list of the specific order "
"to compile the ASN.1 files where the first tuple-element is "
"one of `wildcard' | `file' | `dir' and the second the filename "
"in string format. Defaults to `[{wildcard, \"**/*.asn1\"}]'."}
"in string format. Defaults to `[{wildcard, \"**/*.asn1\"}]'."},
{overrides, $O, "overrides", binary,
"An Erlang term [{file | re, string}, [Opt]}] with specific options."}
]},
{short_desc, "Compile ASN.1 with Rebar3"},
{desc, "Compile ASN.1 with Rebar3"}
Expand All @@ -41,7 +43,9 @@ resolve_special_args(PreState) ->
lists:foldl(fun (F, State) -> F(State) end,
DefaultState,
[fun resolve_compile_opts/1,
fun resolve_compile_order/1]).
fun resolve_compile_order/1,
fun resolve_compile_overrides/1
]).

resolve_compile_opts(State) ->
CompileOpts = provider_asn1_util:get_arg(State, compile_opts),
Expand All @@ -62,6 +66,15 @@ resolve_compile_order(State) ->
provider_asn1_util:set_arg(State, compile_order, NewCompileOrder);
true -> State
end.
resolve_compile_overrides(State) ->
FileCompileOpts = provider_asn1_util:get_arg(State, overrides),
if
is_binary(FileCompileOpts) ->
{ok, Toks, _} = erl_scan:string(binary_to_list(FileCompileOpts) ++ "."),
{ok, NewFileCompileOpts} = erl_parse:parse_term(Toks),
provider_asn1_util:set_arg(State, overrides, NewFileCompileOpts);
true -> State
end.

-spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}.
do(PreState) ->
Expand Down Expand Up @@ -90,7 +103,7 @@ process_app(State, AppPath) ->
Asns ->
ensure_dir(State, GenPath),
ensure_dir(State, IncludePath),
lists:foreach(fun(AsnFile) -> generate_asn(State, GenPath, AsnFile) end, Asns),
lists:foreach(fun(AsnFile) -> generate_asn(State, GenPath, AsnFile, AppPath) end, Asns),
move_asns(State, GenPath, SrcPath, IncludePath, Asns)
end.

Expand All @@ -107,14 +120,14 @@ move_asns(State, GenPath, SrcPath, IncludePath, Asns) ->
format_error(Reason) ->
provider_asn1_util:format_error(Reason).

generate_asn(State, Path, AsnFile) ->
generate_asn(State, Path, AsnFile, AppPath) ->
rebar_api:info("~s", [AsnFile]),
Args = provider_asn1_util:get_args(State),
Args = apply_file_overrides(AsnFile, provider_asn1_util:get_args(State)),
provider_asn1_util:verbose_out(State, "Args: ~p", [Args]),
Encoding = proplists:get_value(encoding, Args),
Verbose = proplists:get_value(verbose, Args),
CompileArgs = [verbose || Verbose] ++ [noobj, Encoding, {outdir, Path}]
++ proplists:get_value(compile_opts, Args),
CompileOpts = fix_paths(AppPath, proplists:get_value(compile_opts, Args)),
CompileArgs = CompileOpts ++ [verbose || Verbose] ++ [noobj, Encoding, {outdir, Path}],
provider_asn1_util:verbose_out(State, "Beginning compile with opts: ~p", [CompileArgs]),
case asn1ct:compile(AsnFile, CompileArgs) of
{error, E} ->
Expand Down Expand Up @@ -167,3 +180,32 @@ is_latest(ASNFileName, ASNPath, GenPath) ->
TargetFileName = filename:basename(ASNFileName, ".asn1") ++ ".erl",
Target = filename:join(GenPath, TargetFileName),
filelib:last_modified(Source) > filelib:last_modified(Target).

apply_file_overrides(File, Args) ->
{[OverridesArgs], OtherArgs} = proplists:split(Args, [overrides]),
case OverridesArgs of
[{overrides, Overrides}] -> match_file_overrides(File, Overrides);
[] -> []
end ++ OtherArgs.

match_file_overrides(_File, []) -> [];
match_file_overrides(File, [{{file, BName}, Args}|Rest]) ->
case filename:basename(File) of
BName -> Args;
_ -> match_file_overrides(File, Rest)
end;
match_file_overrides(File, [{{re, Pat}, Args}|Rest]) ->
case re:run(File, Pat, [{capture, none}]) of
nomatch -> match_file_overrides(File, Rest);
match -> Args
end;
match_file_overrides(File, [ _ | Rest ]) ->
match_file_overrides(File, Rest).

fix_paths(AppPath, Args) ->
% there are issues when using relative paths in nested applications,
% make them absolut be prepending the AppPath.
lists:map(fun
({i, Path}) -> {i, filename:absname(Path, AppPath)};
(Arg) -> Arg
end, Args).

0 comments on commit 2ade47c

Please sign in to comment.