rubocop-gusto 11.1.1 → 11.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +22 -0
- data/config/gusto_cops.yml +14 -3
- data/config/rails.yml +6 -0
- data/lib/rubocop/cop/gusto/feature_flag_constants.rb +35 -0
- data/lib/rubocop/cop/gusto/pluck_on_select.rb +57 -0
- data/lib/rubocop/cop/gusto/smart_todo_team.rb +50 -0
- data/lib/rubocop/cop/gusto/unreferenced_let.rb +1 -1
- data/lib/rubocop/gusto/version.rb +1 -1
- metadata +32 -2
- data/lib/rubocop/cop/gusto/rails_env.rb +0 -77
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 63e4d5c0598bcf51b28b73659d6ef7d2441d350b425f8d34ac4b02dc7eaaf41c
|
|
4
|
+
data.tar.gz: 0ac1b025edbc7f1add82364538074752bd47c2272d8b5fd59fc3aa90db9b052c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 827456db6259cd5414df4d864b65b360cf67f1ba6f8d047d4e4d5bc3374fe42f9220d7012bbf8b1f84fcbac1b5b6d675ea9bc42a77a26ef59f86a0179b92800d
|
|
7
|
+
data.tar.gz: 7543bc23e8c2aaf3747bbfe9e661fb0c83c1a62d23dad639dc95bbc60a7ecd913dce2bc3c8057f35183b8a9367105ee2b6e64821513f50d6365aa74e1935b776
|
data/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,28 @@
|
|
|
3
3
|
- Remove redundant `Rails: Enabled: true` from `config/rails.yml` (already set by rubocop-rails' own defaults)
|
|
4
4
|
- Enable `Rails/DefaultScope` cop (disabled by default in rubocop-rails)
|
|
5
5
|
|
|
6
|
+
## [11.3.0](https://github.com/Gusto/rubocop-gusto/compare/v11.2.0...v11.3.0) (2026-06-29)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* add Gusto/FeatureFlagConstants cop (RR-890) ([#144](https://github.com/Gusto/rubocop-gusto/issues/144)) ([9058e0e](https://github.com/Gusto/rubocop-gusto/commit/9058e0e3055445a6be1818f2c142013239773bb5))
|
|
12
|
+
|
|
13
|
+
## [11.2.0](https://github.com/Gusto/rubocop-gusto/compare/v11.1.1...v11.2.0) (2026-06-26)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
### Features
|
|
17
|
+
|
|
18
|
+
* add Gusto/PluckOnSelect cop ([#137](https://github.com/Gusto/rubocop-gusto/issues/137)) ([d87a5cc](https://github.com/Gusto/rubocop-gusto/commit/d87a5ccf45f3f0fca89ed6b6e28cd6f61fc8b023))
|
|
19
|
+
* add Gusto/SmartTodoTeam cop enforcing valid team in TODOs (RR-866) ([#143](https://github.com/Gusto/rubocop-gusto/issues/143)) ([8d36bf5](https://github.com/Gusto/rubocop-gusto/commit/8d36bf58983c32d48ff90b3862eb273f543e60a7))
|
|
20
|
+
* Ensure rubocop-gusto has access to CodeTeams everywhere it runs (RR-880) ([#141](https://github.com/Gusto/rubocop-gusto/issues/141)) ([b2184ba](https://github.com/Gusto/rubocop-gusto/commit/b2184ba3430359e1210206a09746c979f3826ce3))
|
|
21
|
+
* replace Gusto/RailsEnv with upstream Rails/Env ([#106](https://github.com/Gusto/rubocop-gusto/issues/106)) ([7e00033](https://github.com/Gusto/rubocop-gusto/commit/7e0003347dcbed728e4346a7ec2b4f215923a69d))
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
### Bug Fixes
|
|
25
|
+
|
|
26
|
+
* use UTF-8 encoding when reading support files in UnreferencedLet ([#136](https://github.com/Gusto/rubocop-gusto/issues/136)) ([651dd25](https://github.com/Gusto/rubocop-gusto/commit/651dd252843a5cfd81dc72bab0abc4b57143c138))
|
|
27
|
+
|
|
6
28
|
## [11.1.1](https://github.com/Gusto/rubocop-gusto/compare/v11.1.0...v11.1.1) (2026-06-18)
|
|
7
29
|
|
|
8
30
|
|
data/config/gusto_cops.yml
CHANGED
|
@@ -43,6 +43,9 @@ Gusto/FactoryClassesOrModules:
|
|
|
43
43
|
Include:
|
|
44
44
|
- 'spec/**/factories/*.rb'
|
|
45
45
|
|
|
46
|
+
Gusto/FeatureFlagConstants:
|
|
47
|
+
Description: 'FeatureFlag keys should be constants, not strings.'
|
|
48
|
+
|
|
46
49
|
Gusto/MinByMaxBy:
|
|
47
50
|
Description: 'Checks for the use of `min` or `max` with a proc. Corrects to `min_by` or `max_by`.'
|
|
48
51
|
Safe: false
|
|
@@ -67,6 +70,9 @@ Gusto/PerformClassMethod:
|
|
|
67
70
|
WorkerModules:
|
|
68
71
|
- Sidekiq::Worker
|
|
69
72
|
|
|
73
|
+
Gusto/PluckOnSelect:
|
|
74
|
+
Description: "Do not use `.pluck` on `.select`. Use one or the other."
|
|
75
|
+
|
|
70
76
|
Gusto/PolymorphicTypeValidation:
|
|
71
77
|
Description: 'Ensures that polymorphic relations include a type validation, which is necessary for generating Sorbet types.'
|
|
72
78
|
Include:
|
|
@@ -80,9 +86,6 @@ Gusto/RablExtends:
|
|
|
80
86
|
Include:
|
|
81
87
|
- '**/*.json.rabl'
|
|
82
88
|
|
|
83
|
-
Gusto/RailsEnv:
|
|
84
|
-
Description: 'Use Feature Flags or config instead of `Rails.env`.'
|
|
85
|
-
|
|
86
89
|
Gusto/RakeConstants:
|
|
87
90
|
Description: 'Do not define a constant in rake file, because they are sometimes `load`ed, instead of `require`d which can lead to warnings about redefining constants.'
|
|
88
91
|
Include:
|
|
@@ -104,6 +107,10 @@ Gusto/RspecDateTimeMock:
|
|
|
104
107
|
Gusto/SidekiqParams:
|
|
105
108
|
Description: 'Sidekiq perform methods cannot take keyword arguments.'
|
|
106
109
|
|
|
110
|
+
Gusto/SmartTodoTeam:
|
|
111
|
+
Description: 'TODO comments must be SmartTodo-formatted and target a valid team (CodeTeams).'
|
|
112
|
+
Enabled: false
|
|
113
|
+
|
|
107
114
|
Gusto/ToplevelConstants:
|
|
108
115
|
Description: 'Prevents top-level constants from being defined outside of initializers.'
|
|
109
116
|
Include:
|
|
@@ -133,3 +140,7 @@ Gusto/UsePaintNotColorize:
|
|
|
133
140
|
|
|
134
141
|
Gusto/VcrRecordings:
|
|
135
142
|
Description: 'VCR should be set to not record in tests. Use vcr: {record: :none}.'
|
|
143
|
+
|
|
144
|
+
# We extend this via Gusto/SmartTodoTeam; don't let the upstream cop run standalone.
|
|
145
|
+
SmartTodo/SmartTodoCop:
|
|
146
|
+
Enabled: false
|
data/config/rails.yml
CHANGED
|
@@ -18,6 +18,9 @@ Gusto/DiscouragedGem:
|
|
|
18
18
|
Gems:
|
|
19
19
|
timecop: "Use Rails' time helpers (e.g., freeze_time, travel_to) instead of Timecop."
|
|
20
20
|
|
|
21
|
+
Gusto/PluckOnSelect:
|
|
22
|
+
Description: "Do not use `.pluck` on `.select`. Use one or the other."
|
|
23
|
+
|
|
21
24
|
Performance/DoubleStartEndWith:
|
|
22
25
|
IncludeActiveSupportAliases: true
|
|
23
26
|
|
|
@@ -55,6 +58,9 @@ Rails/EnumHash:
|
|
|
55
58
|
Include:
|
|
56
59
|
- '**/app/models/**/*'
|
|
57
60
|
|
|
61
|
+
Rails/Env:
|
|
62
|
+
Enabled: true
|
|
63
|
+
|
|
58
64
|
Rails/Exit:
|
|
59
65
|
Include:
|
|
60
66
|
- app/**/*
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Gusto
|
|
6
|
+
# Enforces that `FeatureFlag.active?` is called with a constant rather than a
|
|
7
|
+
# string literal. Defining flag keys as constants keeps them in one place,
|
|
8
|
+
# makes typos a load-time error instead of a silent always-off flag, and lets
|
|
9
|
+
# tools find every reference to a flag.
|
|
10
|
+
#
|
|
11
|
+
# `FeatureFlag` is a constant, so it is never nil and safe navigation
|
|
12
|
+
# (`FeatureFlag&.active?`) is never used; the cop only handles `on_send`.
|
|
13
|
+
#
|
|
14
|
+
# @example
|
|
15
|
+
# # bad
|
|
16
|
+
# FeatureFlag.active?("some_feature_flag")
|
|
17
|
+
#
|
|
18
|
+
# # good
|
|
19
|
+
# FeatureFlag.active?(SomeModule::SOME_FEATURE_FLAG)
|
|
20
|
+
class FeatureFlagConstants < Base
|
|
21
|
+
MSG = "FeatureFlag keys should be constants, not strings"
|
|
22
|
+
RESTRICT_ON_SEND = %i(active?).freeze
|
|
23
|
+
|
|
24
|
+
# @!method feature_flag_with_string?(node)
|
|
25
|
+
def_node_matcher :feature_flag_with_string?, <<~PATTERN
|
|
26
|
+
(send (const nil? :FeatureFlag) :active? (str _) ...)
|
|
27
|
+
PATTERN
|
|
28
|
+
|
|
29
|
+
def on_send(node)
|
|
30
|
+
add_offense(node) if feature_flag_with_string?(node)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Gusto
|
|
6
|
+
# Do not use `.pluck` on `.select`.
|
|
7
|
+
#
|
|
8
|
+
# `.select` returns an ActiveRecord relation with only the selected columns marked for
|
|
9
|
+
# retrieval. `.pluck` returns an array of column values. When chained, `.pluck` is unaware
|
|
10
|
+
# of any directive passed to `.select` (e.g. column aliases or a DISTINCT clause), which
|
|
11
|
+
# can cause unexpected behavior.
|
|
12
|
+
#
|
|
13
|
+
# @example Redundant select
|
|
14
|
+
# # bad
|
|
15
|
+
# User.select(:id).pluck(:id)
|
|
16
|
+
#
|
|
17
|
+
# # good
|
|
18
|
+
# User.pluck(:id)
|
|
19
|
+
#
|
|
20
|
+
# @example Column alias: .pluck raises "Unknown column" because it ignores the alias
|
|
21
|
+
# # bad
|
|
22
|
+
# User.select('id AS id2').pluck('id2')
|
|
23
|
+
#
|
|
24
|
+
# # good: use .select alone if you need the alias
|
|
25
|
+
# User.select(:id, 'id AS id2')
|
|
26
|
+
#
|
|
27
|
+
# # good: use .pluck alone if you don't need the alias
|
|
28
|
+
# User.pluck(:id)
|
|
29
|
+
#
|
|
30
|
+
# @example DISTINCT: .pluck loads all rows, ignoring the DISTINCT from .select
|
|
31
|
+
# # bad
|
|
32
|
+
# User.select('DISTINCT email').pluck(:email)
|
|
33
|
+
#
|
|
34
|
+
# # good
|
|
35
|
+
# User.distinct.pluck(:email)
|
|
36
|
+
#
|
|
37
|
+
class PluckOnSelect < Base
|
|
38
|
+
RESTRICT_ON_SEND = %i(pluck).freeze
|
|
39
|
+
MSG = "Do not use `.pluck` on `.select`."
|
|
40
|
+
|
|
41
|
+
def on_send(node)
|
|
42
|
+
return unless node.receiver
|
|
43
|
+
|
|
44
|
+
receiver_node = node.receiver
|
|
45
|
+
while receiver_node
|
|
46
|
+
if receiver_node.call_type? && receiver_node.method?(:select)
|
|
47
|
+
add_offense(node)
|
|
48
|
+
break
|
|
49
|
+
end
|
|
50
|
+
receiver_node = receiver_node.receiver
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
alias_method :on_csend, :on_send
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "smart_todo_cop" # defines RuboCop::Cop::SmartTodo::SmartTodoCop (also requires "smart_todo")
|
|
4
|
+
require "code_teams"
|
|
5
|
+
|
|
6
|
+
module RuboCop
|
|
7
|
+
module Cop
|
|
8
|
+
module Gusto
|
|
9
|
+
# Enforces SmartTodo syntax (via the upstream `SmartTodo/SmartTodoCop`) and,
|
|
10
|
+
# in addition, requires every TODO's `to:` assignee to name a valid team as
|
|
11
|
+
# defined by CodeTeams (`config/teams/**/*.yml`).
|
|
12
|
+
#
|
|
13
|
+
# All of the upstream cop's failure modes are preserved verbatim via `super`.
|
|
14
|
+
# The only additional offense is raised when an otherwise-valid SmartTodo
|
|
15
|
+
# comment is assigned to an unknown team.
|
|
16
|
+
#
|
|
17
|
+
# @example
|
|
18
|
+
# # bad - assigned to an unknown team
|
|
19
|
+
# # TODO(on: date('2025-01-01'), to: 'NotATeam')
|
|
20
|
+
# # Remove this
|
|
21
|
+
#
|
|
22
|
+
# # good - assigned to a team in config/teams
|
|
23
|
+
# # TODO(on: date('2025-01-01'), to: 'Payroll')
|
|
24
|
+
# # Remove this
|
|
25
|
+
class SmartTodoTeam < ::RuboCop::Cop::SmartTodo::SmartTodoCop
|
|
26
|
+
TEAM_HELP = "TODO `to:` must name a valid team (see config/teams). Match the human readable `name:` key (ex: 'Benefits Admin Transfers'), *not* a sluggified form."
|
|
27
|
+
|
|
28
|
+
# @param processed_source [RuboCop::ProcessedSource]
|
|
29
|
+
# @return [void]
|
|
30
|
+
def on_new_investigation
|
|
31
|
+
# Registers every existing SmartTodo offense. RuboCop dedupes offenses by
|
|
32
|
+
# source range (see Cop::Base#add_offense), so any comment flagged here
|
|
33
|
+
# silently swallows the duplicate team offense we might add below.
|
|
34
|
+
super
|
|
35
|
+
|
|
36
|
+
processed_source.comments.each do |comment|
|
|
37
|
+
next unless TODO_PATTERN.match?(comment.text)
|
|
38
|
+
|
|
39
|
+
# `is_a?(String)` guards CodeTeams.find's Sorbet signature, which raises on a
|
|
40
|
+
# non-string. Such assignees are already flagged by `super` (invalid assignee).
|
|
41
|
+
unknown = metadata(comment.text).assignees.select { |assignee| assignee.is_a?(String) && !CodeTeams.find(assignee) }
|
|
42
|
+
next if unknown.empty?
|
|
43
|
+
|
|
44
|
+
add_offense(comment, message: "Unknown team(s): #{unknown.join(', ')}. #{TEAM_HELP}")
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rubocop-gusto
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 11.
|
|
4
|
+
version: 11.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Gusto Engineering
|
|
@@ -9,6 +9,20 @@ bindir: exe
|
|
|
9
9
|
cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: code_teams
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '0'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '0'
|
|
12
26
|
- !ruby/object:Gem::Dependency
|
|
13
27
|
name: lint_roller
|
|
14
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -93,6 +107,20 @@ dependencies:
|
|
|
93
107
|
- - ">="
|
|
94
108
|
- !ruby/object:Gem::Version
|
|
95
109
|
version: '0'
|
|
110
|
+
- !ruby/object:Gem::Dependency
|
|
111
|
+
name: smart_todo
|
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
|
113
|
+
requirements:
|
|
114
|
+
- - ">="
|
|
115
|
+
- !ruby/object:Gem::Version
|
|
116
|
+
version: '0'
|
|
117
|
+
type: :runtime
|
|
118
|
+
prerelease: false
|
|
119
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
120
|
+
requirements:
|
|
121
|
+
- - ">="
|
|
122
|
+
- !ruby/object:Gem::Version
|
|
123
|
+
version: '0'
|
|
96
124
|
- !ruby/object:Gem::Dependency
|
|
97
125
|
name: thor
|
|
98
126
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -132,20 +160,22 @@ files:
|
|
|
132
160
|
- lib/rubocop/cop/gusto/discouraged_gem.rb
|
|
133
161
|
- lib/rubocop/cop/gusto/execute_migration.rb
|
|
134
162
|
- lib/rubocop/cop/gusto/factory_classes_or_modules.rb
|
|
163
|
+
- lib/rubocop/cop/gusto/feature_flag_constants.rb
|
|
135
164
|
- lib/rubocop/cop/gusto/min_by_max_by.rb
|
|
136
165
|
- lib/rubocop/cop/gusto/no_metaprogramming.rb
|
|
137
166
|
- lib/rubocop/cop/gusto/no_rescue_error_message_checking.rb
|
|
138
167
|
- lib/rubocop/cop/gusto/no_send.rb
|
|
139
168
|
- lib/rubocop/cop/gusto/paperclip_or_attachable.rb
|
|
140
169
|
- lib/rubocop/cop/gusto/perform_class_method.rb
|
|
170
|
+
- lib/rubocop/cop/gusto/pluck_on_select.rb
|
|
141
171
|
- lib/rubocop/cop/gusto/polymorphic_type_validation.rb
|
|
142
172
|
- lib/rubocop/cop/gusto/prefer_process_last_status.rb
|
|
143
173
|
- lib/rubocop/cop/gusto/rabl_extends.rb
|
|
144
|
-
- lib/rubocop/cop/gusto/rails_env.rb
|
|
145
174
|
- lib/rubocop/cop/gusto/rake_constants.rb
|
|
146
175
|
- lib/rubocop/cop/gusto/regexp_bypass.rb
|
|
147
176
|
- lib/rubocop/cop/gusto/rspec_date_time_mock.rb
|
|
148
177
|
- lib/rubocop/cop/gusto/sidekiq_params.rb
|
|
178
|
+
- lib/rubocop/cop/gusto/smart_todo_team.rb
|
|
149
179
|
- lib/rubocop/cop/gusto/toplevel_constants.rb
|
|
150
180
|
- lib/rubocop/cop/gusto/unreferenced_let.rb
|
|
151
181
|
- lib/rubocop/cop/gusto/use_paint_not_colorize.rb
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module RuboCop
|
|
4
|
-
module Cop
|
|
5
|
-
module Gusto
|
|
6
|
-
# NOTE: Being pushed upstream here: https://github.com/rubocop/rubocop-rails/pull/1375
|
|
7
|
-
# Checks for usage of `Rails.env` which can be replaced with Feature Flags
|
|
8
|
-
#
|
|
9
|
-
# Although `local?` is a form of an environment-specific check, it is allowed because
|
|
10
|
-
# it cannot be used to control overall environment rollout, but it can be helpful to
|
|
11
|
-
# distinguish or protect code that is explicitly written to only ever execute in a
|
|
12
|
-
# dev or test environment. `local?` is also a form of a feature flag.
|
|
13
|
-
#
|
|
14
|
-
# @example
|
|
15
|
-
#
|
|
16
|
-
# # bad
|
|
17
|
-
# Rails.env.production? || Rails.env.demo?
|
|
18
|
-
#
|
|
19
|
-
# # good
|
|
20
|
-
# if FeatureFlag.enabled?(:new_feature)
|
|
21
|
-
# # new feature code
|
|
22
|
-
# end
|
|
23
|
-
#
|
|
24
|
-
# # good
|
|
25
|
-
# raise unless Rails.env.local?
|
|
26
|
-
#
|
|
27
|
-
# # good
|
|
28
|
-
# abort ("The Rails environment is running in production mode!") unless Rails.env.local?
|
|
29
|
-
#
|
|
30
|
-
class RailsEnv < Base
|
|
31
|
-
# This allow list is derived from:
|
|
32
|
-
# (Rails.env.methods - Object.instance_methods).select { |m| m.to_s.end_with?('?') }
|
|
33
|
-
# and then removing the environment specific methods like development?, test?, production?
|
|
34
|
-
ALLOWED_LIST = Set.new(
|
|
35
|
-
%i(
|
|
36
|
-
unicode_normalized?
|
|
37
|
-
exclude?
|
|
38
|
-
empty?
|
|
39
|
-
acts_like_string?
|
|
40
|
-
include?
|
|
41
|
-
is_utf8?
|
|
42
|
-
casecmp?
|
|
43
|
-
match?
|
|
44
|
-
starts_with?
|
|
45
|
-
ends_with?
|
|
46
|
-
start_with?
|
|
47
|
-
end_with?
|
|
48
|
-
valid_encoding?
|
|
49
|
-
ascii_only?
|
|
50
|
-
between?
|
|
51
|
-
local?
|
|
52
|
-
)
|
|
53
|
-
).freeze
|
|
54
|
-
MSG = "Use Feature Flags or config instead of `Rails.env`."
|
|
55
|
-
RESTRICT_ON_SEND = %i(env).freeze
|
|
56
|
-
|
|
57
|
-
# @!method prohibited_rails_env?(node)
|
|
58
|
-
def_node_matcher :prohibited_rails_env?, <<~PATTERN
|
|
59
|
-
(send
|
|
60
|
-
(send (const _ :Rails) :env)
|
|
61
|
-
#prohibited_predicate?
|
|
62
|
-
)
|
|
63
|
-
PATTERN
|
|
64
|
-
|
|
65
|
-
def on_send(node)
|
|
66
|
-
add_offense(node.parent) if prohibited_rails_env?(node.parent)
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
private
|
|
70
|
-
|
|
71
|
-
def prohibited_predicate?(name)
|
|
72
|
-
name.to_s.end_with?("?") && !ALLOWED_LIST.include?(name)
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
end
|
|
77
|
-
end
|