railties 7.1.3.4 → 7.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (130) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +177 -742
  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 +73 -38
  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 +15 -86
  11. data/lib/rails/backtrace_cleaner.rb +18 -3
  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 +93 -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 +137 -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 +5 -5
  30. data/lib/rails/gem_version.rb +3 -3
  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/migration.rb +3 -3
  39. data/lib/rails/generators/rails/app/app_generator.rb +53 -24
  40. data/lib/rails/generators/rails/app/templates/Dockerfile.tt +22 -15
  41. data/lib/rails/generators/rails/app/templates/Gemfile.tt +16 -16
  42. data/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb.tt +4 -0
  43. data/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt +8 -1
  44. data/lib/rails/generators/rails/app/templates/app/views/pwa/manifest.json.erb.tt +22 -0
  45. data/lib/rails/generators/rails/app/templates/app/views/pwa/service-worker.js +26 -0
  46. data/lib/rails/generators/rails/app/templates/bin/brakeman.tt +6 -0
  47. data/lib/rails/generators/rails/app/templates/bin/rubocop.tt +7 -0
  48. data/lib/rails/generators/rails/app/templates/bin/setup.tt +6 -2
  49. data/lib/rails/generators/rails/app/templates/config/application.rb.tt +1 -1
  50. data/lib/rails/generators/rails/app/templates/config/databases/mysql.yml.tt +3 -3
  51. data/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml.tt +7 -0
  52. data/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml.tt +8 -1
  53. data/lib/rails/generators/rails/app/templates/config/databases/trilogy.yml.tt +3 -3
  54. data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +14 -7
  55. data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +5 -0
  56. data/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +8 -5
  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 +24 -26
  60. data/lib/rails/generators/rails/app/templates/config/routes.rb.tt +4 -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 +38 -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/test_unit/mailer/templates/functional_test.rb.tt +6 -4
  88. data/lib/rails/generators/test_unit/mailer/templates/preview.rb.tt +3 -2
  89. data/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb +15 -1
  90. data/lib/rails/generators/test_unit/scaffold/templates/api_functional_test.rb.tt +2 -2
  91. data/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb.tt +2 -2
  92. data/lib/rails/generators/test_unit/scaffold/templates/system_test.rb.tt +2 -0
  93. data/lib/rails/generators/test_unit/system/templates/application_system_test_case.rb.tt +1 -1
  94. data/lib/rails/generators/testing/assertions.rb +20 -0
  95. data/lib/rails/generators/testing/behavior.rb +7 -6
  96. data/lib/rails/generators.rb +1 -1
  97. data/lib/rails/health_controller.rb +1 -1
  98. data/lib/rails/info.rb +2 -2
  99. data/lib/rails/mailers_controller.rb +14 -1
  100. data/lib/rails/paths.rb +2 -2
  101. data/lib/rails/pwa_controller.rb +15 -0
  102. data/lib/rails/rack/logger.rb +15 -7
  103. data/lib/rails/railtie/configurable.rb +2 -2
  104. data/lib/rails/railtie.rb +2 -3
  105. data/lib/rails/tasks/framework.rake +0 -26
  106. data/lib/rails/tasks/tmp.rake +1 -1
  107. data/lib/rails/templates/layouts/application.html.erb +1 -1
  108. data/lib/rails/templates/rails/mailers/email.html.erb +12 -8
  109. data/lib/rails/templates/rails/welcome/index.html.erb +4 -2
  110. data/lib/rails/test_help.rb +2 -4
  111. data/lib/rails/test_unit/reporter.rb +8 -2
  112. data/lib/rails/test_unit/runner.rb +26 -2
  113. data/lib/rails/test_unit/test_parser.rb +45 -0
  114. data/lib/rails.rb +7 -4
  115. metadata +42 -32
  116. data/lib/rails/app_updater.rb +0 -40
  117. data/lib/rails/commands/secrets/USAGE +0 -61
  118. data/lib/rails/commands/secrets/secrets_command.rb +0 -47
  119. data/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml.tt +0 -68
  120. data/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml.tt +0 -54
  121. data/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml.tt +0 -70
  122. data/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml.tt +0 -24
  123. data/lib/rails/generators/rails/app/templates/config/databases/oracle.yml.tt +0 -62
  124. data/lib/rails/generators/rails/app/templates/config/databases/sqlserver.yml.tt +0 -53
  125. data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_7_1.rb.tt +0 -284
  126. data/lib/rails/generators/rails/app/templates/public/apple-touch-icon-precomposed.png +0 -0
  127. data/lib/rails/generators/rails/app/templates/public/apple-touch-icon.png +0 -0
  128. data/lib/rails/generators/rails/app/templates/public/favicon.ico +0 -0
  129. data/lib/rails/ruby_version_check.rb +0 -17
  130. 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"
@@ -246,8 +258,6 @@ module Rails
246
258
  def tmp
