railties 7.2.3 → 8.0.0.beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +111 -324
  3. data/README.rdoc +1 -1
  4. data/lib/minitest/rails_plugin.rb +2 -2
  5. data/lib/rails/application/bootstrap.rb +3 -1
  6. data/lib/rails/application/configuration.rb +22 -7
  7. data/lib/rails/application/default_middleware_stack.rb +4 -0
  8. data/lib/rails/application/finisher.rb +2 -2
  9. data/lib/rails/application/routes_reloader.rb +11 -1
  10. data/lib/rails/application.rb +14 -12
  11. data/lib/rails/backtrace_cleaner.rb +1 -1
  12. data/lib/rails/code_statistics.rb +128 -86
  13. data/lib/rails/code_statistics_calculator.rb +78 -76
  14. data/lib/rails/command/helpers/editor.rb +1 -1
  15. data/lib/rails/commands/app/update_command.rb +1 -9
  16. data/lib/rails/commands/console/irb_console.rb +6 -3
  17. data/lib/rails/commands/credentials/USAGE +4 -4
  18. data/lib/rails/commands/credentials/credentials_command.rb +5 -1
  19. data/lib/rails/commands/dev/dev_command.rb +1 -1
  20. data/lib/rails/commands/devcontainer/devcontainer_command.rb +1 -1
  21. data/lib/rails/commands/stats/stats_command.rb +19 -0
  22. data/lib/rails/commands/test/test_command.rb +2 -0
  23. data/lib/rails/dev_caching.rb +2 -2
  24. data/lib/rails/engine/configuration.rb +3 -1
  25. data/lib/rails/engine/lazy_route_set.rb +109 -0
  26. data/lib/rails/engine.rb +8 -3
  27. data/lib/rails/gem_version.rb +4 -4
  28. data/lib/rails/generators/actions.rb +5 -9
  29. data/lib/rails/generators/app_base.rb +49 -31
  30. data/lib/rails/generators/database.rb +101 -67
  31. data/lib/rails/generators/erb/authentication/authentication_generator.rb +15 -0
  32. data/lib/rails/generators/erb/authentication/templates/views/passwords/edit.html.erb +9 -0
  33. data/lib/rails/generators/erb/authentication/templates/views/passwords/new.html.erb +8 -0
  34. data/lib/rails/generators/erb/authentication/templates/views/sessions/new.html.erb +11 -0
  35. data/lib/rails/generators/generated_attribute.rb +16 -11
  36. data/lib/rails/generators/rails/app/app_generator.rb +19 -28
  37. data/lib/rails/generators/rails/app/templates/Dockerfile.tt +12 -3
  38. data/lib/rails/generators/rails/app/templates/Gemfile.tt +23 -8
  39. data/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css.tt +6 -11
  40. data/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt +10 -3
  41. data/lib/rails/generators/rails/app/templates/bin/dev.tt +1 -0
  42. data/lib/rails/generators/rails/app/templates/bin/setup.tt +5 -7
  43. data/lib/rails/generators/rails/app/templates/bin/thrust.tt +4 -0
  44. data/lib/rails/generators/rails/app/templates/config/databases/mysql.yml.tt +23 -0
  45. data/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml.tt +23 -0
  46. data/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml.tt +40 -0
  47. data/lib/rails/generators/rails/app/templates/config/databases/trilogy.yml.tt +23 -0
  48. data/lib/rails/generators/rails/app/templates/config/deploy.yml.tt +124 -0
  49. data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +12 -23
  50. data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +31 -51
  51. data/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +5 -19
  52. data/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt +0 -7
  53. data/lib/rails/generators/rails/app/templates/config/initializers/filter_parameter_logging.rb.tt +1 -1
  54. data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_8_0.rb.tt +25 -0
  55. data/lib/rails/generators/rails/app/templates/config/puma.rb.tt +11 -2
  56. data/lib/rails/generators/rails/app/templates/config/routes.rb.tt +3 -3
  57. data/lib/rails/generators/rails/app/templates/docker-entrypoint.tt +4 -3
  58. data/lib/rails/generators/rails/app/templates/dockerignore.tt +1 -2
  59. data/lib/rails/generators/rails/app/templates/github/ci.yml.tt +1 -3
  60. data/lib/rails/generators/rails/app/templates/gitignore.tt +1 -2
  61. data/lib/rails/generators/rails/app/templates/kamal-secrets.tt +17 -0
  62. data/lib/rails/generators/rails/app/templates/public/400.html +114 -0
  63. data/lib/rails/generators/rails/app/templates/public/404.html +113 -66
  64. data/lib/rails/generators/rails/app/templates/public/406-unsupported-browser.html +113 -65
  65. data/lib/rails/generators/rails/app/templates/public/422.html +113 -66
  66. data/lib/rails/generators/rails/app/templates/public/500.html +113 -65
  67. data/lib/rails/generators/rails/app/templates/public/icon.png +0 -0
  68. data/lib/rails/generators/rails/app/templates/public/icon.svg +2 -2
  69. data/lib/rails/generators/rails/authentication/USAGE +6 -0
  70. data/lib/rails/generators/rails/authentication/authentication_generator.rb +54 -0
  71. data/lib/rails/generators/rails/authentication/templates/controllers/concerns/authentication.rb +55 -0
  72. data/lib/rails/generators/rails/authentication/templates/controllers/passwords_controller.rb +33 -0
  73. data/lib/rails/generators/rails/authentication/templates/controllers/sessions_controller.rb +21 -0
  74. data/lib/rails/generators/rails/authentication/templates/mailers/passwords_mailer.rb +6 -0
  75. data/lib/rails/generators/rails/authentication/templates/models/current.rb +4 -0
  76. data/lib/rails/generators/rails/authentication/templates/models/session.rb +3 -0
  77. data/lib/rails/generators/rails/authentication/templates/models/user.rb +6 -0
  78. data/lib/rails/generators/rails/authentication/templates/test/mailers/previews/passwords_mailer_preview.rb +7 -0
  79. data/lib/rails/generators/rails/authentication/templates/views/passwords_mailer/reset.html.erb +4 -0
  80. data/lib/rails/generators/rails/authentication/templates/views/passwords_mailer/reset.text.erb +2 -0
  81. data/lib/rails/generators/rails/credentials/templates/credentials.yml.tt +4 -0
  82. data/lib/rails/generators/rails/db/system/change/change_generator.rb +1 -1
  83. data/lib/rails/generators/rails/devcontainer/devcontainer_generator.rb +4 -2
  84. data/lib/rails/generators/rails/devcontainer/templates/devcontainer/devcontainer.json.tt +1 -1
  85. data/lib/rails/generators/rails/plugin/plugin_generator.rb +7 -9
  86. data/lib/rails/generators/rails/plugin/templates/github/ci.yml.tt +2 -3
  87. data/lib/rails/generators/rails/scaffold_controller/templates/api_controller.rb.tt +4 -4
  88. data/lib/rails/generators/rails/scaffold_controller/templates/controller.rb.tt +5 -5
  89. data/lib/rails/generators/rails/script/USAGE +18 -0
  90. data/lib/rails/generators/rails/script/script_generator.rb +18 -0
  91. data/lib/rails/generators/rails/script/templates/script.rb.tt +3 -0
  92. data/lib/rails/generators.rb +6 -5
  93. data/lib/rails/info_controller.rb +10 -4
  94. data/lib/rails/rack/silence_request.rb +33 -0
  95. data/lib/rails/rack.rb +1 -0
  96. data/lib/rails/source_annotation_extractor.rb +31 -14
  97. data/lib/rails/tasks/statistics.rake +13 -28
  98. data/lib/rails/templates/rails/info/notes.html.erb +65 -0
  99. data/lib/rails/test_unit/runner.rb +3 -7
  100. data/lib/rails/test_unit/test_parser.rb +15 -18
  101. metadata +45 -50
  102. data/lib/rails/generators/rails/app/templates/app/assets/config/manifest.js.tt +0 -2
  103. data/lib/rails/generators/rails/app/templates/app/channels/application_cable/channel.rb.tt +0 -4
  104. data/lib/rails/generators/rails/app/templates/app/channels/application_cable/connection.rb.tt +0 -4
  105. data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_7_2.rb.tt +0 -70
  106. data/lib/rails/generators/rails/app/templates/config/initializers/permissions_policy.rb.tt +0 -13
  107. data/lib/rails/generators/rails/app/templates/test/channels/application_cable/connection_test.rb.tt +0 -13
  108. data/lib/rails/generators/rails/plugin/templates/rails/dummy_manifest.js.tt +0 -10
  109. data/lib/rails/generators/rails/plugin/templates/rails/engine_manifest.js.tt +0 -6
  110. data/lib/rails/generators/rails/plugin/templates/rails/javascripts.js.tt +0 -17
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rails
4
+ module Command
5
+ class StatsCommand < Base # :nodoc:
6
+ desc "stats", "Report code statistics (KLOCs, etc) from the application or engine"
7
+ def perform
8
+ require "rails/code_statistics"
9
+ boot_application!
10
+
11
+ stat_directories = Rails::CodeStatistics.directories.map do |name, dir|
12
+ [name, Rails::Command.application_root.join(dir)]
13
+ end.select { |name, dir| File.directory?(dir) }
14
+
15
+ Rails::CodeStatistics.new(*stat_directories).to_s
16
+ end
17
+ end
18
+ end
19
+ end
@@ -31,6 +31,8 @@ module Rails
31
31
  Rails::TestUnit::Runner.parse_options(args)
