rubocop-petal 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/build.yml +5 -3
- data/.gitignore +1 -0
- data/.rubocop.yml +1 -1
- data/CHANGELOG.md +15 -0
- data/Gemfile.lock +5 -5
- data/README.md +9 -2
- data/config/default.yml +31 -0
- data/lib/rubocop/cop/grape/helpers_include_module.rb +61 -0
- data/lib/rubocop/cop/grape/unnecessary_namespace.rb +64 -0
- data/lib/rubocop/cop/migration/use_change_table_bulk.rb +30 -0
- data/lib/rubocop/cop/rspec/authenticated_as.rb +32 -0
- data/lib/rubocop/cop/rspec/create_list_max.rb +42 -0
- data/lib/rubocop/petal/version.rb +1 -1
- data/rubocop-petal.gemspec +2 -2
- metadata +20 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 55cc186c715bd9f5f1b239fbedcf1ff306f82fe4c9aa4be1a3a00dbedf593ce2
|
4
|
+
data.tar.gz: 18690d528f7fc3c9caf8534a4278e6674d6979b0c982981514efa139d5fe47ff
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5ed1e80327d5bbce723c817ed98847e548a7f05b8f770d9023bfe1f81492177bee7d6710851bd1f15c79fc7c536e9517014284923634cf6e0910e4451436a265
|
7
|
+
data.tar.gz: bb64a217f444e47098cddea795e43a12751d0687901a87fbf5e8bc8f627aac999cfbf6885c28ba8a240fdeb2022b0b6bd45ab263108a23e1ba076b5c95486e1e
|
data/.github/workflows/build.yml
CHANGED
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
# main
|
4
|
+
|
5
|
+
# v0.2.0
|
6
|
+
|
7
|
+
* Added cop `RSpec/AuthenticatedAs` ([#3](https://github.com/petalmd/rubocop-petal/pull/3))
|
8
|
+
* Added cop `Grape/UnnecessaryNamespace` ([#2](https://github.com/petalmd/rubocop-petal/pull/2))
|
9
|
+
* Added cop `RSpec/CreateListMax` ([#4](https://github.com/petalmd/rubocop-petal/pull/4))
|
10
|
+
* Added Cop `Migration/UseChangeTableBulk` ([#7](https://github.com/petalmd/rubocop-petal/pull/7))
|
11
|
+
* Added cop `Grape/HelpersIncludeModule` ([#1](https://github.com/petalmd/rubocop-petal/pull/1))
|
12
|
+
|
13
|
+
# v0.1.0
|
14
|
+
|
15
|
+
* First version
|
data/Gemfile.lock
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
rubocop-petal (0.
|
5
|
-
rubocop
|
6
|
-
rubocop-rails
|
4
|
+
rubocop-petal (0.2.0)
|
5
|
+
rubocop (>= 1.7.0, < 2.0)
|
6
|
+
rubocop-rails (~> 2.10.0)
|
7
7
|
|
8
8
|
GEM
|
9
9
|
remote: https://rubygems.org/
|
@@ -51,10 +51,10 @@ GEM
|
|
51
51
|
unicode-display_width (>= 1.4.0, < 3.0)
|
52
52
|
rubocop-ast (1.15.0)
|
53
53
|
parser (>= 3.0.1.1)
|
54
|
-
rubocop-rails (2.
|
54
|
+
rubocop-rails (2.10.1)
|
55
55
|
activesupport (>= 4.2.0)
|
56
56
|
rack (>= 1.1)
|
57
|
-
rubocop (>=
|
57
|
+
rubocop (>= 1.7.0, < 2.0)
|
58
58
|
rubocop-rspec (2.6.0)
|
59
59
|
rubocop (~> 1.19)
|
60
60
|
ruby-progressbar (1.11.0)
|
data/README.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# RuboCop::Petal
|
2
2
|
|
3
3
|
[![Build](https://github.com/petalmd/rubocop-petal/actions/workflows/build.yml/badge.svg)](https://github.com/petalmd/rubocop-petal/actions/workflows/build.yml)
|
4
|
+
[![Gem Version](https://badge.fury.io/rb/rubocop-petal.svg)](https://badge.fury.io/rb/rubocop-petal)
|
4
5
|
|
5
6
|
Petal custom cops. List of cops can be find [here](https://github.com/petalmd/rubocop-petal/tree/main/lib/rubocop/cop).
|
6
7
|
|
@@ -26,21 +27,27 @@ In your `.rubocop.yml` file, add `rubocop-petal`
|
|
26
27
|
|
27
28
|
```yaml
|
28
29
|
require:
|
29
|
-
- rubocop-
|
30
|
+
- rubocop-petal
|
30
31
|
```
|
31
32
|
|
32
33
|
## Development
|
33
34
|
|
34
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests.
|
35
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests.
|
36
|
+
You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
35
37
|
|
36
38
|
To install this gem onto your local machine, run `bundle exec rake install`.
|
37
39
|
|
40
|
+
To run all checks like the CI simply run `bundle exec rake`.
|
41
|
+
|
38
42
|
## Create new cop
|
39
43
|
|
40
44
|
```shell
|
41
45
|
bundle exec rake 'new_cop[Rails/MyNewCop]'
|
42
46
|
```
|
43
47
|
|
48
|
+
Have a look to [RuboCop documentation](https://docs.rubocop.org/rubocop/1.23/development.html) to get started with
|
49
|
+
_node pattern_.
|
50
|
+
|
44
51
|
## Release
|
45
52
|
|
46
53
|
To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
data/config/default.yml
CHANGED
@@ -1,3 +1,34 @@
|
|
1
|
+
RSpec/AuthenticatedAs:
|
2
|
+
Description: 'Suggest to use authenticated_as instead of legacy api_key.'
|
3
|
+
Enabled: true
|
4
|
+
Include:
|
5
|
+
- spec/api/**/*_spec.rb
|
6
|
+
|
7
|
+
RSpec/CreateListMax:
|
8
|
+
Description: 'Prevent creating to most records with `FactoryBot.create_list`.'
|
9
|
+
Enabled: true
|
10
|
+
Max: 5
|
11
|
+
Include:
|
12
|
+
- spec/**/*
|
13
|
+
|
14
|
+
Migration/UseChangeTableBulk:
|
15
|
+
Description: 'Enforces the use of option `bulk: true` with `change_table`'
|
16
|
+
Enabled: true
|
17
|
+
Include:
|
18
|
+
- db/migrate/**
|
19
|
+
|
20
|
+
Grape/HelpersIncludeModule:
|
21
|
+
Description: 'Prevent using helpers with block to include module'
|
22
|
+
Enabled: true
|
23
|
+
Include:
|
24
|
+
- app/api/**/*
|
25
|
+
|
26
|
+
Grape/UnnecessaryNamespace:
|
27
|
+
Description: 'Detect unnecessary usage of Grape namespace.'
|
28
|
+
Enabled: true
|
29
|
+
Include:
|
30
|
+
- app/api/**/*
|
31
|
+
|
1
32
|
Rails/EnumPrefix:
|
2
33
|
Description: 'Set prefix options when using enums.'
|
3
34
|
Enabled: true
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Grape
|
6
|
+
# Prevent usage of Grape `helpers` with a block to include module.
|
7
|
+
# Using a bloc will create a new unnecessary module.
|
8
|
+
#
|
9
|
+
# # bad
|
10
|
+
# helpers do
|
11
|
+
# include MyModule
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# # bad
|
15
|
+
# helpers do
|
16
|
+
# include MyModule
|
17
|
+
# include MyOtherModule
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# # good
|
21
|
+
# helpers MyModule
|
22
|
+
#
|
23
|
+
# # good
|
24
|
+
# helpers MyModule, MyOtherModule
|
25
|
+
class HelpersIncludeModule < Base
|
26
|
+
MSG = 'Use `helpers %<module_name>s` instead of `helpers` with a block.'
|
27
|
+
|
28
|
+
def_node_matcher :helpers?, <<~PATTERN
|
29
|
+
(send nil? :helpers)
|
30
|
+
PATTERN
|
31
|
+
|
32
|
+
def_node_matcher :called_include?, <<~PATTERN
|
33
|
+
(send nil? :include (const _ $_))
|
34
|
+
PATTERN
|
35
|
+
|
36
|
+
def on_send(node)
|
37
|
+
return unless helpers?(node)
|
38
|
+
|
39
|
+
helpers_block_node = node.block_node.children.last
|
40
|
+
block_nodes = block_nodes_in_helpers(helpers_block_node)
|
41
|
+
|
42
|
+
block_nodes.each do |block_node|
|
43
|
+
if (module_name = called_include?(block_node))
|
44
|
+
add_offense(block_node, message: format(MSG, module_name: module_name))
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def block_nodes_in_helpers(node)
|
52
|
+
if node.begin_type?
|
53
|
+
node.children
|
54
|
+
else
|
55
|
+
[node]
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Grape
|
6
|
+
# Detect unnecessary usage of Grape namespace.
|
7
|
+
#
|
8
|
+
# # bad
|
9
|
+
# namespace :my_namespace
|
10
|
+
# get {}
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# # good
|
14
|
+
# get :my_namespace {}
|
15
|
+
#
|
16
|
+
class UnnecessaryNamespace < Base
|
17
|
+
MSG = 'Unnecessary usage of Grape namespace. '\
|
18
|
+
'Specify endpoint name with a argument: `get :my_namespace`.'
|
19
|
+
HTTP_ACTIONS = Set.new(%i[get put post patch delete])
|
20
|
+
GRAPE_NAMESPACE_ALIAS = Set.new(%i[namespace resource resources])
|
21
|
+
METHOD_JUSTIFY_NAMESPACE = Set.new(%i[route_param namespaces resource resources version])
|
22
|
+
|
23
|
+
def_node_matcher :namespace?, <<~PATTERN
|
24
|
+
(send nil? GRAPE_NAMESPACE_ALIAS ({sym | str} _))
|
25
|
+
PATTERN
|
26
|
+
|
27
|
+
def_node_matcher :justify_namespace?, <<~PATTERN
|
28
|
+
(block (send nil? METHOD_JUSTIFY_NAMESPACE ...) ...)
|
29
|
+
PATTERN
|
30
|
+
|
31
|
+
def_node_matcher :http_action?, <<~PATTERN
|
32
|
+
(block (send nil? HTTP_ACTIONS) ...)
|
33
|
+
PATTERN
|
34
|
+
|
35
|
+
def on_send(node)
|
36
|
+
return unless namespace?(node)
|
37
|
+
|
38
|
+
node_to_select_http_action = namespace_node(node)
|
39
|
+
|
40
|
+
return if node_to_select_http_action.any? do |namespace_node|
|
41
|
+
justify_namespace?(namespace_node)
|
42
|
+
end
|
43
|
+
|
44
|
+
http_action_node = select_http_action_block_node(node_to_select_http_action)
|
45
|
+
add_offense(node) if http_action_node.size == 1
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def select_http_action_block_node(nodes)
|
51
|
+
nodes.select { |node| http_action?(node) }
|
52
|
+
end
|
53
|
+
|
54
|
+
def namespace_node(node)
|
55
|
+
if node.block_node.children.last.block_type?
|
56
|
+
[node.block_node.children.last]
|
57
|
+
else
|
58
|
+
node.block_node.children.last.children
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Migration
|
6
|
+
# Use `bulk: true` with `change_table`.
|
7
|
+
# # bad
|
8
|
+
#
|
9
|
+
# change_table :my_table
|
10
|
+
#
|
11
|
+
# # good
|
12
|
+
#
|
13
|
+
# change_table :my_table, bulk: true
|
14
|
+
class UseChangeTableBulk < Base
|
15
|
+
MSG = 'Use `change_table` with `bulk: true`.'
|
16
|
+
RESTRICT_ON_SEND = %i[change_table].freeze
|
17
|
+
|
18
|
+
def_node_matcher :use_bulk?, <<~PATTERN
|
19
|
+
(send nil? :change_table _ (hash <(pair (sym :bulk) true) ...>) ...)
|
20
|
+
PATTERN
|
21
|
+
|
22
|
+
def on_send(node)
|
23
|
+
return if use_bulk?(node)
|
24
|
+
|
25
|
+
add_offense(node)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module RSpec
|
6
|
+
# Suggest to use authenticated_as instead of legacy api_key.
|
7
|
+
# It is faster, can be setup for multiple test.
|
8
|
+
#
|
9
|
+
# # bad
|
10
|
+
# get 'api/my_endpoint', headers: { HTTP_API_KEY: user.api_key }
|
11
|
+
#
|
12
|
+
# # good
|
13
|
+
# authenticated_as user
|
14
|
+
# get 'api/my_endpoint'
|
15
|
+
#
|
16
|
+
class AuthenticatedAs < Base
|
17
|
+
MSG = 'Use `authenticated_as` instead of legacy api_key.'
|
18
|
+
|
19
|
+
def_node_search :use_header_api_key, <<~PATTERN
|
20
|
+
(sym :HTTP_API_KEY)
|
21
|
+
PATTERN
|
22
|
+
|
23
|
+
def on_send(node)
|
24
|
+
api_key_usage = use_header_api_key(node).to_a.first
|
25
|
+
return unless api_key_usage
|
26
|
+
|
27
|
+
add_offense(api_key_usage)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module RSpec
|
6
|
+
# Prevent creating to most records with `FactoryBot.create_list`.
|
7
|
+
# Creating to much records can significantly increase spec time.
|
8
|
+
#
|
9
|
+
# @example Max: 5 (default)
|
10
|
+
# # Maximum amount params allowed for `create_list`.
|
11
|
+
#
|
12
|
+
# # bad
|
13
|
+
# create_list :my_model, 10
|
14
|
+
#
|
15
|
+
# # good
|
16
|
+
# create_list :my_model, 5
|
17
|
+
#
|
18
|
+
# # good
|
19
|
+
# build_stubbed_list :my_model, 10
|
20
|
+
#
|
21
|
+
class CreateListMax < Base
|
22
|
+
MSG = 'Creating more than `%<max_config>s` records is discouraged.'
|
23
|
+
DEFAULT_MAX = 5
|
24
|
+
RESTRICT_ON_SEND = [:create_list].freeze
|
25
|
+
|
26
|
+
def_node_search :create_list, <<~PATTERN
|
27
|
+
(send _ :create_list (sym _) (:int $_) ...)
|
28
|
+
PATTERN
|
29
|
+
|
30
|
+
def on_send(node)
|
31
|
+
amount = create_list(node).to_a.first
|
32
|
+
|
33
|
+
return unless amount
|
34
|
+
|
35
|
+
max_config = cop_config['Max'] || DEFAULT_MAX
|
36
|
+
|
37
|
+
add_offense(node, message: format(MSG, max_config: max_config)) if amount > max_config
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/rubocop-petal.gemspec
CHANGED
@@ -31,6 +31,6 @@ Gem::Specification.new do |spec|
|
|
31
31
|
# For more information and examples about making a new gem, checkout our
|
32
32
|
# guide at: https://bundler.io/guides/creating_gem.html
|
33
33
|
|
34
|
-
spec.add_runtime_dependency 'rubocop'
|
35
|
-
spec.add_dependency 'rubocop-rails'
|
34
|
+
spec.add_runtime_dependency 'rubocop', '>= 1.7.0', '< 2.0'
|
35
|
+
spec.add_dependency 'rubocop-rails', '~> 2.10.0'
|
36
36
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubocop-petal
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jean-Francis Bastien
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-01-
|
11
|
+
date: 2022-01-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubocop
|
@@ -16,28 +16,34 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 1.7.0
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '2.0'
|
20
23
|
type: :runtime
|
21
24
|
prerelease: false
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
23
26
|
requirements:
|
24
27
|
- - ">="
|
25
28
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
29
|
+
version: 1.7.0
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '2.0'
|
27
33
|
- !ruby/object:Gem::Dependency
|
28
34
|
name: rubocop-rails
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
30
36
|
requirements:
|
31
|
-
- - "
|
37
|
+
- - "~>"
|
32
38
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
39
|
+
version: 2.10.0
|
34
40
|
type: :runtime
|
35
41
|
prerelease: false
|
36
42
|
version_requirements: !ruby/object:Gem::Requirement
|
37
43
|
requirements:
|
38
|
-
- - "
|
44
|
+
- - "~>"
|
39
45
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
46
|
+
version: 2.10.0
|
41
47
|
description:
|
42
48
|
email:
|
43
49
|
- jfbastien@petalmd.com
|
@@ -49,6 +55,7 @@ files:
|
|
49
55
|
- ".gitignore"
|
50
56
|
- ".rspec"
|
51
57
|
- ".rubocop.yml"
|
58
|
+
- CHANGELOG.md
|
52
59
|
- Gemfile
|
53
60
|
- Gemfile.lock
|
54
61
|
- LICENSE.txt
|
@@ -59,10 +66,15 @@ files:
|
|
59
66
|
- config/default.yml
|
60
67
|
- lib/rubocop-petal.rb
|
61
68
|
- lib/rubocop/cop/chewy/reset_on_type.rb
|
69
|
+
- lib/rubocop/cop/grape/helpers_include_module.rb
|
70
|
+
- lib/rubocop/cop/grape/unnecessary_namespace.rb
|
71
|
+
- lib/rubocop/cop/migration/use_change_table_bulk.rb
|
62
72
|
- lib/rubocop/cop/petal_cops.rb
|
63
73
|
- lib/rubocop/cop/rails/enum_prefix.rb
|
64
74
|
- lib/rubocop/cop/rails/risky_activerecord_invocation.rb
|
65
75
|
- lib/rubocop/cop/rails/table_name.rb
|
76
|
+
- lib/rubocop/cop/rspec/authenticated_as.rb
|
77
|
+
- lib/rubocop/cop/rspec/create_list_max.rb
|
66
78
|
- lib/rubocop/petal.rb
|
67
79
|
- lib/rubocop/petal/inject.rb
|
68
80
|
- lib/rubocop/petal/version.rb
|