Skip to content

Commit 7400ec8

Browse files
authored
Detect references to ENV outside of config directories (#71)
This cop will report references to `ENV` in files outside of the config directory. The idea is that applications should extract variables from the ENV at boot time, and fail if those variables are not valid.
1 parent 2e5d673 commit 7400ec8

File tree

7 files changed

+72
-2
lines changed

7 files changed

+72
-2
lines changed

Gemfile.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
PATH
22
remote: .
33
specs:
4-
betterlint (1.18.0)
4+
betterlint (1.19.0)
55
rubocop (~> 1.71)
66
rubocop-graphql (~> 1.5)
77
rubocop-performance (~> 1.23)

README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,27 @@ end
130130
```
131131

132132
All three `params.permit` calls will be flagged.
133+
134+
### Betterment/EnvironmentConfiguration
135+
136+
This cop identifies references to `ENV` outside of the config directory.
137+
138+
Environment variables should be parsed at boot time. If an environment variable is missing or invalid,
139+
the application should fail to boot.
140+
141+
If there isn't a better place to assign your environment variable, Rails provides the `config.x` namespace
142+
for [custom configuration](https://guides.rubyonrails.org/configuring.html#custom-configuration):
143+
144+
```ruby
145+
config.x.whatever = ENV.fetch('WHATEVER')
146+
```
147+
148+
Here's how you'd reference this configuration parameter at runtime:
149+
150+
```ruby
151+
Rails.configuration.x.whatever
152+
```
153+
133154
### Betterment/InternalsProtection
134155

135156
This cop is not enabled by default, and must be enabled from your `.rubocop.yml` file:

betterlint.gemspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
55

66
Gem::Specification.new do |s|
77
s.name = "betterlint"
8-
s.version = "1.18.0"
8+
s.version = "1.19.0"
99
s.authors = ["Development"]
1010
s.email = ["[email protected]"]
1111
s.summary = "Betterment rubocop configuration"

config/default.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@ Betterment/DirectDelayedEnqueue:
3939

4040
Betterment/DynamicParams:
4141
StyleGuide: '#bettermentdynamicparams'
42+
43+
Betterment/EnvironmentConfiguration:
44+
StyleGuide: '#bettermentenvironmentconfiguration'
45+
Exclude:
46+
- config/**/*.rb
47+
- spec/**/*.rb
48+
- test/**/*.rb
4249

4350
Betterment/HardcodedID:
4451
AutoCorrect: false

lib/rubocop/cop/betterment.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
require 'rubocop/cop/betterment/authorization_in_controller'
77
require 'rubocop/cop/betterment/direct_delayed_enqueue'
88
require 'rubocop/cop/betterment/dynamic_params'
9+
require 'rubocop/cop/betterment/environment_configuration'
910
require 'rubocop/cop/betterment/fetch_boolean'
1011
require 'rubocop/cop/betterment/hardcoded_id'
1112
require 'rubocop/cop/betterment/implicit_redirect_type'
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# frozen_string_literal: true
2+
3+
module RuboCop
4+
module Cop
5+
module Betterment
6+
class EnvironmentConfiguration < Base
7+
MSG =
8+
"Environment variables should be parsed at boot time and assigned " \
9+
"to `Rails.configuration` or some other configurable object."
10+
11+
# @!method env?(node)
12+
def_node_matcher :env?, '(const nil? :ENV)'
13+
14+
def on_const(node)
15+
add_offense(node) if env?(node)
16+
end
17+
end
18+
end
19+
end
20+
end
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# frozen_string_literal: true
2+
3+
require 'spec_helper'
4+
5+
RSpec.describe RuboCop::Cop::Betterment::EnvironmentConfiguration, :config do
6+
it 'does not allow access to the ENV' do
7+
expect_offense(<<~RUBY)
8+
ENV['RAILS_ENV']
9+
^^^ Environment variables should be parsed at boot time [...]
10+
11+
ENV['RAILS_ENV'] ||= 'test'
12+
^^^ Environment variables should be parsed at boot time [...]
13+
14+
ENV.fetch('FOO')
15+
^^^ Environment variables should be parsed at boot time [...]
16+
17+
ENV.fetch('FOO', nil)
18+
^^^ Environment variables should be parsed at boot time [...]
19+
RUBY
20+
end
21+
end

0 commit comments

Comments
 (0)