diff --git a/.gitignore b/.gitignore index 30cb231e83f1c598336dd4cfa06f74cb3226cecb..93fb0b1144b5301bf1d1471b8c097282687e9820 100644 --- a/.gitignore +++ b/.gitignore @@ -77,6 +77,7 @@ eslint-report.html /.gitlab_kas_secret /webpack-report/ /crystalball/ +/deprecations/ /knapsack/ /rspec_flaky/ /locale/**/LC_MESSAGES diff --git a/.gitlab/ci/rails.gitlab-ci.yml b/.gitlab/ci/rails.gitlab-ci.yml index 0ec875864411db4c8fcb123012c66b5c401fcf5a..3962be8d84d9edd830103bfae31e12a78f784a5b 100644 --- a/.gitlab/ci/rails.gitlab-ci.yml +++ b/.gitlab/ci/rails.gitlab-ci.yml @@ -21,7 +21,7 @@ RUBY_GC_MALLOC_LIMIT: 67108864 RUBY_GC_MALLOC_LIMIT_MAX: 134217728 CRYSTALBALL: "true" - RECORD_KEYWORD_WARNINGS: "true" + RECORD_DEPRECATIONS: "true" needs: ["setup-test-env", "retrieve-tests-metadata", "compile-test-assets"] script: - *base-script @@ -32,13 +32,13 @@ paths: - coverage/ - crystalball/ + - deprecations/ - knapsack/ - rspec_flaky/ - rspec_profiling/ - tmp/capybara/ - tmp/memory_test/ - tmp/feature_flags/ - - tmp/keyword_warn.txt - log/*.log reports: junit: junit_rspec.xml diff --git a/Gemfile b/Gemfile index 5829328bd47a7b6c09ce98126b26145a6cee07d3..63a13c50373254272a62f45a2b6e83bda9b7a33b 100644 --- a/Gemfile +++ b/Gemfile @@ -351,7 +351,7 @@ group :development do end group :development, :test do - gem 'warning', '~> 1.1', require: false + gem 'deprecation_toolkit', '~> 1.5.1', require: false gem 'bullet', '~> 6.1.0' gem 'pry-byebug', '~> 3.9.0', platform: :mri gem 'pry-rails', '~> 0.3.9' diff --git a/Gemfile.lock b/Gemfile.lock index 285befad21914cb81b451a82e0b1f1680be56831..f5d7c409c0cfcaa240aa40769eec8eee5102757c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -224,6 +224,8 @@ GEM declarative-option (0.1.0) default_value_for (3.3.0) activerecord (>= 3.2.0, < 6.1) + deprecation_toolkit (1.5.1) + activesupport (>= 4.2) derailed_benchmarks (1.7.0) benchmark-ips (~> 2) get_process_mem (~> 0) @@ -1222,7 +1224,6 @@ GEM vmstat (2.3.0) warden (1.2.8) rack (>= 2.0.6) - warning (1.1.0) webauthn (2.3.0) android_key_attestation (~> 0.3.0) awrence (~> 1.1) @@ -1303,6 +1304,7 @@ DEPENDENCIES database_cleaner (~> 1.7.0) deckar01-task_list (= 2.3.1) default_value_for (~> 3.3.0) + deprecation_toolkit (~> 1.5.1) derailed_benchmarks device_detector devise (~> 4.7.2) @@ -1519,7 +1521,6 @@ DEPENDENCIES validates_hostname (~> 1.0.10) version_sorter (~> 2.2.4) vmstat (~> 2.3.0) - warning (~> 1.1) webauthn (~> 2.3) webmock (~> 3.9.1) wikicloth (= 0.8.1) diff --git a/rubocop/cop/lint/last_keyword_argument.rb b/rubocop/cop/lint/last_keyword_argument.rb index d437395b8c2a4e82218c00d9fa784cb42a8a88c7..d8f8d03b5529edb2affb60d9430cc6e457b1e015 100644 --- a/rubocop/cop/lint/last_keyword_argument.rb +++ b/rubocop/cop/lint/last_keyword_argument.rb @@ -3,9 +3,18 @@ module RuboCop module Cop module Lint + # This cop only works if there are files from deprecation_toolkit. You can + # generate these files by: + # + # 1. Running specs with RECORD_DEPRECATIONS=1 + # 1. Downloading the complete set of deprecations/ files from a CI + # pipeline (see https://gitlab.com/gitlab-org/gitlab/-/merge_requests/47720) class LastKeywordArgument < Cop MSG = 'Using the last argument as keyword parameters is deprecated'.freeze + DEPRECATIONS_GLOB = File.expand_path('../../../deprecations/**/*.yml', __dir__) + KEYWORD_DEPRECATION_STR = 'maybe ** should be added to the call' + def on_send(node) arg = node.arguments.last return unless arg @@ -48,13 +57,11 @@ def self.keyword_warnings end def self.keywords_list - return [] unless File.exist?(keywords_file_path) - - File.read(keywords_file_path).split("----\n") - end + hash = Dir.glob(DEPRECATIONS_GLOB).each_with_object({}) do |file, hash| + hash.merge!(YAML.safe_load(File.read(file))) + end - def self.keywords_file_path - File.expand_path('../../../tmp/keyword_warn.txt', __dir__) + hash.values.flatten.select { |str| str.include?(KEYWORD_DEPRECATION_STR) }.uniq end end end diff --git a/spec/deprecation_toolkit_env.rb b/spec/deprecation_toolkit_env.rb new file mode 100644 index 0000000000000000000000000000000000000000..bc90f67f0db88b94b737314e9ecc037a7f0bf31f --- /dev/null +++ b/spec/deprecation_toolkit_env.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +if ENV.key?('RECORD_DEPRECATIONS') + require 'deprecation_toolkit' + require 'deprecation_toolkit/rspec' + DeprecationToolkit::Configuration.test_runner = :rspec + DeprecationToolkit::Configuration.deprecation_path = 'deprecations' + DeprecationToolkit::Configuration.behavior = DeprecationToolkit::Behaviors::Record + + # Enable ruby deprecations for keywords, it's suppressed by default in Ruby 2.7.2 + Warning[:deprecated] = true + + kwargs_warnings = [ + # Taken from https://github.com/jeremyevans/ruby-warning/blob/1.1.0/lib/warning.rb#L18 + %r{warning: (?:Using the last argument (?:for `.+' )?as keyword parameters is deprecated; maybe \*\* should be added to the call|Passing the keyword argument (?:for `.+' )?as the last hash parameter is deprecated|Splitting the last argument (?:for `.+' )?into positional and keyword parameters is deprecated|The called method (?:`.+' )?is defined here)\n\z} + ] + DeprecationToolkit::Configuration.warnings_treated_as_deprecation = kwargs_warnings +end diff --git a/spec/rubocop/cop/lint/last_keyword_argument_spec.rb b/spec/rubocop/cop/lint/last_keyword_argument_spec.rb index ae1b442e9b54b00bfc39f6b6e9117c3053e63b61..f942390569bf6615657cb2f363e8b8bc1124383a 100644 --- a/spec/rubocop/cop/lint/last_keyword_argument_spec.rb +++ b/spec/rubocop/cop/lint/last_keyword_argument_spec.rb @@ -13,8 +13,9 @@ described_class.instance_variable_set(:@keyword_warnings, nil) end - context 'file does not exist' do + context 'deprecation files does not exist' do before do + allow(Dir).to receive(:glob).and_return([]) allow(File).to receive(:exist?).and_return(false) end @@ -25,18 +26,37 @@ end end - context 'file does exist' do + context 'deprecation files does exist' do + let(:create_spec_yaml) do + <<~YAML + --- + test_mutations/boards/lists/create#resolve_with_proper_permissions_backlog_list_creates_one_and_only_one_backlog: + - | + DEPRECATION WARNING: /Users/tkuah/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/batch-loader-1.4.0/lib/batch_loader/graphql.rb:38: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call + /Users/tkuah/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/batch-loader-1.4.0/lib/batch_loader.rb:26: warning: The called method `batch' is defined here + test_mutations/boards/lists/create#ready?_raises_an_error_if_required_arguments_are_missing: + - | + DEPRECATION WARNING: /Users/tkuah/code/ee-gdk/gitlab/create_service.rb:1: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call + /Users/tkuah/code/ee-gdk/gitlab/user.rb:17: warning: The called method `call' is defined here + YAML + end + + let(:projects_spec_yaml) do + <<~YAML + --- + test_api/projects_get_/projects_when_unauthenticated_behaves_like_projects_response_returns_an_array_of_projects: + - | + DEPRECATION WARNING: /Users/tkuah/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/state_machines-activerecord-0.6.0/lib/state_machines/integrations/active_record.rb:511: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call + /Users/tkuah/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/activerecord-6.0.3.3/lib/active_record/suppressor.rb:43: warning: The called method `save' is defined here + - | + DEPRECATION WARNING: /Users/tkuah/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/rack-2.2.3/lib/rack/builder.rb:158: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call + /Users/tkuah/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/grape-1.4.0/lib/grape/middleware/error.rb:30: warning: The called method `initialize' is defined here + YAML + end + before do - allow(File).to receive(:exist?).and_return(true) - - allow(File).to receive(:read).and_return(<<~DATA) ----- -create_service.rb:1: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call -user.rb:17: warning: The called method `call' is defined here ----- -/Users/tkuah/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/batch-loader-1.4.0/lib/batch_loader/graphql.rb:38: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call -/Users/tkuah/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/batch-loader-1.4.0/lib/batch_loader.rb:26: warning: The called method `batch' is defined here - DATA + allow(Dir).to receive(:glob).and_return(['deprecations/service/create_spec.yml', 'deprecations/api/projects_spec.yml']) + allow(File).to receive(:read).and_return(create_spec_yaml, projects_spec_yaml) end it 'registers an offense' do diff --git a/spec/ruby_keyword_warning.rb b/spec/ruby_keyword_warning.rb deleted file mode 100644 index 5b53fcd9c769dc1811ac18d14512c9292a6ded1e..0000000000000000000000000000000000000000 --- a/spec/ruby_keyword_warning.rb +++ /dev/null @@ -1,33 +0,0 @@ -# frozen_string_literal: true - -if ENV['RECORD_KEYWORD_WARNINGS'] - require 'warning' - - Warning[:deprecated] = true - - # The warnings are emitted with two calls of Warning.warn. - # In an attempt to group these two calls we use the `----` separator. - - keyword_regex = /: warning: (?:Using the last argument (?:for `.+' )?as keyword parameters is deprecated; maybe \*\* should be added to the call)\n\z/ - method_called_regex = /: warning: (?:The called method (?:`.+' )?is defined here)\n\z/ - actions = { - keyword_regex => proc do |warning| - File.open(File.expand_path('../tmp/keyword_warn.txt', __dir__), "a") do |file| - file.write("----\n") - file.write(warning) - - # keep ruby behaviour of warning in stderr - $stderr.puts(warning) # rubocop:disable Style/StderrPuts - end - end, - method_called_regex => proc do |warning| - File.open(File.expand_path('../tmp/keyword_warn.txt', __dir__), "a") do |file| - file.write(warning) - - # keep ruby behaviour of warning in stderr - $stderr.puts(warning) # rubocop:disable Style/StderrPuts - end - end - } - Warning.process('', actions) -end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index b391551ecc15b78280ddbe864fa61e7ef3330324..49775940584bf0a22f403aaf03befe252d464bae 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -8,7 +8,7 @@ abort 'Aborting...' end -require './spec/ruby_keyword_warning' +require './spec/deprecation_toolkit_env' require './spec/simplecov_env' SimpleCovEnv.start!