railties 7.1.5.1 → 7.2.2.1

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 (131) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +197 -767
  3. data/lib/minitest/rails_plugin.rb +5 -2
  4. data/lib/rails/all.rb +1 -3
  5. data/lib/rails/api/task.rb +6 -4
  6. data/lib/rails/application/bootstrap.rb +5 -6
  7. data/lib/rails/application/configuration.rb +68 -33
  8. data/lib/rails/application/dummy_config.rb +2 -2
  9. data/lib/rails/application/finisher.rb +7 -0
  10. data/lib/rails/application.rb +22 -89
  11. data/lib/rails/backtrace_cleaner.rb +14 -1
  12. data/lib/rails/cli.rb +0 -1
  13. data/lib/rails/command.rb +1 -1
  14. data/lib/rails/commands/app/update_command.rb +102 -0
  15. data/lib/rails/commands/boot/boot_command.rb +14 -0
  16. data/lib/rails/commands/console/console_command.rb +2 -21
  17. data/lib/rails/commands/console/irb_console.rb +146 -0
  18. data/lib/rails/commands/credentials/credentials_command.rb +2 -2
  19. data/lib/rails/commands/dbconsole/dbconsole_command.rb +21 -30
  20. data/lib/rails/commands/devcontainer/devcontainer_command.rb +39 -0
  21. data/lib/rails/commands/rake/rake_command.rb +1 -1
  22. data/lib/rails/commands/runner/runner_command.rb +14 -3
  23. data/lib/rails/commands/server/server_command.rb +5 -3
  24. data/lib/rails/commands/test/test_command.rb +2 -0
  25. data/lib/rails/configuration.rb +10 -1
  26. data/lib/rails/console/app.rb +5 -32
  27. data/lib/rails/console/helpers.rb +5 -16
  28. data/lib/rails/console/methods.rb +23 -0
  29. data/lib/rails/engine.rb +7 -7
  30. data/lib/rails/gem_version.rb +2 -2
  31. data/lib/rails/generators/app_base.rb +70 -49
  32. data/lib/rails/generators/base.rb +5 -1
  33. data/lib/rails/generators/database.rb +227 -69
  34. data/lib/rails/generators/erb/scaffold/templates/edit.html.erb.tt +2 -0
  35. data/lib/rails/generators/erb/scaffold/templates/index.html.erb.tt +2 -0
  36. data/lib/rails/generators/erb/scaffold/templates/new.html.erb.tt +2 -0
  37. data/lib/rails/generators/generated_attribute.rb +26 -1
  38. data/lib/rails/generators/rails/app/app_generator.rb +56 -28
  39. data/lib/rails/generators/rails/app/templates/Dockerfile.tt +22 -15
  40. data/lib/rails/generators/rails/app/templates/Gemfile.tt +17 -17
  41. data/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb.tt +4 -0
  42. data/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt +8 -1
  43. data/lib/rails/generators/rails/app/templates/app/views/pwa/manifest.json.erb.tt +22 -0
  44. data/lib/rails/generators/rails/app/templates/app/views/pwa/service-worker.js +26 -0
  45. data/lib/rails/generators/rails/app/templates/bin/brakeman.tt +6 -0
  46. data/lib/rails/generators/rails/app/templates/bin/rubocop.tt +7 -0
  47. data/lib/rails/generators/rails/app/templates/bin/setup.tt +6 -2
  48. data/lib/rails/generators/rails/app/templates/config/application.rb.tt +1 -1
  49. data/lib/rails/generators/rails/app/templates/config/databases/mysql.yml.tt +3 -3
  50. data/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml.tt +7 -0
  51. data/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml.tt +8 -1
  52. data/lib/rails/generators/rails/app/templates/config/databases/trilogy.yml.tt +3 -3
  53. data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +14 -7
  54. data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +8 -0
  55. data/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +8 -5
  56. data/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt +1 -1
  57. data/lib/rails/generators/rails/app/templates/config/initializers/filter_parameter_logging.rb.tt +1 -1
  58. data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_7_2.rb.tt +70 -0
  59. data/lib/rails/generators/rails/app/templates/config/puma.rb.tt +25 -35
  60. data/lib/rails/generators/rails/app/templates/config/routes.rb.tt +6 -0
  61. data/lib/rails/generators/rails/app/templates/docker-entrypoint.tt +5 -0
  62. data/lib/rails/generators/rails/app/templates/dockerignore.tt +13 -0
  63. data/lib/rails/generators/rails/app/templates/github/ci.yml.tt +138 -0
  64. data/lib/rails/generators/rails/app/templates/github/dependabot.yml +12 -0
  65. data/lib/rails/generators/rails/app/templates/gitignore.tt +3 -3
  66. data/lib/rails/generators/rails/app/templates/public/406-unsupported-browser.html +66 -0
  67. data/lib/rails/generators/rails/app/templates/public/icon.png +0 -0
  68. data/lib/rails/generators/rails/app/templates/public/icon.svg +3 -0
  69. data/lib/rails/generators/rails/app/templates/rubocop.yml.tt +8 -0
  70. data/lib/rails/generators/rails/app/templates/test/application_system_test_case.rb.tt +1 -1
  71. data/lib/rails/generators/rails/controller/controller_generator.rb +1 -1
  72. data/lib/rails/generators/rails/db/system/change/change_generator.rb +131 -20
  73. data/lib/rails/generators/rails/devcontainer/devcontainer_generator.rb +166 -0
  74. data/lib/rails/generators/rails/devcontainer/templates/devcontainer/Dockerfile.tt +3 -0
  75. data/lib/rails/generators/rails/devcontainer/templates/devcontainer/compose.yaml.tt +47 -0
  76. data/lib/rails/generators/rails/devcontainer/templates/devcontainer/devcontainer.json.tt +37 -0
  77. data/lib/rails/generators/rails/migration/migration_generator.rb +4 -0
  78. data/lib/rails/generators/rails/plugin/plugin_generator.rb +40 -7
  79. data/lib/rails/generators/rails/plugin/templates/%name%.gemspec.tt +2 -2
  80. data/lib/rails/generators/rails/plugin/templates/Gemfile.tt +5 -1
  81. data/lib/rails/generators/rails/plugin/templates/app/views/layouts/%namespaced_name%/application.html.erb.tt +2 -0
  82. data/lib/rails/generators/rails/plugin/templates/bin/rubocop.tt +7 -0
  83. data/lib/rails/generators/rails/plugin/templates/github/ci.yml.tt +103 -0
  84. data/lib/rails/generators/rails/plugin/templates/github/dependabot.yml +12 -0
  85. data/lib/rails/generators/rails/plugin/templates/rubocop.yml.tt +8 -0
  86. data/lib/rails/generators/rails/plugin/templates/test/application_system_test_case.rb.tt +1 -1
  87. data/lib/rails/generators/rails/plugin/templates/test/test_helper.rb.tt +2 -2
  88. data/lib/rails/generators/test_unit/mailer/templates/functional_test.rb.tt +6 -4
  89. data/lib/rails/generators/test_unit/mailer/templates/preview.rb.tt +3 -2
  90. data/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb +15 -1
  91. data/lib/rails/generators/test_unit/scaffold/templates/api_functional_test.rb.tt +2 -2
  92. data/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb.tt +2 -2
  93. data/lib/rails/generators/test_unit/scaffold/templates/system_test.rb.tt +2 -0
  94. data/lib/rails/generators/test_unit/system/templates/application_system_test_case.rb.tt +1 -1
  95. data/lib/rails/generators/testing/assertions.rb +20 -0
  96. data/lib/rails/generators/testing/behavior.rb +7 -6
  97. data/lib/rails/generators.rb +6 -2
  98. data/lib/rails/health_controller.rb +1 -1
  99. data/lib/rails/info.rb +2 -2
  100. data/lib/rails/mailers_controller.rb +14 -1
  101. data/lib/rails/paths.rb +2 -2
  102. data/lib/rails/pwa_controller.rb +15 -0
  103. data/lib/rails/rack/logger.rb +15 -7
  104. data/lib/rails/railtie/configurable.rb +2 -2
  105. data/lib/rails/railtie.rb +2 -3
  106. data/lib/rails/tasks/framework.rake +0 -26
  107. data/lib/rails/tasks/tmp.rake +1 -1
  108. data/lib/rails/templates/layouts/application.html.erb +1 -1
  109. data/lib/rails/templates/rails/mailers/email.html.erb +12 -8
  110. data/lib/rails/templates/rails/welcome/index.html.erb +4 -2
  111. data/lib/rails/test_help.rb +2 -4
  112. data/lib/rails/test_unit/reporter.rb +8 -2
  113. data/lib/rails/test_unit/runner.rb +26 -2
  114. data/lib/rails/test_unit/test_parser.rb +45 -0
  115. data/lib/rails.rb +6 -3
  116. metadata +40 -30
  117. data/lib/rails/app_updater.rb +0 -52
  118. data/lib/rails/commands/secrets/USAGE +0 -61
  119. data/lib/rails/commands/secrets/secrets_command.rb +0 -47
  120. data/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml.tt +0 -68
  121. data/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml.tt +0 -54
  122. data/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml.tt +0 -70
  123. data/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml.tt +0 -24
  124. data/lib/rails/generators/rails/app/templates/config/databases/oracle.yml.tt +0 -62
  125. data/lib/rails/generators/rails/app/templates/config/databases/sqlserver.yml.tt +0 -53
  126. data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_7_1.rb.tt +0 -280
  127. data/lib/rails/generators/rails/app/templates/public/apple-touch-icon-precomposed.png +0 -0
  128. data/lib/rails/generators/rails/app/templates/public/apple-touch-icon.png +0 -0
  129. data/lib/rails/generators/rails/app/templates/public/favicon.ico +0 -0
  130. data/lib/rails/ruby_version_check.rb +0 -17
  131. data/lib/rails/secrets.rb +0 -110
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "rails/generators/app_base"
4
+ require "rails/generators/rails/devcontainer/devcontainer_generator"
4
5
 
