lib/rails/generators/app_base.rb in railties-7.1.5 vs lib/rails/generators/app_base.rb in railties-7.2.0.beta1
- old
+ new
@@ -10,16 +10,19 @@
require "active_support/core_ext/array/extract_options"
module Rails
module Generators
class AppBase < Base # :nodoc:
- include Database
include AppName
- NODE_LTS_VERSION = "18.15.0"
+ NODE_LTS_VERSION = "20.11.1"
BUN_VERSION = "1.0.1"
+ JAVASCRIPT_OPTIONS = %w( importmap bun webpack esbuild rollup )
+ CSS_OPTIONS = %w( tailwind bootstrap bulma postcss sass )
+ ASSET_PIPELINE_OPTIONS = %w( none sprockets propshaft )
+
attr_accessor :rails_template
add_shebang_option!
argument :app_path, type: :string
@@ -33,11 +36,12 @@
class_option :template, type: :string, aliases: "-m",
desc: "Path to some #{name} template (can be a filesystem path or URL)"
class_option :database, type: :string, aliases: "-d", default: "sqlite3",
- desc: "Preconfigure for selected database (options: #{DATABASES.join('/')})"
+ enum: Database::DATABASES,
+ desc: "Preconfigure for selected database"
class_option :skip_git, type: :boolean, aliases: "-G", default: nil,
desc: "Skip git init, .gitignore and .gitattributes"
class_option :skip_docker, type: :boolean, default: nil,
@@ -69,11 +73,12 @@
desc: "Skip Action Cable files"
class_option :skip_asset_pipeline, type: :boolean, aliases: "-A", default: nil
class_option :asset_pipeline, type: :string, aliases: "-a", default: "sprockets",
- desc: "Choose your asset pipeline [options: sprockets (default), propshaft]"
+ enum: ASSET_PIPELINE_OPTIONS,
+ desc: "Choose your asset pipeline"
class_option :skip_javascript, type: :boolean, aliases: ["-J", "--skip-js"], default: (true if name == "plugin"),
desc: "Skip JavaScript files"
class_option :skip_hotwire, type: :boolean, default: nil,
@@ -92,13 +97,25 @@
desc: "Skip bootsnap gem"
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 :skip_brakeman, type: :boolean, default: nil,
+ desc: "Skip brakeman setup"
+
+ class_option :skip_ci, type: :boolean, default: nil,
+ desc: "Skip GitHub CI files"
+
class_option :dev, type: :boolean, default: nil,
desc: "Set up the #{name} with Gemfile pointing to your Rails checkout"
+ class_option :devcontainer, type: :boolean, default: false,
+ desc: "Generate devcontainer files"
+
class_option :edge, type: :boolean, default: nil,
desc: "Set up the #{name} with a Gemfile pointing to the #{edge_branch} branch on the Rails repository"
class_option :main, type: :boolean, default: nil, aliases: "--master",
desc: "Set up the #{name} with Gemfile pointing to Rails repository main branch"
@@ -258,11 +275,11 @@
end
def database_gemfile_entry # :doc:
return if options[:skip_active_record]
- gem_name, gem_version = gem_for_database
+ gem_name, gem_version = database.gem
GemfileEntry.version gem_name, gem_version,
"Use #{options[:database]} as the database for Active Record"
end
def web_server_gemfile_entry # :doc:
@@ -343,10 +360,14 @@
def skip_active_storage? # :doc:
options[:skip_active_storage]
end
+ def skip_storage? # :doc:
+ skip_active_storage? && !sqlite3?
+ end
+
def skip_action_cable? # :doc:
options[:skip_action_cable]
end
def skip_action_mailer? # :doc:
@@ -371,11 +392,30 @@
def skip_propshaft?
skip_asset_pipeline? || options[:asset_pipeline] != "propshaft"
end
+ def skip_rubocop?
+ options[:skip_rubocop]
+ end
+ def skip_brakeman?
+ options[:skip_brakeman]
+ end
+
+ def skip_ci?
+ options[:skip_ci]
+ end
+
+ def skip_devcontainer?
+ !options[:devcontainer]
+ end
+
+ def devcontainer?
+ options[:devcontainer]
+ end
+
class GemfileEntry < Struct.new(:name, :version, :comment, :options, :commented_out)
def initialize(name, version, comment, options = {}, commented_out = false)
super
end
@@ -408,14 +448,10 @@
*options.map { |key, value| ", #{key}: #{value.inspect}" },
].compact.join
end
end
- def gem_ruby_version
- Gem::Version.new(Gem::VERSION) >= Gem::Version.new("3.3.13") ? Gem.ruby_version : RUBY_VERSION
- end
-
def rails_prerelease?
options.dev? || options.edge? || options.main?
end
def rails_gemfile_entry
@@ -533,65 +569,47 @@
end
binfixups
end
- def dockerfile_build_packages
- # start with the essentials
- packages = %w(build-essential git pkg-config)
+ def dockerfile_base_packages
+ # Add curl to work with the default healthcheck strategy in Kamal
+ packages = ["curl"]
- # add database support
- packages << build_package_for_database unless skip_active_record?
+ # ActiveRecord databases
+ packages << database.base_package unless skip_active_record?
# ActiveStorage preview support
packages << "libvips" unless skip_active_storage?
- packages << "curl" if using_js_runtime?
+ # jemalloc for memory optimization
+ packages << "libjemalloc2"
+ packages.compact.sort
+ end
+
+ def dockerfile_build_packages
+ # start with the essentials
+ packages = %w(build-essential git pkg-config)
+
+ # add database support
+ packages << database.build_package unless skip_active_record?
+
packages << "unzip" if using_bun?
# node support, including support for building native modules
if using_node?
packages << "node-gyp" # pkg-config already listed above
- # module build process depends on Python, and debian changed
- # how python is installed with the bullseye release. Below
- # is based on debian release included with the Ruby images on
- # Dockerhub.
- case Gem.ruby_version.to_s
- when /^2\.7/
- bullseye = Gem.ruby_version >= Gem::Version.new("2.7.4")
- when /^3\.0/
- bullseye = Gem.ruby_version >= Gem::Version.new("3.0.2")
- else
- bullseye = true
- end
-
- if bullseye
- packages << "python-is-python3"
- else
- packages << "python"
- end
+ packages << "python-is-python3"
end
packages.compact.sort
end
- def dockerfile_deploy_packages
- # Add curl to work with the default healthcheck strategy in Kamal
- packages = ["curl"]
-
- # ActiveRecord databases
- packages << deploy_package_for_database unless skip_active_record?
-
- # ActiveStorage preview support
- packages << "libvips" unless skip_active_storage?
-
- packages.compact.sort
- end
-
def css_gemfile_entry
+ return if options[:api]
return unless options[:css]
if !using_js_runtime? && options[:css] == "tailwind"
GemfileEntry.floats "tailwindcss-rails", "Use Tailwind CSS [https://github.com/rails/tailwindcss-rails]"
elsif !using_js_runtime? && options[:css] == "sass"
@@ -654,11 +672,10 @@
return unless rails_prerelease? && bundle_install?
if !File.exist?(File.expand_path("Gemfile", destination_root))
create_file("Gemfile", <<~GEMFILE)
source "https://rubygems.org"
- git_source(:github) { |repo| "https://github.com/\#{repo}.git" }
#{rails_gemfile_entry}
GEMFILE
run_bundle
@@ -672,11 +689,11 @@
remove_file("Gemfile.lock")
end
end
def run_bundle
- bundle_command("install", "BUNDLE_IGNORE_MESSAGES" => "1") if bundle_install?
+ bundle_command("install --quiet", "BUNDLE_IGNORE_MESSAGES" => "1") if bundle_install?
end
def run_javascript
return if options[:skip_javascript] || !bundle_install?
@@ -750,13 +767,17 @@
end
def dockerfile_chown_directories
directories = %w(log tmp)
- directories << "storage" unless skip_active_storage? && !sqlite3?
+ directories << "storage" unless skip_storage?
directories << "db" unless skip_active_record?
directories.sort
+ end
+
+ def database
+ @database ||= Database.build(options[:database])
end
end
end
end