railties 7.1.3.4 → 7.2.0

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 (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
  ]