32
32
  run_prepare_task if self.args.none?(EXACT_TEST_ARGUMENT_PATTERN)
33
33
  Rails::TestUnit::Runner.run(args)
34
+ rescue Rails::TestUnit::InvalidTestError => error
35
+ raise ArgumentError, error.message
34
36
  end
35
37
 
36
38
  # Define Thor tasks to avoid going through Rake and booting twice when using bin/rails test:*
@@ -12,10 +12,10 @@ module Rails
12
12
 
13
13
  if File.exist?(FILE)
14
14
  delete_cache_file
15
- puts "Development mode is no longer being cached."
15
+ puts "Action Controller caching disabled for development mode."
16
16
  else
17
17
  create_cache_file
18
- puts "Development mode is now being cached."
18
+ puts "Action Controller caching enabled for development mode."
19
19
  end
20
20
 
21
21
  FileUtils.touch "tmp/restart.txt"
@@ -6,7 +6,7 @@ module Rails
6
6
  class Engine
7
7
  class Configuration < ::Rails::Railtie::Configuration
8
8
  attr_reader :root
9
- attr_accessor :middleware, :javascript_path
9
+ attr_accessor :middleware, :javascript_path, :route_set_class, :default_scope
10
10
  attr_writer :eager_load_paths, :autoload_once_paths, :autoload_paths