5
6
  module Rails
6
7
  module ActionMethods # :nodoc:
@@ -15,8 +16,8 @@ module Rails
15
16
  %w(template copy_file directory empty_directory inside
16
17
  empty_directory_with_keep_file create_file chmod shebang).each do |method|
17
18
  class_eval <<-RUBY, __FILE__, __LINE__ + 1
18
- def #{method}(*args, &block)
19
- @generator.send(:#{method}, *args, &block)
19
+ def #{method}(...)
20
+ @generator.send(:#{method}, ...)
20
21
  end
21
22
  RUBY
22
23
  end
@@ -82,6 +83,16 @@ module Rails
82
83
  chmod "bin/docker-entrypoint", 0755 & ~File.umask, verbose: false
83
84
  end
84
85
 
86
+ def cifiles
87
+ empty_directory ".github/workflows"
88
+ template "github/ci.yml", ".github/workflows/ci.yml"
89
+ template "github/dependabot.yml", ".github/dependabot.yml"
90
+ end
91
+
92
+ def rubocop
93
+ template "rubocop.yml", ".rubocop.yml"
94
+ end
95
+
85
96
  def version_control
86
97
  if !options[:skip_git] && !options[:pretend]
87
98
  run git_init_command, capture: options[:quiet], abort_on_failure: false
@@ -98,7 +109,8 @@ module Rails
98
109
  end
99
110
 
100
111
  def bin
101
- directory "bin" do |content|
112
+ exclude_pattern = Regexp.union([(/rubocop/ if skip_rubocop?), (/brakeman/ if skip_brakeman?)].compact)
113
+ directory "bin", { exclude_pattern: exclude_pattern } do |content|
102
114
  "#{shebang}\n" + content
103
115
  end
104
116
  chmod "bin", 0755 & ~File.umask, verbose: false
@@ -116,7 +128,7 @@ module Rails
116
128
  template "application.rb"
117
129
  template "environment.rb"
118
130
  template "cable.yml" unless options[:update] || options[:skip_action_cable]
119
- template "puma.rb" unless options[:update]
131
+ template "puma.rb"
120
132
  template "storage.yml" unless options[:update] || skip_active_storage?
121
133
 
122
134
  directory "environments"
@@ -217,6 +229,8 @@ module Rails
217
229
  end
218
230
 
219
231
  def public_directory
232
+ return if options[:update] && options[:api]
233
+
220
234
  directory "public", "public", recursive: false
221
235
  end
222
236
 
@@ -246,8 +260,6 @@ module Rails
246
260
  def tmp
247
261
  empty_directory_with_keep_file "tmp"
248
262
  empty_directory_with_keep_file "tmp/pids"
249
- empty_directory "tmp/cache"
250
- empty_directory "tmp/cache/assets"
251
263
  end
252
264
 
253
265
  def vendor
@@ -255,15 +267,25 @@ module Rails
255
267
  end
256
268
 
257
269
  def config_target_version
258
- defined?(@config_target_version) ? @config_target_version : Rails::VERSION::STRING.to_f
270
+ @config_target_version || Rails::VERSION::STRING.to_f
271
+ end
272
+
273
+ def devcontainer
274
+ devcontainer_options = {
275
+ database: options[:database],
276
+ redis: !(options[:skip_action_cable] && options[:skip_active_job]),
277
+ system_test: depends_on_system_test?,
278
+ active_storage: !options[:skip_active_storage],
279
+ dev: options[:dev],
280
+ node: using_node?,
281
+ app_name: app_name
282
+ }
283
+
284
+ Rails::Generators::DevcontainerGenerator.new([], devcontainer_options).invoke_all
259
285
  end
260
286
  end
261
287
 
262
288
  module Generators
263
- # We need to store the RAILS_DEV_PATH in a constant, otherwise the path
264
- # can change in Ruby 1.8.7 when we FileUtils.cd.
265
- RAILS_DEV_PATH = File.expand_path("../../../../../..", __dir__)
266
-
267
289
  class AppGenerator < AppBase
268
290
  # :stopdoc:
269
291
 
@@ -273,8 +295,8 @@ module Rails
273
295
  class_option :version, type: :boolean, aliases: "-v", group: :rails, desc: "Show Rails version number and quit"
274
296
  class_option :api, type: :boolean, desc: "Preconfigure smaller stack for API only apps"
275
297
  class_option :minimal, type: :boolean, desc: "Preconfigure a minimal rails app"
276
- class_option :javascript, type: :string, aliases: ["-j", "--js"], default: "importmap", desc: "Choose JavaScript approach [options: importmap (default), bun, webpack, esbuild, rollup]"
277
- class_option :css, type: :string, aliases: "-c", desc: "Choose CSS processor [options: tailwind, bootstrap, bulma, postcss, sass] check https://github.com/rails/cssbundling-rails for more options"
298
+ class_option :javascript, type: :string, aliases: ["-j", "--js"], default: "importmap", enum: JAVASCRIPT_OPTIONS, desc: "Choose JavaScript approach"
299
+ class_option :css, type: :string, aliases: "-c", enum: CSS_OPTIONS, desc: "Choose CSS processor. Check https://github.com/rails/cssbundling-rails for more options"
278
300
  class_option :skip_bundle, type: :boolean, aliases: "-B", default: nil, desc: "Don't run bundle install"
279
301
  class_option :skip_decrypted_diffs, type: :boolean, default: nil, desc: "Don't configure git to show decrypted diffs of encrypted credentials"
280
302
 
@@ -318,10 +340,6 @@ module Rails
318
340
 
319
341
  imply_options(OPTION_IMPLICATIONS, meta_options: META_OPTIONS)
320
342
 
321
- if !options[:skip_active_record] && !DATABASES.include?(options[:database])
322
- raise Error, "Invalid value for --database option. Supported preconfigurations are: #{DATABASES.join(", ")}."
323
- end
324
-
325
343
  @after_bundle_callbacks = []
326
344
  end
327
345
 
@@ -371,6 +389,16 @@ module Rails
371
389
  build(:dockerfiles)
372
390
  end
373
391
 
392
+ def create_rubocop_file
393
+ return if skip_rubocop?
394
+ build(:rubocop)
395
+ end
396
+
397
+ def create_cifiles
398
+ return if skip_ci?
399
+ build(:cifiles)
400
+ end
401
+
374
402
  def create_config_files
375
403
  build(:config)
376
404
  end
@@ -389,11 +417,6 @@ module Rails
389
417
  build(:credentials_diff_enroll)
390
418
  end
391
419
 
392
- def display_upgrade_guide_info
393
- say "\nAfter this, check Rails upgrade guide at https://guides.rubyonrails.org/upgrading_ruby_on_rails.html for more details about upgrading your app."
394
- end
395
- remove_task :display_upgrade_guide_info
396
-
397
420
  def create_boot_file
398
421
  template "config/boot.rb"
399
422
  end
@@ -437,14 +460,18 @@ module Rails
437
460
  end
438
461
 
439
462
  def create_storage_files
440
- build(:storage)
463
+ build(:storage) unless skip_storage?
464
+ end
465
+
466
+ def create_devcontainer_files
467
+ return if skip_devcontainer? || options[:dummy_app]
468
+ build(:devcontainer)
441
469
  end
442
470
 
443
471
  def delete_app_assets_if_api_option
444
472
  if options[:api]
445
473
  remove_dir "app/assets"
446
474
  remove_dir "lib/assets"
447
- remove_dir "tmp/cache/assets"
448
475
  end
449
476
  end
450
477
 
@@ -461,6 +488,7 @@ module Rails
461
488
  remove_dir "app/views"
462
489
  else
463
490
  remove_file "app/views/layouts/application.html.erb"
491
+ remove_dir "app/views/pwa"
464
492
  end
465
493
  end
466
494
  end
@@ -468,11 +496,11 @@ module Rails
468
496
  def delete_public_files_if_api_option
469
497
  if options[:api]
470
498
  remove_file "public/404.html"
499
+ remove_file "public/406-unsupported-browser.html"
471
500
  remove_file "public/422.html"
472
501
  remove_file "public/500.html"
473
- remove_file "public/apple-touch-icon-precomposed.png"
474
- remove_file "public/apple-touch-icon.png"
475
- remove_file "public/favicon.ico"
502
+ remove_file "public/icon.png"
503
+ remove_file "public/icon.svg"
476
504
  end
477
505
  end
478
506
 
@@ -644,7 +672,7 @@ module Rails
644
672
  end
645
673
 
646
674
  def read_rc_file(railsrc)
647
- extra_args = File.readlines(railsrc).flat_map(&:split)
675
+ extra_args = File.readlines(railsrc).flat_map.each { |line| line.split("#", 2).first.split }
648
676
  puts "Using #{extra_args.join(" ")} from #{railsrc}"
649
677
  extra_args
650
678
  end
@@ -1,25 +1,34 @@
1
1
  # syntax = docker/dockerfile:1
2
2
 
3
- # Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile
3
+ # This Dockerfile is designed for production, not development. Use with Kamal or build'n'run by hand:
4
+ # docker build -t my-app .
5
+ # docker run -d -p 80:80 -p 443:443 --name my-app -e RAILS_MASTER_KEY=<value from config/master.key> my-app
6
+
7
+ # Make sure RUBY_VERSION matches the Ruby version in .ruby-version
4
8
  ARG RUBY_VERSION=<%= gem_ruby_version %>
5
- FROM registry.docker.com/library/ruby:$RUBY_VERSION-slim as base
9
+ FROM docker.io/library/ruby:$RUBY_VERSION-slim AS base
6
10
 
7
11
  # Rails app lives here
8
12
  WORKDIR /rails
9
13
 
14
+ # Install base packages
15
+ RUN apt-get update -qq && \
16
+ apt-get install --no-install-recommends -y <%= dockerfile_base_packages.join(" ") %> && \
17
+ rm -rf /var/lib/apt/lists /var/cache/apt/archives
18
+
10
19
  # Set production environment
11
20
  ENV RAILS_ENV="production" \
12
21
  BUNDLE_DEPLOYMENT="1" \
13
22
  BUNDLE_PATH="/usr/local/bundle" \
14
23
  BUNDLE_WITHOUT="development"
15
24
 
16
-
17
25
  # Throw-away build stage to reduce size of final image
18
- FROM base as build
26
+ FROM base AS build
19
27
 
20
28
  # Install packages needed to build gems<%= using_node? ? " and node modules" : "" %>
21
29
  RUN apt-get update -qq && \
22
- apt-get install --no-install-recommends -y <%= dockerfile_build_packages.join(" ") %>
30
+ apt-get install --no-install-recommends -y <%= dockerfile_build_packages.join(" ") %> && \
31
+ rm -rf /var/lib/apt/lists /var/cache/apt/archives
23
32
 
24
33
  <% if using_node? -%>
25
34
  # Install JavaScript dependencies
@@ -76,24 +85,22 @@ RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile
76
85
 
77
86
  <% end -%>
78
87
 
88
+ <% if using_node? -%>
89
+ RUN rm -rf node_modules
90
+ <% end %>
91
+
79
92
  # Final stage for app image
80
93
  FROM base
81
94
 
82
- <% unless dockerfile_deploy_packages.empty? -%>
83
- # Install packages needed for deployment
84
- RUN apt-get update -qq && \
85
- apt-get install --no-install-recommends -y <%= dockerfile_deploy_packages.join(" ") %> && \
86
- rm -rf /var/lib/apt/lists /var/cache/apt/archives
87
-
88
- <% end -%>
89
95
  # Copy built artifacts: gems, application
90
- COPY --from=build /usr/local/bundle /usr/local/bundle
96
+ COPY --from=build "${BUNDLE_PATH}" "${BUNDLE_PATH}"
91
97
  COPY --from=build /rails /rails
92
98
 
93
99
  # Run and own only the runtime files as a non-root user for security
94
- RUN useradd rails --create-home --shell /bin/bash && \
100
+ RUN groupadd --system --gid 1000 rails && \
101
+ useradd rails --uid 1000 --gid 1000 --create-home --shell /bin/bash && \
95
102
  chown -R rails:rails <%= dockerfile_chown_directories.join(" ") %>
96
- USER rails:rails
103
+ USER 1000:1000
97
104
 
98
105
  # Entrypoint prepares the database.
99
106
  ENTRYPOINT ["/rails/bin/docker-entrypoint"]
@@ -1,8 +1,6 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- ruby <%= "\"#{gem_ruby_version}\"" -%>
4
-
5
- <% gemfile_entries.each do |gemfile_entry| %>
3
+ <% gemfile_entries.each do |gemfile_entry| -%>
6
4
  <%= gemfile_entry %>
7
5
  <% end -%>
8
6
  <% unless options.minimal? -%>
@@ -35,34 +33,36 @@ gem "bootsnap", require: false
35
33
 
36
34
  group :development, :test do
37
35
  # See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem
38
- gem "debug", platforms: %i[ mri <%= bundler_windows_platforms %> ]
36
+ gem "debug", platforms: %i[ mri <%= bundler_windows_platforms %> ], require: "debug/prelude"
37
+ <%- unless options.skip_brakeman? -%>
38
+
39
+ # Static analysis for security vulnerabilities [https://brakemanscanner.org/]
40
+ gem "brakeman", require: false
41
+ <%- end -%>
42
+ <%- unless options.skip_rubocop? -%>
43
+
44
+ # Omakase Ruby styling [https://github.com/rails/rubocop-rails-omakase/]
45
+ gem "rubocop-rails-omakase", require: false
46
+ <%- end -%>
39
47
  end
40
48
  <% end -%>
41
49
 
42
- group :development do
43
50
  <%- unless options.api? || options.skip_dev_gems? -%>
51
+ group :development do
44
52
  # Use console on exceptions pages [https://github.com/rails/web-console]
45
53
  gem "web-console"
54
+ <%- if RUBY_VERSION < "3.2" -%>
46
55
 
47
- # Add speed badges [https://github.com/MiniProfiler/rack-mini-profiler]
48
- # gem "rack-mini-profiler"
49
-
50
- <%- end -%>
51
- # Speed up commands on slow machines / big apps [https://github.com/rails/spring]
52
- # gem "spring"
53
- <%- if RUBY_VERSION >= "3.1" && RUBY_VERSION < "3.2" -%>
54
-
55
- gem "error_highlight", ">= 0.4.0", platforms: [:ruby]
56
+ # Highlight the fine-grained location where an error occurred [https://github.com/ruby/error_highlight]
57
+ gem "error_highlight", ">= 0.4.0", platforms: [ :ruby ]
56
58
  <%- end -%>
57
59
  end
60
+ <%- end -%>
58
61
 
59
62
  <%- if depends_on_system_test? -%>
60
63
  group :test do
61
64
  # Use system testing [https://guides.rubyonrails.org/testing.html#system-testing]
62
65
  gem "capybara"
63
66
  gem "selenium-webdriver"
64
- <%- if RUBY_VERSION < "3.0" -%>
65
- gem "webdrivers"
66
- <%- end -%>
67
67
  end
68
68
  <%- end -%>
@@ -1,2 +1,6 @@
1
1
  class ApplicationController < ActionController::<%= options.api? ? "API" : "Base" %>
2
+ <%- unless options.api? -%>
3
+ # Only allow modern browsers supporting webp images, web push, badges, import maps, CSS nesting, and CSS :has.
4
+ allow_browser versions: :modern
5
+ <% end -%>
2
6
  end
@@ -1,11 +1,18 @@
1
1
  <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
- <title><%= camelized %></title>
4
+ <title><%%= content_for(:title) || "<%= app_name.titleize %>" %></title>
5
5
  <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <meta name="apple-mobile-web-app-capable" content="yes">
6
7
  <%%= csrf_meta_tags %>
7
8
  <%%= csp_meta_tag %>
8
9
 
10
+ <%%= yield :head %>
11
+
12
+ <link rel="manifest" href="/manifest.json">
13
+ <link rel="icon" href="/icon.png" type="image/png">
14
+ <link rel="icon" href="/icon.svg" type="image/svg+xml">
15
+ <link rel="apple-touch-icon" href="/icon.png">
9
16
  <%- if options[:skip_hotwire] || options[:skip_javascript] -%>
10
17
  <%%= stylesheet_link_tag "application" %>
11
18
  <%- else -%>
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "<%= camelized %>",
3
+ "icons": [
4
+ {
5
+ "src": "/icon.png",
6
+ "type": "image/png",
7
+ "sizes": "512x512"
8
+ },
9
+ {
10
+ "src": "/icon.png",
11
+ "type": "image/png",
12
+ "sizes": "512x512",
13
+ "purpose": "maskable"
14
+ }
15
+ ],
16
+ "start_url": "/",
17
+ "display": "standalone",
18
+ "scope": "/",
19
+ "description": "<%= camelized %>.",
20
+ "theme_color": "red",
21
+ "background_color": "red"
22
+ }
@@ -0,0 +1,26 @@
1
+ // Add a service worker for processing Web Push notifications:
2
+ //
3
+ // self.addEventListener("push", async (event) => {
4
+ // const { title, options } = await event.data.json()
5
+ // event.waitUntil(self.registration.showNotification(title, options))
6
+ // })
7
+ //
8
+ // self.addEventListener("notificationclick", function(event) {
9
+ // event.notification.close()
10
+ // event.waitUntil(
11
+ // clients.matchAll({ type: "window" }).then((clientList) => {
12
+ // for (let i = 0; i < clientList.length; i++) {
13
+ // let client = clientList[i]
14
+ // let clientPath = (new URL(client.url)).pathname
15
+ //
16
+ // if (clientPath == event.notification.data.path && "focus" in client) {
17
+ // return client.focus()
18
+ // }
19
+ // }
20
+ //
21
+ // if (clients.openWindow) {
22
+ // return clients.openWindow(event.notification.data.path)
23
+ // }
24
+ // })
25
+ // )
26
+ // })
@@ -0,0 +1,6 @@
1
+ require "rubygems"
2
+ require "bundler/setup"
3
+
4
+ ARGV.unshift("--ensure-latest")
5
+
6
+ load Gem.bin_path("brakeman", "brakeman")
@@ -0,0 +1,7 @@
1
+ require "rubygems"
2
+ require "bundler/setup"
3
+
4
+ # explicit rubocop config increases performance slightly while avoiding config confusion.
5
+ ARGV.unshift("--config", File.expand_path("../.rubocop.yml", __dir__))
6
+
7
+ load Gem.bin_path("rubocop", "rubocop")
@@ -1,7 +1,7 @@
1
1
  require "fileutils"
2
2
 
3
- # path to your application root.
4
3
  APP_ROOT = File.expand_path("..", __dir__)
4
+ APP_NAME = "<%= app_name.dasherize %>"
5
5
 
6
6
  def system!(*args)
7
7
  system(*args, exception: true)
@@ -18,7 +18,7 @@ FileUtils.chdir APP_ROOT do
18
18
  <% if using_node? -%>
19
19
 
20
20
  # Install JavaScript dependencies
21
- system("yarn check --check-files") || system!("yarn install")
21
+ system("yarn install --check-files")
22
22
  <% elsif using_bun? -%>
23
23
 
24
24
  # Install JavaScript dependencies
@@ -40,4 +40,8 @@ FileUtils.chdir APP_ROOT do
40
40
 
41
41
  puts "\n== Restarting application server =="
42
42
  system! "bin/rails restart"
43
+
44
+ # puts "\n== Configuring puma-dev =="
45
+ # system "ln -nfs #{APP_ROOT} ~/.puma-dev/#{APP_NAME}"
46
+ # system "curl -Is https://#{APP_NAME}.test/up | head -n 1"
43
47
  end
@@ -18,7 +18,7 @@ module <%= app_const_base %>
18
18
  # Please, add to the `ignore` list any other `lib` subdirectories that do
19
19
  # not contain `.rb` files, or that should not be reloaded or eager loaded.
20
20
  # Common ones are `templates`, `generators`, or `middleware`, for example.
21
- config.autoload_lib(ignore: %w(assets tasks))
21
+ config.autoload_lib(ignore: %w[assets tasks])
22
22
 
23
23
  # Configuration for the application, engines, and railties goes here.
24
24
  #
@@ -15,10 +15,10 @@ default: &default
15
15
  pool: <%%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
16
16
  username: root
17
17
  password:
18
- <% if mysql_socket -%>
19
- socket: <%= mysql_socket %>
18
+ <% if database.socket -%>
19
+ socket: <%= database.socket %>
20
20
  <% else -%>
21
- host: localhost
21
+ host: <%%= ENV.fetch("DB_HOST") { "<%= database.host %>" } %>
22
22
  <% end -%>
23
23
 
24
24
  development:
@@ -18,6 +18,13 @@ default: &default
18
18
  # For details on connection pooling, see Rails configuration guide
19
19
  # https://guides.rubyonrails.org/configuring.html#database-pooling
20
20
  pool: <%%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
21
+ <% if devcontainer? -%>
22
+ <%% if ENV["DB_HOST"] %>
23
+ host: <%%= ENV["DB_HOST"] %>
24
+ username: postgres
25
+ password: postgres
26
+ <%% end %>
27
+ <% end %>
21
28
 
22
29
  development:
23
30
  <<: *default
@@ -20,6 +20,13 @@ test:
20
20
  <<: *default
21
21
  database: storage/test.sqlite3
22
22
 
23
+
24
+ # SQLite3 write its data on the local filesystem, as such it requires
25
+ # persistent disks. If you are deploying to a managed service, you should
26
+ # make sure it provides disk persistence, as many don't.
27
+ #
28
+ # Similarly, if you deploy your application as a Docker container, you must
29
+ # ensure the database is located in a persisted volume.
23
30
  production:
24
31
  <<: *default
25
- database: storage/production.sqlite3
32
+ # database: path/to/persistent/storage/production.sqlite3
@@ -15,10 +15,10 @@ default: &default
15
15
  pool: <%%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
16
16
  username: root
17
17
  password:
18
- <% if mysql_socket -%>
19
- socket: <%= mysql_socket %>
18
+ <% if database.socket -%>
19
+ socket: <%= database.socket %>
20
20
  <% else -%>
21
- host: localhost
21
+ host: <%%= ENV.fetch("DB_HOST") { "<%= database.host %>" } %>
22
22
  <% end -%>
23
23
 
24
24
  development:
@@ -14,7 +14,7 @@ Rails.application.configure do
14
14
  # Show full error reports.
15
15
  config.consider_all_requests_local = true
16
16
 
17
- # Enable server timing
17
+ # Enable server timing.
18
18
  config.server_timing = true
19
19
 
20
20
  # Enable/disable caching. By default caching is disabled.
@@ -26,9 +26,7 @@ Rails.application.configure do
26
26
 
27
27
  <%- end -%>
28
28
  config.cache_store = :memory_store
29
- config.public_file_server.headers = {
30
- "Cache-Control" => "public, max-age=#{2.days.to_i}"
31
- }
29
+ config.public_file_server.headers = { "Cache-Control" => "public, max-age=#{2.days.to_i}" }
32
30
  else
33
31
  config.action_controller.perform_caching = false
34
32
 
@@ -44,7 +42,11 @@ Rails.application.configure do
44
42
  # Don't care if the mailer can't send.
45
43
  config.action_mailer.raise_delivery_errors = false
46
44
 
45
+ # Disable caching for Action Mailer templates even if Action Controller
46
+ # caching is enabled.
47
47
  config.action_mailer.perform_caching = false
48
+
49
+ config.action_mailer.default_url_options = { host: "localhost", port: 3000 }
48
50
  <%- end -%>
49
51
 
50
52
  # Print deprecation notices to the Rails logger.
@@ -72,19 +74,24 @@ Rails.application.configure do
72
74
  <%- unless skip_sprockets? -%>
73
75
  # Suppress logger output for asset requests.
74
76
  config.assets.quiet = true
75
- <%- end -%>
76
77
 
78
+ <%- end -%>
77
79
  # Raises error for missing translations.
78
80
  # config.i18n.raise_on_missing_translations = true
79
81
 
80
82
  # Annotate rendered view with file names.
81
- # config.action_view.annotate_rendered_view_with_filenames = true
83
+ config.action_view.annotate_rendered_view_with_filenames = true
82
84
 
83
85
  <%- unless skip_action_cable? -%>
84
86
  # Uncomment if you wish to allow Action Cable access from any origin.
85
87
  # config.action_cable.disable_request_forgery_protection = true
86
88
 
87
89
  <%- end -%>
88
- # Raise error when a before_action's only/except options reference missing actions
90
+ # Raise error when a before_action's only/except options reference missing actions.
89
91
  config.action_controller.raise_on_missing_callback_actions = true
92
+ <%- unless skip_rubocop? -%>
93
+
94
+ # Apply autocorrection by RuboCop to files generated by `bin/rails generate`.
95
+ # config.generators.apply_rubocop_autocorrect_after_generate!
96
+ <%- end -%>
90
97
  end
@@ -59,6 +59,9 @@ Rails.application.configure do
59
59
  # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
60
60
  config.force_ssl = true
61
61
 
62
+ # Skip http-to-https redirect for the default health check endpoint.
63
+ # config.ssl_options = { redirect: { exclude: ->(request) { request.path == "/up" } } }
64
+
62
65
  # Log to STDOUT by default
63
66
  config.logger = ActiveSupport::Logger.new(STDOUT)
64
67
  .tap { |logger| logger.formatter = ::Logger::Formatter.new }
@@ -82,6 +85,8 @@ Rails.application.configure do
82
85
 
83
86
  <%- end -%>
84
87
  <%- unless options.skip_action_mailer? -%>
88
+ # Disable caching for Action Mailer templates even if Action Controller
89
+ # caching is enabled.
85
90
  config.action_mailer.perform_caching = false
86
91
 
87
92
  # Ignore bad email addresses and do not raise email delivery errors.
@@ -99,6 +104,9 @@ Rails.application.configure do
99
104
 
100
105
  # Do not dump schema after migrations.
101
106
  config.active_record.dump_schema_after_migration = false
107
+
108
+ # Only use :id for inspections in production.
109
+ config.active_record.attributes_for_inspect = [ :id ]
102
110
  <%- end -%>
103
111
 
104
112
  # Enable DNS rebinding protection and other `Host` header attacks.
@@ -18,10 +18,7 @@ Rails.application.configure do
18
18
  config.eager_load = ENV["CI"].present?
19
19
 
20
20
  # Configure public file server for tests with Cache-Control for performance.
21
- config.public_file_server.enabled = true
22
- config.public_file_server.headers = {
23
- "Cache-Control" => "public, max-age=#{1.hour.to_i}"
24
- }
21
+ config.public_file_server.headers = { "Cache-Control" => "public, max-age=#{1.hour.to_i}" }
25
22
 
26
23
  # Show full error reports and disable caching.
27
24
  config.consider_all_requests_local = true
@@ -40,6 +37,8 @@ Rails.application.configure do
40
37
 
41
38
  <%- end -%>
42
39
  <%- unless options.skip_action_mailer? -%>
40
+ # Disable caching for Action Mailer templates even if Action Controller
41
+ # caching is enabled.
43
42
  config.action_mailer.perform_caching = false
44
43
 
45
44
  # Tell Action Mailer not to deliver emails to the real world.
@@ -47,6 +46,10 @@ Rails.application.configure do
47
46
  # ActionMailer::Base.deliveries array.
48
47
  config.action_mailer.delivery_method = :test
49
48
 
49
+ # Unlike controllers, the mailer instance doesn't have any context about the
50
+ # incoming request so you'll need to provide the :host parameter yourself.
51
+ config.action_mailer.default_url_options = { host: "www.example.com" }
52
+
50
53
  <%- end -%>
51
54
  # Print deprecation notices to the stderr.
52
55
  config.active_support.deprecation = :stderr
@@ -63,6 +66,6 @@ Rails.application.configure do
63
66
  # Annotate rendered view with file names.
64
67
  # config.action_view.annotate_rendered_view_with_filenames = true
65
68
 
66
- # Raise error when a before_action's only/except options reference missing actions
69
+ # Raise error when a before_action's only/except options reference missing actions.
67
70
  config.action_controller.raise_on_missing_callback_actions = true
68
71
  end
@@ -10,5 +10,5 @@ Rails.application.config.assets.version = "1.0"
10
10
  # Precompile additional assets.
11
11
  # application.js, application.css, and all non-JS/CSS in the app/assets
12
12
  # folder are already added.
13
- # Rails.application.config.assets.precompile += %w( admin.js admin.css )
13
+ # Rails.application.config.assets.precompile += %w[ admin.js admin.css ]
14
14
  <% end -%>