diff --git a/README.md b/README.md index 1936ce7..e5d996b 100644 --- a/README.md +++ b/README.md @@ -100,6 +100,28 @@ linters: - '**/local-lib/**/*' ``` +## Severity + +You can specify the severity of each linter. The severity can be `info`, `refactor`, `convention`, `warning`, `error` or `fatal`. By default the severity of all linters is `error`. + +Linters with severity less than `error` will not be included in the total count of errors and will not cause the command to exit with a non-zero status. + +```yaml +--- +linters: + ErbSafety: + enabled: true + severity: info +``` + +You can set a custom severity for the command running `erblint` with the `--fail-level` option, this will set the minimum severity level to consider when exiting with a non-zero status. + +```sh +# will exit with a non-zero status if there are any linters with +# severity warning or greater +erblint foo.erb --fail-level W +``` + ## Linters | Available Linters | Default | Description | diff --git a/lib/erb_lint/cli.rb b/lib/erb_lint/cli.rb index ee95c75..87570e7 100644 --- a/lib/erb_lint/cli.rb +++ b/lib/erb_lint/cli.rb @@ -362,7 +362,16 @@ def option_parser @options[:enabled_linters] = linters end - opts.on("--fail-level SEVERITY", "Minimum severity for exit with error code") do |level| + opts.on( + "--fail-level SEVERITY", + "Minimum severity for exit with error code.", + " [I] info", + " [R] refactor", + " [C] convention", + " [W] warning", + " [E] error", + " [F] fatal", + ) do |level| parsed_severity = SEVERITY_CODE_TABLE[level.upcase.to_sym] || (SEVERITY_NAMES & [level.downcase]).first if parsed_severity.nil? diff --git a/lib/erb_lint/linter_config.rb b/lib/erb_lint/linter_config.rb index 1e5c3d8..0c91ee1 100644 --- a/lib/erb_lint/linter_config.rb +++ b/lib/erb_lint/linter_config.rb @@ -2,6 +2,7 @@ require "active_support" require "smart_properties" +require "erb_lint/utils/severity_levels" module ERBLint class LinterConfig @@ -21,6 +22,11 @@ def to_array_of(klass) property :enabled, accepts: [true, false], default: false, reader: :enabled? property :exclude, accepts: array_of?(String), default: -> { [] } + property :severity, + accepts: ERBLint::Utils::SeverityLevels::SEVERITY_NAMES, + default: :error, + reader: :severity, + converts: lambda { |value| value.to_sym } def initialize(config = {}) config = config.dup.deep_stringify_keys diff --git a/lib/erb_lint/offense.rb b/lib/erb_lint/offense.rb index 07e73bf..07f7983 100644 --- a/lib/erb_lint/offense.rb +++ b/lib/erb_lint/offense.rb @@ -14,7 +14,7 @@ def initialize(linter, source_range, message, context = nil, severity = nil) @source_range = source_range @message = message @context = context - @severity = severity + @severity = severity || linter.config.severity @disabled = false end diff --git a/spec/erb_lint/linter_config_spec.rb b/spec/erb_lint/linter_config_spec.rb index 52f4c67..c0b0617 100644 --- a/spec/erb_lint/linter_config_spec.rb +++ b/spec/erb_lint/linter_config_spec.rb @@ -13,7 +13,7 @@ let(:config_hash) { {} } it "returns default config" do - expect(subject).to(eq("enabled" => false, "exclude" => [])) + expect(subject).to(eq("enabled" => false, "exclude" => [], "severity" => :error)) end end @@ -97,6 +97,40 @@ class CustomConfig < described_class end end + describe "#severity" do + subject { linter_config.severity } + + context "when no severity is set" do + let(:config_hash) { {} } + it { expect(subject).to(eq(:error)) } + end + + describe "when severity is a valid value" do + valid_severities = ERBLint::Utils::SeverityLevels::SEVERITY_NAMES + + valid_severities.each do |severity| + context "when severity is #{severity}" do + let(:config_hash) { { severity: severity } } + it { expect(subject).to(eq(severity)) } + end + end + end + + context "when severity is an invalid value" do + let(:config_hash) { { severity: "bogus" } } + + it do + expect { subject }.to( + raise_error( + described_class::Error, + "ERBLint::LinterConfig does not accept :bogus as value for the property severity. Only accepts: \ +[:info, :refactor, :convention, :warning, :error, :fatal]", + ), + ) + end + end + end + describe "#excludes_file?" do context "when glob matches" do let(:config_hash) { { exclude: ["vendor/**/*"] } } diff --git a/spec/erb_lint/runner_config_spec.rb b/spec/erb_lint/runner_config_spec.rb index 91bba34..1efc085 100644 --- a/spec/erb_lint/runner_config_spec.rb +++ b/spec/erb_lint/runner_config_spec.rb @@ -126,7 +126,7 @@ class MySchema < ERBLint::LinterConfig it { expect(subject.class).to(eq(ERBLint::Linters::FinalNewline::ConfigSchema)) } it "fills linter config with defaults from schema" do - expect(subject.to_hash).to(eq("enabled" => false, "exclude" => [], "present" => true)) + expect(subject.to_hash).to(eq("enabled" => false, "exclude" => [], "present" => true, "severity" => :error)) end it "is disabled by default" do expect(subject.enabled?).to(eq(false))