Class: RuboCop::Cop::Generator

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

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 =
"  # frozen_string_literal: true\n\n  # TODO: when finished, run `rake generate_cops_documentation` to update the docs\n  module RuboCop\n    module Cop\n      module %<department>s\n        # TODO: Write cop description and example of bad / good code. For every\n        # `SupportedStyle` and unique configuration, there needs to be examples.\n        # Examples must have valid Ruby syntax. Do not use upticks.\n        #\n        # @example EnforcedStyle: bar (default)\n        #   # Description of the `bar` style.\n        #\n        #   # bad\n        #   bad_bar_method\n        #\n        #   # bad\n        #   bad_bar_method(args)\n        #\n        #   # good\n        #   good_bar_method\n        #\n        #   # good\n        #   good_bar_method(args)\n        #\n        # @example EnforcedStyle: foo\n        #   # Description of the `foo` style.\n        #\n        #   # bad\n        #   bad_foo_method\n        #\n        #   # bad\n        #   bad_foo_method(args)\n        #\n        #   # good\n        #   good_foo_method\n        #\n        #   # good\n        #   good_foo_method(args)\n        #\n        class %<cop_name>s < Cop\n          # TODO: Implement the cop in here.\n          #\n          # In many cases, you can use a node matcher for matching node pattern.\n          # See https://github.com/rubocop-hq/rubocop/blob/master/lib/rubocop/node_pattern.rb\n          #\n          # For example\n          MSG = 'Use `#good_method` instead of `#bad_method`.'.freeze\n\n          def_node_matcher :bad_method?, <<-PATTERN\n            (send nil? :bad_method ...)\n          PATTERN\n\n          def on_send(node)\n            return unless bad_method?(node)\n\n            add_offense(node)\n          end\n        end\n      end\n    end\n  end\n".strip_indent
SPEC_TEMPLATE =
"  # frozen_string_literal: true\n\n  RSpec.describe RuboCop::Cop::%<department>s::%<cop_name>s do\n    subject(:cop) { described_class.new(config) }\n\n    let(:config) { RuboCop::Config.new }\n\n    # TODO: Write test code\n    #\n    # For example\n    it 'registers an offense when using `#bad_method`' do\n      expect_offense(<<-RUBY.strip_indent)\n        bad_method\n        ^^^^^^^^^^ Use `#good_method` instead of `#bad_method`.\n      RUBY\n    end\n\n    it 'does not register an offense when using `#good_method`' do\n      expect_no_offenses(<<-RUBY.strip_indent)\n        good_method\n      RUBY\n    end\n  end\n".strip_indent
CONFIGURATION_ADDED_MESSAGE =
"  [modify] A configuration for the cop is added into %<configuration_file_path>s.\n           If you want to disable the cop by default, set `Enabled` option to false.\n".strip_indent

Instance Method Summary collapse

Constructor Details

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

Returns a new instance of Generator.

Raises:

  • (ArgumentError)


106
107
108
109
110
111
112
113
# File 'lib/rubocop/cop/generator.rb', line 106

def initialize(name, github_user, output: $stdout)
  @badge = Badge.parse(name)
  @github_user = github_user
  @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') ⇒ Object



130
131
132
133
134
135
136
137
138
139
140
# File 'lib/rubocop/cop/generator.rb', line 130

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

  injector.inject do
    output.puts(format(CONFIGURATION_ADDED_MESSAGE,
                       configuration_file_path: config_file_path))
  end
end

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



123
124
125
126
127
128
# File 'lib/rubocop/cop/generator.rb', line 123

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

#todoObject



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

def todo
  "    Do 3 steps:\n      1. Add an entry to the \"New features\" section in CHANGELOG.md,\n         e.g. \"Add new `\#{badge}` cop. ([@\#{github_user}][])\"\n      2. Modify the description of \#{badge} in config/default.yml\n      3. Implement your new cop in the generated file!\n  TODO\nend\n".strip_indent

#write_sourceObject



115
116
117
# File 'lib/rubocop/cop/generator.rb', line 115

def write_source
  write_unless_file_exists(source_path, generated_source)
end

#write_specObject



119
120
121
# File 'lib/rubocop/cop/generator.rb', line 119

def write_spec
  write_unless_file_exists(spec_path, generated_spec)
end