-
-
Notifications
You must be signed in to change notification settings - Fork 266
/
environment_variable_access.rb
67 lines (60 loc) · 2.01 KB
/
environment_variable_access.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# frozen_string_literal: true
module RuboCop
module Cop
module Rails
# Looks for direct access to environment variables through the
# `ENV` variable within the application code. This can lead to runtime
# errors due to misconfiguration that could have been discovered at boot
# time if the environment variables were loaded as part of initialization
# and copied into the application's configuration or secrets. The cop can
# be configured to allow either reads or writes if required.
#
# @example
# # good
# Rails.application.config.foo
# Rails.application.config.x.foo.bar
# Rails.application.secrets.foo
# Rails.application.config.foo = "bar"
#
# @example AllowReads: false (default)
# # bad
# ENV["FOO"]
# ENV.fetch("FOO")
#
# @example AllowReads: true
# # good
# ENV["FOO"]
# ENV.fetch("FOO")
#
# @example AllowWrites: false (default)
# # bad
# ENV["FOO"] = "bar"
#
# @example AllowWrites: true
# # good
# ENV["FOO"] = "bar"
class EnvironmentVariableAccess < Base
READ_MSG = 'Do not read from `ENV` directly post initialization.'
WRITE_MSG = 'Do not write to `ENV` directly post initialization.'
def on_const(node)
add_offense(node, message: READ_MSG) if env_read?(node) && !allow_reads?
add_offense(node, message: WRITE_MSG) if env_write?(node) && !allow_writes?
end
def_node_search :env_read?, <<~PATTERN
^(send (const {cbase nil?} :ENV) !:[]= ...)
PATTERN
def_node_search :env_write?, <<~PATTERN
{^(indexasgn (const {cbase nil?} :ENV) ...)
^(send (const {cbase nil?} :ENV) :[]= ...)}
PATTERN
private
def allow_reads?
cop_config['AllowReads'] == true
end
def allow_writes?
cop_config['AllowWrites'] == true
end
end
end
end
end