247
259
  empty_directory_with_keep_file "tmp"
248
260
  empty_directory_with_keep_file "tmp/pids"
249
- empty_directory "tmp/cache"
250
- empty_directory "tmp/cache/assets"
251
261
  end
252
262
 
253
263
  def vendor
@@ -255,7 +265,21 @@ module Rails
255
265
  end
256
266
 
257
267
  def config_target_version
258
- defined?(@config_target_version) ? @config_target_version : Rails::VERSION::STRING.to_f
268
+ @config_target_version || Rails::VERSION::STRING.to_f
269
+ end
270
+
271
+ def devcontainer
272
+ devcontainer_options = {
273
+ database: options[:database],
274
+ redis: !(options[:skip_action_cable] && options[:skip_active_job]),
275
+ system_test: depends_on_system_test?,
276
+ active_storage: !options[:skip_active_storage],
277
+ dev: options[:dev],
278
+ node: using_node?,
279
+ app_name: app_name
280
+ }
281
+
282
+ Rails::Generators::DevcontainerGenerator.new([], devcontainer_options).invoke_all
259
283
  end
260
284
  end
261
285
 
@@ -273,8 +297,8 @@ module Rails
273
297
  class_option :version, type: :boolean, aliases: "-v", group: :rails, desc: "Show Rails version number and quit"
274
298
  class_option :api, type: :boolean, desc: "Preconfigure smaller stack for API only apps"
275
299
  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"
300
+ class_option :javascript, type: :string, aliases: ["-j", "--js"], default: "importmap", enum: JAVASCRIPT_OPTIONS, desc: "Choose JavaScript approach"
301
+ 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
302
  class_option :skip_bundle, type: :boolean, aliases: "-B", default: nil, desc: "Don't run bundle install"
279
303
  class_option :skip_decrypted_diffs, type: :boolean, default: nil, desc: "Don't configure git to show decrypted diffs of encrypted credentials"
280
304
 
@@ -318,10 +342,6 @@ module Rails
318
342
 
319
343
  imply_options(OPTION_IMPLICATIONS, meta_options: META_OPTIONS)
320
344
 
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
345
  @after_bundle_callbacks = []
326
346
  end
327
347
 
@@ -371,6 +391,16 @@ module Rails
371
391
  build(:dockerfiles)
372
392
  end
373
393
 
394
+ def create_rubocop_file
395
+ return if skip_rubocop?
396
+ build(:rubocop)
397
+ end
398
+
399
+ def create_cifiles
400
+ return if skip_ci?
401
+ build(:cifiles)
402
+ end
403
+
374
404
  def create_config_files
375
405
  build(:config)
376
406
  end
@@ -389,11 +419,6 @@ module Rails
389
419
  build(:credentials_diff_enroll)
390
420
  end
391
421
 
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
422
  def create_boot_file
398
423
  template "config/boot.rb"
399
424
  end
@@ -437,14 +462,18 @@ module Rails
437
462
  end
438
463
 
439
464
  def create_storage_files
440
- build(:storage)
465
+ build(:storage) unless skip_storage?
466
+ end
467
+
468
+ def create_devcontainer_files
469
+ return if skip_devcontainer? || options[:dummy_app]
470
+ build(:devcontainer)
441
471
  end
442
472
 
443
473
  def delete_app_assets_if_api_option
444
474
  if options[:api]
445
475
  remove_dir "app/assets"
446
476
  remove_dir "lib/assets"
447
- remove_dir "tmp/cache/assets"
448
477
  end
449
478
  end
450
479
 
@@ -468,11 +497,11 @@ module Rails
468
497
  def delete_public_files_if_api_option
469
498
  if options[:api]
470
499
  remove_file "public/404.html"
500
+ remove_file "public/406-unsupported-browser.html"
471
501
  remove_file "public/422.html"
472
502
  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"
503
+ remove_file "public/icon.png"
504
+ remove_file "public/icon.svg"
476
505
  end
477
506
  end
478
507
 
@@ -644,7 +673,7 @@ module Rails
644
673
  end
645
674
 
646
675
  def read_rc_file(railsrc)
647
- extra_args = File.readlines(railsrc).flat_map(&:split)
676
+ extra_args = File.readlines(railsrc).flat_map.each { |line| line.split("#", 2).first.split }
648
677
  puts "Using #{extra_args.join(" ")} from #{railsrc}"
649
678
  extra_args
650
679
  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
-
56
+ # Highlight the fine-grained location where an error occurred [https://github.com/ruby/error_highlight]
55
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.
@@ -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
@@ -4,5 +4,5 @@
4
4
  # Use this to limit dissemination of sensitive information.
5
5
  # See the ActiveSupport::ParameterFilter documentation for supported notations and behaviors.
6
6
  Rails.application.config.filter_parameters += [
7
- :passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn
7
+ :passw, :email, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn
8
8
  ]