gitlab-styles 4.2.0 → 5.3.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/.editorconfig +18 -0
 - data/.gitlab-ci.yml +5 -16
 - data/.gitlab/merge_request_templates/New Static Analysis Check.md +21 -0
 - data/.gitlab/merge_request_templates/Release.md +4 -4
 - data/.rubocop.yml +3 -1
 - data/Gemfile +2 -2
 - data/gitlab-styles.gemspec +6 -5
 - data/lib/gitlab/styles/rubocop.rb +3 -14
 - data/lib/gitlab/styles/rubocop/cop/active_record_dependent.rb +1 -1
 - data/lib/gitlab/styles/rubocop/cop/code_reuse/active_record.rb +131 -0
 - data/lib/gitlab/styles/rubocop/cop/custom_error_class.rb +6 -3
 - data/lib/gitlab/styles/rubocop/cop/gem_fetcher.rb +1 -1
 - data/lib/gitlab/styles/rubocop/cop/line_break_after_guard_clauses.rb +1 -1
 - data/lib/gitlab/styles/rubocop/cop/line_break_around_conditional_block.rb +132 -0
 - data/lib/gitlab/styles/rubocop/cop/migration/update_large_table.rb +1 -1
 - data/lib/gitlab/styles/rubocop/cop/polymorphic_associations.rb +1 -1
 - data/lib/gitlab/styles/rubocop/cop/rspec/base.rb +18 -0
 - data/lib/gitlab/styles/rubocop/cop/rspec/empty_line_after_let_block.rb +65 -0
 - data/lib/gitlab/styles/rubocop/cop/rspec/empty_line_after_shared_example.rb +6 -6
 - data/lib/gitlab/styles/rubocop/cop/rspec/example_starting_character.rb +124 -0
 - data/lib/gitlab/styles/rubocop/cop/rspec/have_link_parameters.rb +10 -5
 - data/lib/gitlab/styles/rubocop/cop/rspec/single_line_hook.rb +3 -2
 - data/lib/gitlab/styles/rubocop/cop/rspec/verbose_include_metadata.rb +10 -13
 - data/lib/gitlab/styles/rubocop/model_helpers.rb +1 -1
 - data/lib/gitlab/styles/rubocop/rspec/helpers.rb +17 -0
 - data/lib/gitlab/styles/version.rb +1 -1
 - data/rubocop-all.yml +1 -0
 - data/rubocop-bundler.yml +1 -0
 - data/rubocop-code_reuse.yml +24 -0
 - data/rubocop-default.yml +1 -0
 - data/rubocop-gemspec.yml +1 -0
 - data/rubocop-layout.yml +6 -0
 - data/rubocop-lint.yml +63 -5
 - data/rubocop-metrics.yml +1 -0
 - data/rubocop-migrations.yml +1 -0
 - data/rubocop-naming.yml +1 -0
 - data/rubocop-performance.yml +48 -0
 - data/rubocop-rails.yml +79 -0
 - data/rubocop-rspec.yml +10 -0
 - data/rubocop-security.yml +1 -0
 - data/rubocop-style.yml +91 -1
 - metadata +23 -15
 - data/.rubocop_todo.yml +0 -7
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 53b2719f9b6600bdfd8b362ad363f86f35dbae708f8ebd41f1ef2e2429d4c4f0
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: f480238835c2218118ea34ac3ebf2869e2386e500304530fd08a112701175845
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: f5d87f035504e911546c7aaaaad23bac44035f65848d0a3c74cf284bdddd4e8f460c6da7e4766ee9465f75051d38d5e1d3c4b674bc910ce320204e356a9f3622
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: b97be714bb886604639de5d788284b0c8af1b081ce279c8a5fdf6dafff9b2aeee83060576f0ce0322bb49168ccdc58a4abafd0de13442425d705523d9d6a6a5d
         
     | 
    
        data/.editorconfig
    ADDED
    
    | 
         @@ -0,0 +1,18 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # top-most EditorConfig file
         
     | 
| 
      
 2 
     | 
    
         
            +
            root = true
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            # Unix-style newlines with a newline ending every file
         
     | 
| 
      
 5 
     | 
    
         
            +
            [*]
         
     | 
| 
      
 6 
     | 
    
         
            +
            end_of_line = lf
         
     | 
| 
      
 7 
     | 
    
         
            +
            trim_trailing_whitespace = true
         
     | 
| 
      
 8 
     | 
    
         
            +
            insert_final_newline = true
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            [*.{rb,yml}]
         
     | 
| 
      
 11 
     | 
    
         
            +
            indent_size = 2
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            [*.{rb,yml,md}]
         
     | 
| 
      
 14 
     | 
    
         
            +
            indent_style = space
         
     | 
| 
      
 15 
     | 
    
         
            +
            charset = utf-8
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            [*.{md,markdown}]
         
     | 
| 
      
 18 
     | 
    
         
            +
            trim_trailing_whitespace = false
         
     | 
    
        data/.gitlab-ci.yml
    CHANGED
    
    | 
         @@ -1,9 +1,9 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            stages:
         
     | 
| 
       2 
     | 
    
         
            -
              - release
         
     | 
| 
       3 
2 
     | 
    
         
             
              - test
         
     | 
