gitlab-styles 1.0.0 → 2.0.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/README.md +1 -1
- data/gitlab-styles.gemspec +1 -1
- data/lib/gitlab/styles/rubocop.rb +0 -15
- data/lib/gitlab/styles/version.rb +1 -1
- data/rubocop-default.yml +0 -11
- metadata +3 -18
- data/lib/gitlab/styles/rubocop/cop/migration/add_column.rb +0 -56
- data/lib/gitlab/styles/rubocop/cop/migration/add_column_with_default_to_large_table.rb +0 -59
- data/lib/gitlab/styles/rubocop/cop/migration/add_concurrent_foreign_key.rb +0 -31
- data/lib/gitlab/styles/rubocop/cop/migration/add_concurrent_index.rb +0 -38
- data/lib/gitlab/styles/rubocop/cop/migration/add_index.rb +0 -52
- data/lib/gitlab/styles/rubocop/cop/migration/add_timestamps.rb +0 -29
- data/lib/gitlab/styles/rubocop/cop/migration/datetime.rb +0 -40
- data/lib/gitlab/styles/rubocop/cop/migration/hash_index.rb +0 -55
- data/lib/gitlab/styles/rubocop/cop/migration/remove_concurrent_index.rb +0 -33
- data/lib/gitlab/styles/rubocop/cop/migration/remove_index.rb +0 -30
- data/lib/gitlab/styles/rubocop/cop/migration/reversible_add_column_with_default.rb +0 -39
- data/lib/gitlab/styles/rubocop/cop/migration/safer_boolean_column.rb +0 -98
- data/lib/gitlab/styles/rubocop/cop/migration/timestamps.rb +0 -31
- data/lib/gitlab/styles/rubocop/cop/migration/update_column_in_batches.rb +0 -45
- data/lib/gitlab/styles/rubocop/cop/project_path_helper.rb +0 -55
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 428a98eba0188d3e0da5edce2a199920e67f9f7d
|
|
4
|
+
data.tar.gz: 2524287dacb4b19dbc0fc80db30566bd4d98c55a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3ee7038b87dab11c007c0c30927500cce85a17c24b1aa496398ecf26eaa17188d0a76091433330d949dd91c5f831acd51e5ae74ae08e1f284c7b13c7d6603561
|
|
7
|
+
data.tar.gz: 8e8c88aaec1d8eee2a872638903fe6574ef99a3cd0bff47e80c2ae7755f03e6067056d4b5232fcb802ce7c5fafe989e4315d377b0b038ebffd26431ec2f37bb9
|
data/README.md
CHANGED
data/gitlab-styles.gemspec
CHANGED
|
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
|
|
|
9
9
|
spec.email = ['remy@rymai.me']
|
|
10
10
|
|
|
11
11
|
spec.summary = 'GitLab style guides and shared style configs.'
|
|
12
|
-
spec.homepage = 'https://
|
|
12
|
+
spec.homepage = 'https://gitlab.com/gitlab-org/gitlab-styles'
|
|
13
13
|
spec.license = 'MIT'
|
|
14
14
|
|
|
15
15
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
|
@@ -3,23 +3,8 @@ require 'gitlab/styles/rubocop/cop/gem_fetcher'
|
|
|
3
3
|
require 'gitlab/styles/rubocop/cop/active_record_serialize'
|
|
4
4
|
require 'gitlab/styles/rubocop/cop/redirect_with_status'
|
|
5
5
|
require 'gitlab/styles/rubocop/cop/polymorphic_associations'
|
|
6
|
-
require 'gitlab/styles/rubocop/cop/project_path_helper'
|
|
7
6
|
require 'gitlab/styles/rubocop/cop/active_record_dependent'
|
|
8
7
|
require 'gitlab/styles/rubocop/cop/in_batches'
|
|
9
|
-
require 'gitlab/styles/rubocop/cop/migration/add_column'
|
|
10
|
-
require 'gitlab/styles/rubocop/cop/migration/add_column_with_default_to_large_table'
|
|
11
|
-
require 'gitlab/styles/rubocop/cop/migration/add_concurrent_foreign_key'
|
|
12
|
-
require 'gitlab/styles/rubocop/cop/migration/add_concurrent_index'
|
|
13
|
-
require 'gitlab/styles/rubocop/cop/migration/add_index'
|
|
14
|
-
require 'gitlab/styles/rubocop/cop/migration/add_timestamps'
|
|
15
|
-
require 'gitlab/styles/rubocop/cop/migration/datetime'
|
|
16
|
-
require 'gitlab/styles/rubocop/cop/migration/safer_boolean_column'
|
|
17
|
-
require 'gitlab/styles/rubocop/cop/migration/hash_index'
|
|
18
|
-
require 'gitlab/styles/rubocop/cop/migration/remove_concurrent_index'
|
|
19
|
-
require 'gitlab/styles/rubocop/cop/migration/remove_index'
|
|
20
|
-
require 'gitlab/styles/rubocop/cop/migration/reversible_add_column_with_default'
|
|
21
|
-
require 'gitlab/styles/rubocop/cop/migration/timestamps'
|
|
22
|
-
require 'gitlab/styles/rubocop/cop/migration/update_column_in_batches'
|
|
23
8
|
require 'gitlab/styles/rubocop/cop/rspec/single_line_hook'
|
|
24
9
|
|
|
25
10
|
module Gitlab
|
data/rubocop-default.yml
CHANGED
|
@@ -5,7 +5,6 @@ require:
|
|
|
5
5
|
|
|
6
6
|
AllCops:
|
|
7
7
|
TargetRubyVersion: 2.3
|
|
8
|
-
TargetRailsVersion: 4.2
|
|
9
8
|
# Cop names are not d§splayed in offense messages by default. Change behavior
|
|
10
9
|
# by overriding DisplayCopNames, or by giving the -D/--display-cop-names
|
|
11
10
|
# option.
|
|
@@ -15,16 +14,6 @@ AllCops:
|
|
|
15
14
|
# -S/--display-style-guide option.
|
|
16
15
|
DisplayStyleGuide: false
|
|
17
16
|
# Exclude some GitLab files
|
|
18
|
-
Exclude:
|
|
19
|
-
- 'vendor/**/*'
|
|
20
|
-
- 'node_modules/**/*'
|
|
21
|
-
- 'db/*'
|
|
22
|
-
- 'db/fixtures/**/*'
|
|
23
|
-
- 'db/geo/*'
|
|
24
|
-
- 'tmp/**/*'
|
|
25
|
-
- 'bin/**/*'
|
|
26
|
-
- 'generator_templates/**/*'
|
|
27
|
-
- 'builds/**/*'
|
|
28
17
|
|
|
29
18
|
# Gems in consecutive lines should be alphabetically sorted
|
|
30
19
|
Bundler/OrderedGems:
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: gitlab-styles
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 2.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- GitLab
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2017-09-
|
|
11
|
+
date: 2017-09-19 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rubocop
|
|
@@ -120,29 +120,14 @@ files:
|
|
|
120
120
|
- lib/gitlab/styles/rubocop/cop/custom_error_class.rb
|
|
121
121
|
- lib/gitlab/styles/rubocop/cop/gem_fetcher.rb
|
|
122
122
|
- lib/gitlab/styles/rubocop/cop/in_batches.rb
|
|
123
|
-
- lib/gitlab/styles/rubocop/cop/migration/add_column.rb
|
|
124
|
-
- lib/gitlab/styles/rubocop/cop/migration/add_column_with_default_to_large_table.rb
|
|
125
|
-
- lib/gitlab/styles/rubocop/cop/migration/add_concurrent_foreign_key.rb
|
|
126
|
-
- lib/gitlab/styles/rubocop/cop/migration/add_concurrent_index.rb
|
|
127
|
-
- lib/gitlab/styles/rubocop/cop/migration/add_index.rb
|
|
128
|
-
- lib/gitlab/styles/rubocop/cop/migration/add_timestamps.rb
|
|
129
|
-
- lib/gitlab/styles/rubocop/cop/migration/datetime.rb
|
|
130
|
-
- lib/gitlab/styles/rubocop/cop/migration/hash_index.rb
|
|
131
|
-
- lib/gitlab/styles/rubocop/cop/migration/remove_concurrent_index.rb
|
|
132
|
-
- lib/gitlab/styles/rubocop/cop/migration/remove_index.rb
|
|
133
|
-
- lib/gitlab/styles/rubocop/cop/migration/reversible_add_column_with_default.rb
|
|
134
|
-
- lib/gitlab/styles/rubocop/cop/migration/safer_boolean_column.rb
|
|
135
|
-
- lib/gitlab/styles/rubocop/cop/migration/timestamps.rb
|
|
136
|
-
- lib/gitlab/styles/rubocop/cop/migration/update_column_in_batches.rb
|
|
137
123
|
- lib/gitlab/styles/rubocop/cop/polymorphic_associations.rb
|
|
138
|
-
- lib/gitlab/styles/rubocop/cop/project_path_helper.rb
|
|
139
124
|
- lib/gitlab/styles/rubocop/cop/redirect_with_status.rb
|
|
140
125
|
- lib/gitlab/styles/rubocop/cop/rspec/single_line_hook.rb
|
|
141
126
|
- lib/gitlab/styles/rubocop/migration_helpers.rb
|
|
142
127
|
- lib/gitlab/styles/rubocop/model_helpers.rb
|
|
143
128
|
- lib/gitlab/styles/version.rb
|
|
144
129
|
- rubocop-default.yml
|
|
145
|
-
homepage: https://
|
|
130
|
+
homepage: https://gitlab.com/gitlab-org/gitlab-styles
|
|
146
131
|
licenses:
|
|
147
132
|
- MIT
|
|
148
133
|
metadata: {}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
require_relative '../../migration_helpers'
|
|
2
|
-
|
|
3
|
-
module Gitlab
|
|
4
|
-
module Styles
|
|
5
|
-
module Rubocop
|
|
6
|
-
module Cop
|
|
7
|
-
module Migration
|
|
8
|
-
# Cop that checks if columns are added in a way that doesn't require
|
|
9
|
-
# downtime.
|
|
10
|
-
class AddColumn < RuboCop::Cop::Cop
|
|
11
|
-
include MigrationHelpers
|
|
12
|
-
|
|
13
|
-
WHITELISTED_TABLES = [:application_settings].freeze
|
|
14
|
-
|
|
15
|
-
MSG = '`add_column` with a default value requires downtime, ' \
|
|
16
|
-
'use `add_column_with_default` instead'.freeze
|
|
17
|
-
|
|
18
|
-
def on_send(node)
|
|
19
|
-
return unless in_migration?(node)
|
|
20
|
-
|
|
21
|
-
name = node.children[1]
|
|
22
|
-
|
|
23
|
-
return unless name == :add_column
|
|
24
|
-
|
|
25
|
-
# Ignore whitelisted tables.
|
|
26
|
-
return if table_whitelisted?(node.children[2])
|
|
27
|
-
|
|
28
|
-
opts = node.children.last
|
|
29
|
-
|
|
30
|
-
return unless opts&.type == :hash
|
|
31
|
-
|
|
32
|
-
opts.each_node(:pair) do |pair|
|
|
33
|
-
if hash_key_type(pair) == :sym && hash_key_name(pair) == :default
|
|
34
|
-
add_offense(node, :selector)
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def table_whitelisted?(symbol)
|
|
40
|
-
symbol&.type == :sym &&
|
|
41
|
-
WHITELISTED_TABLES.include?(symbol.children[0])
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def hash_key_type(pair)
|
|
45
|
-
pair.children[0].type
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def hash_key_name(pair)
|
|
49
|
-
pair.children[0].children[0]
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
end
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
require_relative '../../migration_helpers'
|
|
2
|
-
|
|
3
|
-
module Gitlab
|
|
4
|
-
module Styles
|
|
5
|
-
module Rubocop
|
|
6
|
-
module Cop
|
|
7
|
-
module Migration
|
|
8
|
-
# This cop checks for `add_column_with_default` on a table that's been
|
|
9
|
-
# explicitly blacklisted because of its size.
|
|
10
|
-
#
|
|
11
|
-
# Even though this helper performs the update in batches to avoid
|
|
12
|
-
# downtime, using it with tables with millions of rows still causes a
|
|
13
|
-
# significant delay in the deploy process and is best avoided.
|
|
14
|
-
#
|
|
15
|
-
# See https://gitlab.com/gitlab-com/infrastructure/issues/1602 for more
|
|
16
|
-
# information.
|
|
17
|
-
class AddColumnWithDefaultToLargeTable < RuboCop::Cop::Cop
|
|
18
|
-
include MigrationHelpers
|
|
19
|
-
|
|
20
|
-
MSG = 'Using `add_column_with_default` on the `%s` table will take a ' \
|
|
21
|
-
'long time to complete, and should be avoided unless absolutely ' \
|
|
22
|
-
'necessary'.freeze
|
|
23
|
-
|
|
24
|
-
LARGE_TABLES = %i[
|
|
25
|
-
ci_pipelines
|
|
26
|
-
ci_builds
|
|
27
|
-
events
|
|
28
|
-
issues
|
|
29
|
-
merge_request_diff_files
|
|
30
|
-
merge_request_diffs
|
|
31
|
-
merge_requests
|
|
32
|
-
namespaces
|
|
33
|
-
notes
|
|
34
|
-
projects
|
|
35
|
-
routes
|
|
36
|
-
users
|
|
37
|
-
].freeze
|
|
38
|
-
|
|
39
|
-
def_node_matcher :add_column_with_default?, <<~PATTERN
|
|
40
|
-
(send nil :add_column_with_default $(sym ...) ...)
|
|
41
|
-
PATTERN
|
|
42
|
-
|
|
43
|
-
def on_send(node)
|
|
44
|
-
return unless in_migration?(node)
|
|
45
|
-
|
|
46
|
-
matched = add_column_with_default?(node)
|
|
47
|
-
return unless matched
|
|
48
|
-
|
|
49
|
-
table = matched.to_a.first
|
|
50
|
-
return unless LARGE_TABLES.include?(table)
|
|
51
|
-
|
|
52
|
-
add_offense(node, :expression, format(MSG, table))
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
end
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
require_relative '../../migration_helpers'
|
|
2
|
-
|
|
3
|
-
module Gitlab
|
|
4
|
-
module Styles
|
|
5
|
-
module Rubocop
|
|
6
|
-
module Cop
|
|
7
|
-
module Migration
|
|
8
|
-
# Cop that checks if `add_concurrent_foreign_key` is used instead of
|
|
9
|
-
# `add_foreign_key`.
|
|
10
|
-
class AddConcurrentForeignKey < RuboCop::Cop::Cop
|
|
11
|
-
include MigrationHelpers
|
|
12
|
-
|
|
13
|
-
MSG = '`add_foreign_key` requires downtime, use `add_concurrent_foreign_key` instead'.freeze
|
|
14
|
-
|
|
15
|
-
def on_send(node)
|
|
16
|
-
return unless in_migration?(node)
|
|
17
|
-
|
|
18
|
-
name = node.children[1]
|
|
19
|
-
|
|
20
|
-
add_offense(node, :selector) if name == :add_foreign_key
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def method_name(node)
|
|
24
|
-
node.children.first
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
require_relative '../../migration_helpers'
|
|
2
|
-
|
|
3
|
-
module Gitlab
|
|
4
|
-
module Styles
|
|
5
|
-
module Rubocop
|
|
6
|
-
module Cop
|
|
7
|
-
module Migration
|
|
8
|
-
# Cop that checks if `add_concurrent_index` is used with `up`/`down` methods
|
|
9
|
-
# and not `change`.
|
|
10
|
-
class AddConcurrentIndex < RuboCop::Cop::Cop
|
|
11
|
-
include MigrationHelpers
|
|
12
|
-
|
|
13
|
-
MSG = '`add_concurrent_index` is not reversible so you must manually define ' \
|
|
14
|
-
'the `up` and `down` methods in your migration class, using `remove_concurrent_index` in `down`'.freeze
|
|
15
|
-
|
|
16
|
-
def on_send(node)
|
|
17
|
-
return unless in_migration?(node)
|
|
18
|
-
|
|
19
|
-
name = node.children[1]
|
|
20
|
-
|
|
21
|
-
return unless name == :add_concurrent_index
|
|
22
|
-
|
|
23
|
-
node.each_ancestor(:def) do |def_node|
|
|
24
|
-
next unless method_name(def_node) == :change
|
|
25
|
-
|
|
26
|
-
add_offense(def_node, :name)
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def method_name(node)
|
|
31
|
-
node.children.first
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
end
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
require_relative '../../migration_helpers'
|
|
2
|
-
|
|
3
|
-
module Gitlab
|
|
4
|
-
module Styles
|
|
5
|
-
module Rubocop
|
|
6
|
-
module Cop
|
|
7
|
-
module Migration
|
|
8
|
-
# Cop that checks if indexes are added in a concurrent manner.
|
|
9
|
-
class AddIndex < RuboCop::Cop::Cop
|
|
10
|
-
include MigrationHelpers
|
|
11
|
-
|
|
12
|
-
MSG = '`add_index` requires downtime, use `add_concurrent_index` instead'.freeze
|
|
13
|
-
|
|
14
|
-
def on_def(node)
|
|
15
|
-
return unless in_migration?(node)
|
|
16
|
-
|
|
17
|
-
new_tables = []
|
|
18
|
-
|
|
19
|
-
node.each_descendant(:send) do |send_node|
|
|
20
|
-
first_arg = first_argument(send_node)
|
|
21
|
-
|
|
22
|
-
# The first argument of "create_table" / "add_index" is the table
|
|
23
|
-
# name.
|
|
24
|
-
new_tables << first_arg if create_table?(send_node)
|
|
25
|
-
|
|
26
|
-
next if method_name(send_node) != :add_index
|
|
27
|
-
|
|
28
|
-
# Using "add_index" is fine for newly created tables as there's no
|
|
29
|
-
# data in these tables yet.
|
|
30
|
-
next if new_tables.include?(first_arg)
|
|
31
|
-
|
|
32
|
-
add_offense(send_node, :selector)
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def create_table?(node)
|
|
37
|
-
method_name(node) == :create_table
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def method_name(node)
|
|
41
|
-
node.children[1]
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def first_argument(node)
|
|
45
|
-
node.children[2] ? node.children[0] : nil
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
end
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
require_relative '../../migration_helpers'
|
|
2
|
-
|
|
3
|
-
module Gitlab
|
|
4
|
-
module Styles
|
|
5
|
-
module Rubocop
|
|
6
|
-
module Cop
|
|
7
|
-
module Migration
|
|
8
|
-
# Cop that checks if 'add_timestamps' method is called with timezone information.
|
|
9
|
-
class AddTimestamps < RuboCop::Cop::Cop
|
|
10
|
-
include MigrationHelpers
|
|
11
|
-
|
|
12
|
-
MSG = 'Do not use `add_timestamps`, use `add_timestamps_with_timezone` instead'.freeze
|
|
13
|
-
|
|
14
|
-
# Check methods.
|
|
15
|
-
def on_send(node)
|
|
16
|
-
return unless in_migration?(node)
|
|
17
|
-
|
|
18
|
-
add_offense(node, :selector) if method_name(node) == :add_timestamps
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def method_name(node)
|
|
22
|
-
node.children[1]
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
require_relative '../../migration_helpers'
|
|
2
|
-
|
|
3
|
-
module Gitlab
|
|
4
|
-
module Styles
|
|
5
|
-
module Rubocop
|
|
6
|
-
module Cop
|
|
7
|
-
module Migration
|
|
8
|
-
# Cop that checks if datetime data type is added with timezone information.
|
|
9
|
-
class Datetime < RuboCop::Cop::Cop
|
|
10
|
-
include MigrationHelpers
|
|
11
|
-
|
|
12
|
-
MSG = 'Do not use the `datetime` data type, use `datetime_with_timezone` instead'.freeze
|
|
13
|
-
|
|
14
|
-
# Check methods in table creation.
|
|
15
|
-
def on_def(node)
|
|
16
|
-
return unless in_migration?(node)
|
|
17
|
-
|
|
18
|
-
node.each_descendant(:send) do |send_node|
|
|
19
|
-
add_offense(send_node, :selector) if method_name(send_node) == :datetime
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
# Check methods.
|
|
24
|
-
def on_send(node)
|
|
25
|
-
return unless in_migration?(node)
|
|
26
|
-
|
|
27
|
-
node.each_descendant do |descendant|
|
|
28
|
-
add_offense(node, :expression) if descendant.type == :sym && descendant.children.last == :datetime
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def method_name(node)
|
|
33
|
-
node.children[1]
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
end
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
require 'set'
|
|
2
|
-
require_relative '../../migration_helpers'
|
|
3
|
-
|
|
4
|
-
module Gitlab
|
|
5
|
-
module Styles
|
|
6
|
-
module Rubocop
|
|
7
|
-
module Cop
|
|
8
|
-
module Migration
|
|
9
|
-
# Cop that prevents the use of hash indexes in database migrations
|
|
10
|
-
class HashIndex < RuboCop::Cop::Cop
|
|
11
|
-
include MigrationHelpers
|
|
12
|
-
|
|
13
|
-
MSG = 'hash indexes should be avoided at all costs since they are not ' \
|
|
14
|
-
'recorded in the PostgreSQL WAL, you should use a btree index instead'.freeze
|
|
15
|
-
|
|
16
|
-
NAMES = Set.new([:add_index, :index, :add_concurrent_index]).freeze
|
|
17
|
-
|
|
18
|
-
def on_send(node)
|
|
19
|
-
return unless in_migration?(node)
|
|
20
|
-
|
|
21
|
-
name = node.children[1]
|
|
22
|
-
|
|
23
|
-
return unless NAMES.include?(name)
|
|
24
|
-
|
|
25
|
-
opts = node.children.last
|
|
26
|
-
|
|
27
|
-
return unless opts&.type == :hash
|
|
28
|
-
|
|
29
|
-
opts.each_node(:pair) do |pair|
|
|
30
|
-
next unless hash_key_type(pair) == :sym &&
|
|
31
|
-
hash_key_name(pair) == :using
|
|
32
|
-
|
|
33
|
-
if hash_key_value(pair).to_s == 'hash'
|
|
34
|
-
add_offense(pair, :expression)
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def hash_key_type(pair)
|
|
40
|
-
pair.children[0].type
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def hash_key_name(pair)
|
|
44
|
-
pair.children[0].children[0]
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def hash_key_value(pair)
|
|
48
|
-
pair.children[1].children[0]
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
end
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
require_relative '../../migration_helpers'
|
|
2
|
-
|
|
3
|
-
module Gitlab
|
|
4
|
-
module Styles
|
|
5
|
-
module Rubocop
|
|
6
|
-
module Cop
|
|
7
|
-
module Migration
|
|
8
|
-
# Cop that checks if `remove_concurrent_index` is used with `up`/`down` methods
|
|
9
|
-
# and not `change`.
|
|
10
|
-
class RemoveConcurrentIndex < RuboCop::Cop::Cop
|
|
11
|
-
include MigrationHelpers
|
|
12
|
-
|
|
13
|
-
MSG = '`remove_concurrent_index` is not reversible so you must manually define ' \
|
|
14
|
-
'the `up` and `down` methods in your migration class, using `add_concurrent_index` in `down`'.freeze
|
|
15
|
-
|
|
16
|
-
def on_send(node)
|
|
17
|
-
return unless in_migration?(node)
|
|
18
|
-
return unless node.children[1] == :remove_concurrent_index
|
|
19
|
-
|
|
20
|
-
node.each_ancestor(:def) do |def_node|
|
|
21
|
-
add_offense(def_node, :name) if method_name(def_node) == :change
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def method_name(node)
|
|
26
|
-
node.children[0]
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
end
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
require_relative '../../migration_helpers'
|
|
2
|
-
|
|
3
|
-
module Gitlab
|
|
4
|
-
module Styles
|
|
5
|
-
module Rubocop
|
|
6
|
-
module Cop
|
|
7
|
-
module Migration
|
|
8
|
-
# Cop that checks if indexes are removed in a concurrent manner.
|
|
9
|
-
class RemoveIndex < RuboCop::Cop::Cop
|
|
10
|
-
include MigrationHelpers
|
|
11
|
-
|
|
12
|
-
MSG = '`remove_index` requires downtime, use `remove_concurrent_index` instead'.freeze
|
|
13
|
-
|
|
14
|
-
def on_def(node)
|
|
15
|
-
return unless in_migration?(node)
|
|
16
|
-
|
|
17
|
-
node.each_descendant(:send) do |send_node|
|
|
18
|
-
add_offense(send_node, :selector) if method_name(send_node) == :remove_index
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def method_name(node)
|
|
23
|
-
node.children[1]
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
end
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
require_relative '../../migration_helpers'
|
|
2
|
-
|
|
3
|
-
module Gitlab
|
|
4
|
-
module Styles
|
|
5
|
-
module Rubocop
|
|
6
|
-
module Cop
|
|
7
|
-
module Migration
|
|
8
|
-
# Cop that checks if `add_column_with_default` is used with `up`/`down` methods
|
|
9
|
-
# and not `change`.
|
|
10
|
-
class ReversibleAddColumnWithDefault < RuboCop::Cop::Cop
|
|
11
|
-
include MigrationHelpers
|
|
12
|
-
|
|
13
|
-
def_node_matcher :add_column_with_default?, <<~PATTERN
|
|
14
|
-
(send nil :add_column_with_default $...)
|
|
15
|
-
PATTERN
|
|
16
|
-
|
|
17
|
-
def_node_matcher :defines_change?, <<~PATTERN
|
|
18
|
-
(def :change ...)
|
|
19
|
-
PATTERN
|
|
20
|
-
|
|
21
|
-
MSG = '`add_column_with_default` is not reversible so you must manually define ' \
|
|
22
|
-
'the `up` and `down` methods in your migration class, using `remove_column` in `down`'.freeze
|
|
23
|
-
|
|
24
|
-
def on_send(node)
|
|
25
|
-
return unless in_migration?(node)
|
|
26
|
-
return unless add_column_with_default?(node)
|
|
27
|
-
|
|
28
|
-
node.each_ancestor(:def) do |def_node|
|
|
29
|
-
next unless defines_change?(def_node)
|
|
30
|
-
|
|
31
|
-
add_offense(def_node, :name)
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
end
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
require_relative '../../migration_helpers'
|
|
2
|
-
|
|
3
|
-
module Gitlab
|
|
4
|
-
module Styles
|
|
5
|
-
module Rubocop
|
|
6
|
-
module Cop
|
|
7
|
-
module Migration
|
|
8
|
-
# This cop requires a default value and disallows nulls for boolean
|
|
9
|
-
# columns on small tables.
|
|
10
|
-
#
|
|
11
|
-
# In general, this prevents 3-state-booleans.
|
|
12
|
-
# https://robots.thoughtbot.com/avoid-the-threestate-boolean-problem
|
|
13
|
-
#
|
|
14
|
-
# In particular, for the `application_settings` table, this ensures that
|
|
15
|
-
# upgraded installations get a proper default for the new boolean setting.
|
|
16
|
-
# A developer might otherwise mistakenly assume that a value in
|
|
17
|
-
# `ApplicationSetting.defaults` is sufficient.
|
|
18
|
-
#
|
|
19
|
-
# See https://gitlab.com/gitlab-org/gitlab-ee/issues/2750 for more
|
|
20
|
-
# information.
|
|
21
|
-
class SaferBooleanColumn < RuboCop::Cop::Cop
|
|
22
|
-
include MigrationHelpers
|
|
23
|
-
|
|
24
|
-
DEFAULT_OFFENSE = 'Boolean columns on the `%s` table should have a default. You may wish to use `add_column_with_default`.'.freeze
|
|
25
|
-
NULL_OFFENSE = 'Boolean columns on the `%s` table should disallow nulls.'.freeze
|
|
26
|
-
DEFAULT_AND_NULL_OFFENSE = 'Boolean columns on the `%s` table should have a default and should disallow nulls. You may wish to use `add_column_with_default`.'.freeze
|
|
27
|
-
|
|
28
|
-
SMALL_TABLES = %i[
|
|
29
|
-
application_settings
|
|
30
|
-
].freeze
|
|
31
|
-
|
|
32
|
-
def_node_matcher :add_column?, <<~PATTERN
|
|
33
|
-
(send nil :add_column $...)
|
|
34
|
-
PATTERN
|
|
35
|
-
|
|
36
|
-
def on_send(node)
|
|
37
|
-
return unless in_migration?(node)
|
|
38
|
-
|
|
39
|
-
matched = add_column?(node)
|
|
40
|
-
|
|
41
|
-
return unless matched
|
|
42
|
-
|
|
43
|
-
table, _, type = matched.to_a.take(3).map(&:children).map(&:first)
|
|
44
|
-
opts = matched[3]
|
|
45
|
-
|
|
46
|
-
return unless SMALL_TABLES.include?(table) && type == :boolean
|
|
47
|
-
|
|
48
|
-
no_default = no_default?(opts)
|
|
49
|
-
nulls_allowed = nulls_allowed?(opts)
|
|
50
|
-
|
|
51
|
-
offense = if no_default && nulls_allowed
|
|
52
|
-
DEFAULT_AND_NULL_OFFENSE
|
|
53
|
-
elsif no_default
|
|
54
|
-
DEFAULT_OFFENSE
|
|
55
|
-
elsif nulls_allowed
|
|
56
|
-
NULL_OFFENSE
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
add_offense(node, :expression, format(offense, table)) if offense
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def no_default?(opts)
|
|
63
|
-
return true unless opts
|
|
64
|
-
|
|
65
|
-
each_hash_node_pair(opts) do |key, value|
|
|
66
|
-
return value == 'nil' if key == :default
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
def nulls_allowed?(opts)
|
|
71
|
-
return true unless opts
|
|
72
|
-
|
|
73
|
-
each_hash_node_pair(opts) do |key, value|
|
|
74
|
-
return value != 'false' if key == :null
|
|
75
|
-
end
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
def each_hash_node_pair(hash_node, &block)
|
|
79
|
-
hash_node.each_node(:pair) do |pair|
|
|
80
|
-
key = hash_pair_key(pair)
|
|
81
|
-
value = hash_pair_value(pair)
|
|
82
|
-
yield(key, value)
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
def hash_pair_key(pair)
|
|
87
|
-
pair.children[0].children[0]
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
def hash_pair_value(pair)
|
|
91
|
-
pair.children[1].source
|
|
92
|
-
end
|
|
93
|
-
end
|
|
94
|
-
end
|
|
95
|
-
end
|
|
96
|
-
end
|
|
97
|
-
end
|
|
98
|
-
end
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
require_relative '../../migration_helpers'
|
|
2
|
-
|
|
3
|
-
module Gitlab
|
|
4
|
-
module Styles
|
|
5
|
-
module Rubocop
|
|
6
|
-
module Cop
|
|
7
|
-
module Migration
|
|
8
|
-
# Cop that checks if 'timestamps' method is called with timezone information.
|
|
9
|
-
class Timestamps < RuboCop::Cop::Cop
|
|
10
|
-
include MigrationHelpers
|
|
11
|
-
|
|
12
|
-
MSG = 'Do not use `timestamps`, use `timestamps_with_timezone` instead'.freeze
|
|
13
|
-
|
|
14
|
-
# Check methods in table creation.
|
|
15
|
-
def on_def(node)
|
|
16
|
-
return unless in_migration?(node)
|
|
17
|
-
|
|
18
|
-
node.each_descendant(:send) do |send_node|
|
|
19
|
-
add_offense(send_node, :selector) if method_name(send_node) == :timestamps
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def method_name(node)
|
|
24
|
-
node.children[1]
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
require_relative '../../migration_helpers'
|
|
2
|
-
|
|
3
|
-
module Gitlab
|
|
4
|
-
module Styles
|
|
5
|
-
module Rubocop
|
|
6
|
-
module Cop
|
|
7
|
-
module Migration
|
|
8
|
-
# Cop that checks if a spec file exists for any migration using
|
|
9
|
-
# `update_column_in_batches`.
|
|
10
|
-
class UpdateColumnInBatches < RuboCop::Cop::Cop
|
|
11
|
-
include MigrationHelpers
|
|
12
|
-
|
|
13
|
-
MSG = 'Migration running `update_column_in_batches` must have a spec file at' \
|
|
14
|
-
' `%s`.'.freeze
|
|
15
|
-
|
|
16
|
-
def on_send(node)
|
|
17
|
-
return unless in_migration?(node)
|
|
18
|
-
return unless node.children[1] == :update_column_in_batches
|
|
19
|
-
|
|
20
|
-
spec_path = spec_filename(node)
|
|
21
|
-
|
|
22
|
-
add_offense(node, :expression, format(MSG, spec_path)) unless File.exist?(File.expand_path(spec_path, rails_root))
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
private
|
|
26
|
-
|
|
27
|
-
def spec_filename(node)
|
|
28
|
-
source_name = node.location.expression.source_buffer.name
|
|
29
|
-
path = Pathname.new(source_name).relative_path_from(rails_root)
|
|
30
|
-
dirname = File.dirname(path)
|
|
31
|
-
.sub(%r{\Adb/(migrate|post_migrate)}, 'spec/migrations')
|
|
32
|
-
filename = File.basename(source_name, '.rb').sub(/\A\d+_/, '')
|
|
33
|
-
|
|
34
|
-
File.join(dirname, "#{filename}_spec.rb")
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
def rails_root
|
|
38
|
-
Pathname.new(File.expand_path('../../..', __dir__))
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
end
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
module Gitlab
|
|
2
|
-
module Styles
|
|
3
|
-
module Rubocop
|
|
4
|
-
module Cop
|
|
5
|
-
class ProjectPathHelper < RuboCop::Cop::Cop
|
|
6
|
-
MSG = 'Use short project path helpers without explicitly passing the namespace: ' \
|
|
7
|
-
'`foo_project_bar_path(project, bar)` instead of ' \
|
|
8
|
-
'`foo_namespace_project_bar_path(project.namespace, project, bar)`.'.freeze
|
|
9
|
-
|
|
10
|
-
METHOD_NAME_PATTERN = /\A([a-z_]+_)?namespace_project(?:_[a-z_]+)?_(?:url|path)\z/
|
|
11
|
-
|
|
12
|
-
def on_send(node)
|
|
13
|
-
return unless method_name(node).to_s =~ METHOD_NAME_PATTERN
|
|
14
|
-
|
|
15
|
-
namespace_expr, project_expr = arguments(node)
|
|
16
|
-
return unless namespace_expr && project_expr
|
|
17
|
-
|
|
18
|
-
return unless namespace_expr.type == :send
|
|
19
|
-
return unless method_name(namespace_expr) == :namespace
|
|
20
|
-
return unless receiver(namespace_expr) == project_expr
|
|
21
|
-
|
|
22
|
-
add_offense(node, :selector)
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def autocorrect(node)
|
|
26
|
-
helper_name = method_name(node).to_s.sub('namespace_project', 'project')
|
|
27
|
-
|
|
28
|
-
arguments = arguments(node)
|
|
29
|
-
arguments.shift # Remove namespace argument
|
|
30
|
-
|
|
31
|
-
replacement = "#{helper_name}(#{arguments.map(&:source).join(', ')})"
|
|
32
|
-
|
|
33
|
-
lambda do |corrector|
|
|
34
|
-
corrector.replace(node.source_range, replacement)
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
private
|
|
39
|
-
|
|
40
|
-
def receiver(node)
|
|
41
|
-
node.children[0]
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def method_name(node)
|
|
45
|
-
node.children[1]
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def arguments(node)
|
|
49
|
-
node.children[2..-1]
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
end
|