Skip to content

Commit fa3eab4

Browse files
IzzetteThomas Hareau
andauthored
Ruby 3.0 in support matrix (#43)
* Ruby 3.0 in support matrix * Support interoperability betwen ruby 2.x and 3.x * Using ruby2_keywords Co-authored-by: Thomas Hareau <[email protected]>
1 parent b49cd47 commit fa3eab4

11 files changed

+84
-46
lines changed

.github/workflows/continuous-integration-workflow.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ jobs:
4141
strategy:
4242
matrix:
4343
postgres: [ 9.6, 11.7 ]
44-
ruby: [ 2.5, 2.6, 2.7 ]
44+
ruby: [ 2.5, 2.6, 2.7, 3.0 ]
4545
services:
4646
postgres:
4747
image: postgres:${{ matrix.postgres }}

Gemfile.lock

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ PATH
44
safe-pg-migrations (1.2.3)
55
activerecord (>= 5.2)
66
activesupport (>= 5.2)
7+
ruby2_keywords (>= 0.0.4)
78

89
GEM
910
remote: https://rubygems.org/
@@ -53,6 +54,7 @@ GEM
5354
ruby-progressbar (~> 1.7)
5455
unicode-display_width (~> 1.0, >= 1.0.1)
5556
ruby-progressbar (1.10.0)
57+
ruby2_keywords (0.0.4)
5658
tzinfo (2.0.4)
5759
concurrent-ruby (~> 1.0)
5860
unicode-display_width (1.4.0)

lib/safe-pg-migrations/base.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# frozen_string_literal: true
22

3+
require 'ruby2_keywords'
34
require 'safe-pg-migrations/configuration'
45
require 'safe-pg-migrations/plugins/verbose_sql_logger'
56
require 'safe-pg-migrations/plugins/blocking_activity_logger'
@@ -50,13 +51,13 @@ def close_alternate_connection
5051
@alternate_connection = nil
5152
end
5253

53-
def say(*args)
54+
ruby2_keywords def say(*args)
5455
return unless current_migration
5556

5657
current_migration.say(*args)
5758
end
5859

59-
def say_method_call(method, *args)
60+
ruby2_keywords def say_method_call(method, *args)
6061
say "#{method}(#{args.map(&:inspect) * ', '})", true
6162
end
6263

@@ -91,6 +92,7 @@ def disable_ddl_transaction
9192

9293
safety_assured { super(*args) }
9394
end
95+
ruby2_keywords method
9496
end
9597
end
9698
end

lib/safe-pg-migrations/plugins/blocking_activity_logger.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ module BlockingActivityLogger
2121
define_method method do |*args, &block|
2222
log_blocking_queries { super(*args, &block) }
2323
end
24+
ruby2_keywords method
2425
end
2526

2627
private

lib/safe-pg-migrations/plugins/idem_potent_statements.rb

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22

33
module SafePgMigrations
44
module IdemPotentStatements
5-
def add_index(table_name, column_name, **options)
5+
ruby2_keywords def add_index(table_name, column_name, *args)
6+
options = args.last.is_a?(Hash) ? args.last : {}
67
index_name = options.key?(:name) ? options[:name].to_s : index_name(table_name, index_column_names(column_name))
78
return super unless index_name_exists?(table_name, index_name)
89

@@ -12,49 +13,52 @@ def add_index(table_name, column_name, **options)
1213
super
1314
end
1415

15-
def add_column(table_name, column_name, type, options = {})
16+
ruby2_keywords def add_column(table_name, column_name, type, *)
1617
return super unless column_exists?(table_name, column_name)
1718

1819
SafePgMigrations.say("/!\\ Column '#{column_name}' already exists in '#{table_name}'. Skipping statement.", true)
1920
end
2021

21-
def remove_column(table_name, column_name, type = nil, options = {})
22+
ruby2_keywords def remove_column(table_name, column_name, type = nil, *)
2223
return super if column_exists?(table_name, column_name)
2324

2425
SafePgMigrations.say("/!\\ Column '#{column_name}' not found on table '#{table_name}'. Skipping statement.", true)
2526
end
2627

27-
def remove_index(table_name, options = {})
28+
ruby2_keywords def remove_index(table_name, *args)
29+
options = args.last.is_a?(Hash) ? args.last : {}
2830
index_name = options.key?(:name) ? options[:name].to_s : index_name(table_name, options)
2931

3032
return super if index_name_exists?(table_name, index_name)
3133

3234
SafePgMigrations.say("/!\\ Index '#{index_name}' not found on table '#{table_name}'. Skipping statement.", true)
3335
end
3436

35-
def add_foreign_key(from_table, to_table, **options)
36-
options_or_to_table = options.slice(:name, :column).presence || to_table
37-
return super unless foreign_key_exists?(from_table, options_or_to_table)
37+
ruby2_keywords def add_foreign_key(from_table, to_table, *args)
38+
options = args.last.is_a?(Hash) ? args.last : {}
39+
suboptions = options.slice(:name, :column)
40+
return super unless foreign_key_exists?(from_table, suboptions.present? ? nil : to_table, **suboptions)
3841

3942
SafePgMigrations.say(
4043
"/!\\ Foreign key '#{from_table}' -> '#{to_table}' already exists. Skipping statement.",
4144
true
4245
)
4346
end
4447

45-
def create_table(table_name, comment: nil, **options)
48+
ruby2_keywords def create_table(table_name, *args)
49+
options = args.last.is_a?(Hash) ? args.last : {}
4650
return super if options[:force] || !table_exists?(table_name)
4751

4852
SafePgMigrations.say "/!\\ Table '#{table_name}' already exists.", true
4953

50-
td = create_table_definition(table_name, **options)
54+
td = create_table_definition(table_name, *args)
5155

5256
yield td if block_given?
5357

5458
SafePgMigrations.say(td.indexes.empty? ? '-- Skipping statement' : '-- Creating indexes', true)
5559

5660
td.indexes.each do |column_name, index_options|
57-
add_index(table_name, column_name, index_options)
61+
add_index(table_name, column_name, **index_options)
5862
end
5963
end
6064

lib/safe-pg-migrations/plugins/statement_insurer.rb

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
# frozen_string_literal: true
22

33
module SafePgMigrations
4-
module StatementInsurer
4+
module StatementInsurer # rubocop:disable Metrics/ModuleLength
55
PG_11_VERSION_NUM = 110_000
66

77
%i[change_column_null change_column].each do |method|
88
define_method method do |*args, &block|
99
with_setting(:statement_timeout, SafePgMigrations.config.pg_safe_timeout) { super(*args, &block) }
1010
end
11+
ruby2_keywords method
1112
end
1213

13-
def add_column(table_name, column_name, type, **options)
14+
ruby2_keywords def add_column(table_name, column_name, type, *args) # rubocop:disable Metrics/CyclomaticComplexity
15+
options = args.last.is_a?(Hash) ? args.last : {}
1416
return super if SafePgMigrations.pg_version_num >= PG_11_VERSION_NUM
1517

1618
default = options.delete(:default)
@@ -36,17 +38,21 @@ def add_column(table_name, column_name, type, **options)
3638
end
3739
end
3840

39-
def add_foreign_key(from_table, to_table, **options)
41+
ruby2_keywords def add_foreign_key(from_table, to_table, *args)
42+
options = args.last.is_a?(Hash) ? args.last : {}
4043
validate_present = options.key? :validate
4144
options[:validate] = false unless validate_present
45+
with_setting(:statement_timeout, SafePgMigrations.config.pg_safe_timeout) do
46+
super(from_table, to_table, **options)
47+
end
4248

43-
with_setting(:statement_timeout, SafePgMigrations.config.pg_safe_timeout) { super }
49+
return if validate_present
4450

45-
options_or_to_table = options.slice(:name, :column).presence || to_table
46-
without_statement_timeout { validate_foreign_key from_table, options_or_to_table } unless validate_present
51+
suboptions = options.slice(:name, :column)
52+
without_statement_timeout { validate_foreign_key from_table, suboptions.present? ? nil : to_table, **suboptions }
4753
end
4854

49-
def create_table(*)
55+
ruby2_keywords def create_table(*)
5056
with_setting(:statement_timeout, SafePgMigrations.config.pg_safe_timeout) do
5157
super do |td|
5258
yield td if block_given?
@@ -65,17 +71,17 @@ def add_index(table_name, column_name, **options)
6571
options[:algorithm] = :concurrently
6672
end
6773

68-
SafePgMigrations.say_method_call(:add_index, table_name, column_name, options)
74+
SafePgMigrations.say_method_call(:add_index, table_name, column_name, **options)
6975

70-
without_timeout { super }
76+
without_timeout { super(table_name, column_name, **options) }
7177
end
7278

73-
def remove_index(table_name, options = {})
74-
options = { column: options } unless options.is_a?(Hash)
75-
options[:algorithm] = :concurrently
76-
SafePgMigrations.say_method_call(:remove_index, table_name, options)
79+
ruby2_keywords def remove_index(table_name, *args)
80+
options = args.last.is_a?(Hash) ? args.last : { column: args.last }
81+
options[:algorithm] = :concurrently unless options.key?(:algorithm)
82+
SafePgMigrations.say_method_call(:remove_index, table_name, **options)
7783

78-
without_timeout { super }
84+
without_timeout { super(table_name, **options) }
7985
end
8086

8187
def backfill_column_default(table_name, column_name)

lib/safe-pg-migrations/plugins/statement_retrier.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ module StatementRetrier
1010
define_method method do |*args, &block|
1111
retry_if_lock_timeout { super(*args, &block) }
1212
end
13+
ruby2_keywords method
1314
end
1415

1516
private

lib/safe-pg-migrations/plugins/useless_statements_logger.rb

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,27 @@
22

33
module SafePgMigrations
44
module UselessStatementsLogger
5-
def self.warn_useless(action, link = nil, *args)
6-
SafePgMigrations.say "/!\\ No need to explicitly use #{action}, safe-pg-migrations does it for you", *args
7-
SafePgMigrations.say "\t see #{link} for more details", *args if link
5+
class << self
6+
ruby2_keywords def warn_useless(action, link = nil, *args)
7+
SafePgMigrations.say "/!\\ No need to explicitly use #{action}, safe-pg-migrations does it for you", *args
8+
SafePgMigrations.say "\t see #{link} for more details", *args if link
9+
end
810
end
911

10-
def add_index(*, **options)
12+
ruby2_keywords def add_index(*args)
13+
options = args.last.is_a?(Hash) ? args.last : {}
1114
warn_for_index(**options)
1215
super
1316
end
1417

15-
def remove_index(table_name, options = {})
16-
warn_for_index(options) if options.is_a? Hash
18+
ruby2_keywords def remove_index(table_name, *args)
19+
options = args.last.is_a?(Hash) ? args.last : {}
20+
warn_for_index(**options) unless options.empty?
1721
super
1822
end
1923

20-
def add_foreign_key(*, **options)
24+
ruby2_keywords def add_foreign_key(*args)
25+
options = args.last.is_a?(Hash) ? args.last : {}
2126
if options[:validate] == false
2227
UselessStatementsLogger.warn_useless '`validate: :false`', 'https://github.com/doctolib/safe-pg-migrations#safe_add_foreign_key'
2328
end

safe-pg-migrations.gemspec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ Gem::Specification.new do |s|
2424

2525
s.add_dependency 'activerecord', '>= 5.2'
2626
s.add_dependency 'activesupport', '>= 5.2'
27+
s.add_dependency 'ruby2_keywords', '>= 0.0.4'
2728

2829
s.add_development_dependency 'bundler'
2930
s.add_development_dependency 'minitest'

test/safe_pg_migrations_test.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ def test_statement_retry
7373
' -> Statement was being blocked by the following query:',
7474
' -> ',
7575
], calls[0..4]
76-
assert_match(/\s*-> transaction started 1 second ago:\s*BEGIN; SELECT 1 FROM users/, calls[5])
76+
assert_match(/\s*-> transaction started \d+ seconds? ago:\s*BEGIN; SELECT 1 FROM users/, calls[5])
7777
assert_equal [
7878
' -> ',
7979
' -> Retrying in 1 seconds...',

0 commit comments

Comments
 (0)