Skip to content

Commit

Permalink
Add rubocop-rails-omakase to new Rails applications (#50486)
Browse files Browse the repository at this point in the history
* Add rubocop to new rails app generator

This setups a basic rubocop config for new rails apps using the `rubocop-rails-omakase` gem:
https://github.com/rails/rubocop-rails-omakase

It can be skipped with the `--skip-rubocop` flag.
  • Loading branch information
zzak committed Dec 30, 2023
1 parent 7b9e9ee commit 0fb5f67
Show file tree
Hide file tree
Showing 9 changed files with 59 additions and 3 deletions.
4 changes: 4 additions & 0 deletions railties/CHANGELOG.md
@@ -1,3 +1,7 @@
* Add RuboCop with rules from rubocop-rails-omakase by default. Skip with --skip-rubocop.

*DHH* and *zzak*

* Use `bin/rails runner --skip-executor` option to not wrap the runner script
with an Executor.

Expand Down
7 changes: 7 additions & 0 deletions railties/lib/rails/generators/app_base.rb
Expand Up @@ -100,6 +100,9 @@ def self.add_shared_options_for(name)
class_option :skip_dev_gems, type: :boolean, default: nil,
desc: "Skip development gems (e.g., web-console)"

class_option :skip_rubocop, type: :boolean, default: nil,
desc: "Skip RuboCop setup"

class_option :dev, type: :boolean, default: nil,
desc: "Set up the #{name} with Gemfile pointing to your Rails checkout"

Expand Down Expand Up @@ -379,6 +382,10 @@ def skip_propshaft?
skip_asset_pipeline? || options[:asset_pipeline] != "propshaft"
end

def skip_rubocop?
options[:skip_rubocop]
end


class GemfileEntry < Struct.new(:name, :version, :comment, :options, :commented_out)
def initialize(name, version, comment, options = {}, commented_out = false)
Expand Down
12 changes: 11 additions & 1 deletion railties/lib/rails/generators/rails/app/app_generator.rb
Expand Up @@ -82,6 +82,10 @@ def dockerfiles
chmod "bin/docker-entrypoint", 0755 & ~File.umask, verbose: false
end

def rubocop
template "rubocop.yml", ".rubocop.yml"
end

def version_control
if !options[:skip_git] && !options[:pretend]
run git_init_command, capture: options[:quiet], abort_on_failure: false
Expand All @@ -98,7 +102,8 @@ def app
end

def bin
directory "bin" do |content|
options = skip_rubocop? ? { exclude_pattern: /rubocop/ } : {}
directory "bin", **options do |content|
"#{shebang}\n" + content
end
chmod "bin", 0755 & ~File.umask, verbose: false
Expand Down Expand Up @@ -367,6 +372,11 @@ def create_dockerfiles
build(:dockerfiles)
end

def create_rubocop_file
return if skip_rubocop?
build(:rubocop)
end

def create_config_files
build(:config)
end
Expand Down
5 changes: 5 additions & 0 deletions railties/lib/rails/generators/rails/app/templates/Gemfile.tt
Expand Up @@ -40,6 +40,11 @@ end
<% end -%>

group :development do
<%- unless options.skip_rubocop? -%>
# Omakase Ruby styling [https://github.com/rails/rubocop-rails-omakase/]
gem "rubocop-rails-omakase", require: false

<%- end -%>
<%- unless options.api? || options.skip_dev_gems? -%>
# Use console on exceptions pages [https://github.com/rails/web-console]
gem "web-console"
Expand Down
@@ -0,0 +1,7 @@
require "rubygems"
require "bundler/setup"

# explicit rubocop config increases performance slightly while avoiding config confusion.
ARGV.unshift("--config", File.expand_path("../.rubocop.yml", __dir__))

load Gem.bin_path("rubocop", "rubocop")
Expand Up @@ -18,7 +18,7 @@ module <%= app_const_base %>
# Please, add to the `ignore` list any other `lib` subdirectories that do
# not contain `.rb` files, or that should not be reloaded or eager loaded.
# Common ones are `templates`, `generators`, or `middleware`, for example.
config.autoload_lib(ignore: %w(assets tasks))
config.autoload_lib(ignore: %w[assets tasks])

# Configuration for the application, engines, and railties goes here.
#
Expand Down
@@ -0,0 +1,8 @@
# Omakase Ruby styling for Rails
inherit_gem: { rubocop-rails-omakase: rubocop.yml }

# Overwrite or add rules to create your own house style
#
# # Use `[a, [b, c]]` not `[ a, [ b, c ] ]`
# Layout/SpaceInsideArrayLiteralBrackets:
# Enabled: false
@@ -1,5 +1,5 @@
require "test_helper"

class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
driven_by :selenium, using: :chrome, screen_size: [1400, 1400]
driven_by :selenium, using: :chrome, screen_size: [ 1400, 1400 ]
end
15 changes: 15 additions & 0 deletions railties/test/generators/app_generator_test.rb
Expand Up @@ -8,6 +8,7 @@
.gitattributes
.gitignore
.dockerignore
.rubocop.yml
.ruby-version
README.md
Gemfile
Expand Down Expand Up @@ -39,6 +40,7 @@
bin/docker-entrypoint
bin/rails
bin/rake
bin/rubocop
bin/setup
config/application.rb
config/boot.rb
Expand Down Expand Up @@ -623,6 +625,19 @@ def test_inclusion_of_a_debugger
end
end

def test_inclusion_of_rubocop
run_generator
assert_gem "rubocop-rails-omakase"
end

def test_rubocop_is_skipped_if_required
run_generator [destination_root, "--skip-rubocop"]

assert_no_gem "rubocop"
assert_no_file "bin/rubocop"
assert_no_file ".rubocop.yml"
end

def test_usage_read_from_file
assert_called(File, :read, returns: "USAGE FROM FILE") do
assert_equal "USAGE FROM FILE", Rails::Generators::AppGenerator.desc
Expand Down

0 comments on commit 0fb5f67

Please sign in to comment.