From 0fc5e5987994197e7b625af9966f7bbbccb8991f Mon Sep 17 00:00:00 2001 From: Sijawusz Pur Rahnama Date: Mon, 7 Oct 2024 07:06:11 +0200 Subject: [PATCH] Implement rule versioning support --- src/ameba/cli/cmd.cr | 9 +++++++++ src/ameba/config.cr | 28 +++++++++++++++++++++++++++ src/ameba/formatter/todo_formatter.cr | 2 ++ src/ameba/runner.cr | 12 ++++++++++-- 4 files changed, 49 insertions(+), 2 deletions(-) diff --git a/src/ameba/cli/cmd.cr b/src/ameba/cli/cmd.cr index f87030785..22c1d2f28 100644 --- a/src/ameba/cli/cmd.cr +++ b/src/ameba/cli/cmd.cr @@ -18,6 +18,9 @@ module Ameba::Cli config.autocorrect = autocorrect config.stdin_filename = opts.stdin_filename + if version = opts.version + config.version = version + end if globs = opts.globs config.globs = globs end @@ -53,6 +56,7 @@ module Ameba::Cli private class Opts property config : Path? + property version : String? property formatter : Symbol | String | Nil property globs : Array(String)? property only : Array(String)? @@ -90,6 +94,11 @@ module Ameba::Cli opts.config = Path[path] unless path.empty? end + parser.on("-u", "--up-to-version VERSION", + "Choose a version") do |version| + opts.version = version + end + parser.on("-f", "--format FORMATTER", "Choose an output formatter: #{Config.formatter_names}") do |formatter| opts.formatter = formatter diff --git a/src/ameba/config.cr b/src/ameba/config.cr index 6f80fba21..38d458d75 100644 --- a/src/ameba/config.cr +++ b/src/ameba/config.cr @@ -1,3 +1,4 @@ +require "semantic_version" require "yaml" require "./glob_utils" @@ -63,6 +64,9 @@ class Ameba::Config getter rules : Array(Rule::Base) property severity = Severity::Convention + # Returns an ameba version to be used by `Ameba::Runner`. + property version : SemanticVersion? + # Returns a list of paths (with wildcards) to files. # Represents a list of sources to be inspected. # If globs are not set, it will return default list of files. @@ -100,6 +104,9 @@ class Ameba::Config @excluded = load_array_section(config, "Excluded") @globs = load_array_section(config, "Globs", DEFAULT_GLOBS) + if version = config["version"]?.try(&.as_s).presence + self.version = version + end if formatter_name = load_formatter_name(config) self.formatter = formatter_name end @@ -194,6 +201,16 @@ class Ameba::Config @formatter = formatter.new end + # Sets version from string. + # + # ``` + # config = Ameba::Config.load + # config.version = "1.6.0" + # ``` + def version=(version : String) + @version = SemanticVersion.parse(version) + end + # Updates rule properties. # # ``` @@ -329,6 +346,17 @@ class Ameba::Config @[YAML::Field(key: "Excluded")] property excluded : Array(String)? {% end %} + + {% unless properties["since_version".id] %} + @[YAML::Field(key: "SinceVersion")] + property since_version : String? + {% end %} + + def since_version : SemanticVersion? + if version = @since_version + SemanticVersion.parse(version) + end + end end macro included diff --git a/src/ameba/formatter/todo_formatter.cr b/src/ameba/formatter/todo_formatter.cr index 00a2d28f1..e99ac533a 100644 --- a/src/ameba/formatter/todo_formatter.cr +++ b/src/ameba/formatter/todo_formatter.cr @@ -61,6 +61,8 @@ module Ameba::Formatter # The point is for the user to remove these configuration records # one by one as the reported problems are removed from the code base. + version: "#{VERSION}" + HEADER end diff --git a/src/ameba/runner.cr b/src/ameba/runner.cr index 5a526fac0..62008cf85 100644 --- a/src/ameba/runner.cr +++ b/src/ameba/runner.cr @@ -49,6 +49,9 @@ module Ameba # Returns `true` if correctable issues should be autocorrected. private getter? autocorrect : Bool + # Returns an ameba version up to which the rules should be ran. + property version : SemanticVersion? + # Instantiates a runner using a `config`. # # ``` @@ -62,7 +65,12 @@ module Ameba @sources = config.sources @formatter = config.formatter @severity = config.severity - @rules = config.rules.select(&.enabled?).reject!(&.special?) + @version = config.version + @rules = config.rules.select do |rule| + rule.enabled? && !rule.special? && + (!(version = @version) || !(since_version = rule.since_version) || + since_version <= version) + end @autocorrect = config.autocorrect? @unneeded_disable_directive_rule = @@ -70,7 +78,7 @@ module Ameba .find &.class.==(Rule::Lint::UnneededDisableDirective) end - protected def initialize(@rules, @sources, @formatter, @severity, @autocorrect = false) + protected def initialize(@rules, @sources, @formatter, @severity, @autocorrect = false, @version = nil) end # Performs the inspection. Iterates through all sources and test it using