rubocop-graphql 0.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 +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +78 -0
- data/config/default.yml +72 -0
- data/lib/rubocop-graphql.rb +22 -0
- data/lib/rubocop/cop/graphql/argument_description.rb +36 -0
- data/lib/rubocop/cop/graphql/argument_name.rb +39 -0
- data/lib/rubocop/cop/graphql/cop.rb +92 -0
- data/lib/rubocop/cop/graphql/extract_input_type.rb +41 -0
- data/lib/rubocop/cop/graphql/extract_type.rb +98 -0
- data/lib/rubocop/cop/graphql/field_definitions.rb +159 -0
- data/lib/rubocop/cop/graphql/field_description.rb +36 -0
- data/lib/rubocop/cop/graphql/field_method.rb +79 -0
- data/lib/rubocop/cop/graphql/field_name.rb +39 -0
- data/lib/rubocop/cop/graphql/object_description.rb +67 -0
- data/lib/rubocop/cop/graphql/resolver_method_length.rb +40 -0
- data/lib/rubocop/cop/graphql_cops.rb +14 -0
- data/lib/rubocop/graphql.rb +12 -0
- data/lib/rubocop/graphql/argument.rb +39 -0
- data/lib/rubocop/graphql/argument/block.rb +31 -0
- data/lib/rubocop/graphql/argument/kwargs.rb +32 -0
- data/lib/rubocop/graphql/ext/snake_case.rb +17 -0
- data/lib/rubocop/graphql/field.rb +80 -0
- data/lib/rubocop/graphql/field/block.rb +31 -0
- data/lib/rubocop/graphql/field/kwargs.rb +64 -0
- data/lib/rubocop/graphql/inject.rb +18 -0
- data/lib/rubocop/graphql/node_pattern.rb +28 -0
- data/lib/rubocop/graphql/schema_member.rb +35 -0
- data/lib/rubocop/graphql/version.rb +5 -0
- metadata +130 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 328663a392bcbb8e7a53bfaf2ba8e7323e9382893c8f290fa6b40e965155ebe1
|
4
|
+
data.tar.gz: cb76dad975e6dab191f1fac2ae6c45b677fb06bddbb26f36494a18108e1acf56
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a87c4e9ee55fb176eaf98ba520a7942c7a4ee4af3531b7cc90a0039f739a5e5400ce4e21b0d694e59b00ca0bb2771585f07a50699c55496a8794eec1a38900f3
|
7
|
+
data.tar.gz: cedeb68f255f806a1e12de6776722f3aadce5f82fe7c0e4ace7979593d7f84abc8f27fee1cff5ced953076f88247e4aadf0599f30b02b5a35436d946f976a353
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2020 DmitryTsepelev
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
# RuboCop::GraphQL
|
2
|
+
|
3
|
+
[Rubocop](https://github.com/rubocop-hq/rubocop) extension for enforcing [graphql-ruby](https://github.com/rmosolgo/graphql-ruby) best practices.
|
4
|
+
|
5
|
+
<p align="center">
|
6
|
+
<a href="https://evilmartians.com/?utm_source=graphql-rubocop">
|
7
|
+
<img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg" alt="Sponsored by Evil Martians" width="236" height="54">
|
8
|
+
</a>
|
9
|
+
</p>
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
Install the gem:
|
14
|
+
|
15
|
+
```bash
|
16
|
+
gem install rubocop-graphql
|
17
|
+
```
|
18
|
+
|
19
|
+
If you use bundler put this in your Gemfile:
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
gem 'rubocop-graphql', require: false
|
23
|
+
```
|
24
|
+
|
25
|
+
## Usage
|
26
|
+
|
27
|
+
You need to tell RuboCop to load the GraphQL extension. There are three ways to do this:
|
28
|
+
|
29
|
+
### RuboCop configuration file
|
30
|
+
|
31
|
+
Put this into your `.rubocop.yml`.
|
32
|
+
|
33
|
+
```yaml
|
34
|
+
require: rubocop-graphql
|
35
|
+
```
|
36
|
+
|
37
|
+
Alternatively, use the following array notation when specifying multiple extensions.
|
38
|
+
|
39
|
+
```yaml
|
40
|
+
require:
|
41
|
+
- rubocop-other-extension
|
42
|
+
- rubocop-graphql
|
43
|
+
```
|
44
|
+
|
45
|
+
Now you can run `rubocop` and it will automatically load the RuboCop GraphQL cops together with the standard cops.
|
46
|
+
|
47
|
+
### Command line
|
48
|
+
|
49
|
+
```sh
|
50
|
+
rubocop --require rubocop-graphql
|
51
|
+
```
|
52
|
+
|
53
|
+
### Rake task
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
RuboCop::RakeTask.new do |task|
|
57
|
+
task.requires << 'rubocop-graphql'
|
58
|
+
end
|
59
|
+
```
|
60
|
+
|
61
|
+
## The Cops
|
62
|
+
|
63
|
+
All cops are located under [`lib/rubocop/cop/graphql`](lib/rubocop/cop/graphql), and contain examples and documentation.
|
64
|
+
|
65
|
+
In your `.rubocop.yml`, you may treat the GraphQL cops just like any other cop. For example:
|
66
|
+
|
67
|
+
```yaml
|
68
|
+
GraphQL/ResolverMethodLength:
|
69
|
+
Max: 3
|
70
|
+
```
|
71
|
+
|
72
|
+
## Contributing
|
73
|
+
|
74
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/DmitryTsepelev/rubocop-graphql.
|
75
|
+
|
76
|
+
## License
|
77
|
+
|
78
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/config/default.yml
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
AllCops:
|
2
|
+
GraphQL:
|
3
|
+
Patterns:
|
4
|
+
- "(?:^|/)graphql/"
|
5
|
+
|
6
|
+
GraphQL/ArgumentDescription:
|
7
|
+
Enabled: true
|
8
|
+
VersionAdded: '0.80'
|
9
|
+
Description: 'Ensures all arguments have a description'
|
10
|
+
|
11
|
+
GraphQL/ArgumentName:
|
12
|
+
Enabled: true
|
13
|
+
VersionAdded: '0.80'
|
14
|
+
Description: 'This cop checks whether argument names are snake_case'
|
15
|
+
|
16
|
+
GraphQL/ResolverMethodLength:
|
17
|
+
Enabled: true
|
18
|
+
VersionAdded: '0.80'
|
19
|
+
Description: 'Checks resolver methods are not too long'
|
20
|
+
Max: 10
|
21
|
+
CountComments: false
|
22
|
+
ExcludedMethods: []
|
23
|
+
|
24
|
+
GraphQL/FieldDefinitions:
|
25
|
+
Enabled: true
|
26
|
+
VersionAdded: '0.80'
|
27
|
+
Description: 'Checks consistency of field definitions'
|
28
|
+
EnforcedStyle: group_definitions
|
29
|
+
SupportedStyles:
|
30
|
+
- group_definitions
|
31
|
+
- define_resolver_after_definition
|
32
|
+
|
33
|
+
GraphQL/FieldDescription:
|
34
|
+
Enabled: true
|
35
|
+
VersionAdded: '0.80'
|
36
|
+
Description: 'Ensures all fields have a description'
|
37
|
+
|
38
|
+
GraphQL/FieldMethod:
|
39
|
+
Enabled: true
|
40
|
+
VersionAdded: '0.80'
|
41
|
+
Description: 'Checks :method option is used for appropriate fields'
|
42
|
+
|
43
|
+
GraphQL/FieldName:
|
44
|
+
Enabled: true
|
45
|
+
VersionAdded: '0.80'
|
46
|
+
Description: 'This cop checks whether field names are snake_case'
|
47
|
+
|
48
|
+
GraphQL/ExtractInputType:
|
49
|
+
Enabled: true
|
50
|
+
VersionAdded: '0.80'
|
51
|
+
Description: 'Suggests using input type instead of many arguments'
|
52
|
+
MaxArguments: 2
|
53
|
+
|
54
|
+
GraphQL/ExtractType:
|
55
|
+
Enabled: true
|
56
|
+
VersionAdded: '0.80'
|
57
|
+
Description: 'Suggests extracting fields with common prefixes to the separate type'
|
58
|
+
MaxFields: 2
|
59
|
+
Prefixes:
|
60
|
+
- is
|
61
|
+
- with
|
62
|
+
- avg
|
63
|
+
- min
|
64
|
+
- max
|
65
|
+
|
66
|
+
GraphQL/ObjectDescription:
|
67
|
+
Enabled: true
|
68
|
+
VersionAdded: '0.80'
|
69
|
+
Description: 'Ensures all types have a description'
|
70
|
+
Exclude:
|
71
|
+
- '**/*_schema.rb'
|
72
|
+
- '**/base_*.rb'
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rubocop"
|
4
|
+
|
5
|
+
require_relative "rubocop/graphql/ext/snake_case"
|
6
|
+
|
7
|
+
require_relative "rubocop/graphql"
|
8
|
+
require_relative "rubocop/graphql/version"
|
9
|
+
require_relative "rubocop/graphql/inject"
|
10
|
+
require_relative "rubocop/graphql/node_pattern"
|
11
|
+
|
12
|
+
require_relative "rubocop/graphql/argument"
|
13
|
+
require_relative "rubocop/graphql/argument/block"
|
14
|
+
require_relative "rubocop/graphql/argument/kwargs"
|
15
|
+
require_relative "rubocop/graphql/field"
|
16
|
+
require_relative "rubocop/graphql/field/block"
|
17
|
+
require_relative "rubocop/graphql/field/kwargs"
|
18
|
+
require_relative "rubocop/graphql/schema_member"
|
19
|
+
|
20
|
+
RuboCop::GraphQL::Inject.defaults!
|
21
|
+
|
22
|
+
require_relative "rubocop/cop/graphql_cops"
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module GraphQL
|
6
|
+
# This cop checks if each field has a description.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# # good
|
10
|
+
#
|
11
|
+
# class BanUser < BaseMutation
|
12
|
+
# argument :uuid, ID, required: true, description: "UUID of the user to ban"
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# # bad
|
16
|
+
#
|
17
|
+
# class BanUser < BaseMutation
|
18
|
+
# argument :uuid, ID, required: true
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
class ArgumentDescription < Cop
|
22
|
+
include RuboCop::GraphQL::NodePattern
|
23
|
+
|
24
|
+
MSG = "Missing argument description"
|
25
|
+
|
26
|
+
def on_send(node)
|
27
|
+
return unless argument?(node)
|
28
|
+
|
29
|
+
argument = RuboCop::GraphQL::Argument.new(node)
|
30
|
+
|
31
|
+
add_offense(node) unless argument.description
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module GraphQL
|
6
|
+
# This cop checks whether field names are snake_case.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# # good
|
10
|
+
#
|
11
|
+
# class BanUser < BaseMutation
|
12
|
+
# argument :user_id, ID, required: true
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# # bad
|
16
|
+
#
|
17
|
+
# class BanUser < BaseMutation
|
18
|
+
# argument :userId, ID, required: true
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
class ArgumentName < Cop
|
22
|
+
include RuboCop::GraphQL::NodePattern
|
23
|
+
|
24
|
+
using RuboCop::GraphQL::Ext::SnakeCase
|
25
|
+
|
26
|
+
MSG = "Use snake_case for argument names"
|
27
|
+
|
28
|
+
def on_send(node)
|
29
|
+
return unless argument?(node)
|
30
|
+
|
31
|
+
argument = RuboCop::GraphQL::Argument.new(node)
|
32
|
+
return if argument.name.snake_case?
|
33
|
+
|
34
|
+
add_offense(node)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
# Inspied by https://github.com/rubocop-hq/rubocop-rspec/blob/3a2088f79737e2e8e0e21482783f7d61411bf021/lib/rubocop/cop/rspec/cop.rb
|
5
|
+
module Cop
|
6
|
+
WorkaroundGraphqlCop = Cop.dup
|
7
|
+
|
8
|
+
# Clone of the the normal RuboCop::Cop::Cop class so we can rewrite
|
9
|
+
# the inherited method without breaking functionality
|
10
|
+
class WorkaroundGraphqlCop
|
11
|
+
# Remove the Cop.inherited method to be a noop. Our RSpec::Cop
|
12
|
+
# class will invoke the inherited hook instead
|
13
|
+
class << self
|
14
|
+
undef inherited
|
15
|
+
def inherited(*)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Special case `Module#<` so that the rspec support rubocop exports
|
20
|
+
# is compatible with our subclass
|
21
|
+
def self.<(other)
|
22
|
+
other.equal?(RuboCop::Cop::Cop) || super
|
23
|
+
end
|
24
|
+
end
|
25
|
+
private_constant(:WorkaroundGraphqlCop)
|
26
|
+
|
27
|
+
module GraphQL
|
28
|
+
# @abstract parent class to graphql-ruby cops
|
29
|
+
#
|
30
|
+
# The criteria for whether rubocop-rspec analyzes a certain ruby file
|
31
|
+
# is configured via `AllCops/GraphQL`. For example, if you want to
|
32
|
+
# customize your project to scan all files within a `graph/` directory
|
33
|
+
# then you could add this to your configuration:
|
34
|
+
#
|
35
|
+
# @example configuring analyzed paths
|
36
|
+
#
|
37
|
+
# AllCops:
|
38
|
+
# GraphQL:
|
39
|
+
# Patterns:
|
40
|
+
# - '(?:^|/)graph/'
|
41
|
+
class Cop < WorkaroundGraphqlCop
|
42
|
+
DEFAULT_CONFIGURATION =
|
43
|
+
RuboCop::GraphQL::CONFIG.fetch("AllCops").fetch("GraphQL")
|
44
|
+
|
45
|
+
DEFAULT_PATTERN_RE = Regexp.union(
|
46
|
+
DEFAULT_CONFIGURATION.fetch("Patterns")
|
47
|
+
.map(&Regexp.public_method(:new))
|
48
|
+
)
|
49
|
+
|
50
|
+
# Invoke the original inherited hook so our cops are recognized
|
51
|
+
def self.inherited(subclass)
|
52
|
+
RuboCop::Cop::Cop.inherited(subclass)
|
53
|
+
end
|
54
|
+
|
55
|
+
def relevant_file?(file)
|
56
|
+
relevant_rubocop_graphql_file?(file) && super
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def relevant_rubocop_graphql_file?(file)
|
62
|
+
graphql_pattern =~ file
|
63
|
+
end
|
64
|
+
|
65
|
+
def graphql_pattern
|
66
|
+
if rspec_graphql_config?
|
67
|
+
Regexp.union(rspec_graphql_config.map(&Regexp.public_method(:new)))
|
68
|
+
else
|
69
|
+
DEFAULT_PATTERN_RE
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def all_cops_config
|
74
|
+
config
|
75
|
+
.for_all_cops
|
76
|
+
end
|
77
|
+
|
78
|
+
def rspec_graphql_config?
|
79
|
+
return unless all_cops_config.key?("GraphQL")
|
80
|
+
|
81
|
+
all_cops_config.fetch("GraphQL").key?("Patterns")
|
82
|
+
end
|
83
|
+
|
84
|
+
def rspec_graphql_config
|
85
|
+
all_cops_config
|
86
|
+
.fetch("GraphQL", DEFAULT_CONFIGURATION)
|
87
|
+
.fetch("Patterns")
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module GraphQL
|
6
|
+
class ExtractInputType < Cop
|
7
|
+
# This cop checks fields on common prefix groups
|
8
|
+
#
|
9
|
+
# # @example
|
10
|
+
# # good
|
11
|
+
#
|
12
|
+
# class UpdateUser < BaseMutation
|
13
|
+
# argument :uuid, ID, required: true
|
14
|
+
# argument :user_attributes, UserAttributesInputType
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# # bad
|
18
|
+
#
|
19
|
+
# class UpdateUser < BaseMutation
|
20
|
+
# argument :uuid, ID, required: true
|
21
|
+
# argument :first_name, String, required: true
|
22
|
+
# argument :last_name, String, required: true
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
include RuboCop::GraphQL::NodePattern
|
26
|
+
|
27
|
+
MSG = "Consider moving arguments to a new input type"
|
28
|
+
|
29
|
+
def on_class(node)
|
30
|
+
schema_member = RuboCop::GraphQL::SchemaMember.new(node)
|
31
|
+
|
32
|
+
if (body = schema_member.body)
|
33
|
+
arguments = body.select { |node| argument?(node) }
|
34
|
+
|
35
|
+
add_offense(arguments.last) if arguments.count > cop_config["MaxArguments"]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module GraphQL
|
6
|
+
class ExtractType < Cop
|
7
|
+
# This cop checks fields on common prefix groups
|
8
|
+
#
|
9
|
+
# # @example
|
10
|
+
# # good
|
11
|
+
#
|
12
|
+
# class Types::UserType < Types::BaseObject
|
13
|
+
# field :registered_at, String, null: false
|
14
|
+
# field :contact, Types::ContactType, null: false
|
15
|
+
#
|
16
|
+
# def contact
|
17
|
+
# self
|
18
|
+
# end
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# class Types::ContactType < Types::BaseObject
|
22
|
+
# field :phone, String, null: false
|
23
|
+
# field :first_name, String, null: false
|
24
|
+
# field :last_name, String, null: false
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# # bad
|
28
|
+
#
|
29
|
+
# class Types::UserType < Types::BaseObject
|
30
|
+
# field :registered_at, String, null: false
|
31
|
+
# field :contact_phone, String, null: false
|
32
|
+
# field :contact_first_name, String, null: false
|
33
|
+
# field :contact_last_name, String, null: false
|
34
|
+
# end
|
35
|
+
#
|
36
|
+
include RuboCop::GraphQL::NodePattern
|
37
|
+
|
38
|
+
def on_class(node)
|
39
|
+
schema_member = RuboCop::GraphQL::SchemaMember.new(node)
|
40
|
+
|
41
|
+
if (body = schema_member.body)
|
42
|
+
check_fields_prefixes(body)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
MSG = "Consider moving %<field_names>s to a new type and adding the `%<prefix>s` field instead"
|
49
|
+
|
50
|
+
def check_fields_prefixes(body)
|
51
|
+
sorted_prefixes = fractured(body).sort_by { |k, _| k.size }.reverse
|
52
|
+
already_offenced_fields = []
|
53
|
+
|
54
|
+
sorted_prefixes.each do |prefix, fields|
|
55
|
+
fields -= already_offenced_fields
|
56
|
+
|
57
|
+
next if fields.count < cop_config["MaxFields"]
|
58
|
+
|
59
|
+
add_offense(
|
60
|
+
fields.last.node,
|
61
|
+
message: message(prefix, fields.map(&:name).join(", "))
|
62
|
+
)
|
63
|
+
|
64
|
+
already_offenced_fields += fields
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def fractured(body)
|
69
|
+
body.each_with_object({}) do |node, acc|
|
70
|
+
next unless field?(node)
|
71
|
+
|
72
|
+
field = RuboCop::GraphQL::Field.new(node)
|
73
|
+
next unless field.underscore_name.include?("_")
|
74
|
+
|
75
|
+
*prefixes, _ = field.underscore_name.split("_")
|
76
|
+
|
77
|
+
prefixes.each_with_object([]) do |prefix, prev_prefix|
|
78
|
+
prefix = (prev_prefix + [prefix]).join("_")
|
79
|
+
break if ignored_prefix?(prefix)
|
80
|
+
|
81
|
+
(acc[prefix] ||= []) << field
|
82
|
+
|
83
|
+
prev_prefix << prefix
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def message(prefix, field_names)
|
89
|
+
format(MSG, field_names: field_names, prefix: prefix)
|
90
|
+
end
|
91
|
+
|
92
|
+
def ignored_prefix?(word)
|
93
|
+
cop_config["Prefixes"].include?(word)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|