Class: CustomCopsGenerator::Generator

Inherits:
Object
  • Object
show all
Defined in:
lib/custom_cops_generator/generator.rb

Instance Method Summary collapse

Constructor Details

#initialize(name) ⇒ Generator

Returns a new instance of Generator.



3
4
5
# File 'lib/custom_cops_generator/generator.rb', line 3

def initialize(name)
  @name = name
end

Instance Method Details

#generateObject



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/custom_cops_generator/generator.rb', line 7

def generate
  system('bundle', 'gem', name, exception: true)

  put "lib/#{name}.rb", <<~RUBY
    # frozen_string_literal: true

    require 'rubocop'

    require_relative '#{dirname}'
    require_relative '#{dirname}/version'
    require_relative '#{dirname}/inject'

    RuboCop::#{classname}::Inject.defaults!

    require_relative '#{cops_file_name.sub(/\.rb$/, '').sub(/^lib\//, '')}'
  RUBY

  put "lib/#{dirname}/inject.rb", <<~RUBY
    # frozen_string_literal: true

    # The original code is from https://github.com/rubocop-hq/rubocop-rspec/blob/master/lib/rubocop/rspec/inject.rb
    # See https://github.com/rubocop-hq/rubocop-rspec/blob/master/MIT-LICENSE.md
    module RuboCop
      module #{classname}
        # Because RuboCop doesn't yet support plugins, we have to monkey patch in a
        # bit of our configuration.
        module Inject
          def self.defaults!
            path = CONFIG_DEFAULT.to_s
            hash = ConfigLoader.send(:load_yaml_configuration, path)
            config = Config.new(hash, path)
            puts "configuration from \#{path}" if ConfigLoader.debug?
            config = ConfigLoader.merge_with_default(config, path)
            ConfigLoader.instance_variable_set(:@default_configuration, config)
          end
        end
      end
    end
  RUBY

  put cops_file_name, <<~RUBY
    # frozen_string_literal: true
  RUBY

  put "config/default.yml", <<~YAML
    # Write it!
  YAML

  put 'spec/spec_helper.rb', <<~RUBY
    # frozen_string_literal: true

    require '#{name}'
    require 'rubocop/rspec/support'

    RSpec.configure do |config|
      config.include RuboCop::RSpec::ExpectOffense

      config.disable_monkey_patching!
      config.raise_errors_for_deprecations!
      config.raise_on_warning = true
      config.fail_if_no_examples = true

      config.order = :random
      Kernel.srand config.seed
    end
  RUBY

  put '.rspec', <<~TEXT
    --format documentation
    --color
    --require spec_helper
  TEXT

  patch "lib/#{dirname}.rb", /^  end\nend/, <<~RUBY
        PROJECT_ROOT   = Pathname.new(__dir__).parent.parent.expand_path.freeze
        CONFIG_DEFAULT = PROJECT_ROOT.join('config', 'default.yml').freeze
        CONFIG         = YAML.safe_load(CONFIG_DEFAULT.read).freeze

        private_constant(:CONFIG_DEFAULT, :PROJECT_ROOT)
      end
    end
  RUBY

  patch "lib/#{dirname}.rb", 'module Rubocop', 'module RuboCop'
  patch "lib/#{dirname}/version.rb", 'module Rubocop', 'module RuboCop'
  patch "#{name}.gemspec", 'Rubocop', 'RuboCop'

  patch "#{name}.gemspec", /^end/, <<~RUBY

      spec.add_runtime_dependency 'rubocop'
    end
  RUBY

  patch "Rakefile", /\z/, <<~RUBY

    require 'rspec/core/rake_task'

    RSpec::Core::RakeTask.new(:spec) do |spec|
      spec.pattern = FileList['spec/**/*_spec.rb']
    end

    desc 'Generate a new cop with a template'
    task :new_cop, [:cop] do |_task, args|
      require 'rubocop'

      cop_name = args.fetch(:cop) do
        warn 'usage: bundle exec rake new_cop[Department/Name]'
        exit!
      end

      github_user = `git config github.user`.chop
      github_user = 'your_id' if github_user.empty?

      generator = RuboCop::Cop::Generator.new(cop_name, github_user)

      generator.write_source
      generator.write_spec
      generator.inject_require(root_file_path: '#{cops_file_name}')
      generator.inject_config(config_file_path: 'config/default.yml')

      puts generator.todo
    end
  RUBY

  patch 'Gemfile', /\z/, <<~RUBY
    gem 'rspec'
  RUBY

  puts
  puts <<~MESSAGE
    It's done! You can start developing a new extension of RuboCop in #{root_path}.
    For the next step, you can use the cop generator.

      $ bundle exec rake 'new_cop[#{classname}/SuperCoolCopName]'
  MESSAGE
end