11
11
 
12
12
  # An array of custom autoload paths to be added to the ones defined
@@ -44,6 +44,8 @@ module Rails
44
44
  @generators = app_generators.dup
45
45
  @middleware = Rails::Configuration::MiddlewareStackProxy.new
46
46
  @javascript_path = "javascript"
47
+ @route_set_class = ActionDispatch::Routing::RouteSet
48
+ @default_scope = nil
47
49
 
48
50
  @autoload_paths = []
49
51
  @autoload_once_paths = []
@@ -0,0 +1,109 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :markup: markdown
4
+
5
+ require "action_dispatch/routing/route_set"
6
+
7
+ module Rails
8
+ class Engine
9
+ class LazyRouteSet < ActionDispatch::Routing::RouteSet # :nodoc:
10
+ class NamedRouteCollection < ActionDispatch::Routing::RouteSet::NamedRouteCollection
11
+ def route_defined?(name)
12
+ Rails.application&.reload_routes_unless_loaded
13
+ super
14
+ end
15
+ end
16
+
17
+ module ProxyUrlHelpers
18
+ def url_for(options)
19
+ Rails.application&.reload_routes_unless_loaded
20
+ super
21
+ end
22
+
23
+ def full_url_for(options)
24
+ Rails.application&.reload_routes_unless_loaded
25
+ super
26
+ end
27
+
28
+ def route_for(name, *args)
29
+ Rails.application&.reload_routes_unless_loaded
30
+ super
31
+ end
32
+
33
+ def optimize_routes_generation?
34
+ Rails.application&.reload_routes_unless_loaded
35
+ super
36
+ end
37
+
38
+ def polymorphic_url(record_or_hash_or_array, options = {})
39
+ Rails.application&.reload_routes_unless_loaded
40
+ super
41
+ end
42
+
43
+ def polymorphic_path(record_or_hash_or_array, options = {})
44
+ Rails.application&.reload_routes_unless_loaded
45
+ super
46
+ end
47
+ end
48
+
49
+ def initialize(config = DEFAULT_CONFIG)
50
+ super
51
+ self.named_routes = NamedRouteCollection.new
52
+ named_routes.url_helpers_module.prepend(method_missing_module)
53
+ named_routes.path_helpers_module.prepend(method_missing_module)
54
+ end
55
+
56
+ def generate_extras(options, recall = {})
57
+ Rails.application&.reload_routes_unless_loaded
58
+
59
+ super(options, recall)
60
+ end
61
+
62
+ def generate_url_helpers(supports_path)
63
+ super.tap { |mod| mod.singleton_class.prepend(ProxyUrlHelpers) }
64
+ end
65
+
66
+ def call(req)
67
+ Rails.application&.reload_routes_unless_loaded
68
+ super
69
+ end
70
+
71
+ def draw(&block)
72
+ Rails.application&.reload_routes_unless_loaded
73
+ super
74
+ end
75
+
76
+ def recognize_path(path, environment = {})
77
+ Rails.application&.reload_routes_unless_loaded
78
+ super
79
+ end
80
+
81
+ def routes
82
+ Rails.application&.reload_routes_unless_loaded
83
+ super
84
+ end
85
+
86
+ private
87
+ def method_missing_module
88
+ @method_missing_module ||= Module.new do
89
+ private
90
+ def method_missing(method_name, *args, &block)
91
+ if Rails.application&.reload_routes_unless_loaded
92
+ public_send(method_name, *args, &block)
93
+ else
94
+ super(method_name, *args, &block)
95
+ end
96
+ end
97
+
98
+ def respond_to_missing?(method_name, *args)
99
+ if Rails.application&.reload_routes_unless_loaded
100
+ respond_to?(method_name, *args)
101
+ else
102
+ super(method_name, *args)
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
data/lib/rails/engine.rb CHANGED
@@ -6,7 +6,6 @@ require "active_support/callbacks"
6
6
  require "active_support/core_ext/module/delegation"
