mirror of
https://gitea.invidious.io/iv-org/shard-ameba.git
synced 2024-08-15 00:53:29 +00:00
TODO formatter
This commit is contained in:
parent
bc552d0730
commit
a1854c0aa3
5 changed files with 122 additions and 28 deletions
44
spec/ameba/formatter/todo_formatter_spec.cr
Normal file
44
spec/ameba/formatter/todo_formatter_spec.cr
Normal file
|
@ -0,0 +1,44 @@
|
|||
require "../../spec_helper"
|
||||
|
||||
module Ameba
|
||||
private def create_todo(formatter)
|
||||
s = Source.new "a = 1"
|
||||
s.error DummyRule.new, s.location(1, 2), "message"
|
||||
formatter.finished [s]
|
||||
end
|
||||
|
||||
describe Formatter::TODOFormatter do
|
||||
file = IO::Memory.new
|
||||
subject = Formatter::TODOFormatter.new IO::Memory.new, file
|
||||
|
||||
context "problems not reported" do
|
||||
it "does not create todo" do
|
||||
subject.finished [Source.new ""]
|
||||
file.to_s.empty?.should be_true
|
||||
end
|
||||
end
|
||||
|
||||
context "problems reported" do
|
||||
it "creates a todo with header" do
|
||||
create_todo subject
|
||||
file.to_s.should contain "# This configuration file was generated by"
|
||||
file.to_s.should contain "Ameba version #{VERSION}"
|
||||
end
|
||||
|
||||
it "creates a todo with rule name" do
|
||||
create_todo subject
|
||||
file.to_s.should contain "DummyRule"
|
||||
end
|
||||
|
||||
it "creates a todo with problems count" do
|
||||
create_todo subject
|
||||
file.to_s.should contain "Problems found: 1"
|
||||
end
|
||||
|
||||
it "creates a valid YAML document" do
|
||||
create_todo subject
|
||||
YAML.parse(file.to_s).should_not be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -46,13 +46,11 @@ module Ameba::Cli
|
|||
def run_ameba(opts)
|
||||
config = Ameba::Config.load opts.config
|
||||
config.files = opts.files
|
||||
config.formatter = Ameba::Formatter::BaseFormatter.new if opts.silent
|
||||
|
||||
configure_formatter(config, opts)
|
||||
configure_rules(config, opts)
|
||||
|
||||
runner = Ameba.run(config)
|
||||
generate_config_file(config, runner, opts) if opts.generate
|
||||
exit 1 unless runner.success?
|
||||
exit 1 unless Ameba.run(config).success?
|
||||
rescue e
|
||||
puts "Error: #{e.message}"
|
||||
exit 255
|
||||
|
@ -71,14 +69,14 @@ module Ameba::Cli
|
|||
end
|
||||
end
|
||||
|
||||
private def generate_config_file(config, runner, opts)
|
||||
failed_rules =
|
||||
runner.sources
|
||||
.map { |s| s.errors.map &.rule.name }
|
||||
.flatten
|
||||
.uniq!
|
||||
failed_rules.each { |rule| config.update_rule rule, enabled: false }
|
||||
File.write(opts.config, config.to_yaml)
|
||||
private def configure_formatter(config, opts)
|
||||
if opts.silent
|
||||
config.formatter = Ameba::Formatter::BaseFormatter.new
|
||||
elsif opts.generate
|
||||
config.formatter = Ameba::Formatter::TODOFormatter.new
|
||||
else
|
||||
config.formatter = Ameba::Formatter::DotFormatter.new
|
||||
end
|
||||
end
|
||||
|
||||
private def print_version
|
||||
|
|
|
@ -20,7 +20,7 @@ class Ameba::Config
|
|||
# Creates a new instance of `Ameba::Config` based on YAML parameters.
|
||||
#
|
||||
# `Config.load` uses this constructor to instantiate new config by YAML file.
|
||||
protected def initialize(@config : Hash(YAML::Type, YAML::Type))
|
||||
protected def initialize(@config : YAML::Any)
|
||||
@rules = Rule.rules.map &.new(config)
|
||||
end
|
||||
|
||||
|
@ -31,9 +31,9 @@ class Ameba::Config
|
|||
# ```
|
||||
#
|
||||
def self.load(path = PATH)
|
||||
content = File.exists?(path) ? File.read path : "{}"
|
||||
Config.new YAML.parse(content).as_h
|
||||
rescue e
|
||||
content = File.exists?(path) ? File.read path : ""
|
||||
Config.new YAML.parse(content)
|
||||
rescue
|
||||
raise "Config file is invalid"
|
||||
end
|
||||
|
||||
|
@ -80,15 +80,6 @@ class Ameba::Config
|
|||
@rules[index] = rule
|
||||
end
|
||||
|
||||
def to_yaml(yaml : YAML::Builder)
|
||||
yaml.mapping do
|
||||
rules.each do |rule|
|
||||
rule.name.to_yaml(yaml)
|
||||
rule.to_yaml(yaml)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private def default_files
|
||||
Dir["**/*.cr"].reject(&.starts_with? "lib/")
|
||||
end
|
||||
|
@ -158,8 +149,10 @@ class Ameba::Config
|
|||
properties {}
|
||||
|
||||
def self.new(config = nil)
|
||||
yaml = config.try &.[class_name]?.try &.to_yaml || "{}"
|
||||
from_yaml yaml
|
||||
if (raw = config.try &.raw).is_a? Hash
|
||||
yaml = raw[class_name]?.try &.to_yaml
|
||||
end
|
||||
from_yaml yaml || "{}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -21,7 +21,7 @@ module Ameba::Formatter
|
|||
# Reports a message when inspection is finished.
|
||||
def finished(sources)
|
||||
output << "\n\n"
|
||||
failed_sources = sources.reject { |s| s.valid? }
|
||||
failed_sources = sources.reject &.valid?
|
||||
|
||||
failed_sources.each do |source|
|
||||
source.errors.each do |error|
|
||||
|
|
59
src/ameba/formatter/todo_formatter.cr
Normal file
59
src/ameba/formatter/todo_formatter.cr
Normal file
|
@ -0,0 +1,59 @@
|
|||
module Ameba::Formatter
|
||||
# A formatter that creates a todo config.
|
||||
# Basically, it takes all errors reported and disables corresponding rules
|
||||
# or excludes failed sources from these rules.
|
||||
class TODOFormatter < DotFormatter
|
||||
@io : IO::FileDescriptor | IO::Memory
|
||||
|
||||
def initialize(@output = STDOUT, @io = File.new(Config::PATH, mode: "w"))
|
||||
end
|
||||
|
||||
def finished(sources)
|
||||
super
|
||||
errors = sources.map(&.errors).flatten
|
||||
generate_todo_config errors if errors.any?
|
||||
if (io = @io).is_a?(File)
|
||||
@output << "Created #{io.path}\n"
|
||||
end
|
||||
end
|
||||
|
||||
private def generate_todo_config(errors)
|
||||
@io << header
|
||||
rule_errors_map(errors).each do |rule, rule_errors|
|
||||
@io << "\n# Problems found: #{rule_errors.size}"
|
||||
@io << rule_todo(rule, rule_errors).gsub("---", "")
|
||||
end
|
||||
ensure
|
||||
@io.flush
|
||||
end
|
||||
|
||||
private def rule_errors_map(errors)
|
||||
Hash(Rule::Base, Array(Source::Error)).new.tap do |h|
|
||||
errors.each do |error|
|
||||
h[error.rule] ||= Array(Source::Error).new
|
||||
h[error.rule] << error
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private def header
|
||||
<<-HEADER
|
||||
# This configuration file was generated by `ameba --gen-config`
|
||||
# on #{Time.now} 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, errors)
|
||||
rule.enabled = false
|
||||
YAML.build do |yaml|
|
||||
yaml.mapping do
|
||||
rule.name.to_yaml(yaml)
|
||||
rule.to_yaml(yaml)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue