Rubocop with Standard
RuboCop/Standard configuration with the frustration removed
Used 62 times
B
Ben Morrall
Usage
Modified from the original RuboCoping with legacy post by Evil Martians.
With a few fun changes found along the way.
With a few fun changes found along the way.
Run this command in your Rails app directory in the terminal:
rails app:template LOCATION="https://railsbytes.com/script/VdrsMK"
Template Source
Review the code before running this template on your machine.
say "Hey! Let's configure RuboCop for your project 🤖!\n" \
"For more information, visit https://evilmartians.com/chronicles/rubocoping-with-legacy-bring-your-ruby-code-up-to-standard"
plugins = []
gems = []
specs = []
deps = []
ruby_version = Gem::Version.new(RUBY_VERSION).segments[0..1].join(".")
in_root do
if File.file?("Gemfile.lock")
bundler_parser = Bundler::LockfileParser.new(Bundler.read_file("Gemfile.lock"))
specs = bundler_parser.specs.map(&:name)
locked_version = bundler_parser.ruby_version.match(/(\d+\.\d+\.\d+)/)&.[](1) if bundler_parser.ruby_version
ruby_version = Gem::Version.new(locked_version).segments[0..1].join(".") if locked_version
end
end
in_root do
if File.file?("Gemfile")
bundler_parser = Bundler::Dsl.new
bundler_parser.eval_gemfile("Gemfile")
deps = bundler_parser.dependencies.map(&:name)
end
end
has_rails = ((specs | deps) & %w[activerecord actionpack rails]).any?
if has_rails && yes?("Would your like to install rubocop-rails?")
file ".rubocop/rails.yml", ERB.new(
*[
<<~'TCODE'
require:
- rubocop-rails
- standard-rails
inherit_gem:
standard-rails: config/base.yml
TCODE
], trim_mode: "<>").result(binding)
plugins << ".rubocop/rails.yml"
gems << "rubocop-rails"
gems << "standard-rails"
end
has_rspec = in_root do
((specs | deps) & %w[rspec-core]).any? && File.directory?("spec")
end
if has_rspec && yes?("Would your like to install rubocop-rspec?")
file ".rubocop/rspec.yml", ERB.new(
*[
<<~'TCODE'
require:
- rubocop-rspec
- rubocop-rspec_rails
# Disable all cops by default,
# only enable those defined explcitly in this configuration file
RSpec:
Enabled: false
RSpec/Focus:
Enabled: true
RSpec/EmptyExampleGroup:
Enabled: true
RSpec/EmptyLineAfterExampleGroup:
Enabled: true
RSpec/EmptyLineAfterFinalLet:
Enabled: true
RSpec/EmptyLineAfterHook:
Enabled: true
RSpec/EmptyLineAfterSubject:
Enabled: true
RSpec/HookArgument:
Enabled: true
RSpec/HooksBeforeExamples:
Enabled: true
RSpec/ImplicitExpect:
Enabled: true
RSpec/IteratedExpectation:
Enabled: true
RSpec/LetBeforeExamples:
Enabled: true
RSpec/MissingExampleGroupArgument:
Enabled: true
RSpec/ReceiveCounts:
Enabled: true
TCODE
], trim_mode: "<>").result(binding)
plugins << ".rubocop/rspec.yml"
gems << "rubocop-rspec"
gems << "rubocop-rspec_rails"
end
has_capybara = in_root do
((specs | deps) & %w[capybara]).any?
end
if has_capybara && yes?("Would your like to install rubocop-capybara?")
file ".rubocop/capybara.yml", ERB.new(
*[
<<~'TCODE'
require:
- rubocop-capybara
Capybara/CurrentPathExpectation:
Enabled: true
TCODE
], trim_mode: "<>").result(binding)
plugins << ".rubocop/capybara.yml"
gems << "rubocop-capybara"
end
has_factory_bot = in_root do
((specs | deps) & %w[factory_bot_rails factory_bot]).any?
end
if has_factory_bot && yes?("Would your like to install rubocop-factory_bot?")
file ".rubocop/factory_bot.yml", ERB.new(
*[
<<~'TCODE'
require:
- rubocop-factory_bot
FactoryBot/AttributeDefinedStatically:
Enabled: true
FactoryBot/CreateList:
Enabled: true
TCODE
], trim_mode: "<>").result(binding)
plugins << ".rubocop/factory_bot.yml"
gems << "rubocop-factory_bot"
end
has_minitest = in_root do
((specs | deps) & %w[rspec-core]).any? && File.directory?("test")
end
if has_minitest && yes?("Would your like to install rubocop-minitest?")
file ".rubocop/minitest.yml", ERB.new(
*[
<<~'TCODE'
require:
- rubocop-minitest
TCODE
], trim_mode: "<>").result(binding)
plugins << ".rubocop/minitest.yml"
gems << "rubocop-minitest"
end
has_graphql = ((specs | deps) & %w[graphql]).any?
if has_graphql && yes?("Would your like to install rubocop-graphql?")
file ".rubocop/graphql.yml", ERB.new(
*[
<<~'TCODE'
require:
- rubocop-graphql
TCODE
], trim_mode: "<>").result(binding)
plugins << ".rubocop/graphql.yml"
gems << "rubocop-graphql"
end
in_root do
# Final configuration generation
file ".rubocop/strict.yml", ERB.new(
*[
<<~'TCODE'
Lint/Debugger: # don't leave binding.pry
Enabled: true
Exclude: []
<% if gems.include?("rubocop-rspec") %>
RSpec/Focus: # run ALL tests on CI
Enabled: true
Exclude: []
<% end %>
<% if gems.include?("rubocop-rails") %>
Rails/Output: # Don't leave puts-debugging
Enabled: true
Exclude: []
AutoCorrect: false
Rails/FindEach: # each could badly affect the performance, use find_each
Enabled: true
Exclude: []
Rails/UniqBeforePluck: # uniq.pluck and not pluck.uniq
Enabled: true
Exclude: []
<% end %>
TCODE
], trim_mode: "<>").result(binding)
file ".rubocop.yml", ERB.new(
*[
<<~'TCODE'
inherit_mode:
merge:
- Exclude
require:
- standard
- standard-custom
- standard-performance
- rubocop-performance
inherit_gem:
standard: config/base.yml
standard-performance: config/base.yml
standard-custom: config/base.yml
inherit_from:
<% plugins.each do |plugin| %>
- <%= plugin %>
<% end %>
- .rubocop/strict.yml
AllCops:
NewCops: disable
SuggestExtensions: true
TargetRubyVersion: <%= ruby_version %>
TCODE
], trim_mode: "<>").result(binding)
file "gemfiles/rubocop.gemfile", ERB.new(
*[
<<~'TCODE'
source "https://rubygems.org" do
<% gems.each do |gem| %>
gem "<%= gem %>"
<% end %>
gem "standard", "~> 1.28"
end
TCODE
], trim_mode: "<>").result(binding)
in_root do
if File.file?("Gemfile")
file "Gemfile", File.read("Gemfile") + %(\ngroup :development do\n eval_gemfile "gemfiles/rubocop.gemfile"\nend\n), force: true
end
end
has_bin_rubocop = yes?("Would your like to create a standalone RuboCop executable (bin/rubocop)?")
if has_bin_rubocop
file "bin/rubocop", ERB.new(
*[
<<~'TCODE'
#!/bin/bash
cd $(dirname $0)/..
export BUNDLE_GEMFILE=./gemfiles/rubocop.gemfile
bundle check > /dev/null || bundle install
bundle exec rubocop $@
TCODE
], trim_mode: "<>").result(binding)
in_root { run "chmod +x bin/rubocop" }
end
end
if yes?("Would you like to generate a TODO config?")
# First, run RuboCop and check the output
# with formatter json
in_root do
has_bin_rubocop = File.file?("bin/rubocop")
command = has_bin_rubocop ? "bin/rubocop" : "bundle exec rubocop"
output = Bundler.with_unbundled_env do
# Make sure dependencies are installed
if has_bin_rubocop
`#{command} > /dev/null`
else
run "bundle check > /dev/null || bundle install > /dev/null"
end
`#{command} --format json`
end
require "json"
summary = JSON.parse(output).dig("summary")
if summary["offense_count"] > 0
Bundler.with_unbundled_env do
# Prevent RuboCop from updating the `.rubocop.yml`
run "cp .rubocop.yml .rubocop.yml.bak"
run "#{command} " \
"--auto-gen-config " \
"--auto-gen-only-exclude " \
"--no-exclude-limit " \
"--no-auto-gen-timestamp"
run "mv .rubocop.yml.bak .rubocop.yml"
end
inject_into_file ".rubocop.yml", " - .rubocop_todo.yml\n", before: " - .rubocop/strict.yml"
else
say "No offenses detected, good job! Skipping TODO generation"
end
end
end
say_status :info, "Congratulations! Your project got style! 🎉"
if yes?("Would you like to run RuboCop to check your configuration? (y/n)")
in_root do
if File.file?("bin/rubocop")
Bundler.with_unbundled_env { run "bin/rubocop" }
else
Bundler.with_unbundled_env do
run "bundle check > /dev/null || bundle install > /dev/null"
run "bundle exec rubocop"
end
end
end
end