shard-ameba/src/ameba/formatter/todo_formatter.cr

71 lines
2.1 KiB
Crystal

module Ameba::Formatter
# A formatter that creates a todo config.
# Basically, it takes all issues reported and disables corresponding rules
# or excludes failed sources from these rules.
class TODOFormatter < DotFormatter
def initialize(@output = STDOUT, @config_path : Path = Config::DEFAULT_PATH)
end
def finished(sources)
super
issues = sources.flat_map(&.issues)
unless issues.any? { |issue| !issue.disabled? }
@output.puts "No issues found. File is not generated."
return
end
if issues.any?(&.syntax?)
@output.puts "Unable to generate TODO file. Please fix syntax issues."
return
end
generate_todo_config(issues).tap do |file|
@output.puts "Created #{file.path}"
end
end
private def generate_todo_config(issues)
file = File.new(@config_path, mode: "w")
file << header
rule_issues_map(issues).each do |rule, rule_issues|
file << "\n# Problems found: #{rule_issues.size}"
file << "\n# Run `ameba --only #{rule.name}` for details"
file << rule_todo(rule, rule_issues).gsub("---", "")
end
file
ensure
file.close if file
end
private def rule_issues_map(issues)
Hash(Rule::Base, Array(Issue)).new.tap do |h|
issues.each do |issue|
next if issue.disabled? || issue.rule.is_a?(Rule::Lint::Syntax)
next if issue.correctable? && config[:autocorrect]?
(h[issue.rule] ||= Array(Issue).new) << issue
end
end
end
private def header
<<-HEADER
# This configuration file was generated by `ameba --gen-config`
# on #{Time.utc} using Ameba version #{VERSION}.
# The point is for the user to remove these configuration records
# one by one as the reported problems are removed from the code base.
HEADER
end
private def rule_todo(rule, issues)
rule.excluded = issues
.compact_map(&.location.try &.filename.try &.to_s)
.uniq!
{rule.name => rule}.to_yaml
end
end
end