Skip to content

Commit

Permalink
RubyVersionFile cop (read version from .ruby-version) (#6)
Browse files Browse the repository at this point in the history
  • Loading branch information
jage authored Sep 24, 2020
1 parent b3992d0 commit 86c989f
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 0 deletions.
5 changes: 5 additions & 0 deletions config/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,8 @@ EightyFourCodes/CommandLiteralInjection:
Description: "Check for Command Injection in `` and %x"
Enabled: true
VersionAdded: "0.0.1"

EightyFourCodes/RubyVersionFile:
Description: "Ensure .ruby-version file use in Gemfile"
Enabled: true
VersionAdded: "0.0.1"
48 changes: 48 additions & 0 deletions lib/rubocop/cop/eighty_four_codes/ruby_version_file.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# frozen_string_literal: true

module RuboCop
module Cop
module EightyFourCodes
# Read Ruby version from a .ruby-version file
#
# Instead of staticly defining the Ruby runtime version in Gemfile, load it from
# a .ruby-version file definition. As this Ruby version file is read by rbenv, chruby etc
# it's much easier for the developer to work with multiple projects with different versions.
#
# @example
# # bad
# ruby 2.6.6
#
# # good
# ruby File.read('.ruby-version')
class RubyVersionFile < Base
extend AutoCorrector

MSG = "Control Ruby version via .ruby-version, fix by replacing with File.read('.ruby-version')"

RESTRICT_ON_SEND = %i[ruby].freeze

def_node_matcher :static_version_found?, <<~PATTERN
(send nil? :ruby
$(str _))
PATTERN

def on_send(node)
return unless File.basename(processed_source.file_path).eql?('Gemfile')
static_version_found?(node) do |source_node, source|
message = format(MSG, source: source)

add_offense(
source_node,
message: message
) do |corrector|
corrector.replace(
source_node, "File.read('.ruby-version')"
)
end
end
end
end
end
end
end
41 changes: 41 additions & 0 deletions spec/rubocop/cop/eighty_four_codes/ruby_version_file_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::EightyFourCodes::RubyVersionFile do
subject(:cop) { described_class.new(config) }

let(:config) { RuboCop::Config.new }

it 'registers an offense defined with double quotes' do
expect_offense(<<~'RUBY', 'Gemfile')
ruby "2.6.6"
^^^^^^^ Control Ruby version via .ruby-version, fix by replacing with File.read('.ruby-version')
RUBY

expect_correction(<<~RUBY)
ruby File.read('.ruby-version')
RUBY
end

it 'registers an offense defined with single quotes' do
expect_offense(<<~'RUBY', 'Gemfile')
ruby '2.1.0'
^^^^^^^ Control Ruby version via .ruby-version, fix by replacing with File.read('.ruby-version')
RUBY

expect_correction(<<~RUBY)
ruby File.read('.ruby-version')
RUBY
end

it 'does not register an offense when not in Gemfile' do
expect_no_offenses(<<~RUBY, 'test.rb')
ruby '2.1.0'
RUBY
end

it 'does not register an offense when reading .ruby-version' do
expect_no_offenses(<<~RUBY, 'Gemfile')
ruby File.read('.ruby-version')
RUBY
end
end

0 comments on commit 86c989f

Please sign in to comment.