Skip to content
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
11 changes: 6 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
.rebar3
erl_crash.dump
rebar3.crashdump
_*
.rebar3/
/erl_crash.dump
/rebar3.crashdump
_build/
_checkouts/
doc/
logs
test/logs/
31 changes: 2 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,32 +29,5 @@ $ rebar3 lint
Configuration
---

The plugin supports configuration option `elvis_output_format` in `rebar.config`:

```erlang
{elvis_output_format, plain | colors | parsable}. % default: colors
```

It also supports option `elvis` (in `rebar.config`) as you'd find `elvis`'s own
`config` (inside option `elvis`).

If no `elvis` configuration is present in `rebar.config`, the
plug-in will look for an `elvis.config` file in the project root folder
(but only the `config` section will be applied - this is an `elvis` idiosyncrasy).

The output format may then be configured separately in `rebar.config`, as previously
explained.

This is the default configuration if no input is provided:

```erlang
[#{ dirs => ["apps/*/src/**", "src/**"],
filter => "*.erl",
ruleset => erl_files },
#{ dirs => ["."],
filter => "rebar.config",
ruleset => rebar_config },
#{ dirs => ["."],
filter => "elvis.config",
ruleset => elvis_config }]
```
Read [`elvis_core`'s Configuration](https://github.com/inaka/elvis_core?#configuration)
README section for more information.
27 changes: 26 additions & 1 deletion elvis.config
Original file line number Diff line number Diff line change
@@ -1 +1,26 @@
[].
[
{elvis, [
{config, [
#{
dirs => ["src"],
filter => "*.erl",
ruleset => erl_files_strict
},
#{
dirs => ["test"],
filter => "*.erl",
ruleset => erl_files_test
},
#{
dirs => ["."],
filter => "rebar.config",
ruleset => rebar_config
},
#{
dirs => ["."],
filter => ".gitignore",
ruleset => gitignore
}
]}
]}
].
5 changes: 4 additions & 1 deletion rebar.config
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@

%% == Dependencies and plugins ==

{deps, [{elvis_core, "4.1.1"}]}.
{deps, [
{elvis_core,
{git, "https://github.com/inaka/elvis_core.git", {branch, "fix/config-parse-validate"}}}
Comment on lines +14 to +15
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ we shouldn't merge until this is fixed (via releasing elvis_core's linked pull request)

]}.

