From f671d6f857cac87a6876ad785c90de6a5820d22b Mon Sep 17 00:00:00 2001 From: Vitalii Elenhaupt Date: Wed, 12 Dec 2018 21:45:00 +0200 Subject: [PATCH] Show affected code while using a default formatter --- README.md | 16 +++++---- spec/ameba/cli/cmd_spec.cr | 5 +++ spec/ameba/formatter/dot_formatter_spec.cr | 31 ++++++++++++++++++ src/ameba/cli/cmd.cr | 7 ++++ src/ameba/formatter/base_formatter.cr | 1 + src/ameba/formatter/dot_formatter.cr | 38 +++++++++++++++++++--- src/ameba/rule/layout/line_length.cr | 2 +- 7 files changed, 89 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 3c6fc213..b666938c 100644 --- a/README.md +++ b/README.md @@ -33,15 +33,19 @@ Inspecting 107 files. ...............F.....................F.................................................................... -src/ameba/rule/unneeded_disable_directive.cr:29:7 -Lint/UselessAssign: Useless assignment to variable `s` - -src/ameba/formatter/flycheck_formatter.cr:5:21 +src/ameba/formatter/flycheck_formatter.cr:4:33 Lint/UnusedArgument: Unused argument `location` +> source.issues.each do |e, location| + ^ -Finished in 248.9 milliseconds +src/ameba/formatter/base_formatter.cr:12:7 +Lint/UselessAssign: Useless assignment to variable `s` +> return s += issues.size + ^ -107 inspected, 2 failures. +Finished in 542.64 milliseconds + +129 inspected, 2 failures. ``` diff --git a/spec/ameba/cli/cmd_spec.cr b/spec/ameba/cli/cmd_spec.cr index f4202697..fc9a89e1 100644 --- a/spec/ameba/cli/cmd_spec.cr +++ b/spec/ameba/cli/cmd_spec.cr @@ -62,6 +62,11 @@ module Ameba::Cli c.colors?.should be_false end + it "accepts --without-affected-code flag" do + c = Cli.parse_args %w(--without-affected-code) + c.without_affected_code?.should be_true + end + it "doesn't disable colors by default" do c = Cli.parse_args %w(--all) c.colors?.should be_true diff --git a/spec/ameba/formatter/dot_formatter_spec.cr b/spec/ameba/formatter/dot_formatter_spec.cr index b49700fb..e9e605eb 100644 --- a/spec/ameba/formatter/dot_formatter_spec.cr +++ b/spec/ameba/formatter/dot_formatter_spec.cr @@ -50,6 +50,37 @@ module Ameba::Formatter log.should contain "NamedRuleError" end + it "writes affected code by default" do + output.clear + s = Source.new(%( + a = 22 + puts a + )).tap do |source| + source.add_issue(DummyRule.new, {1, 5}, "DummyRuleError") + end + subject.finished [s] + log = output.to_s + log.should contain "> a = 22" + log.should contain " \e[33m^\e[0m" + end + + it "doesn't write affected code if it is disabled" do + output.clear + s = Source.new(%( + a = 22 + puts a + )).tap do |source| + source.add_issue(DummyRule.new, {1, 5}, "DummyRuleError") + end + + formatter = DotFormatter.new output + formatter.config[:without_affected_code] = true + formatter.finished [s] + log = output.to_s + log.should_not contain "> a = 22" + log.should_not contain " \e[33m^\e[0m" + end + it "does not write disabled issues" do s = Source.new "" s.add_issue(DummyRule.new, location: {1, 1}, diff --git a/src/ameba/cli/cmd.cr b/src/ameba/cli/cmd.cr index 159e7926..f5ae4a22 100644 --- a/src/ameba/cli/cmd.cr +++ b/src/ameba/cli/cmd.cr @@ -27,6 +27,7 @@ module Ameba::Cli property except : Array(String)? property? all = false property? colors = true + property? without_affected_code = false end def parse_args(args, opts = Opts.new) @@ -68,6 +69,11 @@ module Ameba::Cli opts.config = "" end + parser.on("--without-affected-code", + "Stop showing affected code while using a default formatter") do + opts.without_affected_code = true + end + parser.on("--no-color", "Disable colors") do opts.colors = false end @@ -91,6 +97,7 @@ module Ameba::Cli if name = opts.formatter config.formatter = name end + config.formatter.config[:without_affected_code] = opts.without_affected_code? end private def print_version diff --git a/src/ameba/formatter/base_formatter.cr b/src/ameba/formatter/base_formatter.cr index de4d8c6a..26948b4f 100644 --- a/src/ameba/formatter/base_formatter.cr +++ b/src/ameba/formatter/base_formatter.cr @@ -6,6 +6,7 @@ module Ameba::Formatter class BaseFormatter # TODO: allow other IOs getter output : IO::FileDescriptor | IO::Memory + getter config = {} of Symbol => String | Bool def initialize(@output = STDOUT) end diff --git a/src/ameba/formatter/dot_formatter.cr b/src/ameba/formatter/dot_formatter.cr index f3f97028..7d40dba3 100644 --- a/src/ameba/formatter/dot_formatter.cr +++ b/src/ameba/formatter/dot_formatter.cr @@ -19,15 +19,25 @@ module Ameba::Formatter end # Reports a message when inspection is finished. - def finished(sources) - output << "\n\n" + def finished(sources, break_line = "\n\n") + output << break_line + + show_affected_code = !config[:without_affected_code]? failed_sources = sources.reject &.valid? failed_sources.each do |source| source.issues.each do |issue| next if issue.disabled? - output << "#{issue.location}\n".colorize(:cyan) - output << "#{issue.rule.name}: #{issue.message}\n\n".colorize(:red) + next if (location = issue.location).nil? + + output << "#{location}\n".colorize(:cyan) + output << "#{issue.rule.name}: #{issue.message}\n".colorize(:red) + + if show_affected_code && (code = affected_code(source, location)) + output << code + end + + output << "\n" end end @@ -77,5 +87,25 @@ module Ameba::Formatter "#{total} inspected, #{failures} failure#{s}.\n".colorize color end + + private def affected_code(source, location, max_length = 100, placeholder = " ...", prompt = "> ") + line, column = location.line_number, location.column_number + affected_line = source.lines[line - 1]? + + return unless affected_line + + if affected_line.size > max_length && column < max_length + affected_line = affected_line[0, max_length - placeholder.size - 1] + placeholder + end + + stripped = affected_line.lstrip + position = column - (affected_line.size - stripped.size) + prompt.size + + String.build do |str| + str << prompt << stripped << "\n" + str << " " * (position - 1) + str << "^".colorize(:yellow) + end + end end end diff --git a/src/ameba/rule/layout/line_length.cr b/src/ameba/rule/layout/line_length.cr index c69968e6..a4c24d37 100644 --- a/src/ameba/rule/layout/line_length.cr +++ b/src/ameba/rule/layout/line_length.cr @@ -22,7 +22,7 @@ module Ameba::Rule::Layout source.lines.each_with_index do |line, index| next unless line.size > max_length - issue_for({index + 1, line.size}, MSG) + issue_for({index + 1, max_length + 1}, MSG) end end end