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

Add --format option #159

Merged
merged 24 commits into from
Nov 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
09626e4
Add helper methods on Offense to acces line and column more easily
andersonkrs Mar 18, 2020
8dd3978
Add base formatter class for offenses
andersonkrs Mar 18, 2020
d86791c
Add test suite for default formatter
andersonkrs Mar 18, 2020
fc96ed7
Load formatters
andersonkrs Mar 18, 2020
b053e53
Implement default formatter
andersonkrs Mar 18, 2020
eb249ba
Implement compact formatter
andersonkrs Mar 18, 2020
b6161a3
Rename default formatter to multiline
andersonkrs Mar 18, 2020
b20ce70
Fix offenses
andersonkrs Mar 18, 2020
cfcea2f
Add --format param
andersonkrs Mar 18, 2020
b2b4116
Refactoring formatter class to get better api
andersonkrs Mar 18, 2020
49b1e8c
Improve inheritance checking from Formatter class
andersonkrs Mar 18, 2020
4796bb9
Fix rubocop offenses
andersonkrs Mar 18, 2020
ffee034
Remove manual hook to get descendants and use activesupport ext
andersonkrs Mar 19, 2020
db8d589
Extract logic to report all output to formatters
andersonkrs Mar 19, 2020
b33d314
Move stats class to separated file
andersonkrs Mar 19, 2020
a2539a2
Extract all output logic to formatters
andersonkrs Mar 19, 2020
590fbfb
Fix warnings
andersonkrs Mar 19, 2020
c6ace21
Rename formatters to reporters
andersonkrs Mar 19, 2020
f53d898
Fix autoload error
andersonkrs Mar 19, 2020
d285515
Cosmetic changes
andersonkrs Mar 19, 2020
48f2f07
Put preview message logic inside reporter
andersonkrs May 30, 2020
13da592
Document --format option on README
andersonkrs May 30, 2020
4b728a7
Fix offenses
andersonkrs May 30, 2020
dfa13b3
Format stats class
andersonkrs May 30, 2020
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
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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).
7 changes: 7 additions & 0 deletions lib/erb_lint.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,15 @@
require 'erb_lint/runner_config'
require 'erb_lint/runner'
require 'erb_lint/version'
require 'erb_lint/stats'
require 'erb_lint/reporter'

# Load linters
Dir[File.expand_path('erb_lint/linters/**/*.rb', File.dirname(__FILE__))].each do |file|
require file
end

# Load reporters
Dir[File.expand_path('erb_lint/reporters/**/*.rb', File.dirname(__FILE__))].each do |file|
require file
end
65 changes: 31 additions & 34 deletions lib/erb_lint/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,6 @@ class CLI
class ExitWithFailure < RuntimeError; end
class ExitWithSuccess < RuntimeError; end

class Stats
attr_accessor :found, :corrected, :exceptions
def initialize
@found = 0
@corrected = 0
@exceptions = 0
end
end

def initialize
@options = {}
@config = nil
Expand All @@ -51,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)

Expand All @@ -72,20 +66,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
reporter.show

@stats.found == 0 && @stats.exceptions == 0
rescue OptionParser::InvalidOption, OptionParser::InvalidArgument, ExitWithFailure => e
Expand Down Expand Up @@ -126,15 +107,12 @@ def run_with_corrections(runner, filename)
file_content = corrector.corrected_content
runner.clear_offenses
end
offenses_filename = relative_filename(filename)
offenses = runner.offenses || []

@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
@stats.found += offenses.size
@stats.processed_files[offenses_filename] ||= []
@stats.processed_files[offenses_filename] |= offenses
end

def correct(processed_source, offenses)
Expand Down Expand Up @@ -258,6 +236,15 @@ def option_parser
end
end

opts.on("--format FORMAT", format_options_help) do |format|
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|
@options[:lint_all] = config
end
Expand Down Expand Up @@ -289,5 +276,15 @@ def option_parser
end
end
end

def format_options_help
"Report offenses in the given format: "\
"(#{Reporter.available_formats.join(', ')}) (default: multiline)"
end

def invalid_format_error_message(given_format)
formats = Reporter.available_formats.map { |format| " - #{format}\n" }
"#{given_format}: is not a valid format. Available formats:\n#{formats.join}"
end
end
end
8 changes: 8 additions & 0 deletions lib/erb_lint/offense.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
38 changes: 38 additions & 0 deletions lib/erb_lint/reporter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# frozen_string_literal: true
require 'active_support/core_ext/class'

module ERBLint
class Reporter
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 preview; end

def show; end

private

attr_reader :stats, :autocorrect
delegate :processed_files, to: :stats
end
end
60 changes: 60 additions & 0 deletions lib/erb_lint/reporters/compact_reporter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# frozen_string_literal: true

module ERBLint
module Reporters
class CompactReporter < Reporter
def preview
puts "Linting #{stats.files} files with "\
"#{stats.linters} #{'autocorrectable ' if autocorrect}linters..."
end

def show
processed_files.each do |filename, offenses|
offenses.each do |offense|
puts format_offense(filename, offense)
end
end

footer
summary
end

private

def format_offense(filename, offense)
[
"#{filename}:",
"#{offense.line_number}:",
"#{offense.column}: ",
offense.message.to_s,
].join
end

def footer; end

def 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
22 changes: 22 additions & 0 deletions lib/erb_lint/reporters/multiline_reporter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# frozen_string_literal: true
require_relative "compact_reporter"

module ERBLint
module Reporters
class MultilineReporter < CompactReporter
private

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
27 changes: 27 additions & 0 deletions lib/erb_lint/stats.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# frozen_string_literal: true
module ERBLint
class Stats
attr_accessor :found,
:corrected,
:exceptions,
:linters,
:files,
:processed_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
Loading