From e23bac547111f56a6257a3acb9ec9c915ceb3b24 Mon Sep 17 00:00:00 2001
From: Konstantin Ilchenko <konstantin@ilchenko.by>
Date: Wed, 3 Apr 2024 02:18:10 +0200
Subject: [PATCH] FIX: kwargs patching (#313)

Amends method profiler patching to use Ruby 3.0 patterns and enforces Ruby 3.0 and up.
---
 .rubocop                                                 | 1 +
 .rubocop.yml                                             | 9 ++++++++-
 README.md                                                | 4 ++--
 gemfiles/ar_70.gemfile                                   | 2 ++
 .../instrumentation/method_profiler.rb                   | 8 ++++----
 prometheus_exporter.gemspec                              | 4 ++--
 test/instrumentation/method_profiler_test.rb             | 4 ++--
 7 files changed, 21 insertions(+), 11 deletions(-)
 create mode 100644 .rubocop

diff --git a/.rubocop b/.rubocop
new file mode 100644
index 00000000..fc40e8e2
--- /dev/null
+++ b/.rubocop
@@ -0,0 +1 @@
+--ignore-unrecognized-cops
diff --git a/.rubocop.yml b/.rubocop.yml
index 3f1b32d7..17c7f883 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -4,4 +4,11 @@ inherit_gem:
 AllCops:
   Exclude:
     - 'gemfiles/**/*'
-    - 'vendor/**/*'
\ No newline at end of file
+    - 'vendor/**/*'
+
+Discourse/Plugins/NoMonkeyPatching:
+  Enabled: false
+
+Discourse/Plugins/NamespaceMethods:
+  Exclude:
+    - bin/prometheus_exporter
diff --git a/README.md b/README.md
index 73b42cf6..d20e53d3 100644
--- a/README.md
+++ b/README.md
@@ -40,7 +40,7 @@ To learn more see [Instrumenting Rails with Prometheus](https://samsaffron.com/a
 
 ## Requirements
 
-Minimum Ruby of version 2.6.0 is required, Ruby 2.5.0 is EOL as of March 31st 2021.
+Minimum Ruby of version 3.0.0 is required, Ruby 2.7 is EOL as of March 31st 2023.
 
 ## Migrating from v0.x
 
@@ -884,7 +884,7 @@ prometheus_exporter -p 8080 \
                     --prefix 'foo_'
 ```
 
-You can use `-b` option to bind the `prometheus_exporter` web server to any IPv4 interface with `-b 0.0.0.0`, 
+You can use `-b` option to bind the `prometheus_exporter` web server to any IPv4 interface with `-b 0.0.0.0`,
 any IPv6 interface with `-b ::`, or `-b ANY` to any IPv4/IPv6 interfaces available on your host system.
 
 #### Enabling Basic Authentication
diff --git a/gemfiles/ar_70.gemfile b/gemfiles/ar_70.gemfile
index 095e6608..bc1dfc9c 100644
--- a/gemfiles/ar_70.gemfile
+++ b/gemfiles/ar_70.gemfile
@@ -2,4 +2,6 @@
 
 source "https://rubygems.org"
 
+gem "activerecord", "~> 7.0.0"
+
 gemspec path: "../"
diff --git a/lib/prometheus_exporter/instrumentation/method_profiler.rb b/lib/prometheus_exporter/instrumentation/method_profiler.rb
index f1658df4..045a77f9 100644
--- a/lib/prometheus_exporter/instrumentation/method_profiler.rb
+++ b/lib/prometheus_exporter/instrumentation/method_profiler.rb
@@ -44,7 +44,7 @@ def self.define_methods_on_module(klass, methods, name)
     patch_source_line = __LINE__ + 3
     patches = methods.map do |method_name|
       <<~RUBY
-        def #{method_name}(*args, &blk)
+        def #{method_name}(...)
           unless prof = Thread.current[:_method_profiler]
             return super
           end
@@ -75,13 +75,13 @@ def self.patch_using_alias_method(klass, methods, name)
       <<~RUBY
       unless defined?(#{method_name}__mp_unpatched)
         alias_method :#{method_name}__mp_unpatched, :#{method_name}
-        def #{method_name}(*args, &blk)
+        def #{method_name}(...)
           unless prof = Thread.current[:_method_profiler]
-            return #{method_name}__mp_unpatched(*args, &blk)
+            return #{method_name}__mp_unpatched(...)
           end
           begin
             start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
-            #{method_name}__mp_unpatched(*args, &blk)
+            #{method_name}__mp_unpatched(...)
           ensure
             data = (prof[:#{name}] ||= {duration: 0.0, calls: 0})
             data[:duration] += Process.clock_gettime(Process::CLOCK_MONOTONIC) - start
diff --git a/prometheus_exporter.gemspec b/prometheus_exporter.gemspec
index de1fa497..dffec661 100644
--- a/prometheus_exporter.gemspec
+++ b/prometheus_exporter.gemspec
@@ -34,7 +34,7 @@ Gem::Specification.new do |spec|
   spec.add_development_dependency "oj", "~> 3.0"
   spec.add_development_dependency "rack-test", "~> 0.8.3"
   spec.add_development_dependency "minitest-stub-const", "~> 0.6"
-  spec.add_development_dependency "rubocop-discourse", ">2"
+  spec.add_development_dependency "rubocop-discourse", ">= 3"
   spec.add_development_dependency "appraisal", "~> 2.3"
   spec.add_development_dependency "activerecord", "~> 6.0.0"
   spec.add_development_dependency "redis", "> 5"
@@ -42,5 +42,5 @@ Gem::Specification.new do |spec|
   if !RUBY_ENGINE == 'jruby'
     spec.add_development_dependency "raindrops", "~> 0.19"
   end
-  spec.required_ruby_version = '>= 2.6.0'
+  spec.required_ruby_version = '>= 3.0.0'
 end
diff --git a/test/instrumentation/method_profiler_test.rb b/test/instrumentation/method_profiler_test.rb
index 64026b24..d57c5e62 100644
--- a/test/instrumentation/method_profiler_test.rb
+++ b/test/instrumentation/method_profiler_test.rb
@@ -22,7 +22,7 @@ def some_method
   def test_alias_method_source_location
     file, line = SomeClassPatchedUsingAliasMethod.instance_method(:some_method).source_location
     source = File.read(file).lines[line - 1].strip
-    assert_equal 'def #{method_name}(*args, &blk)', source
+    assert_equal 'def #{method_name}(...)', source
   end
 
   def test_alias_method_preserves_behavior
@@ -32,7 +32,7 @@ def test_alias_method_preserves_behavior
   def test_prepend_source_location
     file, line = SomeClassPatchedUsingPrepend.instance_method(:some_method).source_location
     source = File.read(file).lines[line - 1].strip
-    assert_equal 'def #{method_name}(*args, &blk)', source
+    assert_equal 'def #{method_name}(...)', source
   end
 
   def test_prepend_preserves_behavior