From 3d3626accc43625c5e54f2c279a5d41040353682 Mon Sep 17 00:00:00 2001 From: Sijawusz Pur Rahnama Date: Sat, 4 Nov 2023 01:40:34 +0100 Subject: [PATCH] Introduced new presenter abstraction --- src/ameba.cr | 1 + src/ameba/cli/cmd.cr | 91 +++---------------- src/ameba/presenter/base_presenter.cr | 12 +++ .../presenter/rule_collection_presenter.cr | 34 +++++++ src/ameba/presenter/rule_presenter.cr | 43 +++++++++ 5 files changed, 102 insertions(+), 79 deletions(-) create mode 100644 src/ameba/presenter/base_presenter.cr create mode 100644 src/ameba/presenter/rule_collection_presenter.cr create mode 100644 src/ameba/presenter/rule_presenter.cr diff --git a/src/ameba.cr b/src/ameba.cr index d2eeffc1..e675939a 100644 --- a/src/ameba.cr +++ b/src/ameba.cr @@ -3,6 +3,7 @@ require "./ameba/ast/**" require "./ameba/ext/**" require "./ameba/rule/**" require "./ameba/formatter/*" +require "./ameba/presenter/*" require "./ameba/source/**" # Ameba's entry module. diff --git a/src/ameba/cli/cmd.cr b/src/ameba/cli/cmd.cr index f49a41c6..e9a0ffbd 100644 --- a/src/ameba/cli/cmd.cr +++ b/src/ameba/cli/cmd.cr @@ -5,9 +5,6 @@ require "option_parser" module Ameba::Cli extend self - private ENABLED_MARK = "✓".colorize(:green) - private DISABLED_MARK = "x".colorize(:red) - def run(args = ARGV) opts = parse_args args location_to_explain = opts.location_to_explain @@ -31,11 +28,14 @@ module Ameba::Cli configure_rules(config, opts) if opts.rules? - print_rules(config) + print_rules(config.rules) end - if describe_rule = opts.describe - print_rule_description(describe_rule, config) + if describe_rule_name = opts.describe_rule + unless rule = config.rules.find(&.name.== describe_rule_name) + raise "Unknown rule" + end + describe_rule(rule) end runner = Ameba.run(config) @@ -56,7 +56,7 @@ module Ameba::Cli property globs : Array(String)? property only : Array(String)? property except : Array(String)? - property describe : String? + property describe_rule : String? property location_to_explain : NamedTuple(file: String, line: Int32, column: Int32)? property fail_level : Severity? property? skip_reading_config = false @@ -166,7 +166,7 @@ module Ameba::Cli end private def configure_describe_opts(rule_name, opts) - opts.describe = rule_name.presence + opts.describe_rule = rule_name.presence opts.formatter = :silent end @@ -201,80 +201,13 @@ module Ameba::Cli exit 0 end - private def print_rules(config) - rules = config.rules.to_h do |rule| - name = rule.name.split('/') - name = "%s/%s" % { - name[0...-1].join('/').colorize(:light_gray), - name.last.colorize(:white), - } - {name, rule} - end - longest_name = rules.max_of(&.first.size) - - rules.group_by(&.last.group).each do |group, group_rules| - puts "— %s" % group.colorize(:light_blue).underline - puts - group_rules.each do |name, rule| - puts " %s [%s] %s %s" % { - rule.enabled? ? ENABLED_MARK : DISABLED_MARK, - rule.severity.symbol.to_s.colorize(:green), - name.ljust(longest_name), - rule.description.colorize(:dark_gray), - } - end - puts - end - - puts "Total rules: %s / %s enabled" % { - rules.size.to_s.colorize(:light_blue), - rules.count(&.last.enabled?).to_s.colorize(:light_blue), - } + private def describe_rule(rule) + Presenter::RulePresenter.new.run(rule) exit 0 end - private def print_rule_description(rule_name, config) - rule = config.rules.find(&.name.== rule_name) - raise "Unknown rule" unless rule - - puts - output_title "Rule info" - output_paragraph "%s of a %s severity [enabled: %s]" % { - rule.name.colorize(:magenta), - rule.severity.to_s.colorize(rule.severity.color), - rule.enabled? ? ENABLED_MARK : DISABLED_MARK, - } - if rule_description = colorize_code_fences(rule.description) - output_paragraph rule_description - end - - if rule_doc = colorize_code_fences(rule.class.parsed_doc) - output_title "Detailed description" - output_paragraph rule_doc - end - + private def print_rules(rules) + Presenter::RuleCollectionPresenter.new.run(rules) exit 0 end - - private def output_title(title) - print "### %s\n\n" % title.upcase.colorize(:yellow) - end - - private def output_paragraph(paragraph : String) - output_paragraph(paragraph.lines) - end - - private def output_paragraph(paragraph : Array) - paragraph.each do |line| - puts " #{line}" - end - puts - end - - private def colorize_code_fences(string) - return unless string - string - .gsub(/```(.+?)```/m, &.colorize(:dark_gray)) - .gsub(/`(?!`)(.+?)`/, &.colorize(:dark_gray)) - end end diff --git a/src/ameba/presenter/base_presenter.cr b/src/ameba/presenter/base_presenter.cr new file mode 100644 index 00000000..73f9ad00 --- /dev/null +++ b/src/ameba/presenter/base_presenter.cr @@ -0,0 +1,12 @@ +module Ameba::Presenter + private ENABLED_MARK = "✓".colorize(:green) + private DISABLED_MARK = "x".colorize(:red) + + class BasePresenter + # TODO: allow other IOs + getter output : IO::FileDescriptor | IO::Memory + + def initialize(@output = STDOUT) + end + end +end diff --git a/src/ameba/presenter/rule_collection_presenter.cr b/src/ameba/presenter/rule_collection_presenter.cr new file mode 100644 index 00000000..e833df11 --- /dev/null +++ b/src/ameba/presenter/rule_collection_presenter.cr @@ -0,0 +1,34 @@ +module Ameba::Presenter + class RuleCollectionPresenter < BasePresenter + def run(rules) + rules = rules.to_h do |rule| + name = rule.name.split('/') + name = "%s/%s" % { + name[0...-1].join('/').colorize(:light_gray), + name.last.colorize(:white), + } + {name, rule} + end + longest_name = rules.max_of(&.first.size) + + rules.group_by(&.last.group).each do |group, group_rules| + output.puts "— %s" % group.colorize(:light_blue).underline + output.puts + group_rules.each do |name, rule| + output.puts " %s [%s] %s %s" % { + rule.enabled? ? ENABLED_MARK : DISABLED_MARK, + rule.severity.symbol.to_s.colorize(:green), + name.ljust(longest_name), + rule.description.colorize(:dark_gray), + } + end + output.puts + end + + output.puts "Total rules: %s / %s enabled" % { + rules.size.to_s.colorize(:light_blue), + rules.count(&.last.enabled?).to_s.colorize(:light_blue), + } + end + end +end diff --git a/src/ameba/presenter/rule_presenter.cr b/src/ameba/presenter/rule_presenter.cr new file mode 100644 index 00000000..a790ac4b --- /dev/null +++ b/src/ameba/presenter/rule_presenter.cr @@ -0,0 +1,43 @@ +module Ameba::Presenter + class RulePresenter < BasePresenter + def run(rule) + output.puts + output_title "Rule info" + output_paragraph "%s of a %s severity [enabled: %s]" % { + rule.name.colorize(:magenta), + rule.severity.to_s.colorize(rule.severity.color), + rule.enabled? ? ENABLED_MARK : DISABLED_MARK, + } + if rule_description = colorize_code_fences(rule.description) + output_paragraph rule_description + end + + if rule_doc = colorize_code_fences(rule.class.parsed_doc) + output_title "Detailed description" + output_paragraph rule_doc + end + end + + private def output_title(title) + output.print "### %s\n\n" % title.upcase.colorize(:yellow) + end + + private def output_paragraph(paragraph : String) + output_paragraph(paragraph.lines) + end + + private def output_paragraph(paragraph : Array) + paragraph.each do |line| + output.puts " #{line}" + end + output.puts + end + + private def colorize_code_fences(string) + return unless string + string + .gsub(/```(.+?)```/m, &.colorize(:dark_gray)) + .gsub(/`(?!`)(.+?)`/, &.colorize(:dark_gray)) + end + end +end