7
7
  require "active_support/core_ext/object/try"
8
8
  require "pathname"
9
- require "thread"
10
9
 
11
10
  module Rails
12
11
  # +Rails::Engine+ allows you to wrap a specific \Rails application or subset of
@@ -349,6 +348,7 @@ module Rails
349
348
  # config.railties_order = [Blog::Engine, :main_app, :all]
350
349
  class Engine < Railtie
351
350
  autoload :Configuration, "rails/engine/configuration"
351
+ autoload :LazyRouteSet, "rails/engine/lazy_route_set"
352
352
 
353
353
  class << self
354
354
  attr_accessor :called_from, :isolated
@@ -385,7 +385,8 @@ module Rails
385
385
  def isolate_namespace(mod)
386
386
  engine_name(generate_railtie_name(mod.name))
387
387
 
388
- routes.default_scope = { module: ActiveSupport::Inflector.underscore(mod.name) }
388
+ config.default_scope = { module: ActiveSupport::Inflector.underscore(mod.name) }
389
+
389
390
  self.isolated = true
390
391
 
391
392
  unless mod.respond_to?(:railtie_namespace)
@@ -543,7 +544,7 @@ module Rails
543
544
  # Defines the routes for this engine. If a block is given to
544
545
  # routes, it is appended to the engine.
545
546
  def routes(&block)
546
- @routes ||= ActionDispatch::Routing::RouteSet.new_with_config(config)
547
+ @routes ||= config.route_set_class.new_with_config(config)
547
548
  @routes.append(&block) if block_given?
548
549
  @routes
549
550
  end
@@ -588,6 +589,10 @@ module Rails
588
589
  config.eager_load_paths.freeze
589
590
  end
590
591
 
592
+ initializer :make_routes_lazy, before: :bootstrap_hook do |app|
593
+ config.route_set_class = LazyRouteSet if Rails.env.local?
594
+ end
595
+
591
596
  initializer :add_routing_paths do |app|
592
597
  routing_paths = paths["config/routes.rb"].existent
593
598
  external_paths = self.paths["config/routes"].paths
@@ -7,10 +7,10 @@ module Rails
7
7
  end
8
8
 
9
9
  module VERSION
10
- MAJOR = 7
11
- MINOR = 2
12
- TINY = 3
13
- PRE = nil
10
+ MAJOR = 8
11
+ MINOR = 0
12
+ TINY = 0
13
+ PRE = "beta1"
14
14
 
15
15
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
16
16
  end
@@ -445,8 +445,8 @@ module Rails
445
445
 
