From 09626e4c9872abd71246f6e6165243e61bbf5c5a Mon Sep 17 00:00:00 2001 From: Anderson Macedo Date: Wed, 18 Mar 2020 04:45:32 +0000 Subject: [PATCH 01/24] Add helper methods on Offense to acces line and column more easily --- lib/erb_lint/offense.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/erb_lint/offense.rb b/lib/erb_lint/offense.rb index a39ca567..fa3341e3 100644 --- a/lib/erb_lint/offense.rb +++ b/lib/erb_lint/offense.rb @@ -31,5 +31,13 @@ def ==(other) def line_range Range.new(source_range.line, source_range.last_line) end + + def line_number + line_range.begin + end + + def column + source_range.column + end end end From 8dd39781835026af9ceedc432c24a2b13a9f20d6 Mon Sep 17 00:00:00 2001 From: Anderson Macedo Date: Wed, 18 Mar 2020 04:45:59 +0000 Subject: [PATCH 02/24] Add base formatter class for offenses --- lib/erb_lint/formatter.rb | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 lib/erb_lint/formatter.rb diff --git a/lib/erb_lint/formatter.rb b/lib/erb_lint/formatter.rb new file mode 100644 index 00000000..1accff98 --- /dev/null +++ b/lib/erb_lint/formatter.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module ERBLint + class Formatter + def initialize(offenses, filename, autocorrect) + @offenses = offenses + @filename = filename + @autocorrect = autocorrect + end + + def format + offenses.map { |offense| format_offense(offense) } + end + + private + + attr_reader :offenses, :filename, :autocorrect + end +end From d86791c5774d9fe29358c6a7a7147d8fa20f7c8c Mon Sep 17 00:00:00 2001 From: Anderson Macedo Date: Wed, 18 Mar 2020 04:46:18 +0000 Subject: [PATCH 03/24] Add test suite for default formatter --- .../formatters/default_formatter_spec.rb | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 spec/erb_lint/formatters/default_formatter_spec.rb diff --git a/spec/erb_lint/formatters/default_formatter_spec.rb b/spec/erb_lint/formatters/default_formatter_spec.rb new file mode 100644 index 00000000..d2e6715a --- /dev/null +++ b/spec/erb_lint/formatters/default_formatter_spec.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe ERBLint::Formatters::DefaultFormatter do + describe '.format' do + subject { described_class.new(offenses, filename, autocorrect).format } + + let(:filename) { 'app/views/subscriptions/_loader.html.erb' } + let(:offenses) do + [ + instance_double(ERBLint::Offense, + message: 'Extra space detected where there should be no space.', + line_number: 1, + column: 7), + instance_double(ERBLint::Offense, + message: 'Remove newline before `%>` to match start of tag.', + line_number: 52, + column: 10), + ] + end + + context 'when autocorrect is false' do + let(:autocorrect) { false } + + it "generates formatted offenses without no corrected warning" do + result = subject + + expect(result.size).to(eq(2)) + + expect(result[0]).to(eq(<<~OUT)) + Extra space detected where there should be no space. + In file: app/views/subscriptions/_loader.html.erb:1 + + OUT + + expect(result[1]).to(eq(<<~OUT)) + Remove newline before `%>` to match start of tag. + In file: app/views/subscriptions/_loader.html.erb:52 + + OUT + end + end + + context 'when autocorrect is true' do + let(:autocorrect) { true } + + it 'generates formatted offenses with no corrected warning' do + result = subject + + expect(result.size).to(eq(2)) + + expect(result[0]).to(eq(<<~OUT)) + Extra space detected where there should be no space.\e[31m (not autocorrected)\e[0m + In file: app/views/subscriptions/_loader.html.erb:1 + + OUT + + expect(result[1]).to(eq(<<~OUT)) + Remove newline before `%>` to match start of tag.\e[31m (not autocorrected)\e[0m + In file: app/views/subscriptions/_loader.html.erb:52 + + OUT + end + end + end +end From fc96ed791aae6280ef20d225337db1b5a1c676c7 Mon Sep 17 00:00:00 2001 From: Anderson Macedo Date: Wed, 18 Mar 2020 04:46:47 +0000 Subject: [PATCH 04/24] Load formatters --- lib/erb_lint.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/erb_lint.rb b/lib/erb_lint.rb index 7393dc2f..b4744032 100644 --- a/lib/erb_lint.rb +++ b/lib/erb_lint.rb @@ -10,8 +10,14 @@ require 'erb_lint/runner_config' require 'erb_lint/runner' require 'erb_lint/version' +require 'erb_lint/formatter' # Load linters Dir[File.expand_path('erb_lint/linters/**/*.rb', File.dirname(__FILE__))].each do |file| require file end + +# Load formatters +Dir[File.expand_path('erb_lint/formatters/**/*.rb', File.dirname(__FILE__))].each do |file| + require file +end From b053e531de5427a4fafbdb5e7893b25622be0846 Mon Sep 17 00:00:00 2001 From: Anderson Macedo Date: Wed, 18 Mar 2020 04:47:06 +0000 Subject: [PATCH 05/24] Implement default formatter --- lib/erb_lint/formatters/default_formatter.rb | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 lib/erb_lint/formatters/default_formatter.rb diff --git a/lib/erb_lint/formatters/default_formatter.rb b/lib/erb_lint/formatters/default_formatter.rb new file mode 100644 index 00000000..e945e4cb --- /dev/null +++ b/lib/erb_lint/formatters/default_formatter.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module ERBLint + module Formatters + class DefaultFormatter < Formatter + private + + def format_offense(offense) + <<~EOF + #{offense.message}#{Rainbow(' (not autocorrected)').red if autocorrect} + In file: #{filename}:#{offense.line_number} + + EOF + end + end + end +end From eb249ba773a061638beba255dd0c37ea8374f890 Mon Sep 17 00:00:00 2001 From: Anderson Macedo Date: Wed, 18 Mar 2020 04:47:40 +0000 Subject: [PATCH 06/24] Implement compact formatter --- lib/erb_lint/formatters/compact_formatter.rb | 18 +++++++++++ .../formatters/compact_formatter_spec.rb | 30 +++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 lib/erb_lint/formatters/compact_formatter.rb create mode 100644 spec/erb_lint/formatters/compact_formatter_spec.rb diff --git a/lib/erb_lint/formatters/compact_formatter.rb b/lib/erb_lint/formatters/compact_formatter.rb new file mode 100644 index 00000000..98dc74b5 --- /dev/null +++ b/lib/erb_lint/formatters/compact_formatter.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +module ERBLint + module Formatters + class CompactFormatter < Formatter + private + + def format_offense(offense) + [ + "#{filename}:", + "#{offense.line_number}:", + "#{offense.column}: ", + offense.message.to_s, + ].join + end + end + end +end diff --git a/spec/erb_lint/formatters/compact_formatter_spec.rb b/spec/erb_lint/formatters/compact_formatter_spec.rb new file mode 100644 index 00000000..5438ea06 --- /dev/null +++ b/spec/erb_lint/formatters/compact_formatter_spec.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe ERBLint::Formatters::CompactFormatter do + describe '.format' do + subject { described_class.new(offenses, filename, false).format } + + let(:filename) { 'app/views/users/show.html.erb' } + let(:offenses) do + [ + instance_double(ERBLint::Offense, + message: 'Extra space detected where there should be no space.', + line_number: 61, + column: 10), + instance_double(ERBLint::Offense, + message: 'Remove multiple trailing newline at the end of the file.', + line_number: 125, + column: 1), + ] + end + + it "generates formatted offenses" do + expect(subject).to(eq([ + 'app/views/users/show.html.erb:61:10: Extra space detected where there should be no space.', + 'app/views/users/show.html.erb:125:1: Remove multiple trailing newline at the end of the file.' + ])) + end + end +end From b6161a3976bc2911ecf183734fc216346a54e36f Mon Sep 17 00:00:00 2001 From: Anderson Macedo Date: Wed, 18 Mar 2020 13:11:07 +0000 Subject: [PATCH 07/24] Rename default formatter to multiline --- .../formatters/{default_formatter.rb => multiline_formatter.rb} | 2 +- .../{default_formatter_spec.rb => multiline_formatter_spec.rb} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename lib/erb_lint/formatters/{default_formatter.rb => multiline_formatter.rb} (88%) rename spec/erb_lint/formatters/{default_formatter_spec.rb => multiline_formatter_spec.rb} (97%) diff --git a/lib/erb_lint/formatters/default_formatter.rb b/lib/erb_lint/formatters/multiline_formatter.rb similarity index 88% rename from lib/erb_lint/formatters/default_formatter.rb rename to lib/erb_lint/formatters/multiline_formatter.rb index e945e4cb..303a0038 100644 --- a/lib/erb_lint/formatters/default_formatter.rb +++ b/lib/erb_lint/formatters/multiline_formatter.rb @@ -2,7 +2,7 @@ module ERBLint module Formatters - class DefaultFormatter < Formatter + class MultilineFormatter < Formatter private def format_offense(offense) diff --git a/spec/erb_lint/formatters/default_formatter_spec.rb b/spec/erb_lint/formatters/multiline_formatter_spec.rb similarity index 97% rename from spec/erb_lint/formatters/default_formatter_spec.rb rename to spec/erb_lint/formatters/multiline_formatter_spec.rb index d2e6715a..00addf84 100644 --- a/spec/erb_lint/formatters/default_formatter_spec.rb +++ b/spec/erb_lint/formatters/multiline_formatter_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -describe ERBLint::Formatters::DefaultFormatter do +describe ERBLint::Formatters::MultilineFormatter do describe '.format' do subject { described_class.new(offenses, filename, autocorrect).format } From b20ce7016d1de530332c4df4eea0755afcd4714f Mon Sep 17 00:00:00 2001 From: Anderson Macedo Date: Wed, 18 Mar 2020 13:49:33 +0000 Subject: [PATCH 08/24] Fix offenses --- spec/erb_lint/formatters/compact_formatter_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/erb_lint/formatters/compact_formatter_spec.rb b/spec/erb_lint/formatters/compact_formatter_spec.rb index 5438ea06..308d3f9b 100644 --- a/spec/erb_lint/formatters/compact_formatter_spec.rb +++ b/spec/erb_lint/formatters/compact_formatter_spec.rb @@ -19,11 +19,11 @@ column: 1), ] end - + it "generates formatted offenses" do expect(subject).to(eq([ 'app/views/users/show.html.erb:61:10: Extra space detected where there should be no space.', - 'app/views/users/show.html.erb:125:1: Remove multiple trailing newline at the end of the file.' + 'app/views/users/show.html.erb:125:1: Remove multiple trailing newline at the end of the file.', ])) end end From cfcea2f804a0da01f76e1fb28be531a7458581d1 Mon Sep 17 00:00:00 2001 From: Anderson Macedo Date: Wed, 18 Mar 2020 13:50:39 +0000 Subject: [PATCH 09/24] Add --format param --- lib/erb_lint/cli.rb | 40 ++++++++++++++++++++++++------- spec/erb_lint/cli_spec.rb | 50 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 8 deletions(-) diff --git a/lib/erb_lint/cli.rb b/lib/erb_lint/cli.rb index 46c204f6..0a1672d5 100644 --- a/lib/erb_lint/cli.rb +++ b/lib/erb_lint/cli.rb @@ -30,6 +30,7 @@ def initialize @config = nil @files = [] @stats = Stats.new + @formatter_klass = Formatters::MultilineFormatter end def run(args = ARGV) @@ -126,15 +127,13 @@ def run_with_corrections(runner, filename) file_content = corrector.corrected_content runner.clear_offenses end + offenses = runner.offenses + @stats.found += offenses.size - @stats.found += runner.offenses.size - runner.offenses.each do |offense| - puts <<~EOF - #{offense.message}#{Rainbow(' (not autocorrected)').red if autocorrect?} - In file: #{relative_filename(filename)}:#{offense.line_range.begin} - - EOF - end + formatter = @formatter_klass.new(offenses, filename, autocorrect?) + formatter + .format + .each { |formatted_offense| puts formatted_offense } end def correct(processed_source, offenses) @@ -258,6 +257,11 @@ def option_parser end end + opts.on("--format FORMAT", format_options_help) do |format| + @formatter_klass = "#{ERBLint::Formatters}::#{format.camelize}Formatter".safe_constantize + failure!(invalid_format_error_message(format)) if @formatter_klass.nil? + end + opts.on("--lint-all", "Lint all files matching configured glob [default: #{DEFAULT_LINT_ALL_GLOB}]") do |config| @options[:lint_all] = config end @@ -289,5 +293,25 @@ def option_parser end end end + + def format_options_help + "Report offenses in the given format: "\ + "(#{available_formatters.join(', ')}) (default: multiline)" + end + + def invalid_format_error_message(given_format) + formats = available_formatters.map { |format| " - #{format}\n" } + "#{given_format}: is not a valid format. Available formats:\n#{formats.join}" + end + + def available_formatters + Formatters + .constants + .select { |constant| Formatters.const_get(constant).is_a?(Class) } + .map(&:to_s) + .map(&:underscore) + .map { |klass_name| klass_name.sub("_formatter", "") } + .sort + end end end diff --git a/spec/erb_lint/cli_spec.rb b/spec/erb_lint/cli_spec.rb index 794e0cb7..febb32fc 100644 --- a/spec/erb_lint/cli_spec.rb +++ b/spec/erb_lint/cli_spec.rb @@ -73,6 +73,13 @@ def run(_processed_source) it 'shows usage' do expect { subject }.to(output(/erblint \[options\] \[file1, file2, ...\]/).to_stdout) end + + it 'shows format instructions' do + expect { subject }.to( + output(/Report offenses in the given format: \(compact, multiline\) \(default: multiline\)/).to_stdout + ) + end + it 'is successful' do expect(subject).to(be(true)) end @@ -258,6 +265,49 @@ def run(_processed_source) end end + context 'with --format compact' do + let(:args) do + [ + '--enable-linter', 'linter_with_errors,final_newline', + '--format', 'compact', + linted_dir + ] + end + + it 'shows all error messages and line numbers' do + expect { subject }.to(output(Regexp.new(Regexp.escape(<<~EOF))).to_stdout) + /app/views/template.html.erb:1:1: fake message from a fake linter + /app/views/template.html.erb:1:19: Missing a trailing newline at the end of the file. + EOF + end + + it 'is not successful' do + expect(subject).to(be(false)) + end + end + + context 'with invalid --format option' do + let(:args) do + [ + '--enable-linter', 'linter_with_errors,final_newline', + '--format', 'nonexistentformat', + linted_dir + ] + end + + it 'shows all error messages and line numbers' do + expect { subject }.to(output(Regexp.new(Regexp.escape(<<~EOF.strip))).to_stderr) + nonexistentformat: is not a valid format. Available formats: + - compact + - multiline + EOF + end + + it 'is not successful' do + expect(subject).to(be(false)) + end + end + context 'when no errors are found' do let(:args) { ['--enable-linter', 'linter_without_errors', linted_dir] } From b2b411678df27e6a1fc3e5678cdaa4d6e0ee72fe Mon Sep 17 00:00:00 2001 From: Anderson Macedo Date: Wed, 18 Mar 2020 13:54:22 +0000 Subject: [PATCH 10/24] Refactoring formatter class to get better api --- lib/erb_lint/cli.rb | 6 +++--- lib/erb_lint/formatter.rb | 7 +++---- spec/erb_lint/formatters/compact_formatter_spec.rb | 2 +- spec/erb_lint/formatters/multiline_formatter_spec.rb | 2 +- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/lib/erb_lint/cli.rb b/lib/erb_lint/cli.rb index 0a1672d5..5595cb58 100644 --- a/lib/erb_lint/cli.rb +++ b/lib/erb_lint/cli.rb @@ -130,10 +130,10 @@ def run_with_corrections(runner, filename) offenses = runner.offenses @stats.found += offenses.size - formatter = @formatter_klass.new(offenses, filename, autocorrect?) + formatter = @formatter_klass.new(filename, autocorrect?) formatter - .format - .each { |formatted_offense| puts formatted_offense } + .format(offenses) + .each { |offense| puts offense } end def correct(processed_source, offenses) diff --git a/lib/erb_lint/formatter.rb b/lib/erb_lint/formatter.rb index 1accff98..72a59023 100644 --- a/lib/erb_lint/formatter.rb +++ b/lib/erb_lint/formatter.rb @@ -2,18 +2,17 @@ module ERBLint class Formatter - def initialize(offenses, filename, autocorrect) - @offenses = offenses + def initialize(filename, autocorrect) @filename = filename @autocorrect = autocorrect end - def format + def format(offenses) offenses.map { |offense| format_offense(offense) } end private - attr_reader :offenses, :filename, :autocorrect + attr_reader :filename, :autocorrect end end diff --git a/spec/erb_lint/formatters/compact_formatter_spec.rb b/spec/erb_lint/formatters/compact_formatter_spec.rb index 308d3f9b..5acb744a 100644 --- a/spec/erb_lint/formatters/compact_formatter_spec.rb +++ b/spec/erb_lint/formatters/compact_formatter_spec.rb @@ -4,7 +4,7 @@ describe ERBLint::Formatters::CompactFormatter do describe '.format' do - subject { described_class.new(offenses, filename, false).format } + subject { described_class.new(filename, false).format(offenses) } let(:filename) { 'app/views/users/show.html.erb' } let(:offenses) do diff --git a/spec/erb_lint/formatters/multiline_formatter_spec.rb b/spec/erb_lint/formatters/multiline_formatter_spec.rb index 00addf84..b971537c 100644 --- a/spec/erb_lint/formatters/multiline_formatter_spec.rb +++ b/spec/erb_lint/formatters/multiline_formatter_spec.rb @@ -4,7 +4,7 @@ describe ERBLint::Formatters::MultilineFormatter do describe '.format' do - subject { described_class.new(offenses, filename, autocorrect).format } + subject { described_class.new(filename, autocorrect).format(offenses) } let(:filename) { 'app/views/subscriptions/_loader.html.erb' } let(:offenses) do From 49b1e8ce3dfeef5a248477539b57479f2702a2e2 Mon Sep 17 00:00:00 2001 From: Anderson Macedo Date: Wed, 18 Mar 2020 14:35:13 +0000 Subject: [PATCH 11/24] Improve inheritance checking from Formatter class --- lib/erb_lint/cli.rb | 6 +++--- lib/erb_lint/formatter.rb | 9 +++++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/lib/erb_lint/cli.rb b/lib/erb_lint/cli.rb index 5595cb58..7d089758 100644 --- a/lib/erb_lint/cli.rb +++ b/lib/erb_lint/cli.rb @@ -305,10 +305,10 @@ def invalid_format_error_message(given_format) end def available_formatters - Formatters - .constants - .select { |constant| Formatters.const_get(constant).is_a?(Class) } + Formatter + .descendants .map(&:to_s) + .map(&:demodulize) .map(&:underscore) .map { |klass_name| klass_name.sub("_formatter", "") } .sort diff --git a/lib/erb_lint/formatter.rb b/lib/erb_lint/formatter.rb index 72a59023..2955d151 100644 --- a/lib/erb_lint/formatter.rb +++ b/lib/erb_lint/formatter.rb @@ -2,6 +2,15 @@ module ERBLint class Formatter + def self.inherited(klass) + @descendants ||= [] + @descendants << klass + end + + def self.descendants + @descendants || [] + end + def initialize(filename, autocorrect) @filename = filename @autocorrect = autocorrect From 4796bb9858d02bb689dfb59fe585ad405af6eff5 Mon Sep 17 00:00:00 2001 From: Anderson Macedo Date: Wed, 18 Mar 2020 14:44:37 +0000 Subject: [PATCH 12/24] Fix rubocop offenses --- lib/erb_lint/formatter.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/erb_lint/formatter.rb b/lib/erb_lint/formatter.rb index 2955d151..c61f3bcd 100644 --- a/lib/erb_lint/formatter.rb +++ b/lib/erb_lint/formatter.rb @@ -6,7 +6,7 @@ def self.inherited(klass) @descendants ||= [] @descendants << klass end - + def self.descendants @descendants || [] end From ffee034b0df80d70f76196b71d6b82b6174fa88e Mon Sep 17 00:00:00 2001 From: Anderson Macedo Date: Thu, 19 Mar 2020 03:59:09 +0000 Subject: [PATCH 13/24] Remove manual hook to get descendants and use activesupport ext --- lib/erb_lint/formatter.rb | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/lib/erb_lint/formatter.rb b/lib/erb_lint/formatter.rb index c61f3bcd..6995103d 100644 --- a/lib/erb_lint/formatter.rb +++ b/lib/erb_lint/formatter.rb @@ -1,27 +1,19 @@ # frozen_string_literal: true +require 'active_support/core_ext/class' module ERBLint class Formatter - def self.inherited(klass) - @descendants ||= [] - @descendants << klass - end - - def self.descendants - @descendants || [] - end + delegate :files, to: :stats - def initialize(filename, autocorrect) - @filename = filename + def initialize(stats, autocorrect) @autocorrect = autocorrect + @stats = stats end - def format(offenses) - offenses.map { |offense| format_offense(offense) } - end + def format; end private - attr_reader :filename, :autocorrect + attr_reader :stats, :autocorrect end end From db8d589050ca483cec29a3b94a93ff4bd287dcdd Mon Sep 17 00:00:00 2001 From: Anderson Macedo Date: Thu, 19 Mar 2020 03:59:49 +0000 Subject: [PATCH 14/24] Extract logic to report all output to formatters --- lib/erb_lint/cli.rb | 29 +++++---------- lib/erb_lint/formatters/compact_formatter.rb | 36 ++++++++++++++++++- .../formatters/multiline_formatter.rb | 4 +-- 3 files changed, 45 insertions(+), 24 deletions(-) diff --git a/lib/erb_lint/cli.rb b/lib/erb_lint/cli.rb index 7d089758..0fe0ba3f 100644 --- a/lib/erb_lint/cli.rb +++ b/lib/erb_lint/cli.rb @@ -17,11 +17,12 @@ class ExitWithFailure < RuntimeError; end class ExitWithSuccess < RuntimeError; end class Stats - attr_accessor :found, :corrected, :exceptions + attr_accessor :found, :corrected, :exceptions, :files def initialize @found = 0 @corrected = 0 @exceptions = 0 + @files = {} end end @@ -73,20 +74,7 @@ def run(args = ARGV) end end - if @stats.corrected > 0 - corrected_found_diff = @stats.found - @stats.corrected - if corrected_found_diff > 0 - warn(Rainbow( - "#{@stats.corrected} error(s) corrected and #{corrected_found_diff} error(s) remaining in ERB files" - ).red) - else - puts Rainbow("#{@stats.corrected} error(s) corrected in ERB files").green - end - elsif @stats.found > 0 - warn(Rainbow("#{@stats.found} error(s) were found in ERB files").red) - else - puts Rainbow("No errors were found in ERB files").green - end + @formatter_klass.new(@stats, autocorrect?).format @stats.found == 0 && @stats.exceptions == 0 rescue OptionParser::InvalidOption, OptionParser::InvalidArgument, ExitWithFailure => e @@ -127,13 +115,12 @@ def run_with_corrections(runner, filename) file_content = corrector.corrected_content runner.clear_offenses end - offenses = runner.offenses - @stats.found += offenses.size + offenses_filename = relative_filename(filename) + offenses = runner.offenses || [] - formatter = @formatter_klass.new(filename, autocorrect?) - formatter - .format(offenses) - .each { |offense| puts offense } + @stats.found += offenses.size + @stats.files[offenses_filename] ||= [] + @stats.files[offenses_filename] |= offenses end def correct(processed_source, offenses) diff --git a/lib/erb_lint/formatters/compact_formatter.rb b/lib/erb_lint/formatters/compact_formatter.rb index 98dc74b5..552e7bc4 100644 --- a/lib/erb_lint/formatters/compact_formatter.rb +++ b/lib/erb_lint/formatters/compact_formatter.rb @@ -3,9 +3,19 @@ module ERBLint module Formatters class CompactFormatter < Formatter + def format + files.each do |filename, offenses| + offenses.each do |offense| + puts format_offense(filename, offense) + end + end + + report_summary + end + private - def format_offense(offense) + def format_offense(filename, offense) [ "#{filename}:", "#{offense.line_number}:", @@ -13,6 +23,30 @@ def format_offense(offense) offense.message.to_s, ].join end + + def report_summary + if stats.corrected > 0 + report_corrected_offenses + elsif stats.found > 0 + warn(Rainbow("#{stats.found} error(s) were found in ERB files").red) + else + puts Rainbow("No errors were found in ERB files").green + end + end + + def report_corrected_offenses + corrected_found_diff = stats.found - stats.corrected + + if corrected_found_diff > 0 + message = Rainbow( + "#{stats.corrected} error(s) corrected and #{corrected_found_diff} error(s) remaining in ERB files" + ).red + + warn(message) + else + puts Rainbow("#{stats.corrected} error(s) corrected in ERB files").green + end + end end end end diff --git a/lib/erb_lint/formatters/multiline_formatter.rb b/lib/erb_lint/formatters/multiline_formatter.rb index 303a0038..9879a885 100644 --- a/lib/erb_lint/formatters/multiline_formatter.rb +++ b/lib/erb_lint/formatters/multiline_formatter.rb @@ -2,10 +2,10 @@ module ERBLint module Formatters - class MultilineFormatter < Formatter + class MultilineFormatter < CompactFormatter private - def format_offense(offense) + def format_offense(filename, offense) <<~EOF #{offense.message}#{Rainbow(' (not autocorrected)').red if autocorrect} In file: #{filename}:#{offense.line_number} From b33d31427892769d27cf050ba746a5351d8f2613 Mon Sep 17 00:00:00 2001 From: Anderson Macedo Date: Thu, 19 Mar 2020 04:03:50 +0000 Subject: [PATCH 15/24] Move stats class to separated file --- lib/erb_lint/stats.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 lib/erb_lint/stats.rb diff --git a/lib/erb_lint/stats.rb b/lib/erb_lint/stats.rb new file mode 100644 index 00000000..ebdb76f0 --- /dev/null +++ b/lib/erb_lint/stats.rb @@ -0,0 +1,12 @@ +module ERBLint + class Stats + attr_accessor :found, :corrected, :exceptions, :files + + def initialize + @found = 0 + @corrected = 0 + @exceptions = 0 + @files = {} + end + end +end \ No newline at end of file From a2539a2187edeff63d2bc348ad901766c7881de8 Mon Sep 17 00:00:00 2001 From: Anderson Macedo Date: Thu, 19 Mar 2020 04:37:31 +0000 Subject: [PATCH 16/24] Extract all output logic to formatters --- lib/erb_lint.rb | 1 + lib/erb_lint/cli.rb | 10 ----- lib/erb_lint/stats.rb | 15 ++++---- .../formatters/compact_formatter_spec.rb | 38 +++++++++++++++---- .../formatters/multiline_formatter_spec.rb | 36 ++++++++---------- 5 files changed, 55 insertions(+), 45 deletions(-) diff --git a/lib/erb_lint.rb b/lib/erb_lint.rb index b4744032..b9bf1f8e 100644 --- a/lib/erb_lint.rb +++ b/lib/erb_lint.rb @@ -10,6 +10,7 @@ require 'erb_lint/runner_config' require 'erb_lint/runner' require 'erb_lint/version' +require 'erb_lint/stats' require 'erb_lint/formatter' # Load linters diff --git a/lib/erb_lint/cli.rb b/lib/erb_lint/cli.rb index 0fe0ba3f..b2fa25a5 100644 --- a/lib/erb_lint/cli.rb +++ b/lib/erb_lint/cli.rb @@ -16,16 +16,6 @@ class CLI class ExitWithFailure < RuntimeError; end class ExitWithSuccess < RuntimeError; end - class Stats - attr_accessor :found, :corrected, :exceptions, :files - def initialize - @found = 0 - @corrected = 0 - @exceptions = 0 - @files = {} - end - end - def initialize @options = {} @config = nil diff --git a/lib/erb_lint/stats.rb b/lib/erb_lint/stats.rb index ebdb76f0..3d66e1be 100644 --- a/lib/erb_lint/stats.rb +++ b/lib/erb_lint/stats.rb @@ -1,12 +1,13 @@ +# frozen_string_literal: true module ERBLint class Stats attr_accessor :found, :corrected, :exceptions, :files - - def initialize - @found = 0 - @corrected = 0 - @exceptions = 0 - @files = {} + + def initialize(found: 0, corrected: 0, exceptions: 0, files: {}) + @found = found + @corrected = corrected + @exceptions = exceptions + @files = files end end -end \ No newline at end of file +end diff --git a/spec/erb_lint/formatters/compact_formatter_spec.rb b/spec/erb_lint/formatters/compact_formatter_spec.rb index 5acb744a..b2d5d031 100644 --- a/spec/erb_lint/formatters/compact_formatter_spec.rb +++ b/spec/erb_lint/formatters/compact_formatter_spec.rb @@ -4,10 +4,19 @@ describe ERBLint::Formatters::CompactFormatter do describe '.format' do - subject { described_class.new(filename, false).format(offenses) } + subject { described_class.new(stats, false).format } - let(:filename) { 'app/views/users/show.html.erb' } - let(:offenses) do + let(:stats) do + ERBLint::Stats.new( + found: 4, + files: { + 'app/views/users/show.html.erb' => show_file_offenses, + 'app/views/shared/_notifications.html.erb' => notification_file_offenses + } + ) + end + + let(:show_file_offenses) do [ instance_double(ERBLint::Offense, message: 'Extra space detected where there should be no space.', @@ -20,11 +29,26 @@ ] end + let(:notification_file_offenses) do + [ + instance_double(ERBLint::Offense, + message: 'Indent with spaces instead of tabs.', + line_number: 3, + column: 1), + instance_double(ERBLint::Offense, + message: 'Extra space detected where there should be no space.', + line_number: 7, + column: 1), + ] + end + it "generates formatted offenses" do - expect(subject).to(eq([ - 'app/views/users/show.html.erb:61:10: Extra space detected where there should be no space.', - 'app/views/users/show.html.erb:125:1: Remove multiple trailing newline at the end of the file.', - ])) + expect { subject }.to(output(<<~MESSAGE).to_stdout) + app/views/users/show.html.erb:61:10: Extra space detected where there should be no space. + app/views/users/show.html.erb:125:1: Remove multiple trailing newline at the end of the file. + app/views/shared/_notifications.html.erb:3:1: Indent with spaces instead of tabs. + app/views/shared/_notifications.html.erb:7:1: Extra space detected where there should be no space. + MESSAGE end end end diff --git a/spec/erb_lint/formatters/multiline_formatter_spec.rb b/spec/erb_lint/formatters/multiline_formatter_spec.rb index b971537c..d6b6e950 100644 --- a/spec/erb_lint/formatters/multiline_formatter_spec.rb +++ b/spec/erb_lint/formatters/multiline_formatter_spec.rb @@ -4,9 +4,17 @@ describe ERBLint::Formatters::MultilineFormatter do describe '.format' do - subject { described_class.new(filename, autocorrect).format(offenses) } + subject { described_class.new(stats, autocorrect).format } + + let(:stats) do + ERBLint::Stats.new( + found: 2, + files: { + 'app/views/subscriptions/_loader.html.erb' => offenses, + } + ) + end - let(:filename) { 'app/views/subscriptions/_loader.html.erb' } let(:offenses) do [ instance_double(ERBLint::Offense, @@ -24,21 +32,14 @@ let(:autocorrect) { false } it "generates formatted offenses without no corrected warning" do - result = subject - - expect(result.size).to(eq(2)) - - expect(result[0]).to(eq(<<~OUT)) + expect { subject }.to(output(<<~MESSAGE).to_stdout) Extra space detected where there should be no space. In file: app/views/subscriptions/_loader.html.erb:1 - OUT - - expect(result[1]).to(eq(<<~OUT)) Remove newline before `%>` to match start of tag. In file: app/views/subscriptions/_loader.html.erb:52 - OUT + MESSAGE end end @@ -46,21 +47,14 @@ let(:autocorrect) { true } it 'generates formatted offenses with no corrected warning' do - result = subject - - expect(result.size).to(eq(2)) - - expect(result[0]).to(eq(<<~OUT)) + expect { subject }.to(output(<<~MESSAGE).to_stdout) Extra space detected where there should be no space.\e[31m (not autocorrected)\e[0m In file: app/views/subscriptions/_loader.html.erb:1 - OUT - - expect(result[1]).to(eq(<<~OUT)) Remove newline before `%>` to match start of tag.\e[31m (not autocorrected)\e[0m In file: app/views/subscriptions/_loader.html.erb:52 - - OUT + + MESSAGE end end end From 590fbfb7c7e0356b8aeb2286a7331511dbb55614 Mon Sep 17 00:00:00 2001 From: Anderson Macedo Date: Thu, 19 Mar 2020 04:50:54 +0000 Subject: [PATCH 17/24] Fix warnings --- spec/erb_lint/formatters/compact_formatter_spec.rb | 2 +- spec/erb_lint/formatters/multiline_formatter_spec.rb | 11 ++--------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/spec/erb_lint/formatters/compact_formatter_spec.rb b/spec/erb_lint/formatters/compact_formatter_spec.rb index b2d5d031..4f0635da 100644 --- a/spec/erb_lint/formatters/compact_formatter_spec.rb +++ b/spec/erb_lint/formatters/compact_formatter_spec.rb @@ -11,7 +11,7 @@ found: 4, files: { 'app/views/users/show.html.erb' => show_file_offenses, - 'app/views/shared/_notifications.html.erb' => notification_file_offenses + 'app/views/shared/_notifications.html.erb' => notification_file_offenses, } ) end diff --git a/spec/erb_lint/formatters/multiline_formatter_spec.rb b/spec/erb_lint/formatters/multiline_formatter_spec.rb index d6b6e950..43e85742 100644 --- a/spec/erb_lint/formatters/multiline_formatter_spec.rb +++ b/spec/erb_lint/formatters/multiline_formatter_spec.rb @@ -46,15 +46,8 @@ context 'when autocorrect is true' do let(:autocorrect) { true } - it 'generates formatted offenses with no corrected warning' do - expect { subject }.to(output(<<~MESSAGE).to_stdout) - Extra space detected where there should be no space.\e[31m (not autocorrected)\e[0m - In file: app/views/subscriptions/_loader.html.erb:1 - - Remove newline before `%>` to match start of tag.\e[31m (not autocorrected)\e[0m - In file: app/views/subscriptions/_loader.html.erb:52 - - MESSAGE + it 'generates formatted offenses with not autocorrected warning' do + expect { subject }.to(output(/(not autocorrected)/).to_stdout) end end end From c6ace2164f7982df8e347275cfaf171d226a765c Mon Sep 17 00:00:00 2001 From: Anderson Macedo Date: Thu, 19 Mar 2020 05:23:51 +0000 Subject: [PATCH 18/24] Rename formatters to reporters --- lib/erb_lint.rb | 6 +-- lib/erb_lint/cli.rb | 27 ++++++-------- lib/erb_lint/formatter.rb | 19 ---------- lib/erb_lint/reporter.rb | 37 +++++++++++++++++++ .../compact_reporter.rb} | 6 +-- .../multiline_reporter.rb} | 4 +- .../compact_reporter_spec.rb} | 8 ++-- .../multiline_reporter_spec.rb} | 10 ++--- 8 files changed, 65 insertions(+), 52 deletions(-) delete mode 100644 lib/erb_lint/formatter.rb create mode 100644 lib/erb_lint/reporter.rb rename lib/erb_lint/{formatters/compact_formatter.rb => reporters/compact_reporter.rb} (94%) rename lib/erb_lint/{formatters/multiline_formatter.rb => reporters/multiline_reporter.rb} (81%) rename spec/erb_lint/{formatters/compact_formatter_spec.rb => reporters/compact_reporter_spec.rb} (90%) rename spec/erb_lint/{formatters/multiline_formatter_spec.rb => reporters/multiline_reporter_spec.rb} (81%) diff --git a/lib/erb_lint.rb b/lib/erb_lint.rb index b9bf1f8e..bf955fcd 100644 --- a/lib/erb_lint.rb +++ b/lib/erb_lint.rb @@ -11,14 +11,14 @@ require 'erb_lint/runner' require 'erb_lint/version' require 'erb_lint/stats' -require 'erb_lint/formatter' +require 'erb_lint/reporter' # Load linters Dir[File.expand_path('erb_lint/linters/**/*.rb', File.dirname(__FILE__))].each do |file| require file end -# Load formatters -Dir[File.expand_path('erb_lint/formatters/**/*.rb', File.dirname(__FILE__))].each do |file| +# Load reporters +Dir[File.expand_path('erb_lint/reporters/**/*.rb', File.dirname(__FILE__))].each do |file| require file end diff --git a/lib/erb_lint/cli.rb b/lib/erb_lint/cli.rb index b2fa25a5..646536aa 100644 --- a/lib/erb_lint/cli.rb +++ b/lib/erb_lint/cli.rb @@ -21,7 +21,6 @@ def initialize @config = nil @files = [] @stats = Stats.new - @formatter_klass = Formatters::MultilineFormatter end def run(args = ARGV) @@ -64,7 +63,9 @@ def run(args = ARGV) end end - @formatter_klass.new(@stats, autocorrect?).format + @options[:format] ||= :multiline + reporter = Reporter.create_reporter(@options[:format], @stats, autocorrect?) + reporter.show @stats.found == 0 && @stats.exceptions == 0 rescue OptionParser::InvalidOption, OptionParser::InvalidArgument, ExitWithFailure => e @@ -235,8 +236,12 @@ def option_parser end opts.on("--format FORMAT", format_options_help) do |format| - @formatter_klass = "#{ERBLint::Formatters}::#{format.camelize}Formatter".safe_constantize - failure!(invalid_format_error_message(format)) if @formatter_klass.nil? + unless Reporter.available_format?(format) + error_message = invalid_format_error_message(format) + failure!(error_message) + end + + @options[:format] = format end opts.on("--lint-all", "Lint all files matching configured glob [default: #{DEFAULT_LINT_ALL_GLOB}]") do |config| @@ -273,22 +278,12 @@ def option_parser def format_options_help "Report offenses in the given format: "\ - "(#{available_formatters.join(', ')}) (default: multiline)" + "(#{Reporter.available_formats.join(', ')}) (default: multiline)" end def invalid_format_error_message(given_format) - formats = available_formatters.map { |format| " - #{format}\n" } + formats = Reporter.available_formats.map { |format| " - #{format}\n" } "#{given_format}: is not a valid format. Available formats:\n#{formats.join}" end - - def available_formatters - Formatter - .descendants - .map(&:to_s) - .map(&:demodulize) - .map(&:underscore) - .map { |klass_name| klass_name.sub("_formatter", "") } - .sort - end end end diff --git a/lib/erb_lint/formatter.rb b/lib/erb_lint/formatter.rb deleted file mode 100644 index 6995103d..00000000 --- a/lib/erb_lint/formatter.rb +++ /dev/null @@ -1,19 +0,0 @@ -# frozen_string_literal: true -require 'active_support/core_ext/class' - -module ERBLint - class Formatter - delegate :files, to: :stats - - def initialize(stats, autocorrect) - @autocorrect = autocorrect - @stats = stats - end - - def format; end - - private - - attr_reader :stats, :autocorrect - end -end diff --git a/lib/erb_lint/reporter.rb b/lib/erb_lint/reporter.rb new file mode 100644 index 00000000..fec21fc4 --- /dev/null +++ b/lib/erb_lint/reporter.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true +require 'active_support/core_ext/class' + +module ERBLint + class Reporter + delegate :files, to: :stats + + def self.create_reporter(format, *args) + reporter_klass = "#{ERBLint::Reporters}::#{format.to_s.camelize}Reporter".constantize + reporter_klass.new(*args) + end + + def self.available_format?(format) + available_formats.include?(format.to_s) + end + + def self.available_formats + descendants + .map(&:to_s) + .map(&:demodulize) + .map(&:underscore) + .map { |klass_name| klass_name.sub("_reporter", "") } + .sort + end + + def initialize(stats, autocorrect) + @stats = stats + @autocorrect = autocorrect + end + + def show; end + + private + + attr_reader :stats, :autocorrect + end +end diff --git a/lib/erb_lint/formatters/compact_formatter.rb b/lib/erb_lint/reporters/compact_reporter.rb similarity index 94% rename from lib/erb_lint/formatters/compact_formatter.rb rename to lib/erb_lint/reporters/compact_reporter.rb index 552e7bc4..6fb00ede 100644 --- a/lib/erb_lint/formatters/compact_formatter.rb +++ b/lib/erb_lint/reporters/compact_reporter.rb @@ -1,9 +1,9 @@ # frozen_string_literal: true module ERBLint - module Formatters - class CompactFormatter < Formatter - def format + module Reporters + class CompactReporter < Reporter + def show files.each do |filename, offenses| offenses.each do |offense| puts format_offense(filename, offense) diff --git a/lib/erb_lint/formatters/multiline_formatter.rb b/lib/erb_lint/reporters/multiline_reporter.rb similarity index 81% rename from lib/erb_lint/formatters/multiline_formatter.rb rename to lib/erb_lint/reporters/multiline_reporter.rb index 9879a885..13fa84b4 100644 --- a/lib/erb_lint/formatters/multiline_formatter.rb +++ b/lib/erb_lint/reporters/multiline_reporter.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true module ERBLint - module Formatters - class MultilineFormatter < CompactFormatter + module Reporters + class MultilineReporter < CompactReporter private def format_offense(filename, offense) diff --git a/spec/erb_lint/formatters/compact_formatter_spec.rb b/spec/erb_lint/reporters/compact_reporter_spec.rb similarity index 90% rename from spec/erb_lint/formatters/compact_formatter_spec.rb rename to spec/erb_lint/reporters/compact_reporter_spec.rb index 4f0635da..67bb36cf 100644 --- a/spec/erb_lint/formatters/compact_formatter_spec.rb +++ b/spec/erb_lint/reporters/compact_reporter_spec.rb @@ -2,9 +2,9 @@ require 'spec_helper' -describe ERBLint::Formatters::CompactFormatter do - describe '.format' do - subject { described_class.new(stats, false).format } +describe ERBLint::Reporters::CompactReporter do + describe '.show' do + subject { described_class.new(stats, false).show } let(:stats) do ERBLint::Stats.new( @@ -42,7 +42,7 @@ ] end - it "generates formatted offenses" do + it "displays formatted offenses output" do expect { subject }.to(output(<<~MESSAGE).to_stdout) app/views/users/show.html.erb:61:10: Extra space detected where there should be no space. app/views/users/show.html.erb:125:1: Remove multiple trailing newline at the end of the file. diff --git a/spec/erb_lint/formatters/multiline_formatter_spec.rb b/spec/erb_lint/reporters/multiline_reporter_spec.rb similarity index 81% rename from spec/erb_lint/formatters/multiline_formatter_spec.rb rename to spec/erb_lint/reporters/multiline_reporter_spec.rb index 43e85742..46006b94 100644 --- a/spec/erb_lint/formatters/multiline_formatter_spec.rb +++ b/spec/erb_lint/reporters/multiline_reporter_spec.rb @@ -2,9 +2,9 @@ require 'spec_helper' -describe ERBLint::Formatters::MultilineFormatter do - describe '.format' do - subject { described_class.new(stats, autocorrect).format } +describe ERBLint::Reporters::MultilineReporter do + describe '.show' do + subject { described_class.new(stats, autocorrect).show } let(:stats) do ERBLint::Stats.new( @@ -31,7 +31,7 @@ context 'when autocorrect is false' do let(:autocorrect) { false } - it "generates formatted offenses without no corrected warning" do + it 'displays formatted offenses output' do expect { subject }.to(output(<<~MESSAGE).to_stdout) Extra space detected where there should be no space. In file: app/views/subscriptions/_loader.html.erb:1 @@ -46,7 +46,7 @@ context 'when autocorrect is true' do let(:autocorrect) { true } - it 'generates formatted offenses with not autocorrected warning' do + it 'displays not autocorrected warning' do expect { subject }.to(output(/(not autocorrected)/).to_stdout) end end From f53d89882fea077cef5943de7010b51ce4f14c9c Mon Sep 17 00:00:00 2001 From: Anderson Macedo Date: Thu, 19 Mar 2020 05:35:20 +0000 Subject: [PATCH 19/24] Fix autoload error --- lib/erb_lint/reporters/multiline_reporter.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/erb_lint/reporters/multiline_reporter.rb b/lib/erb_lint/reporters/multiline_reporter.rb index 13fa84b4..f656abc2 100644 --- a/lib/erb_lint/reporters/multiline_reporter.rb +++ b/lib/erb_lint/reporters/multiline_reporter.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true +require_relative "compact_reporter" module ERBLint module Reporters From d285515f78b020f50b1b5b28e207f7ecbee2f0df Mon Sep 17 00:00:00 2001 From: Anderson Macedo Date: Thu, 19 Mar 2020 05:46:59 +0000 Subject: [PATCH 20/24] Cosmetic changes --- lib/erb_lint/reporter.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/erb_lint/reporter.rb b/lib/erb_lint/reporter.rb index fec21fc4..904c941a 100644 --- a/lib/erb_lint/reporter.rb +++ b/lib/erb_lint/reporter.rb @@ -3,8 +3,6 @@ module ERBLint class Reporter - delegate :files, to: :stats - def self.create_reporter(format, *args) reporter_klass = "#{ERBLint::Reporters}::#{format.to_s.camelize}Reporter".constantize reporter_klass.new(*args) @@ -33,5 +31,6 @@ def show; end private attr_reader :stats, :autocorrect + delegate :files, to: :stats end end From 48f2f07ab14cc1a30c4a70f3b354e5f2bff68c56 Mon Sep 17 00:00:00 2001 From: Anderson Macedo Date: Sat, 30 May 2020 13:18:29 -0300 Subject: [PATCH 21/24] Put preview message logic inside reporter --- lib/erb_lint/cli.rb | 15 ++++++++------- lib/erb_lint/reporter.rb | 4 +++- lib/erb_lint/reporters/compact_reporter.rb | 14 +++++++++++--- lib/erb_lint/reporters/multiline_reporter.rb | 6 +++++- lib/erb_lint/stats.rb | 12 ++++++++++-- spec/erb_lint/cli_spec.rb | 4 ++++ spec/erb_lint/reporters/compact_reporter_spec.rb | 2 +- .../erb_lint/reporters/multiline_reporter_spec.rb | 3 ++- 8 files changed, 44 insertions(+), 16 deletions(-) diff --git a/lib/erb_lint/cli.rb b/lib/erb_lint/cli.rb index 646536aa..cdb90df5 100644 --- a/lib/erb_lint/cli.rb +++ b/lib/erb_lint/cli.rb @@ -42,9 +42,12 @@ def run(args = ARGV) failure!('no linter available with current configuration') end - puts "Linting #{lint_files.size} files with "\ - "#{enabled_linter_classes.size} #{'autocorrectable ' if autocorrect?}linters..." - puts + @options[:format] ||= :multiline + @stats.files = lint_files.size + @stats.linters = enabled_linter_classes.size + + reporter = Reporter.create_reporter(@options[:format], @stats, autocorrect?) + reporter.preview runner = ERBLint::Runner.new(file_loader, @config) @@ -63,8 +66,6 @@ def run(args = ARGV) end end - @options[:format] ||= :multiline - reporter = Reporter.create_reporter(@options[:format], @stats, autocorrect?) reporter.show @stats.found == 0 && @stats.exceptions == 0 @@ -110,8 +111,8 @@ def run_with_corrections(runner, filename) offenses = runner.offenses || [] @stats.found += offenses.size - @stats.files[offenses_filename] ||= [] - @stats.files[offenses_filename] |= offenses + @stats.processed_files[offenses_filename] ||= [] + @stats.processed_files[offenses_filename] |= offenses end def correct(processed_source, offenses) diff --git a/lib/erb_lint/reporter.rb b/lib/erb_lint/reporter.rb index 904c941a..ff5e484d 100644 --- a/lib/erb_lint/reporter.rb +++ b/lib/erb_lint/reporter.rb @@ -26,11 +26,13 @@ def initialize(stats, autocorrect) @autocorrect = autocorrect end + def preview; end + def show; end private attr_reader :stats, :autocorrect - delegate :files, to: :stats + delegate :processed_files, to: :stats end end diff --git a/lib/erb_lint/reporters/compact_reporter.rb b/lib/erb_lint/reporters/compact_reporter.rb index 6fb00ede..434100b5 100644 --- a/lib/erb_lint/reporters/compact_reporter.rb +++ b/lib/erb_lint/reporters/compact_reporter.rb @@ -3,14 +3,20 @@ module ERBLint module Reporters class CompactReporter < Reporter + def preview + puts "Linting #{stats.files} files with "\ + "#{stats.linters} #{'autocorrectable ' if autocorrect}linters..." + end + def show - files.each do |filename, offenses| + processed_files.each do |filename, offenses| offenses.each do |offense| puts format_offense(filename, offense) end end - report_summary + footer + summary end private @@ -24,7 +30,9 @@ def format_offense(filename, offense) ].join end - def report_summary + def footer; end + + def summary if stats.corrected > 0 report_corrected_offenses elsif stats.found > 0 diff --git a/lib/erb_lint/reporters/multiline_reporter.rb b/lib/erb_lint/reporters/multiline_reporter.rb index f656abc2..3e8d014d 100644 --- a/lib/erb_lint/reporters/multiline_reporter.rb +++ b/lib/erb_lint/reporters/multiline_reporter.rb @@ -8,11 +8,15 @@ class MultilineReporter < CompactReporter def format_offense(filename, offense) <<~EOF + #{offense.message}#{Rainbow(' (not autocorrected)').red if autocorrect} In file: #{filename}:#{offense.line_number} - EOF end + + def footer + puts + end end end end diff --git a/lib/erb_lint/stats.rb b/lib/erb_lint/stats.rb index 3d66e1be..f28fa8f3 100644 --- a/lib/erb_lint/stats.rb +++ b/lib/erb_lint/stats.rb @@ -1,13 +1,21 @@ # frozen_string_literal: true module ERBLint class Stats - attr_accessor :found, :corrected, :exceptions, :files + attr_accessor :found, + :corrected, + :exceptions, + :linters, + :files, + :processed_files - def initialize(found: 0, corrected: 0, exceptions: 0, files: {}) + def initialize(found: 0, corrected: 0, exceptions: 0, + linters: 0, files: 0, processed_files: {}) @found = found @corrected = corrected @exceptions = exceptions + @linters = linters @files = files + @processed_files = processed_files end end end diff --git a/spec/erb_lint/cli_spec.rb b/spec/erb_lint/cli_spec.rb index febb32fc..52a98c0a 100644 --- a/spec/erb_lint/cli_spec.rb +++ b/spec/erb_lint/cli_spec.rb @@ -139,11 +139,13 @@ def run(_processed_source) context 'when errors are found' do it 'shows all error messages and line numbers' do expect { subject }.to(output(Regexp.new(Regexp.escape(<<~EOF))).to_stdout) + fake message from a fake linter In file: /app/views/template.html.erb:1 Missing a trailing newline at the end of the file. In file: /app/views/template.html.erb:1 + EOF end @@ -248,11 +250,13 @@ def run(_processed_source) context 'when errors are found' do it 'shows all error messages and line numbers' do expect { subject }.to(output(Regexp.new(Regexp.escape(<<~EOF))).to_stdout) + fake message from a fake linter In file: /app/views/template.html.erb:1 Missing a trailing newline at the end of the file. In file: /app/views/template.html.erb:1 + EOF end diff --git a/spec/erb_lint/reporters/compact_reporter_spec.rb b/spec/erb_lint/reporters/compact_reporter_spec.rb index 67bb36cf..d51092cf 100644 --- a/spec/erb_lint/reporters/compact_reporter_spec.rb +++ b/spec/erb_lint/reporters/compact_reporter_spec.rb @@ -9,7 +9,7 @@ let(:stats) do ERBLint::Stats.new( found: 4, - files: { + processed_files: { 'app/views/users/show.html.erb' => show_file_offenses, 'app/views/shared/_notifications.html.erb' => notification_file_offenses, } diff --git a/spec/erb_lint/reporters/multiline_reporter_spec.rb b/spec/erb_lint/reporters/multiline_reporter_spec.rb index 46006b94..f783021d 100644 --- a/spec/erb_lint/reporters/multiline_reporter_spec.rb +++ b/spec/erb_lint/reporters/multiline_reporter_spec.rb @@ -9,7 +9,7 @@ let(:stats) do ERBLint::Stats.new( found: 2, - files: { + processed_files: { 'app/views/subscriptions/_loader.html.erb' => offenses, } ) @@ -33,6 +33,7 @@ it 'displays formatted offenses output' do expect { subject }.to(output(<<~MESSAGE).to_stdout) + Extra space detected where there should be no space. In file: app/views/subscriptions/_loader.html.erb:1 From 13da592348612b3b81efb51b9066cf3c271664db Mon Sep 17 00:00:00 2001 From: Anderson Macedo Date: Sat, 30 May 2020 13:21:03 -0300 Subject: [PATCH 22/24] Document --format option on README --- README.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/README.md b/README.md index 3c9aebba..dfb4b681 100644 --- a/README.md +++ b/README.md @@ -488,6 +488,35 @@ def autocorrect(_processed_source, offense) end ``` +## Output formats + +You can change the output format of ERB Lint by specifying formatters with the `-f/--format` option. + +### Multiline (default) + +```sh +$ erblint +Linting 8 files with 12 linters... + +Remove multiple trailing newline at the end of the file. +In file: app/views/users/show.html.erb:95 + +Remove newline before `%>` to match start of tag. +In file: app/views/subscriptions/index.html.erb:38 + +2 error(s) were found in ERB files +``` + +### Compact + +```sh +erblint --format compact +Linting 8 files with 12 linters... +app/views/users/show.html.erb:95:0: Remove multiple trailing newline at the end of the file. +app/views/users/_graph.html.erb:27:37: Extra space detected where there should be no space +2 error(s) were found in ERB files +``` + ## License This project is released under the [MIT license](LICENSE.txt). From 4b728a7cb06b6c8b7971b6204bad7b2323fabe34 Mon Sep 17 00:00:00 2001 From: Anderson Macedo Date: Sat, 30 May 2020 13:29:37 -0300 Subject: [PATCH 23/24] Fix offenses --- lib/erb_lint/cli.rb | 2 +- lib/erb_lint/stats.rb | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/erb_lint/cli.rb b/lib/erb_lint/cli.rb index cdb90df5..f26d212a 100644 --- a/lib/erb_lint/cli.rb +++ b/lib/erb_lint/cli.rb @@ -45,7 +45,7 @@ def run(args = ARGV) @options[:format] ||= :multiline @stats.files = lint_files.size @stats.linters = enabled_linter_classes.size - + reporter = Reporter.create_reporter(@options[:format], @stats, autocorrect?) reporter.preview diff --git a/lib/erb_lint/stats.rb b/lib/erb_lint/stats.rb index f28fa8f3..d7d7c5a0 100644 --- a/lib/erb_lint/stats.rb +++ b/lib/erb_lint/stats.rb @@ -8,8 +8,12 @@ class Stats :files, :processed_files - def initialize(found: 0, corrected: 0, exceptions: 0, - linters: 0, files: 0, processed_files: {}) + def initialize(found: 0, + corrected: 0, + exceptions: 0, + linters: 0, + files: 0, + processed_files: {}) @found = found @corrected = corrected @exceptions = exceptions From dfa13b3eda99816132526d8e5d06a8d169bbba3f Mon Sep 17 00:00:00 2001 From: Anderson Macedo Date: Sat, 30 May 2020 13:37:06 -0300 Subject: [PATCH 24/24] Format stats class --- lib/erb_lint/stats.rb | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/erb_lint/stats.rb b/lib/erb_lint/stats.rb index d7d7c5a0..3b4952c7 100644 --- a/lib/erb_lint/stats.rb +++ b/lib/erb_lint/stats.rb @@ -8,12 +8,14 @@ class Stats :files, :processed_files - def initialize(found: 0, - corrected: 0, - exceptions: 0, - linters: 0, - files: 0, - processed_files: {}) + def initialize( + found: 0, + corrected: 0, + exceptions: 0, + linters: 0, + files: 0, + processed_files: {} + ) @found = found @corrected = corrected @exceptions = exceptions