rubocop-brands_insurance 0.0.2.pre.rc.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: b78dfa9d49167cd428caa869e3233539739bf0609ca423c95206d437d0a30491
4
+ data.tar.gz: edd592a746d2ea5396a5585ce01dd504698fba5767f55ae5f238ce0ae9541468
5
+ SHA512:
6
+ metadata.gz: 9576f39c77c22ac92247b9f3fe45e8a48298570c6c125bee83cc45aa0d4367ccd37410ddd5b975202a69ef664d75d4bd1252f42d26266b4874d1db7d20cb32cc
7
+ data.tar.gz: fd679b7562290fc20b46c61d7d4cd29d0d7bd0ae7b818e25398aa35c019cca50d55c658a99ad88085ef9808b3c589bbcb9fc393577b9af8b33286d0a7bd19699
data/README.adoc ADDED
@@ -0,0 +1,50 @@
1
+ = Rubocop::BrandsInsurance
2
+
3
+ Gem for custom rubocop rules for BrandsInsurance
4
+
5
+ Welcome to your new gem!
6
+ In this directory, you'll find the files you need to be able to package up your Ruby library into a gem.
7
+ Put your Ruby code in the file ``lib/rubocop/brands_insurance``.
8
+ To experiment with that code, run
9
+ ``bin/console`` for an interactive prompt.
10
+
11
+ TODO: Delete this and the text above, and describe your gem
12
+
13
+ == Installation
14
+
15
+ Add this line to your application's Gemfile:
16
+
17
+ [source,ruby]
18
+ ----
19
+ gem 'rubocop-brands_insurance', require: false
20
+ ----
21
+
22
+ And then execute:
23
+
24
+ $ bundle install
25
+
26
+ Or install it yourself as:
27
+
28
+ $ gem install rubocop-brands_insurance
29
+
30
+ == Usage
31
+
32
+ Add ``BrandsInsurance/*`` cops to your ``.rubocop.yml`` config file
33
+
34
+ [source,yaml]
35
+ ----
36
+ BrandsInsurance/Style/DisallowedMethods:
37
+ Enabled: true
38
+ ----
39
+
40
+ == Departments
41
+
42
+ * xref:./docs/cops/style/README.adoc[``Style``]
43
+
44
+ == Contributing
45
+
46
+ See xref:./CONTRIBUTING.adoc[CONTRIBUTING] for how to add your own rule
47
+
48
+ == Changelog
49
+
50
+ See xref:./CHANGELOG.adoc[CHANGELOG] see see changes
@@ -0,0 +1,4 @@
1
+ BrandsInsurance/Style/DisallowedMethods:
2
+ Description: 'Disallows the usage of `#abort` and `#tap` methods'
3
+ Enabled: pending
4
+ VersionAdded: '<<next>>'
@@ -0,0 +1,7 @@
1
+ = Style
2
+
3
+ Style cops check for stylistic consistency of your code
4
+
5
+ == Cops
6
+
7
+ * xref:./disallowed_methods/README.adoc[``Style/DisallowedMethods``]
@@ -0,0 +1,28 @@
1
+ = ``Style/DisallowedMethods``
2
+
3
+ == Description
4
+
5
+ Certain methods should not be used
6
+
7
+ == Examples
8
+
9
+ [source,ruby]
10
+ ----
11
+ # Bad (Don't use `tap`)
12
+ tap do
13
+ end
14
+
15
+ # Bad (Don't use `abort`)
16
+ abort
17
+
18
+ # Good (Use `raise` instead of `abort`)
19
+ raise
20
+ ----
21
+
22
+ == Configurable Attributes
23
+
24
+ There are no configurable attributes
25
+
26
+ == References
27
+
28
+ https://github.com/BrandsInsurance/expert-chainsaw/issues/434
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ # The original code is from https://github.com/rubocop/rubocop-rspec/blob/master/lib/rubocop/rspec/inject.rb
4
+ # See https://github.com/rubocop/rubocop-rspec/blob/master/MIT-LICENSE.md
5
+ module RuboCop
6
+ module BrandsInsurance
7
+ # Because RuboCop doesn't yet support plugins, we have to monkey patch in a
8
+ # bit of our configuration.
9
+ module Inject
10
+ def self.defaults!
11
+ path = CONFIG_DEFAULT.to_s
12
+ hash = ConfigLoader.__send__(:load_yaml_configuration, path)
13
+ config = Config.new(hash, path).tap(&:make_excludes_absolute)
14
+ puts("configuration from #{path}") if ConfigLoader.debug?
15
+ config = ConfigLoader.merge_with_default(config, path)
16
+ ConfigLoader.instance_variable_set(:@default_configuration, config)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module BrandsInsurance
5
+ VERSION = '0.0.2-rc.1'
6
+ end
7
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'brands_insurance/version'
4
+ require 'yaml'
5
+
6
+ module RuboCop
7
+ module BrandsInsurance
8
+ class Error < StandardError; end
9
+ # Your code goes here...
10
+ PROJECT_ROOT = Pathname.new(__dir__).parent.parent.expand_path.freeze
11
+ CONFIG_DEFAULT = PROJECT_ROOT.join('config', 'default.yml').freeze
12
+ CONFIG = ::YAML.safe_load(CONFIG_DEFAULT.read).freeze
13
+
14
+ private_constant(:CONFIG_DEFAULT, :PROJECT_ROOT)
15
+ end
16
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module BrandsInsurance
6
+ class Generator
7
+ class CopReadmeInjector < DeptReadmeInjector
8
+ TEMPLATE =
9
+ '* xref:./%<cop_folder>s/README.adoc[``%<department>s/%<cop>s``]'
10
+
11
+ # :nodoc:
12
+ def initialize(badge:, **kwargs)
13
+ super(badge: badge, **kwargs)
14
+
15
+ @cop = badge.cop_name
16
+ end
17
+
18
+ private
19
+
20
+ attr_reader :cop
21
+
22
+ def new_readme_entry
23
+ format(TEMPLATE, {
24
+ department_folder: snake_case(department),
25
+ cop_folder: snake_case(cop),
26
+ department: department,
27
+ cop: cop
28
+ })
29
+ end
30
+
31
+ def line_is_good?(line)
32
+ return true if super
33
+
34
+ matches = line.match(target_regex)
35
+ return false if matches.nil?
36
+
37
+ department == matches[:department] && cop < matches[:cop]
38
+ end
39
+
40
+ def target_regex
41
+ %r{\* xref:\./docs/cops/[a-z_]+/[a-z_]+/README\.adoc\[``(?<department>[a-zA-Z_]+)/(?<cop>[a-zA-Z_]+)``\]}
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module BrandsInsurance
6
+ class Generator
7
+ class DeptReadmeInjector
8
+ TEMPLATE = '* xref:./docs/cops/%<department_folder>s/README.adoc[``%<department>s``]'
9
+
10
+ # :nodoc:
11
+ def initialize(readme_file_path:, badge:, department:)
12
+ @readme_file_path = readme_file_path
13
+ @badge = badge
14
+ @department = department
15
+ @output = output
16
+ end
17
+
18
+ # :nodoc:
19
+ def inject
20
+ target_line = find_target_line
21
+ if target_line
22
+ readme_entries.insert(target_line, "#{new_readme_entry}\n")
23
+ else
24
+ readme_entries.push("#{new_readme_entry}")
25
+ end
26
+
27
+ File.write(readme_file_path, readme_entries.join(''))
28
+
29
+ yield if block_given?
30
+ end
31
+
32
+ private
33
+
34
+ attr_reader :readme_file_path, :badge, :department, :output
35
+
36
+ def readme_entries
37
+ @readme_entries ||= File.readlines(readme_file_path)
38
+ end
39
+
40
+ def new_readme_entry
41
+ format(TEMPLATE, {
42
+ department_folder: snake_case(department),
43
+ department: department
44
+ })
45
+ end
46
+
47
+ def find_target_line
48
+ readme_entries.find.with_index do |line, index|
49
+ return index if line_is_good?(line)
50
+ end
51
+
52
+ return nil
53
+ end
54
+
55
+ def line_is_good?(line)
56
+ matches = line.match(target_regex)
57
+ return false if matches.nil?
58
+
59
+ department < line.match(target_regex)[:department]
60
+ end
61
+
62
+ def target_regex
63
+ %r{\* xref:\./docs/cops/[a-z_]+/README\.adoc\[``(?<department>[a-zA-Z_]+)``\]}
64
+ end
65
+
66
+ def snake_case(camel_case_string)
67
+ camel_case_string
68
+ .gsub('RSpec', 'Rspec')
69
+ .gsub(%r{([^A-Z/])([A-Z]+)}, '\1_\2')
70
+ .gsub(%r{([A-Z])([A-Z][^A-Z\d/]+)}, '\1_\2')
71
+ .downcase
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,239 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './generator/dept_readme_injector'
4
+ require_relative './generator/cop_readme_injector'
5
+
6
+ module RuboCop
7
+ module Cop
8
+ module BrandsInsurance
9
+ class Generator
10
+ COP_DOC = <<~RUBY
11
+ # TODO: Write cop description and example of bad / good code. For every
12
+ # `SupportedStyle` and unique configuration, there needs to be examples.
13
+ # Examples must have valid Ruby syntax. Do not use upticks.
14
+ #
15
+ # @safety
16
+ # Delete this section if the cop is not unsafe (`Safe: false` or
17
+ # `SafeAutoCorrect: false`), or use it to explain how the cop is
18
+ # unsafe.
19
+ #
20
+ # @example EnforcedStyle: bar (default)
21
+ # # Description of the `bar` style.
22
+ #
23
+ # # bad
24
+ # bad_bar_method
25
+ #
26
+ # # bad
27
+ # bad_bar_method(args)
28
+ #
29
+ # # good
30
+ # good_bar_method
31
+ #
32
+ # # good
33
+ # good_bar_method(args)
34
+ #
35
+ # @example EnforcedStyle: foo
36
+ # # Description of the `foo` style.
37
+ #
38
+ # # bad
39
+ # bad_foo_method
40
+ #
41
+ # # bad
42
+ # bad_foo_method(args)
43
+ #
44
+ # # good
45
+ # good_foo_method
46
+ #
47
+ # # good
48
+ # good_foo_method(args)
49
+ #
50
+ RUBY
51
+ SOURCE_TEMPLATE = <<~RUBY
52
+ # frozen_string_literal: true
53
+
54
+ module RuboCop
55
+ module Cop
56
+ module %<department>s
57
+ class %<cop_name>s < Base
58
+ # TODO: Implement the cop in here.
59
+ #
60
+ # In many cases, you can use a node matcher for matching node pattern.
61
+ # See https://github.com/rubocop/rubocop-ast/blob/master/lib/rubocop/ast/node_pattern.rb
62
+ #
63
+ # For example
64
+ MSG = 'Use `#good_method` instead of `#bad_method`.'
65
+
66
+ # TODO: Don't call `on_send` unless the method name is in this list
67
+ # If you don't need `on_send` in the cop you created, remove it.
68
+ RESTRICT_ON_SEND = %%i[bad_method].freeze
69
+
70
+ # @!method bad_method?(node)
71
+ def_node_matcher :bad_method?, <<~PATTERN
72
+ (send nil? :bad_method ...)
73
+ PATTERN
74
+
75
+ def on_send(node)
76
+ return unless bad_method?(node)
77
+
78
+ add_offense(node)
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+ RUBY
85
+ README_ADDED_MESSAGE =
86
+ '[modify] A link for the %<dept_vs_cop>s has been added into ' \
87
+ '%<readme_file_path>s.'
88
+
89
+ DEPT_README_TEMPLATE = <<~ADOC
90
+ = %<department>s
91
+
92
+ Describe the department here
93
+
94
+ == Cops
95
+
96
+ ADOC
97
+ COP_README_TEMPLATE = <<~ADOC
98
+ = ``%<department>s/%<cop_name>s``
99
+
100
+ == Description
101
+
102
+ Add a description here
103
+
104
+ == Examples
105
+
106
+ [source,ruby]
107
+ ----
108
+ # Bad
109
+ # Add a bad example here
110
+
111
+ # Good
112
+ # Add a good example here
113
+ ----
114
+
115
+ == Configurable Attributes
116
+
117
+ |===
118
+ |Name |Default value |Configurable values
119
+
120
+ |Max
121
+ |120
122
+ |Integer
123
+
124
+ |===
125
+
126
+ == References
127
+
128
+ https://github.com/BrandsInsurance/expert-chainsaw/issues
129
+ ADOC
130
+
131
+ def initialize(name, output: $stdout)
132
+ name = ['BrandsInsurance', name].join('/') unless name.start_with?('BrandsInsurance/')
133
+
134
+ unless name.count('/') == 2
135
+ raise(
136
+ [
137
+ 'You must provide a single department under BrandsInsurance i.e. BrandsInsurance/Department/CopName',
138
+ 'or Department/CopName'
139
+ ].join(' ')
140
+ )
141
+ end
142
+
143
+ @base_gen = RuboCop::Cop::Generator.new(name, output: output)
144
+ end
145
+
146
+ # Calls methods in the base class
147
+ #
148
+ # @return [*]
149
+ #
150
+ def method_missing(...)
151
+ @base_gen.__send__(...)
152
+ end
153
+
154
+ # `self` responds to `method_name` if `@base_gen` does
155
+ #
156
+ def respond_to_missing?(method_name, include_private = false)
157
+ @base_gen.respond_to?(method_name, include_private)
158
+ end
159
+
160
+ def write_dept_readme
161
+ return if File.exists?(dept_docs_path)
162
+
163
+ write_unless_file_exists(dept_docs_path, generated_dept_docs)
164
+ end
165
+
166
+ def write_cop_readme
167
+ write_unless_file_exists(docs_path, generated_cop_docs)
168
+ end
169
+
170
+ def inject_dept_readme(readme_file_path: 'README.adoc')
171
+ # Add this dept to base readme if not already there
172
+ injector = DeptReadmeInjector.new(
173
+ readme_file_path: readme_file_path,
174
+ badge: badge,
175
+ department: department
176
+ )
177
+
178
+ injector.inject do
179
+ output.puts(format(README_ADDED_MESSAGE, readme_file_path: readme_file_path, dept_vs_cop: 'department'))
180
+ end
181
+ end
182
+
183
+ def inject_cop_readme(readme_file_path: dept_docs_path)
184
+ # Add this cop to the dept readme
185
+ injector = CopReadmeInjector.new(
186
+ readme_file_path: readme_file_path,
187
+ badge: badge,
188
+ department: department
189
+ )
190
+
191
+ injector.inject do
192
+ output.puts(format(README_ADDED_MESSAGE, readme_file_path: readme_file_path, dept_vs_cop: 'cop'))
193
+ end
194
+ end
195
+
196
+ private
197
+
198
+ def department
199
+ badge.department_name.gsub('BrandsInsurance/', '')
200
+ end
201
+
202
+ def generated_dept_docs
203
+ generate_readme(DEPT_README_TEMPLATE)
204
+ end
205
+
206
+ def generated_cop_docs
207
+ generate_readme(COP_README_TEMPLATE)
208
+ end
209
+
210
+ def generate_readme(template)
211
+ format(template, {
212
+ department: department,
213
+ cop_name: badge.cop_name,
214
+ cop_folder: snake_case(badge.cop_name.to_s)
215
+ })
216
+ end
217
+
218
+ def dept_docs_path
219
+ File.join(
220
+ 'docs',
221
+ 'cops',
222
+ snake_case(department),
223
+ 'README.adoc'
224
+ )
225
+ end
226
+
227
+ def docs_path
228
+ File.join(
229
+ 'docs',
230
+ 'cops',
231
+ snake_case(department),
232
+ "#{snake_case(badge.cop_name.to_s)}",
233
+ 'README.adoc'
234
+ )
235
+ end
236
+ end
237
+ end
238
+ end
239
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module BrandsInsurance
6
+ module Style
7
+ # @example EnforcedStyle: foo
8
+ # # Description of the `foo` style.
9
+ #
10
+ # # bad
11
+ # abort
12
+ #
13
+ # # bad
14
+ # abort(args)
15
+ #
16
+ # # bad
17
+ # tap {}
18
+ #
19
+ # # bad
20
+ # tap do
21
+ # end
22
+ #
23
+ # # good
24
+ # raise
25
+ #
26
+ # # good
27
+ # raise(args)
28
+ #
29
+ class DisallowedMethods < RuboCop::Cop::Base
30
+ # In many cases, you can use a node matcher for matching node pattern.
31
+ # See https://github.com/rubocop/rubocop-ast/blob/master/lib/rubocop/ast/node_pattern.rb
32
+ #
33
+ # For example
34
+ MESSAGES = {
35
+ abort: 'Use `#raise` instead of `#abort`.',
36
+ tap: 'Do not use `#tap`'
37
+ }
38
+
39
+ # `on_send` will only be called if the method name is in this list
40
+ RESTRICT_ON_SEND = %i[abort tap].freeze
41
+
42
+ # @!method using_abort?(node)
43
+ def_node_matcher :using_abort?, <<~PATTERN
44
+ (send nil? :abort ...)
45
+ PATTERN
46
+
47
+ # @!method using_tap?(node)
48
+ def_node_matcher :using_tap?, <<~PATTERN
49
+ (send nil? :tap ...)
50
+ PATTERN
51
+
52
+ # :nodoc:
53
+ def on_send(node)
54
+ message =
55
+ if using_abort?(node)
56
+ :abort
57
+ elsif using_tap?(node)
58
+ :tap
59
+ end
60
+
61
+ return if message.nil?
62
+
63
+ add_offense(node, message: MESSAGES.fetch(message))
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'brands_insurance/style/disallowed_methods'
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rubocop'
4
+
5
+ require_relative 'rubocop/brands_insurance'
6
+ require_relative 'rubocop/cop/brands_insurance/generator'
7
+ require_relative 'rubocop/brands_insurance/inject'
8
+ require_relative 'rubocop/brands_insurance/version'
9
+
10
+ RuboCop::BrandsInsurance::Inject.defaults!
11
+
12
+ require_relative 'rubocop/cop/brands_insurance_cops'
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rubocop-brands_insurance
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2.pre.rc.1
5
+ platform: ruby
6
+ authors:
7
+ - Brands Insurance
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2023-03-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rubocop
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.43'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.43'
27
+ description:
28
+ email:
29
+ - documents@brandsinsurance.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - README.adoc
35
+ - config/default.yml
36
+ - docs/cops/style/README.adoc
37
+ - docs/cops/style/disallowed_methods/README.adoc
38
+ - lib/rubocop-brands_insurance.rb
39
+ - lib/rubocop/brands_insurance.rb
40
+ - lib/rubocop/brands_insurance/inject.rb
41
+ - lib/rubocop/brands_insurance/version.rb
42
+ - lib/rubocop/cop/brands_insurance/generator.rb
43
+ - lib/rubocop/cop/brands_insurance/generator/cop_readme_injector.rb
44
+ - lib/rubocop/cop/brands_insurance/generator/dept_readme_injector.rb
45
+ - lib/rubocop/cop/brands_insurance/style/disallowed_methods.rb
46
+ - lib/rubocop/cop/brands_insurance_cops.rb
47
+ homepage: https://github.com/BrandsInsurance/expert-chainsaw/
48
+ licenses: []
49
+ metadata:
50
+ homepage_uri: https://github.com/BrandsInsurance/expert-chainsaw/
51
+ source_code_uri: https://github.com/BrandsInsurance/expert-chainsaw/plugins/rubocop/brandsinsurance
52
+ changelog_uri: https://github.com/BrandsInsurance/expert-chainsaw/plugins/rubocop/brandsinsurance/CHANGELOG.adoc
53
+ post_install_message:
54
+ rdoc_options: []
55
+ require_paths:
56
+ - lib
57
+ required_ruby_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: 3.0.1
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">"
65
+ - !ruby/object:Gem::Version
66
+ version: 1.3.1
67
+ requirements: []
68
+ rubygems_version: 3.2.15
69
+ signing_key:
70
+ specification_version: 4
71
+ summary: Custom cops for BrandsInsurance
72
+ test_files: []