446
446
  private
447
447
  # Define log for backwards compatibility. If just one argument is sent,
448
- # invoke +say+, otherwise invoke +say_status+. Differently from +say+ and
449
- # similarly to +say_status+, this method respects the +quiet?+ option given.
448
+ # invoke say, otherwise invoke say_status. Differently from say and
449
+ # similarly to say_status, this method respects the quiet? option given.
450
450
  def log(*args) # :doc:
451
451
  if args.size == 1
452
452
  say args.first.to_s unless options.quiet?
@@ -456,7 +456,7 @@ module Rails
456
456
  end
457
457
  end
458
458
 
459
- # Runs the supplied command using either +rake+ or +rails+
459
+ # Runs the supplied command using either "rake ..." or "rails ..."
460
460
  # based on the executor parameter provided.
461
461
  def execute_command(executor, command, options = {}) # :doc:
462
462
  log executor, command
@@ -490,16 +490,12 @@ module Rails
490
490
  end
491
491
  alias rebase_indentation optimize_indentation
492
492
 
493
- # Returns a string corresponding to the current indentation level
494
- # (i.e. 2 * <code>@indentation</code> spaces). See also
495
- # #with_indentation, which can be used to manage the indentation level.
493
+ # Indent the +Gemfile+ to the depth of @indentation
496
494
  def indentation # :doc:
497
495
  " " * @indentation
498
496
  end
499
497
 
500
- # Increases the current indentation indentation level for the duration
501
- # of the given block, and decreases it after the block ends. Call
502
- # #indentation to get an indentation string.
498
+ # Manage +Gemfile+ indentation for a DSL action block
503
499
  def with_indentation(&block) # :doc:
504
500
  @indentation += 1
505
501
  instance_eval(&block)
@@ -19,7 +19,6 @@ module Rails
19
19
 
20
20
  JAVASCRIPT_OPTIONS = %w( importmap bun webpack esbuild rollup )
21
21
  CSS_OPTIONS = %w( tailwind bootstrap bulma postcss sass )
22
- ASSET_PIPELINE_OPTIONS = %w( none sprockets propshaft )
23
22
 
24
23
  attr_accessor :rails_template
25
24
  add_shebang_option!
@@ -74,10 +73,6 @@ module Rails
74
73
 
75
74
  class_option :skip_asset_pipeline, type: :boolean, aliases: "-A", default: nil
76
75
 
77
- class_option :asset_pipeline, type: :string, aliases: "-a", default: "sprockets",
78
- enum: ASSET_PIPELINE_OPTIONS,
79
- desc: "Choose your asset pipeline"
80
-
81
76
  class_option :skip_javascript, type: :boolean, aliases: ["-J", "--skip-js"], default: (true if name == "plugin"),
82
77
  desc: "Skip JavaScript files"
83
78
 
@@ -99,6 +94,9 @@ module Rails
99
94
  class_option :skip_dev_gems, type: :boolean, default: nil,
100
95
  desc: "Skip development gems (e.g., web-console)"
101
96
 
97
+ class_option :skip_thruster, type: :boolean, default: nil,
98
+ desc: "Skip Thruster setup"
99
+
102
100
  class_option :skip_rubocop, type: :boolean, default: nil,
103
101
  desc: "Skip RuboCop setup"
104
102
 
@@ -108,10 +106,16 @@ module Rails
108
106
  class_option :skip_ci, type: :boolean, default: nil,
109
107
  desc: "Skip GitHub CI files"
110
108
 
109
+ class_option :skip_kamal, type: :boolean, default: nil,
110
+ desc: "Skip Kamal setup"
111
+
112
+ class_option :skip_solid, type: :boolean, default: nil,
113
+ desc: "Skip Solid Cache & Queue setup"
114
+
111
115
  class_option :dev, type: :boolean, default: nil,
112
116
  desc: "Set up the #{name} with Gemfile pointing to your Rails checkout"
113
117
 
114
- class_option :devcontainer, type: :boolean, default: false,
118
+ class_option :devcontainer, type: :boolean, default: nil,
115
119
  desc: "Generate devcontainer files"
116
120
 
117
121
  class_option :edge, type: :boolean, default: nil,
@@ -197,7 +201,7 @@ module Rails
197
201
 