{project_plugins, [
{rebar3_hank, "~> 1.4.0"},
Expand Down
5 changes: 1 addition & 4 deletions rebar.lock
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
{"1.2.0",
[{<<"elvis_core">>,{pkg,<<"elvis_core">>,<<"4.1.1">>},0},
{<<"katana_code">>,{pkg,<<"katana_code">>,<<"2.4.1">>},1},
[{<<"katana_code">>,{pkg,<<"katana_code">>,<<"2.4.1">>},1},
{<<"zipper">>,{pkg,<<"zipper">>,<<"1.1.0">>},1}]}.
[
{pkg_hash,[
{<<"elvis_core">>, <<"0F69E9F1512C1EA68C65ABC805079DC3A5B22E0E16E0DE8DDDBB780A43D007A9">>},
{<<"katana_code">>, <<"4C116DC6CF6E5ABCFBB95BD904EBEED36D79463D1EED349CF47A828F4723BAC4">>},
{<<"zipper">>, <<"FA775C01BCD33225BE89AF320C10CE61D23943109F4D5CA718551D0C492D7E35">>}]},
{pkg_hash_ext,[
{<<"elvis_core">>, <<"80A562574B8D974A2E7544E9A9455716D04C9E095DBC8C8915E2468031DD1385">>},
{<<"katana_code">>, <<"58EFC63B5D9DABC82230CAB50CDE7F7B259287A690ED699F79A7FA80F49B0B3A">>},
{<<"zipper">>, <<"4644C83AE83EF3C09860CB5ED597B0C759FBBCD64AD5B00A62F51AE48AEF7535">>}]}
].
10 changes: 6 additions & 4 deletions src/rebar3_lint.erl
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ init(State) ->
{ok, State1}.

%% @private
-spec main([]) -> ok | {fail, [elvis_result:file()]}.
main([]) ->
ok = application:load(elvis_core),
elvis_core:rock(
rebar3_lint_prv:default_config()
).
case elvis_config:config() of
{fail, [{throw, {invalid_config, Message}}]} ->
elvis_utils:abort(Message, []);
DefaultConfig ->
ok = elvis_core:rock(DefaultConfig)
end.
122 changes: 29 additions & 93 deletions src/rebar3_lint_prv.erl
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
-module(rebar3_lint_prv).

-export([init/1, do/1]).
-export([default_config/0]).

-define(PROVIDER, lint).
-define(DEPS, [compile, app_discovery]).

%% ===================================================================
%% Public API
Expand All @@ -13,101 +9,41 @@
init(State) ->
Provider =
providers:create([
{name, ?PROVIDER},
{name, lint},
{module, ?MODULE},
{bare, true},
{deps, ?DEPS},
{deps, [compile, app_discovery]},
{example, "rebar3 lint"},
{opts, []},
{short_desc, "A rebar plugin for elvis"},
{desc, "A rebar linter plugin based on elvis"}
{short_desc, "A rebar3 plugin for Elvis"},
{desc, "A rebar3 plugin for Elvis, the Erlang linter"}
]),
{ok, rebar_state:add_provider(State, Provider)}.

-spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, {string(), any()}}.
-spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}.
do(State) ->
Elvis = get_elvis_config(State),
_ = rebar_log:log(info, "elvis analysis starting, this may take a while...", []),
try elvis_core:rock(Elvis) of
ok ->
{ok, State};
{fail, [{throw, Error} | _]} ->
rebar_api:abort("elvis_core threw an exception: ~p", [Error]);
{fail, _} ->
{error, "Linting failed"}
catch
Error ->
rebar_api:abort("elvis_core threw an exception: ~p", [Error])
ErrorOrOkElvisConfig =
case elvis_config:config() of
{fail, [{throw, {invalid_config, Message0}}]} ->
% When we implement warnings_as_errors, revisit this
% Maybe think about making this the default for `elvis_config:config()`
% with an output notice
{error, Message0};
[] ->
elvis_utils:warn("Elvis: elvis.config not defined; using default", []),
{ok, elvis_config:default()};
ElvisConfig0 ->
{ok, ElvisConfig0}
end,
case ErrorOrOkElvisConfig of
{error, Message} ->
{error, io_lib:format("Elvis: invalid configuration: ~s", [Message])};
{ok, ElvisConfig} ->
_ = elvis_utils:info("analysis starting, this may take a while...", []),
case elvis_core:rock(ElvisConfig) of
ok ->
{ok, State};
{fail, _} ->
{error, "Elvis: linting failed"}
end
end.

-spec get_elvis_config(rebar_state:t()) -> elvis_config:configs().
get_elvis_config(State) ->
try_elvis_config_rebar(State).

-spec try_elvis_config_rebar(rebar_state:t()) -> elvis_config:configs().
try_elvis_config_rebar(State) ->
rebar_api:debug("Looking for Elvis in rebar.config", []),
handle_output_format(State),
case rebar_state:get(State, elvis, no_config) of
no_config ->
try_elvis_config_file(State);
Config ->
Config
end.

-spec handle_output_format(rebar_state:t()) -> ok.
handle_output_format(State) ->
case rebar_state:get(State, elvis_output_format, no_config) of
no_config ->
ok;
plain ->
application:set_env(elvis_core, output_format, plain);
colors ->
application:set_env(elvis_core, output_format, colors);
parsable ->
application:set_env(elvis_core, output_format, parsable);
Other ->
rebar_api:abort(
"~p is not a valid elvis output format. Must be either plain, colors or"
"parsable",
[Other]
)
end.

-spec try_elvis_config_file(rebar_state:t()) -> elvis_config:configs().
try_elvis_config_file(State) ->
Filename =
filename:join(
rebar_dir:root_dir(State), "elvis.config"
),
rebar_api:debug("Looking for Elvis in ~s", [Filename]),
try elvis_config:from_file(Filename) of
[] ->
rebar_api:debug("Using default Elvis configuration", []),
default_config();
Config ->
Config
catch
Error ->
rebar_api:abort("Error reading Elvis config from ~s: ~p", [Filename, Error])
end.

-spec default_config() -> elvis_config:configs().
default_config() ->
[
#{
dirs => ["apps/*/src/**", "src/**"],
filter => "*.erl",
ruleset => erl_files
},
#{
dirs => ["."],
filter => "rebar.config",
ruleset => rebar_config
},
#{
dirs => ["."],
filter => "elvis.config",
ruleset => elvis_config
}
].
27 changes: 27 additions & 0 deletions test/elvis.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
% A bad config. to use in tests
[
{elvis, [
{config, [
#{
dirs => ["src"],
filter => "*.erl",
ruleset => erl_files_strict
},
#{
dirs => ["test"],
filter => "*.erl",
ruleset => erl_files_test
},
#{
dirs => ["."],
filter => "rebar.config",
ruleset => rebar_config
},
#{
dirs => ["."],
filter => ".gitignore",
ruleset => gitignore
}
]}
]}
].
3 changes: 2 additions & 1 deletion test/test_app_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ test_app(_Config) ->
rebar_state:new()
),
{ok, _} = rebar3_lint_prv:do(GoodState),
ok = file:set_cwd("test"),
BadState =
rebar_state:set(
GoodState,
Expand All @@ -26,4 +27,4 @@ test_app(_Config) ->
}
]
),
{error, "Linting failed"} = rebar3_lint_prv:do(BadState).
{error, "Elvis: linting failed"} = rebar3_lint_prv:do(BadState).
Loading