From a6bc6074d6a4ad0ee50c58aeff2b2ec3b3479e97 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Wed, 20 Jul 2022 11:20:45 +0900 Subject: [PATCH] Make `Lint/DeprecatedClassMethods` aware of `ENV.clone` and `ENV.dup` Follow up https://github.com/ruby/ruby/pull/4557. This PR makes `Lint/DeprecatedClassMethods` aware of `ENV.clone` and `ENV.dup`. This update is based on the following behaviors: ```console % ruby -v ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-darwin19] % ruby -we 'ENV.clone' -e:1: warning: ENV.clone is deprecated; use ENV.to_h instead % ruby -e 'ENV.dup' -e:1:in `dup': Cannot dup ENV, use ENV.to_h to get a copy of ENV as a hash (TypeError) from -e:1:in `
' ``` --- ...lass_methods_aware_of_env_clone_and_dup.md | 1 + .../cop/lint/deprecated_class_methods.rb | 14 +++++--- .../cop/lint/deprecated_class_methods_spec.rb | 34 +++++++++++++++++++ 3 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 changelog/fix_make_lint_deprecated_class_methods_aware_of_env_clone_and_dup.md diff --git a/changelog/fix_make_lint_deprecated_class_methods_aware_of_env_clone_and_dup.md b/changelog/fix_make_lint_deprecated_class_methods_aware_of_env_clone_and_dup.md new file mode 100644 index 00000000000..e9514059b64 --- /dev/null +++ b/changelog/fix_make_lint_deprecated_class_methods_aware_of_env_clone_and_dup.md @@ -0,0 +1 @@ +* [#10824](https://github.com/rubocop/rubocop/pull/10824): Make `Lint/DeprecatedClassMethods` aware of `ENV.clone` and `ENV.dup`. ([@koic][]) diff --git a/lib/rubocop/cop/lint/deprecated_class_methods.rb b/lib/rubocop/cop/lint/deprecated_class_methods.rb index 4b48bc06bbd..e87c11df60f 100644 --- a/lib/rubocop/cop/lint/deprecated_class_methods.rb +++ b/lib/rubocop/cop/lint/deprecated_class_methods.rb @@ -8,22 +8,22 @@ module Lint # @example # # # bad - # # File.exists?(some_path) # Dir.exists?(some_path) # iterator? # ENV.freeze # Calling `Env.freeze` raises `TypeError` since Ruby 2.7. + # ENV.clone + # ENV.dup # Calling `Env.dup` raises `TypeError` since Ruby 3.1. # Socket.gethostbyname(host) # Socket.gethostbyaddr(host) # - # @example - # # # good - # # File.exist?(some_path) # Dir.exist?(some_path) # block_given? # ENV # `ENV.freeze` cannot prohibit changes to environment variables. + # ENV.to_h + # ENV.to_h # `ENV.dup` cannot dup `ENV`, use `ENV.to_h` to get a copy of `ENV` as a hash. # Addrinfo.getaddrinfo(nodename, service) # Addrinfo.tcp(host, port).getnameinfo class DeprecatedClassMethods < Base @@ -111,6 +111,12 @@ def instance_method? DeprecatedClassMethod.new(:freeze, class_constant: :ENV) => Replacement.new(nil, class_constant: :ENV), + DeprecatedClassMethod.new(:clone, class_constant: :ENV) => + Replacement.new(:to_h, class_constant: :ENV), + + DeprecatedClassMethod.new(:dup, class_constant: :ENV) => + Replacement.new(:to_h, class_constant: :ENV), + DeprecatedClassMethod.new(:gethostbyaddr, class_constant: :Socket, correctable: false) => Replacement.new(:getnameinfo, class_constant: :Addrinfo, instance_method: true), diff --git a/spec/rubocop/cop/lint/deprecated_class_methods_spec.rb b/spec/rubocop/cop/lint/deprecated_class_methods_spec.rb index 654b8471eff..fe8621823b8 100644 --- a/spec/rubocop/cop/lint/deprecated_class_methods_spec.rb +++ b/spec/rubocop/cop/lint/deprecated_class_methods_spec.rb @@ -99,6 +99,40 @@ end end + context 'when using `ENV.clone`' do + it 'registers an offense' do + expect_offense(<<~RUBY) + ENV.clone + ^^^^^ `ENV.clone` is deprecated in favor of `ENV.to_h`. + RUBY + + expect_correction(<<~RUBY) + ENV.to_h + RUBY + end + + it 'does not register an offense for method calls to `ENV` other than `clone`' do + expect_no_offenses('ENV.values') + end + end + + context 'when using `ENV.dup`' do + it 'registers an offense' do + expect_offense(<<~RUBY) + ENV.dup + ^^^ `ENV.dup` is deprecated in favor of `ENV.to_h`. + RUBY + + expect_correction(<<~RUBY) + ENV.to_h + RUBY + end + + it 'does not register an offense for method calls to `ENV` other than `dup`' do + expect_no_offenses('ENV.values') + end + end + context 'prefer `Addrinfo#getnameinfo` over `Socket.gethostbyaddr`' do it 'registers an offense for Socket.gethostbyaddr' do expect_offense(<<~RUBY)