198
202
  OPTION_IMPLICATIONS = { # :nodoc:
199
203
  skip_active_job: [:skip_action_mailer, :skip_active_storage],
200
- skip_active_record: [:skip_active_storage],
204
+ skip_active_record: [:skip_active_storage, :skip_solid],
201
205
  skip_active_storage: [:skip_action_mailbox, :skip_action_text],
202
206
  skip_javascript: [:skip_hotwire],
203
207
  }
@@ -287,12 +291,7 @@ module Rails
287
291
  end
288
292
 
289
293
  def asset_pipeline_gemfile_entry
290
- return if skip_asset_pipeline?
291
-
292
- if options[:asset_pipeline] == "sprockets"
293
- GemfileEntry.floats "sprockets-rails",
294
- "The original asset pipeline for Rails [https://github.com/rails/sprockets-rails]"
295
- elsif options[:asset_pipeline] == "propshaft"
294
+ unless skip_asset_pipeline?
296
295
  GemfileEntry.floats "propshaft", "The modern asset pipeline for Rails [https://github.com/rails/propshaft]"
297
296
  end
298
297
  end
@@ -386,12 +385,8 @@ module Rails
386
385
  options[:skip_asset_pipeline]
387
386
  end
388
387
 
389
- def skip_sprockets?
390
- skip_asset_pipeline? || options[:asset_pipeline] != "sprockets"
391
- end
392
-
393
- def skip_propshaft?
394
- skip_asset_pipeline? || options[:asset_pipeline] != "propshaft"
388
+ def skip_thruster?
389
+ options[:skip_thruster]
395
390
  end
396
391
 
397
392
  def skip_rubocop?
@@ -414,6 +409,14 @@ module Rails
414
409
  options[:devcontainer]
415
410
  end
416
411
 
412
+ def skip_kamal?
413
+ options[:skip_kamal]
414
+ end
415
+
416
+ def skip_solid?
417
+ options[:skip_solid]
418
+ end
419
+
417
420
  class GemfileEntry < Struct.new(:name, :version, :comment, :options, :commented_out)
418
421
  def initialize(name, version, comment, options = {}, commented_out = false)
419
422
  super
@@ -572,7 +575,7 @@ module Rails
572
575
  end
573
576
 
574
577
  def dockerfile_base_packages
575
- # Add curl to work with the default healthcheck strategy in Kamal
578
+ # Add curl to work with the default health check strategy in Kamal
576
579
  packages = ["curl"]
577
580
 
578
581
  # ActiveRecord databases
@@ -589,7 +592,7 @@ module Rails
589
592
 
590
593
  def dockerfile_build_packages
591
594
  # start with the essentials
592
- packages = %w(build-essential git pkg-config libyaml-dev)
595
+ packages = %w(build-essential git pkg-config)
593
596
 
594
597
  # add database support
595
598
  packages << database.build_package unless skip_active_record?
@@ -620,10 +623,10 @@ module Rails
620
623
  end
621
624
 
622
625
  def cable_gemfile_entry
623
- return if options[:skip_action_cable]
624
-
625
- comment = "Use Redis adapter to run Action Cable in production"
626
- GemfileEntry.new("redis", ">= 4.0.1", comment, {}, true)
626
+ if !options[:skip_action_cable] && options[:skip_solid]
627
+ comment = "Use Redis adapter to run Action Cable in production"
628
+ GemfileEntry.new("redis", ">= 4.0.1", comment, {}, true)
629
+ end
627
630
  end
628
631
 
629
632
  def bundle_command(command, env = {})
@@ -665,7 +668,7 @@ module Rails
665
668
  end
666
669
 
667
670
  def depend_on_bootsnap?
668
- !options[:skip_bootsnap] && !options[:dev] && !jruby?
671
+ !options[:skip_bootsnap] && !options[:dev] && !defined?(JRUBY_VERSION)
669
672
  end
670
673
 
671
674
  def target_rails_prerelease(self_command = "new")
@@ -721,8 +724,27 @@ module Rails
721
724
  end
722
725
  end
723
726
 
727
+ def run_kamal
728
+ return if options[:skip_kamal] || !bundle_install?
729
+
730
+ bundle_command "binstubs kamal"
731
+ bundle_command "exec kamal init"
732
+
733
+ template "kamal-secrets.tt", ".kamal/secrets", force: true
734
+ template "config/deploy.yml", force: true
735
+ end
736
+
737
+ def run_solid
738
+ return if skip_solid? || !bundle_install?
739
+
740
+ commands = "solid_cache:install solid_queue:install"
741
+ commands += " solid_cable:install" unless skip_action_cable?
742
+
743
+ rails_command commands
744
+ end
745
+
724
746
  def add_bundler_platforms