| 
      
 3 
     | 
    
         
            +
              - deploy
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
       5 
5 
     | 
    
         
             
            default:
         
     | 
| 
       6 
     | 
    
         
            -
              image: ruby:2. 
     | 
| 
      
 6 
     | 
    
         
            +
              image: ruby:2.7
         
     | 
| 
       7 
7 
     | 
    
         
             
              tags:
         
     | 
| 
       8 
8 
     | 
    
         
             
                - gitlab-org
         
     | 
| 
       9 
9 
     | 
    
         
             
              before_script:
         
     | 
| 
         @@ -29,17 +29,6 @@ specs: 
     | 
|
| 
       29 
29 
     | 
    
         
             
              script:
         
     | 
| 
       30 
30 
     | 
    
         
             
                - bundle exec rspec
         
     | 
| 
       31 
31 
     | 
    
         | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
               
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
                - if: '$CI_COMMIT_TAG'
         
     | 
| 
       36 
     | 
    
         
            -
              script:
         
     | 
| 
       37 
     | 
    
         
            -
                - gem update --system
         
     | 
| 
       38 
     | 
    
         
            -
                - ruby --version
         
     | 
| 
       39 
     | 
    
         
            -
                - gem env version
         
     | 
| 
       40 
     | 
    
         
            -
                - gem build gitlab-styles.gemspec
         
     | 
| 
       41 
     | 
    
         
            -
                - gem push gitlab-styles*.gem
         
     | 
| 
       42 
     | 
    
         
            -
              artifacts:
         
     | 
| 
       43 
     | 
    
         
            -
                paths:
         
     | 
| 
       44 
     | 
    
         
            -
                  - gitlab-styles*.gem
         
     | 
| 
       45 
     | 
    
         
            -
                expire_in: 30 days
         
     | 
| 
      
 32 
     | 
    
         
            +
            include:
         
     | 
| 
      
 33 
     | 
    
         
            +
              - project: 'gitlab-org/quality/pipeline-common'
         
     | 
| 
      
 34 
     | 
    
         
            +
                file: '/ci/gem-release.yml'
         
     | 
| 
         @@ -0,0 +1,21 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ## Description of the proposal
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            <!--
         
     | 
