Class: RuboCop::Cop::Generator Private

Inherits:
Object
  • Object
show all
Defined in:
lib/rubocop/cop/generator.rb,
lib/rubocop/cop/generator/require_file_injector.rb,
lib/rubocop/cop/generator/configuration_injector.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

Source and spec generator for new cops

This generator will take a cop name and generate a source file and spec file when given a valid qualified cop name.

Defined Under Namespace

Classes: ConfigurationInjector, RequireFileInjector

Constant Summary collapse

SOURCE_TEMPLATE =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

<<~RUBY
  # frozen_string_literal: true

  module RuboCop
    module Cop
      module %<department>s
        # TODO: Write cop description and example of bad / good code. For every
        # `SupportedStyle` and unique configuration, there needs to be examples.
        # Examples must have valid Ruby syntax. Do not use upticks.
        #
        # @safety
        #   Delete this section if the cop is not unsafe (`Safe: false` or
        #   `SafeAutoCorrect: false`), or use it to explain how the cop is
        #   unsafe.
        #
        # @example EnforcedStyle: bar (default)
        #   # Description of the `bar` style.
        #
        #   # bad
        #   bad_bar_method
        #
        #   # bad
        #   bad_bar_method(args)
        #
        #   # good
        #   good_bar_method
        #
        #   # good
        #   good_bar_method(args)
        #
        # @example EnforcedStyle: foo
        #   # Description of the `foo` style.
        #
        #   # bad
        #   bad_foo_method
        #
        #   # bad
        #   bad_foo_method(args)
        #
        #   # good
        #   good_foo_method
        #
        #   # good
        #   good_foo_method(args)
        #
        class %<cop_name>s < Base
          # TODO: Implement the cop in here.
          #
          # In many cases, you can use a node matcher for matching node pattern.
          # See https://github.com/rubocop/rubocop-ast/blob/master/lib/rubocop/ast/node_pattern.rb
          #
          # For example
          MSG = 'Use `#good_method` instead of `#bad_method`.'

          # TODO: Don't call `on_send` unless the method name is in this list
          # If you don't need `on_send` in the cop you created, remove it.
          RESTRICT_ON_SEND = %%i[bad_method].freeze

          # @!method bad_method?(node)
          def_node_matcher :bad_method?, <<~PATTERN
            (send nil? :bad_method ...)
          PATTERN

          # Called on every `send` node (method call) while walking the AST.
          # TODO: remove this method if inspecting `send` nodes is unneeded for your cop.
          # By default, this is aliased to `on_csend` as well to handle method calls
          # with safe navigation, remove the alias if this is unnecessary.
          # If kept, ensure your tests cover safe navigation as well!
          def on_send(node)
            return unless bad_method?(node)

            add_offense(node)
          end
          alias on_csend on_send
        end
      end
    end
  end
RUBY
SPEC_TEMPLATE =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

<<~SPEC
  # frozen_string_literal: true

  RSpec.describe RuboCop::Cop::%<department>s::%<cop_name>s, :config do
    let(:config) { RuboCop::Config.new }

    # TODO: Write test code
    #
    # For example
    it 'registers an offense when using `#bad_method`' do
      expect_offense(<<~RUBY)
        bad_method
        ^^^^^^^^^^ Use `#good_method` instead of `#bad_method`.
      RUBY
    end

    it 'does not register an offense when using `#good_method`' do
      expect_no_offenses(<<~RUBY)
        good_method
      RUBY
    end
  end
SPEC
CONFIGURATION_ADDED_MESSAGE =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

'[modify] A configuration for the cop is added into ' \
'%<configuration_file_path>s.'

Instance Method Summary collapse

Constructor Details

#initialize(name, output: $stdout) ⇒ Generator

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new instance of Generator.

Raises:

  • (ArgumentError)


119
120
121
122
123
124
125
# File 'lib/rubocop/cop/generator.rb', line 119

def initialize(name, output: $stdout)
  @badge = Badge.parse(name)
  @output = output
  return if badge.qualified?

  raise ArgumentError, 'Specify a cop name with Department/Name style'
end

Instance Method Details

#inject_config(config_file_path: 'config/default.yml', version_added: '<<next>>') ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/rubocop/cop/generator.rb', line 139

def inject_config(config_file_path: 'config/default.yml',
                  version_added: '<<next>>')
  injector =
    ConfigurationInjector.new(configuration_file_path: config_file_path,
                              badge: badge,
                              version_added: version_added)

  injector.inject do # rubocop:disable Lint/UnexpectedBlockArity
    output.puts(format(CONFIGURATION_ADDED_MESSAGE,
                       configuration_file_path: config_file_path))
  end
end

#inject_require(root_file_path: 'lib/rubocop.rb') ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



135
136
137
# File 'lib/rubocop/cop/generator.rb', line 135

def inject_require(root_file_path: 'lib/rubocop.rb')
  RequireFileInjector.new(source_path: source_path, root_file_path: root_file_path).inject
end

#todoObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



152
153
154
155
156
157
158
159
160
161
162
# File 'lib/rubocop/cop/generator.rb', line 152

def todo
  <<~TODO
    Do 4 steps:
      1. Modify the description of #{badge} in config/default.yml
      2. Implement your new cop in the generated file!
      3. Commit your new cop with a message such as
         e.g. "Add new `#{badge}` cop"
      4. Run `bundle exec rake changelog:new` to generate a changelog entry
         for your new cop.
  TODO
end

#write_sourceObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



127
128
129
# File 'lib/rubocop/cop/generator.rb', line 127

def write_source
  write_unless_file_exists(source_path, generated_source)
end

#write_specObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



131
132
133
# File 'lib/rubocop/cop/generator.rb', line 131

def write_spec
  write_unless_file_exists(spec_path, generated_spec)
end