Add brakeman to new Rails applications (#50507)

It can be skipped with the `--skip-brakeman` flag.

Closes #50501
This commit is contained in:
Vipul A M 2023-12-31 13:09:47 -05:00 committed by GitHub
parent cbd8bd735c
commit 813afbdd74
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 43 additions and 2 deletions

View File

@ -1,3 +1,7 @@
* Add brakeman gem by default for static analysis of security vulnerabilities. Allow skipping with --skip-brakeman option.
*vipulnsward*
* Add RuboCop with rules from rubocop-rails-omakase by default. Skip with --skip-rubocop. * Add RuboCop with rules from rubocop-rails-omakase by default. Skip with --skip-rubocop.
*DHH* and *zzak* *DHH* and *zzak*

View File

@ -103,6 +103,9 @@ module Rails
class_option :skip_rubocop, type: :boolean, default: nil, class_option :skip_rubocop, type: :boolean, default: nil,
desc: "Skip RuboCop setup" desc: "Skip RuboCop setup"
class_option :skip_brakeman, type: :boolean, default: nil,
desc: "Skip brakeman setup"
class_option :dev, type: :boolean, default: nil, class_option :dev, type: :boolean, default: nil,
desc: "Set up the #{name} with Gemfile pointing to your Rails checkout" desc: "Set up the #{name} with Gemfile pointing to your Rails checkout"
@ -386,6 +389,9 @@ module Rails
options[:skip_rubocop] options[:skip_rubocop]
end end
def skip_brakeman?
options[:skip_brakeman]
end
class GemfileEntry < Struct.new(:name, :version, :comment, :options, :commented_out) class GemfileEntry < Struct.new(:name, :version, :comment, :options, :commented_out)
def initialize(name, version, comment, options = {}, commented_out = false) def initialize(name, version, comment, options = {}, commented_out = false)

View File

@ -102,8 +102,8 @@ module Rails
end end
def bin def bin
options = skip_rubocop? ? { exclude_pattern: /rubocop/ } : {} exclude_pattern = Regexp.union([(/rubocop/ if skip_rubocop?), (/brakeman/ if skip_brakeman?)].compact)
directory "bin", **options do |content| directory "bin", { exclude_pattern: exclude_pattern } do |content|
"#{shebang}\n" + content "#{shebang}\n" + content
end end
chmod "bin", 0755 & ~File.umask, verbose: false chmod "bin", 0755 & ~File.umask, verbose: false

View File

@ -40,6 +40,11 @@ end
<% end -%> <% end -%>
group :development do group :development do
<%- unless options.skip_brakeman? -%>
# Static analysis for security vulnerabilities [https://brakemanscanner.org/]
gem "brakeman", require: false
<%- end -%>
<%- unless options.skip_rubocop? -%> <%- unless options.skip_rubocop? -%>
# Omakase Ruby styling [https://github.com/rails/rubocop-rails-omakase/] # Omakase Ruby styling [https://github.com/rails/rubocop-rails-omakase/]
gem "rubocop-rails-omakase", require: false gem "rubocop-rails-omakase", require: false

View File

@ -0,0 +1,4 @@
require "rubygems"
require "bundler/setup"
load Gem.bin_path("brakeman", "brakeman")

View File

@ -38,6 +38,7 @@ DEFAULT_APP_FILES = %w(
app/views/layouts/mailer.html.erb app/views/layouts/mailer.html.erb
app/views/layouts/mailer.text.erb app/views/layouts/mailer.text.erb
bin/docker-entrypoint bin/docker-entrypoint
bin/brakeman
bin/rails bin/rails
bin/rake bin/rake
bin/rubocop bin/rubocop
@ -638,6 +639,27 @@ class AppGeneratorTest < Rails::Generators::TestCase
assert_no_file ".rubocop.yml" assert_no_file ".rubocop.yml"
end end
def test_inclusion_of_brakeman
run_generator
assert_gem "brakeman"
end
def test_brakeman_is_skipped_if_required
puts destination_root
run_generator [destination_root, "--skip-brakeman"]
assert_no_gem "brakeman"
assert_no_file "bin/brakeman"
end
def test_both_brakeman_and_rubocop_binstubs_are_skipped_if_required
puts destination_root
run_generator [destination_root, "--skip-brakeman", "--skip-rubocop"]
assert_no_file "bin/rubocop"
assert_no_file "bin/brakeman"
end
def test_usage_read_from_file def test_usage_read_from_file
assert_called(File, :read, returns: "USAGE FROM FILE") do assert_called(File, :read, returns: "USAGE FROM FILE") do
assert_equal "USAGE FROM FILE", Rails::Generators::AppGenerator.desc assert_equal "USAGE FROM FILE", Rails::Generators::AppGenerator.desc