725
- if bundle_install? && !jruby?
747
+ if bundle_install?
726
748
  # The vast majority of Rails apps will be deployed on `x86_64-linux`.
727
749
  bundle_command("lock --add-platform=x86_64-linux")
728
750
 
@@ -731,10 +753,6 @@ module Rails
731
753
  end
732
754
  end
733
755
 
734
- def jruby?
735
- defined?(JRUBY_VERSION)
736
- end
737
-
738
756
  def generate_bundler_binstub
739
757
  if bundle_install?
740
758
  bundle_command("binstubs bundler")
@@ -3,25 +3,91 @@
3
3
  module Rails
4
4
  module Generators
5
5
  class Database
6
- DATABASES = %w( mysql trilogy postgresql sqlite3 )
6
+ DATABASES = %w( mysql trilogy postgresql sqlite3 mariadb-mysql mariadb-trilogy )
7
+
8
+ module MySQL
9
+ def name
10
+ "mysql"
11
+ end
12
+
13
+ def port
14
+ 3306
15
+ end
16
+
17
+ def service
18
+ {
19
+ "image" => "mysql/mysql-server:8.0",
20
+ "restart" => "unless-stopped",
21
+ "environment" => {
22
+ "MYSQL_ALLOW_EMPTY_PASSWORD" => "true",
23
+ "MYSQL_ROOT_HOST" => "%"
24
+ },
25
+ "volumes" => ["mysql-data:/var/lib/mysql"],
26
+ "networks" => ["default"],
27
+ }
28
+ end
29
+
30
+ def socket
31
+ @socket ||= [
32
+ "/tmp/mysql.sock", # default
33
+ "/var/run/mysqld/mysqld.sock", # debian/gentoo
34
+ "/var/tmp/mysql.sock", # freebsd
35
+ "/var/lib/mysql/mysql.sock", # fedora
36
+ "/opt/local/lib/mysql/mysql.sock", # fedora
37
+ "/opt/local/var/run/mysqld/mysqld.sock", # mac + darwinports + mysql
38
+ "/opt/local/var/run/mysql4/mysqld.sock", # mac + darwinports + mysql4
39
+ "/opt/local/var/run/mysql5/mysqld.sock", # mac + darwinports + mysql5
40
+ "/opt/lampp/var/mysql/mysql.sock" # xampp for linux
41
+ ].find { |f| File.exist?(f) } unless Gem.win_platform?
42
+ end
43
+
44
+ def host
45
+ "127.0.0.1"
46
+ end
47
+ end
48
+
49
+ module MariaDB
50
+ def name
51
+ "mariadb"
52
+ end
53
+
54
+ def port
55
+ 3306
56
+ end
57
+
58
+ def service
59
+ {
60
+ "image" => "mariadb:10.5",
61
+ "restart" => "unless-stopped",
62
+ "networks" => ["default"],
63
+ "volumes" => ["mariadb-data:/var/lib/mysql"],
64
+ "environment" => {
65
+ "MARIADB_ALLOW_EMPTY_ROOT_PASSWORD" => "true",
66
+ },
67
+ }
68
+ end
69
+ end
7
70
 
8
71
  class << self
9
72
  def build(database_name)
10
73
  case database_name
11
- when "mysql" then MySQL.new
74
+ when "mysql" then MySQL2.new
12
75
  when "postgresql" then PostgreSQL.new
13
- when "trilogy" then MariaDB.new
76
+ when "trilogy" then Trilogy.new
14
77
  when "sqlite3" then SQLite3.new
78
+ when "mariadb-mysql" then MariaDBMySQL2.new
79
+ when "mariadb-trilogy" then MariaDBTrilogy.new
15
80
  else Null.new
16
81
  end
17
82
  end
18
83
 
19
84
  def all
20
85
  @all ||= [
21
- MySQL.new,
86
+ MySQL2.new,
22
87
  PostgreSQL.new,
23
- MariaDB.new,
24
88
  SQLite3.new,
89
+ MariaDBMySQL2.new,
90
+ MariaDBTrilogy.new
25
91
  ]
26
92
  end
