From 74b5bfbb2c4b6fd6cdbbc7254bd7084b36e0c85b Mon Sep 17 00:00:00 2001 From: Tim Kelly Date: Wed, 21 Apr 2021 21:44:35 -0500 Subject: [PATCH 1/8] [Fix #7669] Add Bundler/GemVersionDeclaration Cop --- changelog/new_gem_version_declaration.md | 1 + config/default.yml | 12 +++ lib/rubocop.rb | 1 + .../cop/bundler/gem_version_declaration.rb | 101 ++++++++++++++++++ .../bundler/gem_version_declaration_spec.rb | 71 ++++++++++++ 5 files changed, 186 insertions(+) create mode 100644 changelog/new_gem_version_declaration.md create mode 100644 lib/rubocop/cop/bundler/gem_version_declaration.rb create mode 100644 spec/rubocop/cop/bundler/gem_version_declaration_spec.rb diff --git a/changelog/new_gem_version_declaration.md b/changelog/new_gem_version_declaration.md new file mode 100644 index 00000000000..e5627b36f7d --- /dev/null +++ b/changelog/new_gem_version_declaration.md @@ -0,0 +1 @@ +* [#7669](https://github.com/rubocop/rubocop/issues/7669): New cop `Bundler/GemVersionDeclaration` requires or prohibits specifying gem versions. ([@timlkelly][]) diff --git a/config/default.yml b/config/default.yml index c642fb0155c..43c3b1f1d7f 100644 --- a/config/default.yml +++ b/config/default.yml @@ -174,6 +174,18 @@ Bundler/GemComment: IgnoredGems: [] OnlyFor: [] +Bundler/GemVersionDeclaration: + Description: 'Requires or prohibits gem version declarations.' + Enabled: false + VersionAdded: '<>' + EnforcedStyle: 'required' + SupportedStyles: + - 'required' + - 'prohibited' + Include: + - '**/Gemfile' + IgnoredGems: [] + Bundler/InsecureProtocolSource: Description: >- The source `:gemcutter`, `:rubygems` and `:rubyforge` are deprecated diff --git a/lib/rubocop.rb b/lib/rubocop.rb index e8eb895d4a3..aad9e226e05 100644 --- a/lib/rubocop.rb +++ b/lib/rubocop.rb @@ -148,6 +148,7 @@ require_relative 'rubocop/cop/bundler/duplicated_gem' require_relative 'rubocop/cop/bundler/gem_comment' +require_relative 'rubocop/cop/bundler/gem_version_declaration' require_relative 'rubocop/cop/bundler/insecure_protocol_source' require_relative 'rubocop/cop/bundler/ordered_gems' diff --git a/lib/rubocop/cop/bundler/gem_version_declaration.rb b/lib/rubocop/cop/bundler/gem_version_declaration.rb new file mode 100644 index 00000000000..4df1e350cb3 --- /dev/null +++ b/lib/rubocop/cop/bundler/gem_version_declaration.rb @@ -0,0 +1,101 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module Bundler + # Enforce that Gem version declarations are either required + # or prohibited. + # + # @example EnforcedStyle: required (default) + # # bad + # gem 'rubocop' + # + # # good + # gem 'rubocop', '~> 1.12' + # + # # good + # gem 'rubocop', '>= 1.10.0' + # + # # good + # gem 'rubocop', '>= 1.5.0', '< 1.10.0' + # + # @example EnforcedStyle: prohibited + # # good + # gem 'rubocop' + # + # # bad + # gem 'rubocop', '~> 1.12' + # + # # bad + # gem 'rubocop', '>= 1.10.0' + # + # # bad + # gem 'rubocop', '>= 1.5.0', '< 1.10.0' + # + class GemVersionDeclaration < Base + include ConfigurableEnforcedStyle + + REQUIRED_MSG = 'Gem version declaration is required.' + PROHIBITED_MSG = 'Gem version declaration is prohibited.' + VERSION_DECLARATION_REGEX = /^[~<>=]*\s?[0-9.]+/.freeze + + # @!method gem_declaration?(node) + def_node_matcher :gem_declaration?, '(send nil? :gem str ...)' + + # @!method includes_version_declaration?(node) + def_node_matcher :includes_version_declaration?, <<~PATTERN + (send nil? :gem <(str #version_declaration?) ...>) + PATTERN + + def on_send(node) + return unless gem_declaration?(node) + return if ignored_gem?(node) + + if offense?(node) + add_offense(node) + opposite_style_detected + else + correct_style_detected + end + end + + private + + def ignored_gem?(node) + ignored_gems.include?(node.first_argument.value) + end + + def ignored_gems + Array(cop_config['IgnoredGems']) + end + + def message(range) + gem_declaration = range.source + + if required_style? + format(REQUIRED_MSG, gem_declaration: gem_declaration) + elsif prohibited_style? + format(PROHIBITED_MSG, gem_declaration: gem_declaration) + end + end + + def offense?(node) + (required_style? && !includes_version_declaration?(node)) || + (prohibited_style? && includes_version_declaration?(node)) + end + + def prohibited_style? + style == :prohibited + end + + def required_style? + style == :required + end + + def version_declaration?(expression) + expression.match?(VERSION_DECLARATION_REGEX) + end + end + end + end +end diff --git a/spec/rubocop/cop/bundler/gem_version_declaration_spec.rb b/spec/rubocop/cop/bundler/gem_version_declaration_spec.rb new file mode 100644 index 00000000000..83902765288 --- /dev/null +++ b/spec/rubocop/cop/bundler/gem_version_declaration_spec.rb @@ -0,0 +1,71 @@ +# frozen_string_literal: true + +RSpec.describe RuboCop::Cop::Bundler::GemVersionDeclaration, :config do + context 'when EnforcedStyle is set to required (default)' do + let(:cop_config) do + { + 'EnforcedStyle' => 'required', + 'IgnoredGems' => ['rspec'] + } + end + + it 'flags gems without a version declaration' do + expect_offense(<<~RUBY) + gem 'rubocop' + ^^^^^^^^^^^^^ Gem version declaration is required. + gem 'rubocop', require: false + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Gem version declaration is required. + RUBY + end + + it 'ignores gems with a declared version' do + expect_no_offenses(<<~RUBY) + gem 'rubocop', '>=1.10.0' + gem 'rubocop', '~> 1' + gem 'rubocop', '~> 1.12', require: false + gem 'rubocop', '>= 1.5.0', '< 1.10.0', git: 'https://github.com/rubocop/rubocop' + RUBY + end + + it 'ignores gems included in IgnoredGems metadata' do + expect_no_offenses(<<~RUBY) + gem 'rspec' + RUBY + end + end + + context 'when EnforcedStyle is set to prohibited' do + let(:cop_config) do + { + 'EnforcedStyle' => 'prohibited', + 'IgnoredGems' => ['rspec'] + } + end + + it 'flags gems with a version declaration' do + expect_offense(<<~RUBY) + gem 'rubocop', '~> 1' + ^^^^^^^^^^^^^^^^^^^^^ Gem version declaration is prohibited. + gem 'rubocop', '>=1.10.0' + ^^^^^^^^^^^^^^^^^^^^^^^^^ Gem version declaration is prohibited. + gem 'rubocop', '~> 1.12', require: false + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Gem version declaration is prohibited. + gem 'rubocop', '>= 1.5.0', '< 1.10.0', git: 'https://github.com/rubocop/rubocop' + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Gem version declaration is prohibited. + RUBY + end + + it 'ignores gems without a declared version' do + expect_no_offenses(<<~RUBY) + gem 'rubocop' + gem 'rubocop', require: false + RUBY + end + + it 'ignores gems included in IgnoredGems metadata' do + expect_no_offenses(<<~RUBY) + gem 'rspec', '~> 3.10' + RUBY + end + end +end From 03a855eecaffd01ceabe4860b36d5cc0ff48481c Mon Sep 17 00:00:00 2001 From: Tim Kelly Date: Mon, 3 May 2021 18:00:45 -0500 Subject: [PATCH 2/8] Change SupportedStyles prohibited to forbidden --- changelog/new_gem_version_declaration.md | 2 +- config/default.yml | 4 ++-- .../cop/bundler/gem_version_declaration.rb | 16 ++++++++-------- .../cop/bundler/gem_version_declaration_spec.rb | 12 ++++++------ 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/changelog/new_gem_version_declaration.md b/changelog/new_gem_version_declaration.md index e5627b36f7d..dc535224006 100644 --- a/changelog/new_gem_version_declaration.md +++ b/changelog/new_gem_version_declaration.md @@ -1 +1 @@ -* [#7669](https://github.com/rubocop/rubocop/issues/7669): New cop `Bundler/GemVersionDeclaration` requires or prohibits specifying gem versions. ([@timlkelly][]) +* [#7669](https://github.com/rubocop/rubocop/issues/7669): New cop `Bundler/GemVersionDeclaration` requires or forbids specifying gem versions. ([@timlkelly][]) diff --git a/config/default.yml b/config/default.yml index 43c3b1f1d7f..d701ac508e9 100644 --- a/config/default.yml +++ b/config/default.yml @@ -175,13 +175,13 @@ Bundler/GemComment: OnlyFor: [] Bundler/GemVersionDeclaration: - Description: 'Requires or prohibits gem version declarations.' + Description: 'Requires or forbids gem version declarations.' Enabled: false VersionAdded: '<>' EnforcedStyle: 'required' SupportedStyles: - 'required' - - 'prohibited' + - 'forbidden' Include: - '**/Gemfile' IgnoredGems: [] diff --git a/lib/rubocop/cop/bundler/gem_version_declaration.rb b/lib/rubocop/cop/bundler/gem_version_declaration.rb index 4df1e350cb3..139b4f8706a 100644 --- a/lib/rubocop/cop/bundler/gem_version_declaration.rb +++ b/lib/rubocop/cop/bundler/gem_version_declaration.rb @@ -4,7 +4,7 @@ module RuboCop module Cop module Bundler # Enforce that Gem version declarations are either required - # or prohibited. + # or forbidden. # # @example EnforcedStyle: required (default) # # bad @@ -19,7 +19,7 @@ module Bundler # # good # gem 'rubocop', '>= 1.5.0', '< 1.10.0' # - # @example EnforcedStyle: prohibited + # @example EnforcedStyle: forbidden # # good # gem 'rubocop' # @@ -36,7 +36,7 @@ class GemVersionDeclaration < Base include ConfigurableEnforcedStyle REQUIRED_MSG = 'Gem version declaration is required.' - PROHIBITED_MSG = 'Gem version declaration is prohibited.' + FORBIDDEN_MSG = 'Gem version declaration is forbidden.' VERSION_DECLARATION_REGEX = /^[~<>=]*\s?[0-9.]+/.freeze # @!method gem_declaration?(node) @@ -74,18 +74,18 @@ def message(range) if required_style? format(REQUIRED_MSG, gem_declaration: gem_declaration) - elsif prohibited_style? - format(PROHIBITED_MSG, gem_declaration: gem_declaration) + elsif forbidden_style? + format(FORBIDDEN_MSG, gem_declaration: gem_declaration) end end def offense?(node) (required_style? && !includes_version_declaration?(node)) || - (prohibited_style? && includes_version_declaration?(node)) + (forbidden_style? && includes_version_declaration?(node)) end - def prohibited_style? - style == :prohibited + def forbidden_style? + style == :forbidden end def required_style? diff --git a/spec/rubocop/cop/bundler/gem_version_declaration_spec.rb b/spec/rubocop/cop/bundler/gem_version_declaration_spec.rb index 83902765288..79623151e26 100644 --- a/spec/rubocop/cop/bundler/gem_version_declaration_spec.rb +++ b/spec/rubocop/cop/bundler/gem_version_declaration_spec.rb @@ -34,10 +34,10 @@ end end - context 'when EnforcedStyle is set to prohibited' do + context 'when EnforcedStyle is set to forbidden' do let(:cop_config) do { - 'EnforcedStyle' => 'prohibited', + 'EnforcedStyle' => 'forbidden', 'IgnoredGems' => ['rspec'] } end @@ -45,13 +45,13 @@ it 'flags gems with a version declaration' do expect_offense(<<~RUBY) gem 'rubocop', '~> 1' - ^^^^^^^^^^^^^^^^^^^^^ Gem version declaration is prohibited. + ^^^^^^^^^^^^^^^^^^^^^ Gem version declaration is forbidden. gem 'rubocop', '>=1.10.0' - ^^^^^^^^^^^^^^^^^^^^^^^^^ Gem version declaration is prohibited. + ^^^^^^^^^^^^^^^^^^^^^^^^^ Gem version declaration is forbidden. gem 'rubocop', '~> 1.12', require: false - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Gem version declaration is prohibited. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Gem version declaration is forbidden. gem 'rubocop', '>= 1.5.0', '< 1.10.0', git: 'https://github.com/rubocop/rubocop' - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Gem version declaration is prohibited. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Gem version declaration is forbidden. RUBY end From e19796836741228aef7ae1690f6fb05a10749e35 Mon Sep 17 00:00:00 2001 From: Tim Kelly Date: Mon, 3 May 2021 18:15:36 -0500 Subject: [PATCH 3/8] Rename cop to GemVersion --- changelog/new_gem_version.md | 1 + changelog/new_gem_version_declaration.md | 1 - config/default.yml | 2 +- lib/rubocop.rb | 2 +- .../cop/bundler/{gem_version_declaration.rb => gem_version.rb} | 2 +- .../{gem_version_declaration_spec.rb => gem_version_spec.rb} | 2 +- 6 files changed, 5 insertions(+), 5 deletions(-) create mode 100644 changelog/new_gem_version.md delete mode 100644 changelog/new_gem_version_declaration.md rename lib/rubocop/cop/bundler/{gem_version_declaration.rb => gem_version.rb} (98%) rename spec/rubocop/cop/bundler/{gem_version_declaration_spec.rb => gem_version_spec.rb} (96%) diff --git a/changelog/new_gem_version.md b/changelog/new_gem_version.md new file mode 100644 index 00000000000..dd201a7034e --- /dev/null +++ b/changelog/new_gem_version.md @@ -0,0 +1 @@ +* [#7669](https://github.com/rubocop/rubocop/issues/7669): New cop `Bundler/GemVersion` requires or forbids specifying gem versions. ([@timlkelly][]) diff --git a/changelog/new_gem_version_declaration.md b/changelog/new_gem_version_declaration.md deleted file mode 100644 index dc535224006..00000000000 --- a/changelog/new_gem_version_declaration.md +++ /dev/null @@ -1 +0,0 @@ -* [#7669](https://github.com/rubocop/rubocop/issues/7669): New cop `Bundler/GemVersionDeclaration` requires or forbids specifying gem versions. ([@timlkelly][]) diff --git a/config/default.yml b/config/default.yml index d701ac508e9..19a9502cb50 100644 --- a/config/default.yml +++ b/config/default.yml @@ -174,7 +174,7 @@ Bundler/GemComment: IgnoredGems: [] OnlyFor: [] -Bundler/GemVersionDeclaration: +Bundler/GemVersion: Description: 'Requires or forbids gem version declarations.' Enabled: false VersionAdded: '<>' diff --git a/lib/rubocop.rb b/lib/rubocop.rb index aad9e226e05..202f0cfbdd3 100644 --- a/lib/rubocop.rb +++ b/lib/rubocop.rb @@ -148,7 +148,7 @@ require_relative 'rubocop/cop/bundler/duplicated_gem' require_relative 'rubocop/cop/bundler/gem_comment' -require_relative 'rubocop/cop/bundler/gem_version_declaration' +require_relative 'rubocop/cop/bundler/gem_version' require_relative 'rubocop/cop/bundler/insecure_protocol_source' require_relative 'rubocop/cop/bundler/ordered_gems' diff --git a/lib/rubocop/cop/bundler/gem_version_declaration.rb b/lib/rubocop/cop/bundler/gem_version.rb similarity index 98% rename from lib/rubocop/cop/bundler/gem_version_declaration.rb rename to lib/rubocop/cop/bundler/gem_version.rb index 139b4f8706a..3c87ac96576 100644 --- a/lib/rubocop/cop/bundler/gem_version_declaration.rb +++ b/lib/rubocop/cop/bundler/gem_version.rb @@ -32,7 +32,7 @@ module Bundler # # bad # gem 'rubocop', '>= 1.5.0', '< 1.10.0' # - class GemVersionDeclaration < Base + class GemVersion < Base include ConfigurableEnforcedStyle REQUIRED_MSG = 'Gem version declaration is required.' diff --git a/spec/rubocop/cop/bundler/gem_version_declaration_spec.rb b/spec/rubocop/cop/bundler/gem_version_spec.rb similarity index 96% rename from spec/rubocop/cop/bundler/gem_version_declaration_spec.rb rename to spec/rubocop/cop/bundler/gem_version_spec.rb index 79623151e26..235dae39146 100644 --- a/spec/rubocop/cop/bundler/gem_version_declaration_spec.rb +++ b/spec/rubocop/cop/bundler/gem_version_spec.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -RSpec.describe RuboCop::Cop::Bundler::GemVersionDeclaration, :config do +RSpec.describe RuboCop::Cop::Bundler::GemVersion, :config do context 'when EnforcedStyle is set to required (default)' do let(:cop_config) do { From adfbdc148921f341be7cfbc51ca0d469184fc940 Mon Sep 17 00:00:00 2001 From: Tim Kelly Date: Mon, 3 May 2021 18:32:08 -0500 Subject: [PATCH 4/8] Prefer specification over delcaration terminology --- config/default.yml | 2 +- lib/rubocop/cop/bundler/gem_version.rb | 28 ++++++++++---------- spec/rubocop/cop/bundler/gem_version_spec.rb | 24 ++++++++--------- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/config/default.yml b/config/default.yml index 19a9502cb50..3fa2fbb5ad6 100644 --- a/config/default.yml +++ b/config/default.yml @@ -175,7 +175,7 @@ Bundler/GemComment: OnlyFor: [] Bundler/GemVersion: - Description: 'Requires or forbids gem version declarations.' + Description: 'Requires or forbids specifying gem versions.' Enabled: false VersionAdded: '<>' EnforcedStyle: 'required' diff --git a/lib/rubocop/cop/bundler/gem_version.rb b/lib/rubocop/cop/bundler/gem_version.rb index 3c87ac96576..cf06dff4f01 100644 --- a/lib/rubocop/cop/bundler/gem_version.rb +++ b/lib/rubocop/cop/bundler/gem_version.rb @@ -3,7 +3,7 @@ module RuboCop module Cop module Bundler - # Enforce that Gem version declarations are either required + # Enforce that Gem version specifications are either required # or forbidden. # # @example EnforcedStyle: required (default) @@ -35,16 +35,16 @@ module Bundler class GemVersion < Base include ConfigurableEnforcedStyle - REQUIRED_MSG = 'Gem version declaration is required.' - FORBIDDEN_MSG = 'Gem version declaration is forbidden.' - VERSION_DECLARATION_REGEX = /^[~<>=]*\s?[0-9.]+/.freeze + REQUIRED_MSG = 'Gem version specification is required.' + FORBIDDEN_MSG = 'Gem version specification is forbidden.' + VERSION_SPECIFICATION_REGEX = /^[~<>=]*\s?[0-9.]+/.freeze # @!method gem_declaration?(node) def_node_matcher :gem_declaration?, '(send nil? :gem str ...)' - # @!method includes_version_declaration?(node) - def_node_matcher :includes_version_declaration?, <<~PATTERN - (send nil? :gem <(str #version_declaration?) ...>) + # @!method includes_version_specification?(node) + def_node_matcher :includes_version_specification?, <<~PATTERN + (send nil? :gem <(str #version_specification?) ...>) PATTERN def on_send(node) @@ -70,18 +70,18 @@ def ignored_gems end def message(range) - gem_declaration = range.source + gem_specification = range.source if required_style? - format(REQUIRED_MSG, gem_declaration: gem_declaration) + format(REQUIRED_MSG, gem_specification: gem_specification) elsif forbidden_style? - format(FORBIDDEN_MSG, gem_declaration: gem_declaration) + format(FORBIDDEN_MSG, gem_specification: gem_specification) end end def offense?(node) - (required_style? && !includes_version_declaration?(node)) || - (forbidden_style? && includes_version_declaration?(node)) + (required_style? && !includes_version_specification?(node)) || + (forbidden_style? && includes_version_specification?(node)) end def forbidden_style? @@ -92,8 +92,8 @@ def required_style? style == :required end - def version_declaration?(expression) - expression.match?(VERSION_DECLARATION_REGEX) + def version_specification?(expression) + expression.match?(VERSION_SPECIFICATION_REGEX) end end end diff --git a/spec/rubocop/cop/bundler/gem_version_spec.rb b/spec/rubocop/cop/bundler/gem_version_spec.rb index 235dae39146..e99ec9b7bc5 100644 --- a/spec/rubocop/cop/bundler/gem_version_spec.rb +++ b/spec/rubocop/cop/bundler/gem_version_spec.rb @@ -9,16 +9,16 @@ } end - it 'flags gems without a version declaration' do + it 'flags gems that do not specify a version' do expect_offense(<<~RUBY) gem 'rubocop' - ^^^^^^^^^^^^^ Gem version declaration is required. + ^^^^^^^^^^^^^ Gem version specification is required. gem 'rubocop', require: false - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Gem version declaration is required. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Gem version specification is required. RUBY end - it 'ignores gems with a declared version' do + it 'does not flag gems with a specified version' do expect_no_offenses(<<~RUBY) gem 'rubocop', '>=1.10.0' gem 'rubocop', '~> 1' @@ -27,7 +27,7 @@ RUBY end - it 'ignores gems included in IgnoredGems metadata' do + it 'does not flag gems included in AllowedGems metadata' do expect_no_offenses(<<~RUBY) gem 'rspec' RUBY @@ -42,27 +42,27 @@ } end - it 'flags gems with a version declaration' do + it 'flags gems that specify a gem version' do expect_offense(<<~RUBY) gem 'rubocop', '~> 1' - ^^^^^^^^^^^^^^^^^^^^^ Gem version declaration is forbidden. + ^^^^^^^^^^^^^^^^^^^^^ Gem version specification is forbidden. gem 'rubocop', '>=1.10.0' - ^^^^^^^^^^^^^^^^^^^^^^^^^ Gem version declaration is forbidden. + ^^^^^^^^^^^^^^^^^^^^^^^^^ Gem version specification is forbidden. gem 'rubocop', '~> 1.12', require: false - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Gem version declaration is forbidden. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Gem version specification is forbidden. gem 'rubocop', '>= 1.5.0', '< 1.10.0', git: 'https://github.com/rubocop/rubocop' - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Gem version declaration is forbidden. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Gem version specification is forbidden. RUBY end - it 'ignores gems without a declared version' do + it 'does not flag gems without a specified version' do expect_no_offenses(<<~RUBY) gem 'rubocop' gem 'rubocop', require: false RUBY end - it 'ignores gems included in IgnoredGems metadata' do + it 'does not flag gems included in AllowedGems metadata' do expect_no_offenses(<<~RUBY) gem 'rspec', '~> 3.10' RUBY From e534b59274a66a529735b951a8591ce71d41a3a2 Mon Sep 17 00:00:00 2001 From: Tim Kelly Date: Mon, 3 May 2021 18:33:37 -0500 Subject: [PATCH 5/8] Prefer AllowedGems over IgnoredGems --- config/default.yml | 2 +- lib/rubocop/cop/bundler/gem_version.rb | 10 +++++----- spec/rubocop/cop/bundler/gem_version_spec.rb | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/config/default.yml b/config/default.yml index 3fa2fbb5ad6..99bf393876e 100644 --- a/config/default.yml +++ b/config/default.yml @@ -184,7 +184,7 @@ Bundler/GemVersion: - 'forbidden' Include: - '**/Gemfile' - IgnoredGems: [] + AllowedGems: [] Bundler/InsecureProtocolSource: Description: >- diff --git a/lib/rubocop/cop/bundler/gem_version.rb b/lib/rubocop/cop/bundler/gem_version.rb index cf06dff4f01..b7dc9e80c5b 100644 --- a/lib/rubocop/cop/bundler/gem_version.rb +++ b/lib/rubocop/cop/bundler/gem_version.rb @@ -49,7 +49,7 @@ class GemVersion < Base def on_send(node) return unless gem_declaration?(node) - return if ignored_gem?(node) + return if allowed_gem?(node) if offense?(node) add_offense(node) @@ -61,12 +61,12 @@ def on_send(node) private - def ignored_gem?(node) - ignored_gems.include?(node.first_argument.value) + def allowed_gem?(node) + allowed_gems.include?(node.first_argument.value) end - def ignored_gems - Array(cop_config['IgnoredGems']) + def allowed_gems + Array(cop_config['AllowedGems']) end def message(range) diff --git a/spec/rubocop/cop/bundler/gem_version_spec.rb b/spec/rubocop/cop/bundler/gem_version_spec.rb index e99ec9b7bc5..840dbd2e68b 100644 --- a/spec/rubocop/cop/bundler/gem_version_spec.rb +++ b/spec/rubocop/cop/bundler/gem_version_spec.rb @@ -5,7 +5,7 @@ let(:cop_config) do { 'EnforcedStyle' => 'required', - 'IgnoredGems' => ['rspec'] + 'AllowedGems' => ['rspec'] } end @@ -38,7 +38,7 @@ let(:cop_config) do { 'EnforcedStyle' => 'forbidden', - 'IgnoredGems' => ['rspec'] + 'AllowedGems' => ['rspec'] } end From 96299dad8d48b160fcf917b62f4038bafe1b5e1b Mon Sep 17 00:00:00 2001 From: Tim Kelly Date: Mon, 3 May 2021 18:34:47 -0500 Subject: [PATCH 6/8] Include .gemfile and gems.rb file types --- config/default.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/default.yml b/config/default.yml index 99bf393876e..b1d85645867 100644 --- a/config/default.yml +++ b/config/default.yml @@ -183,7 +183,9 @@ Bundler/GemVersion: - 'required' - 'forbidden' Include: + - '**/*.gemfile' - '**/Gemfile' + - '**/gems.rb' AllowedGems: [] Bundler/InsecureProtocolSource: From 90db0f77f008e3323916f6e827b94614598b8d55 Mon Sep 17 00:00:00 2001 From: Tim Kelly Date: Mon, 3 May 2021 19:46:58 -0500 Subject: [PATCH 7/8] Extract gem_declaration? --- lib/rubocop.rb | 1 + lib/rubocop/cop/bundler/gem_comment.rb | 4 +--- lib/rubocop/cop/bundler/gem_version.rb | 4 +--- lib/rubocop/cop/mixin/gem_declaration.rb | 13 +++++++++++++ 4 files changed, 16 insertions(+), 6 deletions(-) create mode 100644 lib/rubocop/cop/mixin/gem_declaration.rb diff --git a/lib/rubocop.rb b/lib/rubocop.rb index 202f0cfbdd3..9fe837cf221 100644 --- a/lib/rubocop.rb +++ b/lib/rubocop.rb @@ -82,6 +82,7 @@ require_relative 'rubocop/cop/mixin/enforce_superclass' require_relative 'rubocop/cop/mixin/first_element_line_break' require_relative 'rubocop/cop/mixin/frozen_string_literal' +require_relative 'rubocop/cop/mixin/gem_declaration' require_relative 'rubocop/cop/mixin/hash_alignment_styles' require_relative 'rubocop/cop/mixin/hash_transform_method' require_relative 'rubocop/cop/mixin/ignored_pattern' diff --git a/lib/rubocop/cop/bundler/gem_comment.rb b/lib/rubocop/cop/bundler/gem_comment.rb index 277a599933f..747276c9ad5 100644 --- a/lib/rubocop/cop/bundler/gem_comment.rb +++ b/lib/rubocop/cop/bundler/gem_comment.rb @@ -82,6 +82,7 @@ module Bundler # class GemComment < Base include DefNode + include GemDeclaration MSG = 'Missing gem description comment.' CHECKED_OPTIONS_CONFIG = 'OnlyFor' @@ -90,9 +91,6 @@ class GemComment < Base RESTRICTIVE_VERSION_PATTERN = /<|~>/.freeze RESTRICT_ON_SEND = %i[gem].freeze - # @!method gem_declaration?(node) - def_node_matcher :gem_declaration?, '(send nil? :gem str ...)' - def on_send(node) return unless gem_declaration?(node) return if ignored_gem?(node) diff --git a/lib/rubocop/cop/bundler/gem_version.rb b/lib/rubocop/cop/bundler/gem_version.rb index b7dc9e80c5b..58da492ffa1 100644 --- a/lib/rubocop/cop/bundler/gem_version.rb +++ b/lib/rubocop/cop/bundler/gem_version.rb @@ -34,14 +34,12 @@ module Bundler # class GemVersion < Base include ConfigurableEnforcedStyle + include GemDeclaration REQUIRED_MSG = 'Gem version specification is required.' FORBIDDEN_MSG = 'Gem version specification is forbidden.' VERSION_SPECIFICATION_REGEX = /^[~<>=]*\s?[0-9.]+/.freeze - # @!method gem_declaration?(node) - def_node_matcher :gem_declaration?, '(send nil? :gem str ...)' - # @!method includes_version_specification?(node) def_node_matcher :includes_version_specification?, <<~PATTERN (send nil? :gem <(str #version_specification?) ...>) diff --git a/lib/rubocop/cop/mixin/gem_declaration.rb b/lib/rubocop/cop/mixin/gem_declaration.rb new file mode 100644 index 00000000000..80251655987 --- /dev/null +++ b/lib/rubocop/cop/mixin/gem_declaration.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + # Common functionality for checking gem declarations. + module GemDeclaration + extend NodePattern::Macros + + # @!method gem_declaration?(node) + def_node_matcher :gem_declaration?, '(send nil? :gem str ...)' + end + end +end From 14cf5c540e51f31a1f38ac02e66fd08480261eea Mon Sep 17 00:00:00 2001 From: Tim Kelly Date: Mon, 3 May 2021 20:20:06 -0500 Subject: [PATCH 8/8] Update VERSION_SPECIFICATION_REGEX --- lib/rubocop/cop/bundler/gem_version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/rubocop/cop/bundler/gem_version.rb b/lib/rubocop/cop/bundler/gem_version.rb index 58da492ffa1..6d73edbf303 100644 --- a/lib/rubocop/cop/bundler/gem_version.rb +++ b/lib/rubocop/cop/bundler/gem_version.rb @@ -38,7 +38,7 @@ class GemVersion < Base REQUIRED_MSG = 'Gem version specification is required.' FORBIDDEN_MSG = 'Gem version specification is forbidden.' - VERSION_SPECIFICATION_REGEX = /^[~<>=]*\s?[0-9.]+/.freeze + VERSION_SPECIFICATION_REGEX = /^\s*[~<>=]*\s*[0-9.]+/.freeze # @!method includes_version_specification?(node) def_node_matcher :includes_version_specification?, <<~PATTERN