diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 13167f117..ff9ed13c5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,7 +17,7 @@ jobs: strategy: fail-fast: false matrix: - ruby: [ruby-2.7, ruby-3.0, ruby-3.1.2, ruby-3.1, ruby-3.2] + ruby: [ruby-3.0, ruby-3.1.2, ruby-3.1, ruby-3.2] os: [ubuntu-latest] include: - os: macos-latest @@ -40,7 +40,7 @@ jobs: strategy: fail-fast: false matrix: - ruby: [ruby-2.7, ruby-3.0, ruby-3.1.2, ruby-3.1, ruby-3.2] + ruby: [ruby-3.0, ruby-3.1.2, ruby-3.1, ruby-3.2] os: [ubuntu-latest] include: - os: macos-latest @@ -65,7 +65,7 @@ jobs: strategy: fail-fast: false matrix: - ruby: [ruby-2.7, ruby-3.0, ruby-3.1.2, ruby-3.1, ruby-3.2] + ruby: [ruby-3.0, ruby-3.1.2, ruby-3.1, ruby-3.2] os: [ubuntu-latest] include: - os: macos-latest @@ -92,7 +92,7 @@ jobs: strategy: fail-fast: false matrix: - ruby: [ruby-2.7, ruby-3.0, ruby-3.1.2, ruby-3.1, ruby-3.2] + ruby: [ruby-3.0, ruby-3.1.2, ruby-3.1, ruby-3.2] os: [ubuntu-latest] steps: - uses: actions/checkout@v3 @@ -108,7 +108,7 @@ jobs: strategy: fail-fast: false matrix: - ruby: [ruby-2.7, ruby-3.0, ruby-3.1.2, ruby-3.1, ruby-3.2] + ruby: [ruby-3.0, ruby-3.1.2, ruby-3.1, ruby-3.2] os: [ubuntu-latest] steps: - uses: actions/checkout@v3 @@ -124,7 +124,7 @@ jobs: strategy: fail-fast: false matrix: - ruby: [ruby-2.7, ruby-3.0, ruby-3.1.2, ruby-3.1, ruby-3.2] + ruby: [ruby-3.0, ruby-3.1.2, ruby-3.1, ruby-3.2] os: [ubuntu-latest] steps: - uses: actions/checkout@v3 @@ -140,7 +140,7 @@ jobs: strategy: fail-fast: false matrix: - ruby: [ruby-2.7, ruby-3.0, ruby-3.1.2, ruby-3.1, ruby-3.2] + ruby: [ruby-3.0, ruby-3.1.2, ruby-3.1, ruby-3.2] os: [ubuntu-latest] steps: - uses: actions/checkout@v3 diff --git a/.rubocop.yml b/.rubocop.yml index b6a29000a..583f77548 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -5,7 +5,7 @@ AllCops: - 'tmp/**/*' - 'vendor/**/*' NewCops: enable - TargetRubyVersion: 2.7 + TargetRubyVersion: 3.0 # This is output on every run of `rubocop` and feels fairly noisy. SuggestExtensions: false diff --git a/Changelog.md b/Changelog.md index 53ad0a4ea..9ba942b2e 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,7 @@ +# v0.11.26 unreleased + +* Drop support for ruby 2.7 + # v0.11.25 2023-10-18 * Add support for commercial organization wide licenses @@ -37,7 +41,7 @@ The old key is still supported but deprecated. - Add ability to provide multiple `--integration-argument` options that get passed down + Add ability to provide multiple `--integration-argument` options that get passed down directly to rspec. Also available in the config file. # v0.11.20 2023-05-22 diff --git a/README.md b/README.md index 7c1594347..1d3ae5fd3 100644 --- a/README.md +++ b/README.md @@ -58,13 +58,12 @@ Supported indicates if a specific Ruby version / Implementation is actively supp | Implementation | Version | Runtime | Syntax | Mutations | Supported | | -------------- | -------------- | ------- | ------------------ | ------------------ | ------------------ | -| cRUBY/MRI | 2.7 | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | cRUBY/MRI | 3.0 | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | cRUBY/MRI | 3.1 | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | cRUBY/MRI | 3.2 | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | jruby | TBD | :email: | :email: | :email: | :email: | | mruby | TBD | :email: | :email: | :email: | :email: | -| cRUBY/MRI | < 2.7 | :no_entry: | :no_entry: | :no_entry: | :no_entry: | +| cRUBY/MRI | < 3.0 | :no_entry: | :no_entry: | :no_entry: | :no_entry: | Labels: diff --git a/lib/mutant.rb b/lib/mutant.rb index d7c6381dc..138252509 100644 --- a/lib/mutant.rb +++ b/lib/mutant.rb @@ -63,8 +63,8 @@ module Mutant env_key = /[a-zA-Z_\d]+/ - ENV_VARIABLE_KEY_VALUE_REGEXP = /\A(?#{env_key}+)=(?.*)\z/.freeze - ENV_VARIABLE_KEY_REGEXP = /\A#{env_key}\z/.freeze + ENV_VARIABLE_KEY_VALUE_REGEXP = /\A(?#{env_key}+)=(?.*)\z/ + ENV_VARIABLE_KEY_REGEXP = /\A#{env_key}\z/ # rubocop:disable Metrics/BlockLength record.call(:require_mutant_lib) do diff --git a/lib/mutant/ast/pattern/lexer.rb b/lib/mutant/ast/pattern/lexer.rb index 7f7041502..855d463bb 100644 --- a/lib/mutant/ast/pattern/lexer.rb +++ b/lib/mutant/ast/pattern/lexer.rb @@ -6,7 +6,7 @@ class Pattern # rubocop:disable Metrics/ClassLength class Lexer WHITESPACE = [' ', "\t", "\n"].to_set.freeze - STRING_PATTERN = /\A[a-zA-Z][_a-zA-Z0-9]*\z/.freeze + STRING_PATTERN = /\A[a-zA-Z][_a-zA-Z0-9]*\z/ SINGLE_CHAR = { diff --git a/lib/mutant/expression.rb b/lib/mutant/expression.rb index 49f1cf86a..1a4294195 100644 --- a/lib/mutant/expression.rb +++ b/lib/mutant/expression.rb @@ -4,8 +4,8 @@ module Mutant # Abstract base class for match expression class Expression - fragment = /[A-Za-z][A-Za-z\d_]*/.freeze - SCOPE_NAME_PATTERN = /(?#{fragment}(?:#{SCOPE_OPERATOR}#{fragment})*)/.freeze + fragment = /[A-Za-z][A-Za-z\d_]*/ + SCOPE_NAME_PATTERN = /(?#{fragment}(?:#{SCOPE_OPERATOR}#{fragment})*)/ SCOPE_SYMBOL_PATTERN = '(?[.#])' private_constant(*constants(false)) diff --git a/lib/mutant/expression/descendants.rb b/lib/mutant/expression/descendants.rb index 72b59fa46..5d32c0702 100644 --- a/lib/mutant/expression/descendants.rb +++ b/lib/mutant/expression/descendants.rb @@ -5,7 +5,7 @@ class Expression class Descendants < self include Anima.new(:const_name) - REGEXP = /\Adescendants:(?.+)\z/.freeze + REGEXP = /\Adescendants:(?.+)\z/ def syntax "descendants:#{const_name}" diff --git a/lib/mutant/expression/method.rb b/lib/mutant/expression/method.rb index 0fe9a374b..b1fd67bf9 100644 --- a/lib/mutant/expression/method.rb +++ b/lib/mutant/expression/method.rb @@ -20,11 +20,11 @@ class Method < self '#' => [Matcher::Methods::Instance].freeze }.freeze - METHOD_NAME_PATTERN = /(?.+)/.freeze + METHOD_NAME_PATTERN = /(?.+)/ private_constant(*constants(false)) - REGEXP = /\A#{SCOPE_NAME_PATTERN}#{SCOPE_SYMBOL_PATTERN}#{METHOD_NAME_PATTERN}\z/.freeze + REGEXP = /\A#{SCOPE_NAME_PATTERN}#{SCOPE_SYMBOL_PATTERN}#{METHOD_NAME_PATTERN}\z/ def initialize(*) super diff --git a/lib/mutant/expression/methods.rb b/lib/mutant/expression/methods.rb index b9750c4a3..6a5df5647 100644 --- a/lib/mutant/expression/methods.rb +++ b/lib/mutant/expression/methods.rb @@ -19,7 +19,7 @@ class Methods < self private_constant(*constants(false)) - REGEXP = /\A#{SCOPE_NAME_PATTERN}#{SCOPE_SYMBOL_PATTERN}\z/.freeze + REGEXP = /\A#{SCOPE_NAME_PATTERN}#{SCOPE_SYMBOL_PATTERN}\z/ def initialize(*) super diff --git a/lib/mutant/expression/namespace.rb b/lib/mutant/expression/namespace.rb index 7c6d9523c..e44af252c 100644 --- a/lib/mutant/expression/namespace.rb +++ b/lib/mutant/expression/namespace.rb @@ -9,7 +9,7 @@ class Namespace < self # Recursive namespace expression class Recursive < self - REGEXP = /\A#{SCOPE_NAME_PATTERN}?\*\z/.freeze + REGEXP = /\A#{SCOPE_NAME_PATTERN}?\*\z/ # Initialize object # @@ -17,7 +17,7 @@ class Recursive < self def initialize(*) super - @syntax = "#{scope_name}*".freeze # rubocop:disable Style/RedundantFreeze + @syntax = "#{scope_name}*".freeze @recursion_pattern = Regexp.union( /\A#{scope_name}\z/, @@ -60,7 +60,7 @@ class Exact < self MATCHER = Matcher::Scope private_constant(*constants(false)) - REGEXP = /\A#{SCOPE_NAME_PATTERN}\z/.freeze + REGEXP = /\A#{SCOPE_NAME_PATTERN}\z/ # Matcher matcher on expression # diff --git a/lib/mutant/integration/rspec.rb b/lib/mutant/integration/rspec.rb index 69ff4652b..3dfdb8180 100644 --- a/lib/mutant/integration/rspec.rb +++ b/lib/mutant/integration/rspec.rb @@ -22,7 +22,7 @@ class Integration class Rspec < self ALL_EXPRESSION = Expression::Namespace::Recursive.new(scope_name: nil) - EXPRESSION_CANDIDATE = /\A([^ ]+)(?: )?/.freeze + EXPRESSION_CANDIDATE = /\A([^ ]+)(?: )?/ EXIT_SUCCESS = 0 DEFAULT_CLI_OPTIONS = %w[--fail-fast spec].freeze TEST_ID_FORMAT = 'rspec:%d:%s/%s' diff --git a/lib/mutant/license/subscription/repository.rb b/lib/mutant/license/subscription/repository.rb index 0c74f23c8..880ef00dc 100644 --- a/lib/mutant/license/subscription/repository.rb +++ b/lib/mutant/license/subscription/repository.rb @@ -6,11 +6,11 @@ class Subscription class Repository include Anima.new(:host, :path) - REMOTE_REGEXP = /\A[^\t]+\t(?[^ ]+) \((?:fetch|push)\)\n\z/.freeze - GIT_SSH_REGEXP = %r{\A[^@]+@(?[^:/]+)[:/](?.+?)(?:\.git)?\z}.freeze - GIT_HTTPS_REGEXP = %r{\Ahttps://(?[^/]+)/(?.+?)(?:\.git)?\z}.freeze + REMOTE_REGEXP = /\A[^\t]+\t(?[^ ]+) \((?:fetch|push)\)\n\z/ + GIT_SSH_REGEXP = %r{\A[^@]+@(?[^:/]+)[:/](?.+?)(?:\.git)?\z} + GIT_HTTPS_REGEXP = %r{\Ahttps://(?[^/]+)/(?.+?)(?:\.git)?\z} WILDCARD = '/*' - WILDCARD_RANGE = (..-WILDCARD.length).freeze + WILDCARD_RANGE = (..-WILDCARD.length) private_constant(*constants(false)) diff --git a/lib/mutant/loader.rb b/lib/mutant/loader.rb index bf958f83d..3adcf0d5d 100644 --- a/lib/mutant/loader.rb +++ b/lib/mutant/loader.rb @@ -5,7 +5,7 @@ class Loader include Anima.new(:binding, :kernel, :source, :subject) FROZEN_STRING_FORMAT = "# frozen_string_literal: true\n%s" - VOID_VALUE_REGEXP = /\A[^:]+:\d+: void value expression/.freeze + VOID_VALUE_REGEXP = /\A[^:]+:\d+: void value expression/ private_constant(*constants(false)) diff --git a/lib/mutant/matcher/config.rb b/lib/mutant/matcher/config.rb index b47bb8e3a..81eecb22e 100644 --- a/lib/mutant/matcher/config.rb +++ b/lib/mutant/matcher/config.rb @@ -11,7 +11,7 @@ class Config :diffs ) - INSPECT_FORMAT = "#<#{self} %s>" + INSPECT_FORMAT = "#<#{self} %s>".freeze ATTRIBUTE_DELIMITER = ' ' ATTRIBUTE_FORMAT = '%s: [%s]' ENUM_DELIMITER = ',' diff --git a/lib/mutant/mutation.rb b/lib/mutant/mutation.rb index 63d729d33..d49788623 100644 --- a/lib/mutant/mutation.rb +++ b/lib/mutant/mutation.rb @@ -7,7 +7,7 @@ class Mutation include Anima.new(:subject, :node) CODE_DELIMITER = "\0" - CODE_RANGE = (..4).freeze + CODE_RANGE = (..4) # Mutation identification code # diff --git a/lib/mutant/mutator/node/index.rb b/lib/mutant/mutator/node/index.rb index 833aaa204..a95e610bb 100644 --- a/lib/mutant/mutator/node/index.rb +++ b/lib/mutant/mutator/node/index.rb @@ -5,7 +5,7 @@ class Mutator class Node # Base mutator for index operations class Index < self - NO_VALUE_RANGE = (1..-1).freeze + NO_VALUE_RANGE = (1..-1) SEND_REPLACEMENTS = %i[at fetch key?].freeze private_constant(*constants(false)) @@ -67,7 +67,7 @@ def index_range # Mutator for index assignments class Assign < self - REGULAR_RANGE = (1..-2).freeze + REGULAR_RANGE = (1..-2) private_constant(*constants(false)) diff --git a/lib/mutant/mutator/node/named_value/access.rb b/lib/mutant/mutator/node/named_value/access.rb index a6d07cbeb..11057cdd4 100644 --- a/lib/mutant/mutator/node/named_value/access.rb +++ b/lib/mutant/mutator/node/named_value/access.rb @@ -18,7 +18,7 @@ def dispatch # Named value access emitter for instance variables class Ivar < Access - NAME_RANGE = (1..-1).freeze + NAME_RANGE = (1..-1) handle(:ivar) diff --git a/lib/mutant/mutator/node/rescue.rb b/lib/mutant/mutator/node/rescue.rb index 5a79d0c9a..369bfcf7a 100644 --- a/lib/mutant/mutator/node/rescue.rb +++ b/lib/mutant/mutator/node/rescue.rb @@ -12,7 +12,7 @@ class Rescue < self define_named_child(:else_body, -1) - RESCUE_INDICES = (1..-2).freeze + RESCUE_INDICES = (1..-2) private diff --git a/lib/mutant/mutator/node/send/attribute_assignment.rb b/lib/mutant/mutator/node/send/attribute_assignment.rb index 081622e9b..632be8da3 100644 --- a/lib/mutant/mutator/node/send/attribute_assignment.rb +++ b/lib/mutant/mutator/node/send/attribute_assignment.rb @@ -7,7 +7,7 @@ class Send # Mutator for attribute assignments class AttributeAssignment < self - ATTRIBUTE_RANGE = (..-2).freeze + ATTRIBUTE_RANGE = (..-2) private_constant(*constants(false)) diff --git a/lib/mutant/repository/diff.rb b/lib/mutant/repository/diff.rb index c85332755..0e8e53426 100644 --- a/lib/mutant/repository/diff.rb +++ b/lib/mutant/repository/diff.rb @@ -6,7 +6,7 @@ module Repository class Diff include Adamantium, Anima.new(:world, :to) - FORMAT = /\A:\d{6} \d{6} [a-f\d]{40} [a-f\d]{40} [ACDMRTUX]\t(.*)\n\z/.freeze + FORMAT = /\A:\d{6} \d{6} [a-f\d]{40} [a-f\d]{40} [ACDMRTUX]\t(.*)\n\z/ private_constant(*constants(false)) @@ -85,8 +85,8 @@ def parse_line(root, line) class Path include Adamantium, Anima.new(:world, :to, :path) - DECIMAL = /(?:0|[1-9]\d*)/.freeze - REGEXP = /\A@@ -(#{DECIMAL})(?:,(#{DECIMAL}))? \+(#{DECIMAL})(?:,(#{DECIMAL}))? @@/.freeze + DECIMAL = /(?:0|[1-9]\d*)/ + REGEXP = /\A@@ -(#{DECIMAL})(?:,(#{DECIMAL}))? \+(#{DECIMAL})(?:,(#{DECIMAL}))? @@/ private_constant(*constants(false)) diff --git a/lib/mutant/repository/diff/ranges.rb b/lib/mutant/repository/diff/ranges.rb index 82f6fa2cf..c083d3df9 100644 --- a/lib/mutant/repository/diff/ranges.rb +++ b/lib/mutant/repository/diff/ranges.rb @@ -4,8 +4,8 @@ module Mutant module Repository class Diff module Ranges - DECIMAL = /(?:0|[1-9]\d*)/.freeze - REGEXP = /\A@@ -(#{DECIMAL})(?:,(#{DECIMAL}))? \+(#{DECIMAL})(?:,(#{DECIMAL}))? @@/.freeze + DECIMAL = /(?:0|[1-9]\d*)/ + REGEXP = /\A@@ -(#{DECIMAL})(?:,(#{DECIMAL}))? \+(#{DECIMAL})(?:,(#{DECIMAL}))? @@/ private_constant(*constants(false)) diff --git a/lib/mutant/subject/config.rb b/lib/mutant/subject/config.rb index a44f9c4d6..319321f3e 100644 --- a/lib/mutant/subject/config.rb +++ b/lib/mutant/subject/config.rb @@ -7,8 +7,8 @@ class Config DEFAULT = new(inline_disable: false, mutation: Mutation::Config::DEFAULT) - DISABLE_REGEXP = /(\s|^)mutant:disable(?:\s|$)/.freeze - SYNTAX_REGEXP = /\A(?:#|=begin\n)/.freeze + DISABLE_REGEXP = /(\s|^)mutant:disable(?:\s|$)/ + SYNTAX_REGEXP = /\A(?:#|=begin\n)/ def self.parse(comments:, mutation:) new( diff --git a/mutant-minitest.gemspec b/mutant-minitest.gemspec index 8aecbd4e5..c34a8e6fc 100644 --- a/mutant-minitest.gemspec +++ b/mutant-minitest.gemspec @@ -17,7 +17,7 @@ Gem::Specification.new do |gem| gem.extra_rdoc_files = %w[LICENSE] - gem.required_ruby_version = '>= 2.7' + gem.required_ruby_version = '>= 3.0' gem.metadata['rubygems_mfa_required'] = 'true' diff --git a/mutant-rspec.gemspec b/mutant-rspec.gemspec index 5f114250d..be39815fa 100644 --- a/mutant-rspec.gemspec +++ b/mutant-rspec.gemspec @@ -18,7 +18,7 @@ Gem::Specification.new do |gem| gem.metadata['rubygems_mfa_required'] = 'true' - gem.required_ruby_version = '>= 2.7' + gem.required_ruby_version = '>= 3.0' gem.add_runtime_dependency('mutant', "= #{gem.version}") gem.add_runtime_dependency('rspec-core', '>= 3.8.0', '< 4.0.0') diff --git a/mutant.gemspec b/mutant.gemspec index ebd303def..c002a2ad9 100644 --- a/mutant.gemspec +++ b/mutant.gemspec @@ -22,7 +22,7 @@ Gem::Specification.new do |gem| gem.metadata['rubygems_mfa_required'] = 'true' - gem.required_ruby_version = '>= 2.7' + gem.required_ruby_version = '>= 3.0' gem.add_runtime_dependency('diff-lcs', '~> 1.3') gem.add_runtime_dependency('parser', '~> 3.2.2', '>= 3.2.2.4') diff --git a/spec/integrations.yml b/spec/integrations.yml index a9e58a8f1..e7372b001 100644 --- a/spec/integrations.yml +++ b/spec/integrations.yml @@ -48,9 +48,6 @@ mutation_coverage: false mutation_generation: true exclude: - # invalid regexp on <2.7 parser - - test/corpus/literal/pattern.rb - - test/corpus/literal/since/27.rb # invalid regexp on <3.0 parser - test/corpus/literal/since/30.rb # invalid regexp on <3.1 parser diff --git a/spec/unit/mutant/expression/parser_spec.rb b/spec/unit/mutant/expression/parser_spec.rb index ac6b92b26..99088884a 100644 --- a/spec/unit/mutant/expression/parser_spec.rb +++ b/spec/unit/mutant/expression/parser_spec.rb @@ -40,14 +40,14 @@ def apply let(:test_a) do Class.new(Mutant::Expression) do include Unparser::Anima.new - const_set(:REGEXP, /\Atest-syntax\z/.freeze) + const_set(:REGEXP, /\Atest-syntax\z/) end end let(:test_b) do Class.new(Mutant::Expression) do include Unparser::Anima.new - const_set(:REGEXP, /^test-syntax$/.freeze) + const_set(:REGEXP, /^test-syntax$/) end end