27
93
  end
@@ -30,6 +96,10 @@ module Rails
30
96
  raise NotImplementedError
31
97
  end
32
98
 
99
+ def template
100
+ raise NotImplementedError
101
+ end
102
+
33
103
  def service
34
104
  raise NotImplementedError
35
105
  end
@@ -69,48 +139,11 @@ module Rails
69
139
  "#{name}-data"
70
140
  end
71
141
 
72
- module MySqlSocket
73
- def socket
74
- @socket ||= [
75
- "/tmp/mysql.sock", # default
76
- "/var/run/mysqld/mysqld.sock", # debian/gentoo
77
- "/var/tmp/mysql.sock", # freebsd
78
- "/var/lib/mysql/mysql.sock", # fedora
79
- "/opt/local/lib/mysql/mysql.sock", # fedora
80
- "/opt/local/var/run/mysqld/mysqld.sock", # mac + darwinports + mysql
81
- "/opt/local/var/run/mysql4/mysqld.sock", # mac + darwinports + mysql4
82
- "/opt/local/var/run/mysql5/mysqld.sock", # mac + darwinports + mysql5
83
- "/opt/lampp/var/mysql/mysql.sock" # xampp for linux
84
- ].find { |f| File.exist?(f) } unless Gem.win_platform?
85
- end
86
-
87
- def host
88
- "localhost"
89
- end
90
- end
91
-
92
- class MySQL < Database
93
- include MySqlSocket
142
+ class MySQL2 < Database
143
+ include MySQL
94
144
 
95
- def name
96
- "mysql"
97
- end
98
-
99
- def service
100
- {
101
- "image" => "mysql/mysql-server:8.0",
102
- "restart" => "unless-stopped",
103
- "environment" => {
104
- "MYSQL_ALLOW_EMPTY_PASSWORD" => "true",
105
- "MYSQL_ROOT_HOST" => "%"
106
- },
107
- "volumes" => ["mysql-data:/var/lib/mysql"],
108
- "networks" => ["default"],
109
- }
110
- end
111
-
112
- def port
113
- 3306
145
+ def template
146
+ "config/databases/mysql.yml"
114
147
  end
115
148
 
116
149
  def gem
@@ -135,6 +168,10 @@ module Rails
135
168
  "postgres"
136
169
  end
137
170
 
171
+ def template
172
+ "config/databases/postgresql.yml"
173
+ end
174
+
138
175
  def service
139
176
  {
140
177
  "image" => "postgres:16.1",
@@ -169,27 +206,11 @@ module Rails
169
206
  end
170
207
  end
171
208
 
172
- class MariaDB < Database
173
- include MySqlSocket
209
+ class Trilogy < Database
210
+ include MySQL
174
211
 
175
- def name
176
- "mariadb"
177
- end
178
-
179
- def service
180
- {
181
- "image" => "mariadb:10.5",
182
- "restart" => "unless-stopped",
183
- "networks" => ["default"],
184
- "volumes" => ["mariadb-data:/var/lib/mysql"],
185
- "environment" => {
186
- "MARIADB_ALLOW_EMPTY_ROOT_PASSWORD" => "true",
187
- },
188
- }
189
- end
190
-
191
- def port
192
- 3306
212
+ def template
213
+ "config/databases/trilogy.yml"
193
214
  end
194
215
 
195
216
  def gem
@@ -214,6 +235,10 @@ module Rails
214
235
  "sqlite3"
215
236
  end
216
237
 
238
+ def template
239
+ "config/databases/sqlite3.yml"
240
+ end
241
+
217
242
  def service
218
243
  nil
219
244
  end
@@ -223,7 +248,7 @@ module Rails
223
248
  end
224
249
 
225
250
  def gem
226
- ["sqlite3", [">= 1.4"]]
251
+ ["sqlite3", [">= 2.1"]]
227
252
  end
228
253
 
229
254
  def base_package
@@ -239,8 +264,17 @@ module Rails
239
264
  end
240
265
  end
241
266
 
267
+ class MariaDBMySQL2 < MySQL2
268
+ include MariaDB
269
+ end
270
+
271
+ class MariaDBTrilogy < Trilogy
272
+ include MariaDB
273
+ end
274
+
242
275
  class Null < Database
243
276
  def name; end
277
+ def template; end
244
278
  def service; end
245
279
  def port; end
246
280
  def volume; end