| 
      
 4 
     | 
    
         
            +
            Please describe the proposal and add a link to the source (for example, http://www.betterspecs.org/).
         
     | 
| 
      
 5 
     | 
    
         
            +
            -->
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            ### Check-list
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            - [ ] Mention this proposal in the relevant Slack channels (e.g. `#development`, `#backend`, `#frontend`)
         
     | 
| 
      
 10 
     | 
    
         
            +
            - [ ] If there is a choice to make between two potential styles, set up an emoji vote in the MR:
         
     | 
| 
      
 11 
     | 
    
         
            +
              - CHOICE_A: :a:
         
     | 
| 
      
 12 
     | 
    
         
            +
              - CHOICE_B: :b:
         
     | 
| 
      
 13 
     | 
    
         
            +
              - Vote yourself for both choices so that people know these are the choices
         
     | 
| 
      
 14 
     | 
    
         
            +
            - [ ] The MR doesn't have significant objections, and is getting a majority of :+1: vs :-1: (remember that [we don't need to reach a consensus](https://about.gitlab.com/handbook/values/#collaboration-is-not-consensus))
         
     | 
| 
      
 15 
     | 
    
         
            +
            - [ ] (If applicable) One style is getting a majority of vote (compared to the other choice)
         
     | 
| 
      
 16 
     | 
    
         
            +
            - [ ] (If applicable) Update the MR with the chosen style
         
     | 
| 
      
 17 
     | 
    
         
            +
            - [ ] Follow the [review process](https://docs.gitlab.com/ee/development/code_review.html) as usual
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            /label ~"Engineering Productivity" ~"development guidelines" ~"static code analysis"
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            /cc @gitlab-org/maintainers/rails-backend
         
     | 
| 
         @@ -7,7 +7,7 @@ with the latest commit from https://gitlab.com/gitlab-org/gitlab-styles/commits/ 
     | 
|
| 
       7 
7 
     | 
    
         
             
            <!-- Keep the sections order but remove the empty sections -->
         
     | 
| 
       8 
8 
     | 
    
         | 
| 
       9 
9 
     | 
    
         
             
            ```markdown
         
     | 
| 
       10 
     | 
    
         
            -
            ### New  
     | 
| 
      
 10 
     | 
    
         
            +
            ### New features and features updates
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
       12 
12 
     | 
    
         
             
            - !aaa <Title of the aaa MR>.
         
     | 
| 
       13 
13 
     | 
    
         | 
| 
         @@ -19,7 +19,7 @@ with the latest commit from https://gitlab.com/gitlab-org/gitlab-styles/commits/ 
     | 
|
| 
       19 
19 
     | 
    
         | 
| 
       20 
20 
     | 
    
         
             
            - !ccc <Title of the ccc MR>.
         
     | 
| 
       21 
21 
     | 
    
         | 
| 
       22 
     | 
    
         
            -
            ### Other changes ( 
     | 
| 
      
 22 
     | 
    
         
            +
            ### Other changes (tooling, technical debt)
         
     | 
| 
       23 
23 
     | 
    
         | 
| 
       24 
24 
     | 
    
         
             
            - !ddd <Title of the ddd MR>.
         
     | 
| 
       25 
25 
     | 
    
         
             
            ```
         
     | 
| 
         @@ -30,6 +30,6 @@ with the latest commit from https://gitlab.com/gitlab-org/gitlab-styles/commits/ 
     | 
|
| 
       30 
30 
     | 
    
         
             
              - [ ] Release notes are accurate.
         
     | 
| 
       31 
31 
     | 
    
         | 
| 
       32 
32 
     | 
    
         
             
            - Checklist after merging:
         
     | 
| 
       33 
     | 
    
         
            -
              - [ ] [ 
     | 
| 
      
 33 
     | 
    
         
            +
              - [ ] [Update the release notes for the newly created tag](docs/release_process.md#how-to).
         
     | 
| 
       34 
34 
     | 
    
         | 
| 
       35 
     | 
    
         
            -
            /label ~"Engineering Productivity" ~ 
     | 
| 
      
 35 
     | 
    
         
            +
            /label ~"Engineering Productivity" ~"feature" ~"feature::maintenance" ~"static code analysis"
         
     | 
    
        data/.rubocop.yml
    CHANGED
    
    
    
        data/Gemfile
    CHANGED
    
    | 
         @@ -7,7 +7,7 @@ gemspec 
     | 
|
| 
       7 
7 
     | 
    
         | 
| 
       8 
8 
     | 
    
         
             
            group :test do
         
     | 
| 
       9 
9 
     | 
    
         
             
              # Pin these dependencies, otherwise a new rule could break the CI pipelines
         
     | 
| 
       10 
     | 
    
         
            -
              gem 'rubocop', '0. 
     | 
| 
       11 
     | 
    
         
            -
              gem 'rubocop-rspec', '1. 
     | 
| 
      
 10 
     | 
    
         
            +
              gem 'rubocop', '0.89.1'
         
     | 
| 
      
 11 
     | 
    
         
            +
              gem 'rubocop-rspec', '1.44.1'
         
     | 
| 
       12 
12 
     | 
    
         
             
              gem 'rspec-parameterized', '0.4.2', require: false
         
     | 
| 
       13 
13 
     | 
    
         
             
            end
         
     | 
    
        data/gitlab-styles.gemspec
    CHANGED
    
    | 
         @@ -5,6 +5,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 
     | 
|
| 
       5 
5 
     | 
    
         
             
            require 'gitlab/styles/version'
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
7 
     | 
    
         
             
            Gem::Specification.new do |spec|
         
     | 
| 
      
 8 
     | 
    
         
            +
              spec.required_ruby_version = '>= 2.6'
         
     | 
| 
       8 
9 
     | 
    
         
             
              spec.name          = 'gitlab-styles'
         
     | 
| 
       9 
10 
     | 
    
         
             
              spec.version       = Gitlab::Styles::VERSION
         
     | 
| 
       10 
11 
     | 
    
         
             
              spec.authors       = ['GitLab']
         
     | 
| 
         @@ -21,13 +22,13 @@ Gem::Specification.new do |spec| 
     | 
|
| 
       21 
22 
     | 
    
         
             
              spec.executables   = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
         
     | 
| 
       22 
23 
     | 
    
         
             
              spec.require_paths = ['lib']
         
     | 
| 
       23 
24 
     | 
    
         | 
| 
       24 
     | 
    
         
            -
              spec.add_dependency 'rubocop', '~> 0. 
     | 
| 
      
 25 
     | 
    
         
            +
              spec.add_dependency 'rubocop', '~> 0.89.1'
         
     | 
| 
       25 
26 
     | 
    
         
             
              spec.add_dependency 'rubocop-gitlab-security', '~> 0.1.0'
         
     | 
| 
       26 
     | 
    
         
            -
              spec.add_dependency 'rubocop-performance', '~> 1. 
     | 
| 
       27 
     | 
    
         
            -
              spec.add_dependency 'rubocop-rails', '~> 2. 
     | 
| 
       28 
     | 
    
         
            -
              spec.add_dependency 'rubocop-rspec', '~> 1. 
     | 
| 
      
 27 
     | 
    
         
            +
              spec.add_dependency 'rubocop-performance', '~> 1.8.1'
         
     | 
| 
      
 28 
     | 
    
         
            +
              spec.add_dependency 'rubocop-rails', '~> 2.8'
         
     | 
| 
      
 29 
     | 
    
         
            +
              spec.add_dependency 'rubocop-rspec', '~> 1.44'
         
     | 
| 
       29 
30 
     | 
    
         | 
| 
       30 
     | 
    
         
            -
              spec.add_development_dependency 'bundler', '~> 1 
     | 
| 
      
 31 
     | 
    
         
            +
              spec.add_development_dependency 'bundler', '~> 2.1'
         
     | 
| 
       31 
32 
     | 
    
         
             
              spec.add_development_dependency 'rake', '~> 10.0'
         
     | 
| 
       32 
33 
     | 
    
         
             
              spec.add_development_dependency 'rspec', '~> 3.0'
         
     | 
| 
       33 
34 
     | 
    
         
             
            end
         
     | 
| 
         @@ -1,19 +1,8 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
            require  
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
            require 
     | 
| 
       6 
     | 
    
         
            -
            require 'gitlab/styles/rubocop/cop/redirect_with_status'
         
     | 
| 
       7 
     | 
    
         
            -
            require 'gitlab/styles/rubocop/cop/polymorphic_associations'
         
     | 
| 
       8 
     | 
    
         
            -
            require 'gitlab/styles/rubocop/cop/active_record_dependent'
         
     | 
| 
       9 
     | 
    
         
            -
            require 'gitlab/styles/rubocop/cop/in_batches'
         
     | 
| 
       10 
     | 
    
         
            -
            require 'gitlab/styles/rubocop/cop/line_break_after_guard_clauses'
         
     | 
| 
       11 
     | 
    
         
            -
            require 'gitlab/styles/rubocop/cop/migration/update_large_table'
         
     | 
| 
       12 
     | 
    
         
            -
            require 'gitlab/styles/rubocop/cop/without_reactive_cache'
         
     | 
| 
       13 
     | 
    
         
            -
            require 'gitlab/styles/rubocop/cop/rspec/single_line_hook'
         
     | 
| 
       14 
     | 
    
         
            -
            require 'gitlab/styles/rubocop/cop/rspec/have_link_parameters'
         
     | 
| 
       15 
     | 
    
         
            -
            require 'gitlab/styles/rubocop/cop/rspec/verbose_include_metadata'
         
     | 
| 
       16 
     | 
    
         
            -
            require 'gitlab/styles/rubocop/cop/rspec/empty_line_after_shared_example'
         
     | 
| 
      
 3 
     | 
    
         
            +
            # Auto-require all cops under `gitlab/styles/rubocop/cop/**/*.rb`
         
     | 
| 
      
 4 
     | 
    
         
            +
            cops_glob = File.join(__dir__, 'rubocop', 'cop', '**', '*.rb')
         
     | 
| 
      
 5 
     | 
    
         
            +
            Dir[cops_glob].sort.each(&method(:require))
         
     | 
| 
       17 
6 
     | 
    
         | 
| 
       18 
7 
     | 
    
         
             
            module Gitlab
         
     | 
| 
       19 
8 
     | 
    
         
             
              module Styles
         
     | 
| 
         @@ -0,0 +1,131 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Gitlab
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Styles
         
     | 
| 
      
 5 
     | 
    
         
            +
                module Rubocop
         
     | 
| 
      
 6 
     | 
    
         
            +
                  module Cop
         
     | 
| 
      
 7 
     | 
    
         
            +
                    module CodeReuse
         
     | 
| 
      
 8 
     | 
    
         
            +
                      # Cop that denies the use of ActiveRecord methods outside of models.
         
     | 
| 
      
 9 
     | 
    
         
            +
                      class ActiveRecord < RuboCop::Cop::Cop
         
     | 
| 
      
 10 
     | 
    
         
            +
                        MSG = 'This method can only be used inside an ActiveRecord model: ' \
         
     | 
| 
      
 11 
     | 
    
         
            +
                    'https://gitlab.com/gitlab-org/gitlab-foss/issues/49653'
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                        # Various methods from ActiveRecord::Querying that are denied. We
         
     | 
| 
      
 14 
     | 
    
         
            +
                        # exclude some generic ones such as `any?` and `first`, as these may
         
     | 
| 
      
 15 
     | 
    
         
            +
                        # lead to too many false positives, since `Array` also supports these
         
     | 
| 
      
 16 
     | 
    
         
            +
                        # methods.
         
     | 
| 
      
 17 
     | 
    
         
            +
                        #
         
     | 
| 
      
 18 
     | 
    
         
            +
                        # The keys of this Hash are the denied method names. The values are
         
     | 
| 
      
 19 
     | 
    
         
            +
                        # booleans that indicate if the method should only be denied if any
         
     | 
| 
      
 20 
     | 
    
         
            +
                        # arguments are provided.
         
     | 
| 
      
 21 
     | 
    
         
            +
                        NOT_ALLOWED = {
         
     | 
| 
      
 22 
     | 
    
         
            +
                          average: true,
         
     | 
| 
      
 23 
     | 
    
         
            +
                          calculate: true,
         
     | 
| 
      
 24 
     | 
    
         
            +
                          count_by_sql: true,
         
     | 
| 
      
 25 
     | 
    
         
            +
                          create_with: true,
         
     | 
| 
      
 26 
     | 
    
         
            +
                          distinct: false,
         
     | 
| 
      
 27 
     | 
    
         
            +
                          eager_load: true,
         
     | 
| 
      
 28 
     | 
    
         
            +
                          exists?: true,
         
     | 
| 
      
 29 
     | 
    
         
            +
                          find_by: true,
         
     | 
| 
      
 30 
     | 
    
         
            +
                          find_by!: true,
         
     | 
| 
      
 31 
     | 
    
         
            +
                          find_by_sql: true,
         
     | 
| 
      
 32 
     | 
    
         
            +
                          find_each: true,
         
     | 
| 
      
 33 
     | 
    
         
            +
                          find_in_batches: true,
         
     | 
| 
      
 34 
     | 
    
         
            +
                          find_or_create_by: true,
         
     | 
| 
      
 35 
     | 
    
         
            +
                          find_or_create_by!: true,
         
     | 
| 
      
 36 
     | 
    
         
            +
                          find_or_initialize_by: true,
         
     | 
| 
      
 37 
     | 
    
         
            +
                          first!: false,
         
     | 
| 
      
 38 
     | 
    
         
            +
                          first_or_create: true,
         
     | 
| 
      
 39 
     | 
    
         
            +
                          first_or_create!: true,
         
     | 
| 
      
 40 
     | 
    
         
            +
                          first_or_initialize: true,
         
     | 
| 
      
 41 
     | 
    
         
            +
                          from: true,
         
     | 
| 
      
 42 
     | 
    
         
            +
                          group: true,
         
     | 
| 
      
 43 
     | 
    
         
            +
                          having: true,
         
     | 
| 
      
 44 
     | 
    
         
            +
                          ids: false,
         
     | 
| 
      
 45 
     | 
    
         
            +
                          includes: true,
         
     | 
| 
      
 46 
     | 
    
         
            +
                          joins: true,
         
     | 
| 
      
 47 
     | 
    
         
            +
                          limit: true,
         
     | 
| 
      
 48 
     | 
    
         
            +
                          lock: false,
         
     | 
| 
      
 49 
     | 
    
         
            +
                          many?: false,
         
     | 
| 
      
 50 
     | 
    
         
            +
                          offset: true,
         
     | 
| 
      
 51 
     | 
    
         
            +
                          order: true,
         
     | 
| 
      
 52 
     | 
    
         
            +
                          pluck: true,
         
     | 
| 
      
 53 
     | 
    
         
            +
                          preload: true,
         
     | 
| 
      
 54 
     | 
    
         
            +
                          readonly: false,
         
     | 
| 
      
 55 
     | 
    
         
            +
                          references: true,
         
     | 
| 
      
 56 
     | 
    
         
            +
                          reorder: true,
         
     | 
| 
      
 57 
     | 
    
         
            +
                          rewhere: true,
         
     | 
| 
      
 58 
     | 
    
         
            +
                          take: false,
         
     | 
| 
      
 59 
     | 
    
         
            +
                          take!: false,
         
     | 
| 
      
 60 
     | 
    
         
            +
                          unscope: false,
         
     | 
| 
      
 61 
     | 
    
         
            +
                          where: false,
         
     | 
| 
      
 62 
     | 
    
         
            +
                          with: true
         
     | 
| 
      
 63 
     | 
    
         
            +
                        }.freeze
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                        def on_send(node)
         
     | 
| 
      
 66 
     | 
    
         
            +
                          receiver = node.children[0]
         
     | 
| 
      
 67 
     | 
    
         
            +
                          send_name = node.children[1]
         
     | 
| 
      
 68 
     | 
    
         
            +
                          first_arg = node.children[2]
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                          return unless receiver && NOT_ALLOWED.key?(send_name)
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                          # If the rule requires an argument to be given, but none are
         
     | 
| 
      
 73 
     | 
    
         
            +
                          # provided, we won't register an offense. This prevents us from
         
     | 
| 
      
 74 
     | 
    
         
            +
                          # adding offenses for `project.group`, while still covering
         
     | 
| 
      
 75 
     | 
    
         
            +
                          # `Project.group(:name)`.
         
     | 
| 
      
 76 
     | 
    
         
            +
                          return if NOT_ALLOWED[send_name] && !first_arg
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
                          add_offense(node, location: :selector)
         
     | 
| 
      
 79 
     | 
    
         
            +
                        end
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                        # We can not auto correct code like this, as it requires manual
         
     | 
| 
      
 82 
     | 
    
         
            +
                        # refactoring. Instead, we'll just allow the surrounding scope.
         
     | 
| 
      
 83 
     | 
    
         
            +
                        #
         
     | 
| 
      
 84 
     | 
    
         
            +
                        # Despite this method's presence, you should not use it. This method
         
     | 
| 
      
 85 
     | 
    
         
            +
                        # exists to make it possible to allow large chunks of offenses we
         
     | 
| 
      
 86 
     | 
    
         
            +
                        # can't fix in the short term. If you are writing new code, follow the
         
     | 
| 
      
 87 
     | 
    
         
            +
                        # code reuse guidelines, instead of allowing any new offenses.
         
     | 
| 
      
 88 
     | 
    
         
            +
                        def autocorrect(node)
         
     | 
| 
      
 89 
     | 
    
         
            +
                          scope = surrounding_scope_of(node)
         
     | 
| 
      
 90 
     | 
    
         
            +
                          indent = indentation_of(scope)
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
                          lambda do |corrector|
         
     | 
| 
      
 93 
     | 
    
         
            +
                            # This prevents us from inserting the same enable/disable comment
         
     | 
| 
      
 94 
     | 
    
         
            +
                            # for a method or block that has multiple offenses.
         
     | 
| 
      
 95 
     | 
    
         
            +
                            next if allowed_scopes.include?(scope)
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
                            corrector.insert_before(
         
     | 
| 
      
 98 
     | 
    
         
            +
                              scope.source_range,
         
     | 
| 
      
 99 
     | 
    
         
            +
                              "# rubocop: disable #{cop_name}\n#{indent}"
         
     | 
| 
      
 100 
     | 
    
         
            +
                            )
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
                            corrector.insert_after(
         
     | 
| 
      
 103 
     | 
    
         
            +
                              scope.source_range,
         
     | 
| 
      
 104 
     | 
    
         
            +
                              "\n#{indent}# rubocop: enable #{cop_name}"
         
     | 
| 
      
 105 
     | 
    
         
            +
                            )
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
                            allowed_scopes << scope
         
     | 
| 
      
 108 
     | 
    
         
            +
                          end
         
     | 
| 
      
 109 
     | 
    
         
            +
                        end
         
     | 
| 
      
 110 
     | 
    
         
            +
             
     | 
| 
      
 111 
     | 
    
         
            +
                        def indentation_of(node)
         
     | 
| 
      
 112 
     | 
    
         
            +
                          ' ' * node.loc.expression.source_line[/\A */].length
         
     | 
| 
      
 113 
     | 
    
         
            +
                        end
         
     | 
| 
      
 114 
     | 
    
         
            +
             
     | 
| 
      
 115 
     | 
    
         
            +
                        def surrounding_scope_of(node)
         
     | 
| 
      
 116 
     | 
    
         
            +
                          %i[def defs block begin].each do |type|
         
     | 
| 
      
 117 
     | 
    
         
            +
                            if (found = node.each_ancestor(type).first)
         
     | 
| 
      
 118 
     | 
    
         
            +
                              return found
         
     | 
| 
      
 119 
     | 
    
         
            +
                            end
         
     | 
| 
      
 120 
     | 
    
         
            +
                          end
         
     | 
| 
      
 121 
     | 
    
         
            +
                        end
         
     | 
| 
      
 122 
     | 
    
         
            +
             
     | 
| 
      
 123 
     | 
    
         
            +
                        def allowed_scopes
         
     | 
| 
      
 124 
     | 
    
         
            +
                          @allowed_scopes ||= Set.new
         
     | 
| 
      
 125 
     | 
    
         
            +
                        end
         
     | 
| 
      
 126 
     | 
    
         
            +
                      end
         
     | 
| 
      
 127 
     | 
    
         
            +
                    end
         
     | 
| 
      
 128 
     | 
    
         
            +
                  end
         
     | 
| 
      
 129 
     | 
    
         
            +
                end
         
     | 
| 
      
 130 
     | 
    
         
            +
              end
         
     | 
| 
      
 131 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -21,7 +21,8 @@ module Gitlab 
     | 
|
| 
       21 
21 
     | 
    
         
             
                      MSG = 'Use `Class.new(SuperClass)` to define an empty custom error class.'
         
     | 
| 
       22 
22 
     | 
    
         | 
| 
       23 
23 
     | 
    
         
             
                      def on_class(node)
         
     | 
| 
       24 
     | 
    
         
            -
                         
     | 
| 
      
 24 
     | 
    
         
            +
                        parent = node.parent_class
         
     | 
| 
      
 25 
     | 
    
         
            +
                        body = node.body
         
     | 
| 
       25 
26 
     | 
    
         | 
| 
       26 
27 
     | 
    
         
             
                        return if body
         
     | 
| 
       27 
28 
     | 
    
         | 
| 
         @@ -29,11 +30,13 @@ module Gitlab 
     | 
|
| 
       29 
30 
     | 
    
         | 
| 
       30 
31 
     | 
    
         
             
                        return unless parent_klass&.to_s&.end_with?('Error')
         
     | 
| 
       31 
32 
     | 
    
         | 
| 
       32 
     | 
    
         
            -
                        add_offense(node 
     | 
| 
      
 33 
     | 
    
         
            +
                        add_offense(node)
         
     | 
| 
       33 
34 
     | 
    
         
             
                      end
         
     | 
| 
       34 
35 
     | 
    
         | 
| 
       35 
36 
     | 
    
         
             
                      def autocorrect(node)
         
     | 
| 
       36 
     | 
    
         
            -
                        klass 
     | 
| 
      
 37 
     | 
    
         
            +
                        klass = node.identifier
         
     | 
| 
      
 38 
     | 
    
         
            +
                        parent = node.parent_class
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
       37 
40 
     | 
    
         
             
                        replacement = "#{class_name_from_node(klass)} = Class.new(#{class_name_from_node(parent)})"
         
     | 
| 
       38 
41 
     | 
    
         | 
| 
       39 
42 
     | 
    
         
             
                        lambda do |corrector|
         
     | 
| 
         @@ -20,7 +20,7 @@ module Gitlab 
     | 
|
| 
       20 
20 
     | 
    
         | 
| 
       21 
21 
     | 
    
         
             
                        node.children.last.each_node(:pair) do |pair|
         
     | 
| 
       22 
22 
     | 
    
         
             
                          key_name = pair.children[0].children[0].to_sym
         
     | 
| 
       23 
     | 
    
         
            -
                          add_offense(node, location: pair.source_range 
     | 
| 
      
 23 
     | 
    
         
            +
                          add_offense(node, location: pair.source_range) if GIT_KEYS.include?(key_name)
         
     | 
| 
       24 
24 
     | 
    
         
             
                        end
         
     | 
| 
       25 
25 
     | 
    
         
             
                      end
         
     | 
| 
       26 
26 
     | 
    
         | 
| 
         @@ -69,7 +69,7 @@ module Gitlab 
     | 
|
| 
       69 
69 
     | 
    
         
             
                        return unless guard_clause?(node)
         
     | 
| 
       70 
70 
     | 
    
         
             
                        return if next_line(node).blank? || clause_last_line?(next_line(node)) || guard_clause?(next_sibling(node))
         
     | 
| 
       71 
71 
     | 
    
         | 
| 
       72 
     | 
    
         
            -
                        add_offense(node 
     | 
| 
      
 72 
     | 
    
         
            +
                        add_offense(node)
         
     | 
| 
       73 
73 
     | 
    
         
             
                      end
         
     | 
| 
       74 
74 
     | 
    
         | 
| 
       75 
75 
     | 
    
         
             
                      def autocorrect(node)
         
     | 
| 
         @@ -0,0 +1,132 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Gitlab
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Styles
         
     | 
| 
      
 5 
     | 
    
         
            +
                module Rubocop
         
     | 
| 
      
 6 
     | 
    
         
            +
                  module Cop
         
     | 
| 
      
 7 
     | 
    
         
            +
                    # Ensures a line break around conditional blocks.
         
     | 
| 
      
 8 
     | 
    
         
            +
                    #
         
     | 
| 
      
 9 
     | 
    
         
            +
                    # @example
         
     | 
| 
      
 10 
     | 
    
         
            +
                    #    # bad
         
     | 
| 
      
 11 
     | 
    
         
            +
                    #    do_something
         
     | 
| 
      
 12 
     | 
    
         
            +
                    #    if condition
         
     | 
| 
      
 13 
     | 
    
         
            +
                    #      do_extra_stuff
         
     | 
| 
      
 14 
     | 
    
         
            +
                    #    end
         
     | 
| 
      
 15 
     | 
    
         
            +
                    #    do_something_more
         
     | 
| 
      
 16 
     | 
    
         
            +
                    #
         
     | 
| 
      
 17 
     | 
    
         
            +
                    #    # good
         
     | 
| 
      
 18 
     | 
    
         
            +
                    #    do_something
         
     | 
| 
      
 19 
     | 
    
         
            +
                    #
         
     | 
| 
      
 20 
     | 
    
         
            +
                    #    if condition
         
     | 
| 
      
 21 
     | 
    
         
            +
                    #      do_extra_stuff
         
     | 
| 
      
 22 
     | 
    
         
            +
                    #    end
         
     | 
| 
      
 23 
     | 
    
         
            +
                    #
         
     | 
| 
      
 24 
     | 
    
         
            +
                    #    do_something_more
         
     | 
| 
      
 25 
     | 
    
         
            +
                    #
         
     | 
| 
      
 26 
     | 
    
         
            +
                    #    # bad
         
     | 
| 
      
 27 
     | 
    
         
            +
                    #    do_something
         
     | 
| 
      
 28 
     | 
    
         
            +
                    #    unless condition
         
     | 
| 
      
 29 
     | 
    
         
            +
                    #      do_extra_stuff
         
     | 
| 
      
 30 
     | 
    
         
            +
                    #    end
         
     | 
| 
      
 31 
     | 
    
         
            +
                    #
         
     | 
| 
      
 32 
     | 
    
         
            +
                    #    do_something_more
         
     | 
| 
      
 33 
     | 
    
         
            +
                    #
         
     | 
| 
      
 34 
     | 
    
         
            +
                    #    # good
         
     | 
| 
      
 35 
     | 
    
         
            +
                    #    def a_method
         
     | 
| 
      
 36 
     | 
    
         
            +
                    #      if condition
         
     | 
| 
      
 37 
     | 
    
         
            +
                    #        do_something
         
     | 
| 
      
 38 
     | 
    
         
            +
                    #      end
         
     | 
| 
      
 39 
     | 
    
         
            +
                    #    end
         
     | 
| 
      
 40 
     | 
    
         
            +
                    #
         
     | 
| 
      
 41 
     | 
    
         
            +
                    #    # good
         
     | 
| 
      
 42 
     | 
    
         
            +
                    #    on_block do
         
     | 
| 
      
 43 
     | 
    
         
            +
                    #      if condition
         
     | 
| 
      
 44 
     | 
    
         
            +
                    #        do_something
         
     | 
| 
      
 45 
     | 
    
         
            +
                    #      end
         
     | 
| 
      
 46 
     | 
    
         
            +
                    #    end
         
     | 
| 
      
 47 
     | 
    
         
            +
                    class LineBreakAroundConditionalBlock < RuboCop::Cop::Cop
         
     | 
| 
      
 48 
     | 
    
         
            +
                      include RuboCop::Cop::RangeHelp
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                      MSG = 'Add a line break around conditional blocks'
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                      def on_if(node)
         
     | 
| 
      
 53 
     | 
    
         
            +
                        # This cop causes errors in haml files, so let's skip those
         
     | 
| 
      
 54 
     | 
    
         
            +
                        return if in_haml?(node)
         
     | 
| 
      
 55 
     | 
    
         
            +
                        return if node.single_line?
         
     | 
| 
      
 56 
     | 
    
         
            +
                        return unless node.if? || node.unless?
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                        add_offense(node) unless previous_line_valid?(node)
         
     | 
| 
      
 59 
     | 
    
         
            +
                        add_offense(node) unless last_line_valid?(node)
         
     | 
| 
      
 60 
     | 
    
         
            +
                      end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                      def autocorrect(node)
         
     | 
| 
      
 63 
     | 
    
         
            +
                        lambda do |corrector|
         
     | 
| 
      
 64 
     | 
    
         
            +
                          line = range_by_whole_lines(node.source_range)
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                          corrector.insert_before(line, "\n") unless previous_line_valid?(node)
         
     | 
| 
      
 67 
     | 
    
         
            +
                          corrector.insert_after(line, "\n") unless last_line_valid?(node)
         
     | 
| 
      
 68 
     | 
    
         
            +
                        end
         
     | 
| 
      
 69 
     | 
    
         
            +
                      end
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                      private
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
                      def previous_line_valid?(node)
         
     | 
| 
      
 74 
     | 
    
         
            +
                        previous_line(node).empty? ||
         
     | 
| 
      
 75 
     | 
    
         
            +
                          start_clause_line?(previous_line(node)) ||
         
     | 
| 
      
 76 
     | 
    
         
            +
                          block_start?(previous_line(node)) ||
         
     | 
| 
      
 77 
     | 
    
         
            +
                          begin_line?(previous_line(node)) ||
         
     | 
| 
      
 78 
     | 
    
         
            +
                          assignment_line?(previous_line(node)) ||
         
     | 
| 
      
 79 
     | 
    
         
            +
                          rescue_line?(previous_line(node))
         
     | 
| 
      
 80 
     | 
    
         
            +
                      end
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
                      def last_line_valid?(node)
         
     | 
| 
      
 83 
     | 
    
         
            +
                        last_line(node).empty? ||
         
     | 
| 
      
 84 
     | 
    
         
            +
                          end_line?(last_line(node)) ||
         
     | 
| 
      
 85 
     | 
    
         
            +
                          end_clause_line?(last_line(node))
         
     | 
| 
      
 86 
     | 
    
         
            +
                      end
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
                      def previous_line(node)
         
     | 
| 
      
 89 
     | 
    
         
            +
                        processed_source[node.loc.line - 2]
         
     | 
| 
      
 90 
     | 
    
         
            +
                      end
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
                      def last_line(node)
         
     | 
| 
      
 93 
     | 
    
         
            +
                        processed_source[node.loc.last_line]
         
     | 
| 
      
 94 
     | 
    
         
            +
                      end
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
                      def start_clause_line?(line)
         
     | 
| 
      
 97 
     | 
    
         
            +
                        line =~ /^\s*(def|=end|#|module|class|if|unless|else|elsif|ensure|when)/
         
     | 
| 
      
 98 
     | 
    
         
            +
                      end
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
                      def end_clause_line?(line)
         
     | 
| 
      
 101 
     | 
    
         
            +
                        line =~ /^\s*(#|rescue|else|elsif|when)/
         
     | 
| 
      
 102 
     | 
    
         
            +
                      end
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
                      def begin_line?(line)
         
     | 
| 
      
 105 
     | 
    
         
            +
                        # an assignment followed by a begin or ust a begin
         
     | 
| 
      
 106 
     | 
    
         
            +
                        line =~ /^\s*(@?(\w|\|+|=|\[|\]|\s)+begin|begin)/
         
     | 
| 
      
 107 
     | 
    
         
            +
                      end
         
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
      
 109 
     | 
    
         
            +
                      def assignment_line?(line)
         
     | 
| 
      
 110 
     | 
    
         
            +
                        line =~ /^\s*.*=/
         
     | 
| 
      
 111 
     | 
    
         
            +
                      end
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
                      def rescue_line?(line)
         
     | 
| 
      
 114 
     | 
    
         
            +
                        line =~ /^\s*rescue/
         
     | 
| 
      
 115 
     | 
    
         
            +
                      end
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
                      def block_start?(line)
         
     | 
| 
      
 118 
     | 
    
         
            +
                        line.match(/ (do|{)( \|.*?\|)?\s?(#.+)?\z/)
         
     | 
| 
      
 119 
     | 
    
         
            +
                      end
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
                      def end_line?(line)
         
     | 
| 
      
 122 
     | 
    
         
            +
                        line =~ /^\s*(end|})/
         
     | 
| 
      
 123 
     | 
    
         
            +
                      end
         
     | 
| 
      
 124 
     | 
    
         
            +
             
     | 
| 
      
 125 
     | 
    
         
            +
                      def in_haml?(node)
         
     | 
| 
      
 126 
     | 
    
         
            +
                        node.location.expression.source_buffer.name.end_with?('.haml.rb')
         
     | 
| 
      
 127 
     | 
    
         
            +
                      end
         
     | 
| 
      
 128 
     | 
    
         
            +
                    end
         
     | 
| 
      
 129 
     | 
    
         
            +
                  end
         
     | 
| 
      
 130 
     | 
    
         
            +
                end
         
     | 
| 
      
 131 
     | 
    
         
            +
              end
         
     | 
| 
      
 132 
     | 
    
         
            +
            end
         
     |