rubocop-sequel 0.3.5 → 0.3.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/config/default.yml +2 -2
- data/lib/rubocop/cop/sequel/concurrent_index.rb +4 -0
- data/lib/rubocop/cop/sequel/helpers/migration.rb +25 -0
- data/lib/rubocop/cop/sequel/irreversible_migration.rb +5 -2
- data/lib/rubocop/cop/sequel/json_column.rb +4 -0
- data/lib/rubocop/cop/sequel/partial_constraint.rb +3 -0
- data/lib/rubocop/sequel/version.rb +1 -1
- data/lib/rubocop-sequel.rb +2 -0
- data/rubocop-sequel.gemspec +1 -1
- data/spec/rubocop/cop/sequel/concurrent_index_spec.rb +6 -4
- data/spec/rubocop/cop/sequel/helpers/migration.rb +19 -0
- data/spec/rubocop/cop/sequel/irreversible_migration_spec.rb +18 -3
- data/spec/rubocop/cop/sequel/json_column_spec.rb +10 -8
- data/spec/rubocop/cop/sequel/partial_constraint_spec.rb +3 -1
- data/spec/spec_helper.rb +2 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8264c5365683296b4ca9330ef776756e3c04ac55bb1ccdb9b2e76ea42d587e95
|
4
|
+
data.tar.gz: 53417ac0da345eba715ef2ce39a7ac60dbd93a0b6a2d174400ff3928bdb8814c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aa8a47c34b42c304ba81f83725298b2e7ed6ba5c5da8432c5869e10f22e728fe3009132e1d7a144492f95e509908cbd3378d055d1bb9ff164c58363794df9210
|
7
|
+
data.tar.gz: a664d80d57e0477053dd8aaf45dc052c306714e610c7f312e1f656b20f0a11d7f9e17394ec63a9bf61353214f10a3d97b0059d826f85ef01399777bfc4225ed0
|
data/.gitignore
CHANGED
data/config/default.yml
CHANGED
@@ -16,8 +16,8 @@ Sequel/IrreversibleMigration:
|
|
16
16
|
Warns against using certain methods inside a migration file's `change` block that would cause the migration to become irreversible.
|
17
17
|
Reference: https://www.rubydoc.info/gems/rubocop-sequel/RuboCop/Cop/Sequel/IrreversibleMigration
|
18
18
|
Enabled: true
|
19
|
-
VersionAdded: 0.3.
|
20
|
-
VersionChanged: 0.3.
|
19
|
+
VersionAdded: 0.3.5
|
20
|
+
VersionChanged: 0.3.6
|
21
21
|
|
22
22
|
Sequel/JSONColumn:
|
23
23
|
Description: >-
|
@@ -5,6 +5,8 @@ module RuboCop
|
|
5
5
|
module Sequel
|
6
6
|
# ConcurrentIndex looks for non-concurrent index creation.
|
7
7
|
class ConcurrentIndex < Base
|
8
|
+
include Helpers::Migration
|
9
|
+
|
8
10
|
MSG = 'Specify `concurrently` option when creating or dropping an index.'
|
9
11
|
RESTRICT_ON_SEND = %i[add_index drop_index].freeze
|
10
12
|
|
@@ -13,6 +15,8 @@ module RuboCop
|
|
13
15
|
MATCHER
|
14
16
|
|
15
17
|
def on_send(node)
|
18
|
+
return unless within_sequel_migration?(node)
|
19
|
+
|
16
20
|
indexes?(node) do |args|
|
17
21
|
add_offense(node.loc.selector, message: MSG) if offensive?(args)
|
18
22
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Sequel
|
6
|
+
module Helpers
|
7
|
+
# Migration contains helper methods for detecting if a node is inside a `Sequel.migration` block
|
8
|
+
module Migration
|
9
|
+
extend NodePattern::Macros
|
10
|
+
|
11
|
+
def_node_matcher :sequel_migration_block?, <<~MATCHER
|
12
|
+
(block
|
13
|
+
(send
|
14
|
+
(const nil? :Sequel) :migration ...)
|
15
|
+
...)
|
16
|
+
MATCHER
|
17
|
+
|
18
|
+
def within_sequel_migration?(node)
|
19
|
+
node.each_ancestor(:block).any? { |ancestor| sequel_migration_block?(ancestor) }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -5,6 +5,8 @@ module RuboCop
|
|
5
5
|
module Sequel
|
6
6
|
# IrreversibleMigration looks for methods inside a `change` block that cannot be reversed.
|
7
7
|
class IrreversibleMigration < Base
|
8
|
+
include Helpers::Migration
|
9
|
+
|
8
10
|
# https://sequel.jeremyevans.net/rdoc/files/doc/migration_rdoc.html#label-A+Basic+Migration
|
9
11
|
VALID_CHANGE_METHODS = %i[
|
10
12
|
create_table
|
@@ -26,11 +28,12 @@ module RuboCop
|
|
26
28
|
set_column_allow_null
|
27
29
|
].freeze
|
28
30
|
|
29
|
-
MSG = 'Avoid using
|
30
|
-
PRIMARY_KEY_MSG = 'Avoid using
|
31
|
+
MSG = 'Avoid using "%<name>s" inside a "change" block. Use "up" & "down" blocks instead.'
|
32
|
+
PRIMARY_KEY_MSG = 'Avoid using "add_primary_key" with an array argument inside a "change" block.'
|
31
33
|
|
32
34
|
def on_block(node)
|
33
35
|
return unless node.method_name == :change
|
36
|
+
return unless within_sequel_migration?(node)
|
34
37
|
|
35
38
|
body = node.body
|
36
39
|
return unless body
|
@@ -5,6 +5,8 @@ module RuboCop
|
|
5
5
|
module Sequel
|
6
6
|
# JSONColumn looks for non-JSONB columns.
|
7
7
|
class JSONColumn < Base
|
8
|
+
include Helpers::Migration
|
9
|
+
|
8
10
|
MSG = 'Use JSONB rather than JSON or hstore'
|
9
11
|
RESTRICT_ON_SEND = %i[add_column].freeze
|
10
12
|
|
@@ -22,12 +24,14 @@ module RuboCop
|
|
22
24
|
|
23
25
|
def on_send(node)
|
24
26
|
return unless json_or_hstore?(node)
|
27
|
+
return unless within_sequel_migration?(node)
|
25
28
|
|
26
29
|
add_offense(node.loc.selector, message: MSG)
|
27
30
|
end
|
28
31
|
|
29
32
|
def on_block(node)
|
30
33
|
return unless node.send_node.method_name == :create_table
|
34
|
+
return unless within_sequel_migration?(node)
|
31
35
|
|
32
36
|
node.each_node(:send) do |method|
|
33
37
|
next unless column_method?(method) || column_type?(method)
|
@@ -5,6 +5,8 @@ module RuboCop
|
|
5
5
|
module Sequel
|
6
6
|
# PartialConstraint looks for missed usage of partial indexes.
|
7
7
|
class PartialConstraint < Base
|
8
|
+
include Helpers::Migration
|
9
|
+
|
8
10
|
MSG = "Constraint can't be partial, use where argument with index"
|
9
11
|
RESTRICT_ON_SEND = %i[add_unique_constraint].freeze
|
10
12
|
|
@@ -14,6 +16,7 @@ module RuboCop
|
|
14
16
|
|
15
17
|
def on_send(node)
|
16
18
|
return unless add_partial_constraint?(node)
|
19
|
+
return unless within_sequel_migration?(node)
|
17
20
|
|
18
21
|
add_offense(node.loc.selector, message: MSG)
|
19
22
|
end
|
data/lib/rubocop-sequel.rb
CHANGED
@@ -7,6 +7,8 @@ require 'rubocop/sequel/inject'
|
|
7
7
|
|
8
8
|
RuboCop::Sequel::Inject.defaults!
|
9
9
|
|
10
|
+
require_relative 'rubocop/cop/sequel/helpers/migration'
|
11
|
+
|
10
12
|
require 'rubocop/cop/sequel/concurrent_index'
|
11
13
|
require 'rubocop/cop/sequel/irreversible_migration'
|
12
14
|
require 'rubocop/cop/sequel/json_column'
|
data/rubocop-sequel.gemspec
CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |gem|
|
|
12
12
|
gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
|
13
13
|
gem.name = 'rubocop-sequel'
|
14
14
|
gem.require_paths = ['lib']
|
15
|
-
gem.version = '0.3.
|
15
|
+
gem.version = '0.3.6'
|
16
16
|
gem.metadata['rubygems_mfa_required'] = 'true'
|
17
17
|
|
18
18
|
gem.required_ruby_version = '>= 2.5'
|
@@ -1,11 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
RSpec.describe RuboCop::Cop::Sequel::ConcurrentIndex do
|
4
|
+
include Spec::Helpers::Migration
|
5
|
+
|
4
6
|
subject(:cop) { described_class.new }
|
5
7
|
|
6
8
|
context 'without the concurrent option' do
|
7
9
|
it 'registers an offense without options' do
|
8
|
-
offenses =
|
10
|
+
offenses = inspect_source_within_migration(<<~SOURCE)
|
9
11
|
add_index(:products, :name)
|
10
12
|
drop_index(:products, :name)
|
11
13
|
SOURCE
|
@@ -13,7 +15,7 @@ RSpec.describe RuboCop::Cop::Sequel::ConcurrentIndex do
|
|
13
15
|
end
|
14
16
|
|
15
17
|
it 'registers an offense with other options' do
|
16
|
-
offenses =
|
18
|
+
offenses = inspect_source_within_migration(<<~SOURCE)
|
17
19
|
add_index(:products, :name, unique: true)
|
18
20
|
drop_index(:products, :name, unique: true)
|
19
21
|
SOURCE
|
@@ -21,7 +23,7 @@ RSpec.describe RuboCop::Cop::Sequel::ConcurrentIndex do
|
|
21
23
|
end
|
22
24
|
|
23
25
|
it 'registers an offense with composite index' do
|
24
|
-
offenses =
|
26
|
+
offenses = inspect_source_within_migration(<<~SOURCE)
|
25
27
|
add_index(:products, [:name, :price], unique: true)
|
26
28
|
drop_index(:products, [:name, :price])
|
27
29
|
SOURCE
|
@@ -30,7 +32,7 @@ RSpec.describe RuboCop::Cop::Sequel::ConcurrentIndex do
|
|
30
32
|
end
|
31
33
|
|
32
34
|
it 'does not register an offense when using concurrent option' do
|
33
|
-
offenses =
|
35
|
+
offenses = inspect_source_within_migration(<<~SOURCE)
|
34
36
|
add_index(:products, :name, unique: true, concurrently: true)
|
35
37
|
drop_index(:products, :name, concurrently: true)
|
36
38
|
SOURCE
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Spec
|
4
|
+
module Helpers
|
5
|
+
module Migration
|
6
|
+
extend CopHelper
|
7
|
+
|
8
|
+
def inspect_source_within_migration(source, file = nil)
|
9
|
+
migration_wrapped_source = <<~SOURCE
|
10
|
+
Sequel.migration do
|
11
|
+
#{source}
|
12
|
+
end
|
13
|
+
SOURCE
|
14
|
+
|
15
|
+
inspect_source(migration_wrapped_source, file)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
RSpec.describe RuboCop::Cop::Sequel::IrreversibleMigration do
|
4
|
+
include Spec::Helpers::Migration
|
5
|
+
|
4
6
|
subject(:cop) { described_class.new }
|
5
7
|
|
6
8
|
context 'when inside a change block' do
|
@@ -28,12 +30,12 @@ RSpec.describe RuboCop::Cop::Sequel::IrreversibleMigration do
|
|
28
30
|
end
|
29
31
|
|
30
32
|
it 'registers an offense when there is an invalid method' do
|
31
|
-
offenses =
|
33
|
+
offenses = inspect_source_within_migration(invalid_source)
|
32
34
|
expect(offenses.size).to eq(2)
|
33
35
|
end
|
34
36
|
|
35
37
|
it 'does not register an offense with valid methods' do
|
36
|
-
offenses =
|
38
|
+
offenses = inspect_source_within_migration(valid_source)
|
37
39
|
expect(offenses).to be_empty
|
38
40
|
end
|
39
41
|
|
@@ -49,7 +51,7 @@ RSpec.describe RuboCop::Cop::Sequel::IrreversibleMigration do
|
|
49
51
|
end
|
50
52
|
|
51
53
|
it 'registers an offense' do
|
52
|
-
offenses =
|
54
|
+
offenses = inspect_source_within_migration(source)
|
53
55
|
expect(offenses.size).to eq(1)
|
54
56
|
end
|
55
57
|
end
|
@@ -68,6 +70,19 @@ RSpec.describe RuboCop::Cop::Sequel::IrreversibleMigration do
|
|
68
70
|
SOURCE
|
69
71
|
end
|
70
72
|
|
73
|
+
it 'does not register an offense with any methods' do
|
74
|
+
offenses = inspect_source_within_migration(source)
|
75
|
+
expect(offenses).to be_empty
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context 'when a change block is used outside of a Sequel migration' do
|
80
|
+
let(:source) do
|
81
|
+
<<~SOURCE
|
82
|
+
it { expect { subject }.to change { document_count(user_id) }.by(-1) }
|
83
|
+
SOURCE
|
84
|
+
end
|
85
|
+
|
71
86
|
it 'does not register an offense with any methods' do
|
72
87
|
offenses = inspect_source(source)
|
73
88
|
expect(offenses).to be_empty
|
@@ -1,48 +1,50 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
RSpec.describe RuboCop::Cop::Sequel::JSONColumn do
|
4
|
+
include Spec::Helpers::Migration
|
5
|
+
|
4
6
|
subject(:cop) { described_class.new }
|
5
7
|
|
6
8
|
context 'with add_column' do
|
7
9
|
it 'registers an offense when using json type' do
|
8
|
-
offenses =
|
10
|
+
offenses = inspect_source_within_migration('add_column(:products, :type, :json)')
|
9
11
|
expect(offenses.size).to eq(1)
|
10
12
|
end
|
11
13
|
|
12
14
|
it 'registers an offense when using hstore type' do
|
13
|
-
offenses =
|
15
|
+
offenses = inspect_source_within_migration('add_column(:products, :type, :hstore)')
|
14
16
|
expect(offenses.size).to eq(1)
|
15
17
|
end
|
16
18
|
|
17
19
|
it 'does not register an offense when using jsonb' do
|
18
|
-
offenses =
|
20
|
+
offenses = inspect_source_within_migration('add_column(:products, :type, :jsonb)')
|
19
21
|
expect(offenses).to be_empty
|
20
22
|
end
|
21
23
|
end
|
22
24
|
|
23
25
|
context 'with create_table' do
|
24
26
|
it 'registers an offense when using json as a method' do
|
25
|
-
offenses =
|
27
|
+
offenses = inspect_source_within_migration('create_table(:products) { json :type, default: {} }')
|
26
28
|
expect(offenses.size).to eq(1)
|
27
29
|
end
|
28
30
|
|
29
31
|
it 'registers an offense when using the column method with hstore' do
|
30
|
-
offenses =
|
32
|
+
offenses = inspect_source_within_migration('create_table(:products) { column :type, :hstore }')
|
31
33
|
expect(offenses.size).to eq(1)
|
32
34
|
end
|
33
35
|
|
34
36
|
it 'does not register an offense when using jsonb as column type`' do
|
35
|
-
offenses =
|
37
|
+
offenses = inspect_source_within_migration('create_table(:products) { column :type, :jsonb }')
|
36
38
|
expect(offenses).to be_empty
|
37
39
|
end
|
38
40
|
|
39
41
|
it 'does not register an offense when using jsonb' do
|
40
|
-
offenses =
|
42
|
+
offenses = inspect_source_within_migration('create_table(:products) { jsonb :type }')
|
41
43
|
expect(offenses).to be_empty
|
42
44
|
end
|
43
45
|
|
44
46
|
it 'does not register an offense when using a simple type' do
|
45
|
-
offenses =
|
47
|
+
offenses = inspect_source_within_migration('create_table(:products) { integer :type, default: 0 }')
|
46
48
|
expect(offenses).to be_empty
|
47
49
|
end
|
48
50
|
end
|
@@ -1,10 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
RSpec.describe RuboCop::Cop::Sequel::PartialConstraint do
|
4
|
+
include Spec::Helpers::Migration
|
5
|
+
|
4
6
|
subject(:cop) { described_class.new }
|
5
7
|
|
6
8
|
it 'registers an offense when using where for constraint' do
|
7
|
-
offenses =
|
9
|
+
offenses = inspect_source_within_migration(<<~RUBY)
|
8
10
|
add_unique_constraint %i[col_1 col_2], where: "state != 'deleted'"
|
9
11
|
RUBY
|
10
12
|
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubocop-sequel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Timothée Peignier
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-10-
|
11
|
+
date: 2024-10-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubocop
|
@@ -43,6 +43,7 @@ files:
|
|
43
43
|
- config/obsoletion.yml
|
44
44
|
- lib/rubocop-sequel.rb
|
45
45
|
- lib/rubocop/cop/sequel/concurrent_index.rb
|
46
|
+
- lib/rubocop/cop/sequel/helpers/migration.rb
|
46
47
|
- lib/rubocop/cop/sequel/irreversible_migration.rb
|
47
48
|
- lib/rubocop/cop/sequel/json_column.rb
|
48
49
|
- lib/rubocop/cop/sequel/migration_name.rb
|
@@ -54,6 +55,7 @@ files:
|
|
54
55
|
- rubocop-sequel.gemspec
|
55
56
|
- spec/project_spec.rb
|
56
57
|
- spec/rubocop/cop/sequel/concurrent_index_spec.rb
|
58
|
+
- spec/rubocop/cop/sequel/helpers/migration.rb
|
57
59
|
- spec/rubocop/cop/sequel/irreversible_migration_spec.rb
|
58
60
|
- spec/rubocop/cop/sequel/json_column_spec.rb
|
59
61
|
- spec/rubocop/cop/sequel/migration_name_spec.rb
|