Skip to content

Commit

Permalink
Merge pull request #6 from rainforestapp/RF-18143/pp/Lint-NoEnv-cop
Browse files Browse the repository at this point in the history
[RF-18143] Port Lint/NoEnv cop from rf-stylez, fix it, make it autocorrect
  • Loading branch information
Bartek Kruszczynski authored May 26, 2020
2 parents 3a5fa67 + fc4ee42 commit c0c4f23
Show file tree
Hide file tree
Showing 9 changed files with 174 additions and 7 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,6 @@
# rspec failure tracking
.rspec_status
Gemfile.lock

# editors
.vscode/
20 changes: 19 additions & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
PATH
remote: .
specs:
get_env (0.1.3)
get_env (0.2.0)

GEM
remote: https://rubygems.org/
specs:
ast (2.4.0)
diff-lcs (1.3)
jaro_winkler (1.5.4)
parallel (1.19.1)
parser (2.7.1.2)
ast (~> 2.4.0)
rainbow (3.0.0)
rake (13.0.1)
rexml (3.2.4)
rspec (3.8.0)
rspec-core (~> 3.8.0)
rspec-expectations (~> 3.8.0)
Expand All @@ -23,6 +30,16 @@ GEM
rspec-support (3.8.0)
rspec_junit_formatter (0.4.1)
rspec-core (>= 2, < 4, != 2.12.0)
rubocop (0.80.1)
jaro_winkler (~> 1.5.1)
parallel (~> 1.10)
parser (>= 2.7.0.1)
rainbow (>= 2.2.2, < 4.0)
rexml
ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 1.7)
ruby-progressbar (1.10.1)
unicode-display_width (1.6.1)

PLATFORMS
ruby
Expand All @@ -33,6 +50,7 @@ DEPENDENCIES
rake
rspec
rspec_junit_formatter
rubocop

BUNDLED WITH
1.17.3
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,19 @@ GetEnv['YOUR_ENV_VARIABLE']
GetEnv.fetch('YOUR_ENV_VARIABLE') # Will raise a KeyError
```

## Rubocop extension

Add this to your `rubocop.yml`:
```yaml
require:
- get_env/cops

Lint/NoENV:
Enabled: true
```
This will flag any instances of `ENV::[]` and `ENV::fetch` as Rubcop offenses.

## Development

After checking out the repo run `rake spec` to run the tests.
Expand Down
15 changes: 12 additions & 3 deletions get_env.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,28 @@ require 'get_env/version'
Gem::Specification.new do |spec|
spec.name = 'get_env'
spec.version = GetEnv::VERSION
spec.authors = ['Simon Mathieu', 'Bartek Kruszczynski', 'Jonathan Barber']
spec.email = ['[email protected]', '[email protected]']
spec.authors = [
'Simon Mathieu',
'Bartek Kruszczynski',
'Jonathan Barber',
'Paul Padier']
spec.email = [
'[email protected]',
'[email protected]',
'[email protected]']

spec.summary = 'Read values from ENV in a reasonable way'
spec.description = 'Read values from ENV in a reasonable way'
spec.homepage = 'https://github.com/rainforestapp/get_env'
spec.license = 'MIT'

spec.files = ['lib/get_env.rb', 'lib/get_env/version.rb']
spec.files = Dir['lib/**/*']
spec.test_files = Dir['spec/**/*']
spec.require_paths = ['lib']

spec.add_development_dependency 'bundler'
spec.add_development_dependency 'rake'
spec.add_development_dependency 'rspec'
spec.add_development_dependency 'rspec_junit_formatter'
spec.add_development_dependency 'rubocop'
end
6 changes: 4 additions & 2 deletions lib/get_env.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
# frozen_string_literal: true
require "get_env/version"

require 'get_env/version'

module GetEnv
def self.[](key)
return nil if key.nil?

v = ENV[key].to_i
return v if v.to_s == ENV[key]

Expand All @@ -19,7 +21,7 @@ def self.[](key)
def self.fetch(key, default = nil)
if ENV.has_key?(key)
self[key]
elsif default != nil
elsif !default.nil?
default
elsif block_given?
yield
Expand Down
3 changes: 3 additions & 0 deletions lib/get_env/cops.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# frozen_string_literal: true

require_relative '../rubocop/cop/lint/no_env'
2 changes: 1 addition & 1 deletion lib/get_env/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module GetEnv
VERSION = '0.1.4'
VERSION = '0.2.0'
end
43 changes: 43 additions & 0 deletions lib/rubocop/cop/lint/no_env.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# frozen_string_literal: true

module RuboCop
module Cop
module Lint
# @example
# # bad
# ENV[]
#
# # bad
# ENV.fetch(..)
#
# # good
# GetEnv[]
#
# # good
# GetEnv.fetch(...)
class NoENV < Cop
MSG = 'Use `GetEnv` instead of `ENV`.'

def_node_matcher :is_ENV_index?, '(send (const nil? :ENV) :[] _key)'
def_node_matcher :is_ENV_fetch?, '(send (const nil? :ENV) :fetch _key ...)'

def on_const(node)
parent = node.parent
return unless is_ENV_index?(parent) || is_ENV_fetch?(parent)

add_offense(node)
end

def autocorrect(node)
lambda do |corrector|
if Gem::Version.new(RuboCop::Version.version) >= Gem::Version.new('0.82.0')
corrector.replace(node, 'GetEnv')
else
corrector.replace(node.loc.expression, 'GetEnv')
end
end
end
end
end
end
end
76 changes: 76 additions & 0 deletions spec/rubocop/cop/lint/no_env_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# frozen_string_literal: true

require 'rubocop'
require 'rubocop/rspec/support'
require_relative '../../../../lib/rubocop/cop/lint/no_env'

RSpec.describe RuboCop::Cop::Lint::NoENV do
include RuboCop::RSpec::ExpectOffense

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

subject(:cop) { described_class.new(config) }

describe '#[]' do
it 'registers an offense when using `ENV`' do
expect_offense(<<~RUBY)
FOO = ENV['FOO']
^^^ Use `GetEnv` instead of `ENV`.
RUBY

expect_correction(<<~RUBY)
FOO = GetEnv['FOO']
RUBY
end

it 'does not register an offense when using `GetEnv`' do
expect_no_offenses(<<~RUBY)
FOO = GetEnv['FOO']
RUBY
end
end

describe '#fetch' do
it 'registers an offense when using `ENV`' do
expect_offense(<<~RUBY)
do_the_thing(ENV.fetch('FOO'))
^^^ Use `GetEnv` instead of `ENV`.
RUBY

expect_correction(<<~RUBY)
do_the_thing(GetEnv.fetch('FOO'))
RUBY
end

it 'registers an offense when using `ENV` with a default value' do
expect_offense(<<~RUBY)
a = x + ENV.fetch('FOO', 42)
^^^ Use `GetEnv` instead of `ENV`.
RUBY

expect_correction(<<~RUBY)
a = x + GetEnv.fetch('FOO', 42)
RUBY
end

it 'does not register an offense when using `GetEnv`' do
expect_no_offenses(<<~RUBY)
do_the_thing(GetEnv.fetch('FOO'))
RUBY
end

it 'does not register an offense when using `GetEnv` with a default value' do
expect_no_offenses(<<~RUBY)
a = x + GetEnv.fetch('FOO', 42)
RUBY
end
end

it 'does not register an offense when using `ENV` for a method not defined by `GetEnv`' do
expect_no_offenses(<<~RUBY)
ENV.map do |var|
foo << var.lowercase
end
RUBY
end
end

0 comments on commit c0c4f23

Please sign in to comment.