railties 7.2.1.1 → 8.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (117) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +122 -278
  3. data/lib/minitest/rails_plugin.rb +1 -1
  4. data/lib/rails/application/bootstrap.rb +0 -1
  5. data/lib/rails/application/configuration.rb +15 -14
  6. data/lib/rails/application/default_middleware_stack.rb +4 -0
  7. data/lib/rails/application/finisher.rb +2 -3
  8. data/lib/rails/application/routes_reloader.rb +11 -1
  9. data/lib/rails/application.rb +5 -0
  10. data/lib/rails/code_statistics.rb +128 -86
  11. data/lib/rails/code_statistics_calculator.rb +78 -76
  12. data/lib/rails/command/helpers/editor.rb +1 -1
  13. data/lib/rails/command.rb +0 -6
  14. data/lib/rails/commands/app/update_command.rb +1 -9
  15. data/lib/rails/commands/console/irb_console.rb +11 -8
  16. data/lib/rails/commands/credentials/USAGE +4 -4
  17. data/lib/rails/commands/credentials/credentials_command.rb +5 -1
  18. data/lib/rails/commands/dev/dev_command.rb +1 -1
  19. data/lib/rails/commands/devcontainer/devcontainer_command.rb +2 -1
  20. data/lib/rails/commands/stats/stats_command.rb +19 -0
  21. data/lib/rails/console/methods.rb +5 -21
  22. data/lib/rails/dev_caching.rb +2 -2
  23. data/lib/rails/engine/configuration.rb +3 -1
  24. data/lib/rails/engine/lazy_route_set.rb +114 -0
  25. data/lib/rails/engine.rb +12 -8
  26. data/lib/rails/gem_version.rb +4 -4
  27. data/lib/rails/generators/app_base.rb +46 -28
  28. data/lib/rails/generators/base.rb +0 -4
  29. data/lib/rails/generators/database.rb +101 -67
  30. data/lib/rails/generators/erb/authentication/authentication_generator.rb +15 -0
  31. data/lib/rails/generators/erb/authentication/templates/app/views/passwords/edit.html.erb +9 -0
  32. data/lib/rails/generators/erb/authentication/templates/app/views/passwords/new.html.erb +8 -0
  33. data/lib/rails/generators/erb/authentication/templates/app/views/sessions/new.html.erb +11 -0
  34. data/lib/rails/generators/generated_attribute.rb +16 -11
  35. data/lib/rails/generators/rails/app/app_generator.rb +20 -32
  36. data/lib/rails/generators/rails/app/templates/Dockerfile.tt +13 -4
  37. data/lib/rails/generators/rails/app/templates/Gemfile.tt +25 -10
  38. data/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css.tt +6 -11
  39. data/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt +10 -3
  40. data/lib/rails/generators/rails/app/templates/bin/dev.tt +1 -0
  41. data/lib/rails/generators/rails/app/templates/bin/setup.tt +5 -8
  42. data/lib/rails/generators/rails/app/templates/bin/thrust.tt +4 -0
  43. data/lib/rails/generators/rails/app/templates/config/databases/mysql.yml.tt +23 -0
  44. data/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml.tt +23 -0
  45. data/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml.tt +40 -0
  46. data/lib/rails/generators/rails/app/templates/config/databases/trilogy.yml.tt +23 -0
  47. data/lib/rails/generators/rails/app/templates/config/deploy.yml.tt +128 -0
  48. data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +12 -23
  49. data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +34 -51
  50. data/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +5 -19
  51. data/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt +0 -7
  52. data/lib/rails/generators/rails/app/templates/config/initializers/filter_parameter_logging.rb.tt +1 -1
  53. data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_8_0.rb.tt +25 -0
  54. data/lib/rails/generators/rails/app/templates/config/puma.rb.tt +11 -2
  55. data/lib/rails/generators/rails/app/templates/config/routes.rb.tt +3 -3
  56. data/lib/rails/generators/rails/app/templates/docker-entrypoint.tt +4 -3
  57. data/lib/rails/generators/rails/app/templates/dockerignore.tt +1 -2
  58. data/lib/rails/generators/rails/app/templates/github/ci.yml.tt +5 -1
  59. data/lib/rails/generators/rails/app/templates/gitignore.tt +1 -2
  60. data/lib/rails/generators/rails/app/templates/kamal-secrets.tt +17 -0
  61. data/lib/rails/generators/rails/app/templates/public/400.html +114 -0
  62. data/lib/rails/generators/rails/app/templates/public/404.html +113 -66
  63. data/lib/rails/generators/rails/app/templates/public/406-unsupported-browser.html +113 -65
  64. data/lib/rails/generators/rails/app/templates/public/422.html +113 -66
  65. data/lib/rails/generators/rails/app/templates/public/500.html +113 -65
  66. data/lib/rails/generators/rails/app/templates/public/icon.png +0 -0
  67. data/lib/rails/generators/rails/app/templates/public/icon.svg +2 -2
  68. data/lib/rails/generators/rails/authentication/USAGE +6 -0
  69. data/lib/rails/generators/rails/authentication/authentication_generator.rb +56 -0
  70. data/lib/rails/generators/rails/authentication/templates/app/controllers/concerns/authentication.rb.tt +55 -0
  71. data/lib/rails/generators/rails/authentication/templates/app/controllers/passwords_controller.rb.tt +33 -0
  72. data/lib/rails/generators/rails/authentication/templates/app/controllers/sessions_controller.rb.tt +21 -0
  73. data/lib/rails/generators/rails/authentication/templates/app/mailers/passwords_mailer.rb.tt +6 -0
  74. data/lib/rails/generators/rails/authentication/templates/app/models/current.rb.tt +4 -0
  75. data/lib/rails/generators/rails/authentication/templates/app/models/session.rb.tt +3 -0
  76. data/lib/rails/generators/rails/authentication/templates/app/models/user.rb.tt +6 -0
  77. data/lib/rails/generators/rails/authentication/templates/app/views/passwords_mailer/reset.html.erb.tt +4 -0
  78. data/lib/rails/generators/rails/authentication/templates/app/views/passwords_mailer/reset.text.erb.tt +2 -0
  79. data/lib/rails/generators/rails/authentication/templates/test/mailers/previews/passwords_mailer_preview.rb.tt +7 -0
  80. data/lib/rails/generators/rails/credentials/templates/credentials.yml.tt +4 -0
  81. data/lib/rails/generators/rails/db/system/change/change_generator.rb +1 -1
  82. data/lib/rails/generators/rails/devcontainer/devcontainer_generator.rb +10 -3
  83. data/lib/rails/generators/rails/devcontainer/templates/devcontainer/Dockerfile.tt +1 -1
  84. data/lib/rails/generators/rails/devcontainer/templates/devcontainer/devcontainer.json.tt +1 -1
  85. data/lib/rails/generators/rails/plugin/plugin_generator.rb +11 -11
  86. data/lib/rails/generators/rails/plugin/templates/Gemfile.tt +1 -1
  87. data/lib/rails/generators/rails/plugin/templates/github/ci.yml.tt +1 -1
  88. data/lib/rails/generators/rails/plugin/templates/test/test_helper.rb.tt +2 -2
  89. data/lib/rails/generators/rails/scaffold_controller/templates/api_controller.rb.tt +2 -2
  90. data/lib/rails/generators/rails/scaffold_controller/templates/controller.rb.tt +3 -3
  91. data/lib/rails/generators/rails/script/USAGE +18 -0
  92. data/lib/rails/generators/rails/script/script_generator.rb +18 -0
  93. data/lib/rails/generators/rails/script/templates/script.rb.tt +3 -0
  94. data/lib/rails/generators/test_unit/authentication/authentication_generator.rb +14 -0
  95. data/lib/rails/generators/test_unit/authentication/templates/test/fixtures/users.yml.tt +9 -0
  96. data/lib/rails/generators/test_unit/authentication/templates/test/models/user_test.rb.tt +7 -0
  97. data/lib/rails/generators.rb +7 -2
  98. data/lib/rails/info_controller.rb +10 -2
  99. data/lib/rails/rack/silence_request.rb +33 -0
  100. data/lib/rails/rack.rb +1 -0
  101. data/lib/rails/railtie.rb +13 -13
  102. data/lib/rails/source_annotation_extractor.rb +31 -14
  103. data/lib/rails/tasks/statistics.rake +13 -28
  104. data/lib/rails/templates/rails/info/notes.html.erb +65 -0
  105. data/lib/rails/test_unit/runner.rb +1 -0
  106. metadata +44 -23
  107. data/lib/rails/console/app.rb +0 -8
  108. data/lib/rails/console/helpers.rb +0 -8
  109. data/lib/rails/generators/rails/app/templates/app/assets/config/manifest.js.tt +0 -2
  110. data/lib/rails/generators/rails/app/templates/app/channels/application_cable/channel.rb.tt +0 -4
  111. data/lib/rails/generators/rails/app/templates/app/channels/application_cable/connection.rb.tt +0 -4
  112. data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_7_2.rb.tt +0 -70
  113. data/lib/rails/generators/rails/app/templates/config/initializers/permissions_policy.rb.tt +0 -13
  114. data/lib/rails/generators/rails/app/templates/test/channels/application_cable/connection_test.rb.tt +0 -13
  115. data/lib/rails/generators/rails/plugin/templates/rails/dummy_manifest.js.tt +0 -10
  116. data/lib/rails/generators/rails/plugin/templates/rails/engine_manifest.js.tt +0 -6
  117. data/lib/rails/generators/rails/plugin/templates/rails/javascripts.js.tt +0 -17
@@ -7,7 +7,7 @@ module Rails
7
7
  class RoutesReloader
8
8
  include ActiveSupport::Callbacks
9
9
 
10
- attr_reader :route_sets, :paths, :external_routes
10
+ attr_reader :route_sets, :paths, :external_routes, :loaded
11
11
  attr_accessor :eager_load
12
12
  attr_writer :run_after_load_paths # :nodoc:
13
13
  delegate :execute_if_updated, :execute, :updated?, to: :updater
@@ -17,9 +17,11 @@ module Rails
17
17
  @route_sets = []
18
18
  @external_routes = []
19
19
  @eager_load = false
20
+ @loaded = false
20
21
  end
21
22
 
22
23
  def reload!
24
+ @loaded = true
23
25
  clear!
24
26
  load_paths
25
27
  finalize!
@@ -28,6 +30,14 @@ module Rails
28
30
  revert
29
31
  end
30
32
 
33
+ def execute_unless_loaded
34
+ unless @loaded
35
+ execute
36
+ ActiveSupport.run_load_hooks(:after_routes_loaded, Rails.application)
37
+ true
38
+ end
39
+ end
40
+
31
41
  private
32
42
  def updater
33
43
  @updater ||= begin
@@ -9,6 +9,7 @@ require "active_support/deprecation"
9
9
  require "active_support/encrypted_configuration"
10
10
  require "active_support/hash_with_indifferent_access"
11
11
  require "active_support/configuration_file"
12
+ require "active_support/parameter_filter"
12
13
  require "rails/engine"
13
14
  require "rails/autoloaders"
14
15
 
@@ -160,6 +161,10 @@ module Rails
160
161
  routes_reloader.reload!
161
162
  end
162
163
 
164
+ def reload_routes_unless_loaded # :nodoc:
165
+ initialized? && routes_reloader.execute_unless_loaded
166
+ end
167
+
163
168
  # Returns a key generator (ActiveSupport::CachingKeyGenerator) for a
164
169
  # specified +secret_key_base+. The return value is memoized, so additional
165
170
  # calls with the same +secret_key_base+ will return the same key generator
@@ -3,115 +3,157 @@
3
3
  require "rails/code_statistics_calculator"
4
4
  require "active_support/core_ext/enumerable"
5
5
 
6
- class CodeStatistics # :nodoc:
7
- TEST_TYPES = ["Controller tests",
8
- "Helper tests",
9
- "Model tests",
10
- "Mailer tests",
11
- "Mailbox tests",
12
- "Channel tests",
13
- "Job tests",
14
- "Integration tests",
15
- "System tests"]
16
-
17
- HEADERS = { lines: " Lines", code_lines: " LOC", classes: "Classes", methods: "Methods" }
18
-
19
- def initialize(*pairs)
20
- @pairs = pairs
21
- @statistics = calculate_statistics
22
- @total = calculate_total if pairs.length > 1
23
- end
6
+ module Rails
7
+ class CodeStatistics
8
+ DIRECTORIES = [
9
+ %w(Controllers app/controllers),
10
+ %w(Helpers app/helpers),
11
+ %w(Jobs app/jobs),
12
+ %w(Models app/models),
13
+ %w(Mailers app/mailers),
14
+ %w(Mailboxes app/mailboxes),
15
+ %w(Channels app/channels),
16
+ %w(Views app/views),
17
+ %w(JavaScripts app/assets/javascripts),
18
+ %w(Stylesheets app/assets/stylesheets),
19
+ %w(JavaScript app/javascript),
20
+ %w(Libraries lib/),
21
+ %w(APIs app/apis),
22
+ %w(Controller\ tests test/controllers),
23
+ %w(Helper\ tests test/helpers),
24
+ %w(Job\ tests test/jobs),
25
+ %w(Model\ tests test/models),
26
+ %w(Mailer\ tests test/mailers),
27
+ %w(Mailbox\ tests test/mailboxes),
28
+ %w(Channel\ tests test/channels),
29
+ %w(Integration\ tests test/integration),
30
+ %w(System\ tests test/system),
31
+ ]
32
+
33
+ TEST_TYPES = ["Controller tests",
34
+ "Helper tests",
35
+ "Model tests",
36
+ "Mailer tests",
37
+ "Mailbox tests",
38
+ "Channel tests",
39
+ "Job tests",
40
+ "Integration tests",
41
+ "System tests"]
42
+
43
+ HEADERS = { lines: " Lines", code_lines: " LOC", classes: "Classes", methods: "Methods" }
44
+
45
+ class_attribute :directories, default: DIRECTORIES
46
+ class_attribute :test_types, default: TEST_TYPES
47
+
48
+ # Add directories to the output of the `bin/rails stats` command.
49
+ #
50
+ # Rails::CodeStatistics.register_directory("My Directory", "path/to/dir")
51
+ #
52
+ # For directories that contain test code, set the `test_directory` argument to true.
53
+ #
54
+ # Rails::CodeStatistics.register_directory("Model specs", "spec/models", test_directory: true)
55
+ def self.register_directory(label, path, test_directory: false)
56
+ self.directories << [label, path]
57
+ self.test_types << label if test_directory
58
+ end
24
59
 
25
- def to_s
26
- print_header
27
- @pairs.each { |pair| print_line(pair.first, @statistics[pair.first]) }
28
- print_splitter
60
+ def initialize(*pairs)
61
+ @pairs = pairs
62
+ @statistics = calculate_statistics
63
+ @total = calculate_total if pairs.length > 1
64
+ end
29
65
 
30
- if @total
31
- print_line("Total", @total)
66
+ def to_s
67
+ print_header
68
+ @pairs.each { |pair| print_line(pair.first, @statistics[pair.first]) }
32
69
  print_splitter
33
- end
34
70
 
35
- print_code_test_stats
36
- end
71
+ if @total
72
+ print_line("Total", @total)
73
+ print_splitter
74
+ end
37
75
 
38
- private
39
- def calculate_statistics
40
- Hash[@pairs.map { |pair| [pair.first, calculate_directory_statistics(pair.last)] }]
76
+ print_code_test_stats
41
77
  end
42
78
 
43
- def calculate_directory_statistics(directory, pattern = /^(?!\.).*?\.(rb|js|ts|css|scss|coffee|rake|erb)$/)
44
- stats = CodeStatisticsCalculator.new
79
+ private
80
+ def calculate_statistics
81
+ Hash[@pairs.map { |pair| [pair.first, calculate_directory_statistics(pair.last)] }]
82
+ end
83
+
84
+ def calculate_directory_statistics(directory, pattern = /^(?!\.).*?\.(rb|js|ts|css|scss|coffee|rake|erb)$/)
85
+ stats = Rails::CodeStatisticsCalculator.new
45
86
 
46
- Dir.foreach(directory) do |file_name|
47
- path = "#{directory}/#{file_name}"
87
+ Dir.foreach(directory) do |file_name|
88
+ path = "#{directory}/#{file_name}"
48
89
 
49
- if File.directory?(path) && !file_name.start_with?(".")
50
- stats.add(calculate_directory_statistics(path, pattern))
51
- elsif file_name&.match?(pattern)
52
- stats.add_by_file_path(path)
90
+ if File.directory?(path) && !file_name.start_with?(".")
91
+ stats.add(calculate_directory_statistics(path, pattern))
92
+ elsif file_name&.match?(pattern)
93
+ stats.add_by_file_path(path)
94
+ end
53
95
  end
54
- end
55
96
 
56
- stats
57
- end
97
+ stats
98
+ end
58
99
 
59
- def calculate_total
60
- @statistics.each_with_object(CodeStatisticsCalculator.new) do |pair, total|
61
- total.add(pair.last)
100
+ def calculate_total
101
+ @statistics.each_with_object(Rails::CodeStatisticsCalculator.new) do |pair, total|
102
+ total.add(pair.last)
103
+ end
62
104
  end
63
- end
64
105
 
65
- def calculate_code
66
- code_loc = 0
67
- @statistics.each { |k, v| code_loc += v.code_lines unless TEST_TYPES.include? k }
68
- code_loc
69
- end
106
+ def calculate_code
107
+ code_loc = 0
108
+ @statistics.each { |k, v| code_loc += v.code_lines unless test_types.include? k }
109
+ code_loc
110
+ end
70
111
 
71
- def calculate_tests
72
- test_loc = 0
73
- @statistics.each { |k, v| test_loc += v.code_lines if TEST_TYPES.include? k }
74
- test_loc
75
- end
112
+ def calculate_tests
113
+ test_loc = 0
114
+ @statistics.each { |k, v| test_loc += v.code_lines if test_types.include? k }
115
+ test_loc
116
+ end
76
117
 
77
- def width_for(label)
78
- [@statistics.values.sum { |s| s.public_send(label) }.to_s.size, HEADERS[label].length].max
79
- end
118
+ def width_for(label)
119
+ [@statistics.values.sum { |s| s.public_send(label) }.to_s.size, HEADERS[label].length].max
120
+ end
80
121
 
81
- def print_header
82
- print_splitter
83
- print "| Name "
84
- HEADERS.each do |k, v|
85
- print " | #{v.rjust(width_for(k))}"
122
+ def print_header
123
+ print_splitter
124
+ print "| Name "
125
+ HEADERS.each do |k, v|
126
+ print " | #{v.rjust(width_for(k))}"
127
+ end
128
+ puts " | M/C | LOC/M |"
129
+ print_splitter
86
130
  end
87
- puts " | M/C | LOC/M |"
88
- print_splitter
89
- end
90
131
 
91
- def print_splitter
92
- print "+----------------------"
93
- HEADERS.each_key do |k|
94
- print "+#{'-' * (width_for(k) + 2)}"
132
+ def print_splitter
133
+ print "+----------------------"
134
+ HEADERS.each_key do |k|
135
+ print "+#{'-' * (width_for(k) + 2)}"
136
+ end
137
+ puts "+-----+-------+"
95
138
  end
96
- puts "+-----+-------+"
97
- end
98
139
 
99
- def print_line(name, statistics)
100
- m_over_c = (statistics.methods / statistics.classes) rescue 0
101
- loc_over_m = (statistics.code_lines / statistics.methods) - 2 rescue 0
140
+ def print_line(name, statistics)
141
+ m_over_c = (statistics.methods / statistics.classes) rescue 0
142
+ loc_over_m = (statistics.code_lines / statistics.methods) - 2 rescue 0
102
143
 
103
- print "| #{name.ljust(20)} "
104
- HEADERS.each_key do |k|
105
- print "| #{statistics.send(k).to_s.rjust(width_for(k))} "
144
+ print "| #{name.ljust(20)} "
145
+ HEADERS.each_key do |k|
146
+ print "| #{statistics.send(k).to_s.rjust(width_for(k))} "
147
+ end
148
+ puts "| #{m_over_c.to_s.rjust(3)} | #{loc_over_m.to_s.rjust(5)} |"
106
149
  end
107
- puts "| #{m_over_c.to_s.rjust(3)} | #{loc_over_m.to_s.rjust(5)} |"
108
- end
109
150
 
110
- def print_code_test_stats
111
- code = calculate_code
112
- tests = calculate_tests
151
+ def print_code_test_stats
152
+ code = calculate_code
153
+ tests = calculate_tests
113
154
 
114
- puts " Code LOC: #{code} Test LOC: #{tests} Code to Test Ratio: 1:#{sprintf("%.1f", tests.to_f / code)}"
115
- puts ""
116
- end
155
+ puts " Code LOC: #{code} Test LOC: #{tests} Code to Test Ratio: 1:#{sprintf("%.1f", tests.to_f / code)}"
156
+ puts ""
157
+ end
158
+ end
117
159
  end
@@ -1,97 +1,99 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class CodeStatisticsCalculator # :nodoc:
4
- attr_reader :lines, :code_lines, :classes, :methods
3
+ module Rails
4
+ class CodeStatisticsCalculator # :nodoc:
5
+ attr_reader :lines, :code_lines, :classes, :methods
5
6
 
6
- PATTERNS = {
7
- rb: {
8
- line_comment: /^\s*#/,
9
- begin_block_comment: /^=begin/,
10
- end_block_comment: /^=end/,
11
- class: /^\s*class\s+[_A-Z]/,
12
- method: /^\s*def\s+[_a-z]/,
13
- },
14
- erb: {
15
- line_comment: %r{((^\s*<%#.*%>)|(<!--.*-->))},
16
- },
17
- css: {
18
- line_comment: %r{^\s*/\*.*\*/},
19
- },
20
- scss: {
21
- line_comment: %r{((^\s*/\*.*\*/)|(^\s*//))},
22
- },
23
- js: {
24
- line_comment: %r{^\s*//},
25
- begin_block_comment: %r{^\s*/\*},
26
- end_block_comment: %r{\*/},
27
- method: /function(\s+[_a-zA-Z][\da-zA-Z]*)?\s*\(/,
28
- },
29
- coffee: {
30
- line_comment: /^\s*#/,
31
- begin_block_comment: /^\s*###/,
32
- end_block_comment: /^\s*###/,
33
- class: /^\s*class\s+[_A-Z]/,
34
- method: /[-=]>/,
7
+ PATTERNS = {
8
+ rb: {
9
+ line_comment: /^\s*#/,
10
+ begin_block_comment: /^=begin/,
11
+ end_block_comment: /^=end/,
12
+ class: /^\s*class\s+[_A-Z]/,
13
+ method: /^\s*def\s+[_a-z]/,
14
+ },
15
+ erb: {
16
+ line_comment: %r{((^\s*<%#.*%>)|(<!--.*-->))},
17
+ },
18
+ css: {
19
+ line_comment: %r{^\s*/\*.*\*/},
20
+ },
21
+ scss: {
22
+ line_comment: %r{((^\s*/\*.*\*/)|(^\s*//))},
23
+ },
24
+ js: {
25
+ line_comment: %r{^\s*//},
26
+ begin_block_comment: %r{^\s*/\*},
27
+ end_block_comment: %r{\*/},
28
+ method: /function(\s+[_a-zA-Z][\da-zA-Z]*)?\s*\(/,
29
+ },
30
+ coffee: {
31
+ line_comment: /^\s*#/,
32
+ begin_block_comment: /^\s*###/,
33
+ end_block_comment: /^\s*###/,
34
+ class: /^\s*class\s+[_A-Z]/,
35
+ method: /[-=]>/,
36
+ }
35
37
  }
36
- }
37
38
 
38
- PATTERNS[:minitest] = PATTERNS[:rb].merge method: /^\s*(def|test)\s+['"_a-z]/
39
- PATTERNS[:rake] = PATTERNS[:rb]
39
+ PATTERNS[:minitest] = PATTERNS[:rb].merge method: /^\s*(def|test)\s+['"_a-z]/
40
+ PATTERNS[:rake] = PATTERNS[:rb]
40
41
 
41
- def initialize(lines = 0, code_lines = 0, classes = 0, methods = 0)
42
- @lines = lines
43
- @code_lines = code_lines
44
- @classes = classes
45
- @methods = methods
46
- end
42
+ def initialize(lines = 0, code_lines = 0, classes = 0, methods = 0)
43
+ @lines = lines
44
+ @code_lines = code_lines
45
+ @classes = classes
46
+ @methods = methods
47
+ end
47
48
 
48
- def add(code_statistics_calculator)
49
- @lines += code_statistics_calculator.lines
50
- @code_lines += code_statistics_calculator.code_lines
51
- @classes += code_statistics_calculator.classes
52
- @methods += code_statistics_calculator.methods
53
- end
49
+ def add(code_statistics_calculator)
50
+ @lines += code_statistics_calculator.lines
51
+ @code_lines += code_statistics_calculator.code_lines
52
+ @classes += code_statistics_calculator.classes
53
+ @methods += code_statistics_calculator.methods
54
+ end
54
55
 
55
- def add_by_file_path(file_path)
56
- File.open(file_path) do |f|
57
- add_by_io(f, file_type(file_path))
56
+ def add_by_file_path(file_path)
57
+ File.open(file_path) do |f|
58
+ add_by_io(f, file_type(file_path))
59
+ end
58
60
  end
59
- end
60
61
 
61
- def add_by_io(io, file_type)
62
- patterns = PATTERNS[file_type] || {}
62
+ def add_by_io(io, file_type)
63
+ patterns = PATTERNS[file_type] || {}
63
64
 
64
- comment_started = false
65
+ comment_started = false
65
66
 
66
- while line = io.gets
67
- @lines += 1
67
+ while line = io.gets
68
+ @lines += 1
68
69
 
69
- if comment_started
70
- if patterns[:end_block_comment] && patterns[:end_block_comment].match?(line)
71
- comment_started = false
72
- end
73
- next
74
- else
75
- if patterns[:begin_block_comment] && patterns[:begin_block_comment].match?(line)
76
- comment_started = true
70
+ if comment_started
71
+ if patterns[:end_block_comment] && patterns[:end_block_comment].match?(line)
72
+ comment_started = false
73
+ end
77
74
  next
75
+ else
76
+ if patterns[:begin_block_comment] && patterns[:begin_block_comment].match?(line)
77
+ comment_started = true
78
+ next
79
+ end
78
80
  end
79
- end
80
81
 
81
- @classes += 1 if patterns[:class] && patterns[:class].match?(line)
82
- @methods += 1 if patterns[:method] && patterns[:method].match?(line)
83
- if !line.match?(/^\s*$/) && (patterns[:line_comment].nil? || !line.match?(patterns[:line_comment]))
84
- @code_lines += 1
82
+ @classes += 1 if patterns[:class] && patterns[:class].match?(line)
83
+ @methods += 1 if patterns[:method] && patterns[:method].match?(line)
84
+ if !line.match?(/^\s*$/) && (patterns[:line_comment].nil? || !line.match?(patterns[:line_comment]))
85
+ @code_lines += 1
86
+ end
85
87
  end
86
88
  end
87
- end
88
89
 
89
- private
90
- def file_type(file_path)
91
- if file_path.end_with? "_test.rb"
92
- :minitest
93
- else
94
- File.extname(file_path).delete_prefix(".").downcase.to_sym
90
+ private
91
+ def file_type(file_path)
92
+ if file_path.end_with? "_test.rb"
93
+ :minitest
94
+ else
95
+ File.extname(file_path).delete_prefix(".").downcase.to_sym
96
+ end
95
97
  end
96
- end
98
+ end
97
99
  end
@@ -16,7 +16,7 @@ module Rails
16
16
  if editor.to_s.empty?
17
17
  say "No $VISUAL or $EDITOR to open file in. Assign one like this:"
18
18
  say ""
19
- say %(VISUAL="mate --wait" #{executable(current_subcommand)})
19
+ say %(VISUAL="code --wait" #{executable(current_subcommand)})
20
20
  say ""
21
21
  say "For editors that fork and exit immediately, it's important to pass a wait flag;"
22
22
  say "otherwise, the file will be saved immediately with no chance to edit."
data/lib/rails/command.rb CHANGED
@@ -23,12 +23,6 @@ module Rails
23
23
  super(message)
24
24
  end
25
25
 
26
- if !Exception.method_defined?(:detailed_message) # Ruby 3.2+
27
- def detailed_message(...)
28
- message
29
- end
30
- end
31
-
32
26
  if defined?(DidYouMean::Correctable) && defined?(DidYouMean::SpellChecker)
33
27
  include DidYouMean::Correctable
34
28
 
@@ -73,21 +73,13 @@ module Rails
73
73
  skip_rubocop: skip_gem?("rubocop"),
74
74
  skip_test: !defined?(Rails::TestUnitRailtie),
75
75
  skip_system_test: Rails.application.config.generators.system_tests.nil?,
76
- asset_pipeline: asset_pipeline,
77
76
  skip_asset_pipeline: asset_pipeline.nil?,
78
77
  skip_bootsnap: !defined?(Bootsnap),
79
78
  }.merge(options)
80
79
  end
81
80
 
82
81
  def asset_pipeline
83
- case
84
- when defined?(Sprockets::Railtie)
85
- "sprockets"
86
- when defined?(Propshaft::Railtie)
87
- "propshaft"
88
- else
89
- nil
90
- end
82
+ "propshaft" if defined?(Propshaft::Railtie)
91
83
  end
92
84
 
93
85
  def skip_gem?(gem_name)
@@ -6,7 +6,6 @@ require "irb/command"
6
6
  module Rails
7
7
  class Console
8
8
  class RailsHelperBase < IRB::HelperMethod::Base
9
- include ConsoleMethods
10
9
  end
11
10
 
12
11
  class ControllerHelper < RailsHelperBase
@@ -51,9 +50,16 @@ module Rails
51
50
  end
52
51
  end
53
52
 
54
- class Reloader < IRB::Command::Base
55
- include ConsoleMethods
53
+ class ReloadHelper < RailsHelperBase
54
+ description "Reloads the Rails application."
55
+
56
+ def execute
57
+ puts "Reloading..."
58
+ Rails.application.reloader.reload!
59
+ end
60
+ end
56
61
 
62
+ class ReloadCommand < IRB::Command::Base
57
63
  category "Rails console"
58
64
  description "Reloads the Rails application."
59
65
 
@@ -67,7 +73,8 @@ module Rails
67
73
  IRB::HelperMethod.register(:controller, ControllerInstance)
68
74
  IRB::HelperMethod.register(:new_session, NewSession)
69
75
  IRB::HelperMethod.register(:app, AppInstance)
70
- IRB::Command.register(:reload!, Reloader)
76
+ IRB::HelperMethod.register(:reload!, ReloadHelper)
77
+ IRB::Command.register(:reload!, ReloadCommand)
71
78
 
72
79
  class IRBConsole
73
80
  def initialize(app)
@@ -110,10 +117,6 @@ module Rails
110
117
  end
111
118
  end
112
119
 
113
- # Because some users/libs use Rails::ConsoleMethods to extend Rails console,
114
- # we still include it for backward compatibility.
115
- IRB::ExtendCommandBundle.include ConsoleMethods
116
-
117
120
  # Respect user's choice of prompt mode.
118
121
  IRB.conf[:PROMPT_MODE] = :RAILS_PROMPT if IRB.conf[:PROMPT_MODE] == :DEFAULT
119
122
  IRB::Irb.new.run(IRB.conf)
@@ -38,8 +38,8 @@ Set up Git to Diff Credentials:
38
38
  Running the command enrolls the project such that all credentials files use the
39
39
  "rails_credentials" diff driver in .gitattributes.
40
40
 
41
- Additionally since Git requires the driver itself to be set up in a config file
42
- that isn't tracked Rails automatically ensures it's configured when running
41
+ Additionally, since Git requires the driver itself to be set up in a config file
42
+ that isn't tracked, Rails automatically ensures it's configured when running
43
43
  `<%= executable(:edit) %>`.
44
44
 
45
45
  Otherwise each co-worker would have to run enable manually, including on each new
@@ -48,8 +48,8 @@ Set up Git to Diff Credentials:
48
48
  To disenroll from this feature, run `<%= executable(:diff) %> --disenroll`.
49
49
 
50
50
  Editing Credentials:
51
- This will open a temporary file in `$VISUAL` or `$EDITOR` with the decrypted
52
- contents to edit the encrypted credentials.
51
+ `<%= executable(:edit) %>` will open a temporary file in `$VISUAL` or `$EDITOR`
52
+ with the decrypted contents to edit the encrypted credentials.
53
53
 
54
54
  When the temporary file is next saved the contents are encrypted and written to
55
55
  `config/credentials.yml.enc` while the file itself is destroyed to prevent credentials
@@ -128,7 +128,11 @@ module Rails
128
128
  end
129
129
 
130
130
  def extract_environment_from_path(path)
131
- available_environments.find { |env| path.end_with?("#{env}.yml.enc") }
131
+ available_environments.find { |env| path.end_with?("#{env}.yml.enc") } || extract_custom_environment(path)
132
+ end
133
+
134
+ def extract_custom_environment(path)
135
+ path =~ %r{config/credentials/(.+)\.yml\.enc} && $1
132
136
  end
133
137
  end
134
138
  end
@@ -5,7 +5,7 @@ require "rails/dev_caching"
5
5
  module Rails
6
6
  module Command
7
7
  class DevCommand < Base # :nodoc:
8
- desc "cache", "Toggle development mode caching on/off"
8
+ desc "cache", "Toggle Action Controller development mode caching on/off"
9
9
  def cache
10
10
  Rails::DevCaching.enable_by_file
11
11
  end
@@ -24,9 +24,10 @@ module Rails
24
24
  app_name: Rails.application.railtie_name.chomp("_application"),
25
25
  database: !!defined?(ActiveRecord) && database,
26
26
  active_storage: !!defined?(ActiveStorage),
27
- redis: !!(defined?(ActionCable) || defined?(ActiveJob)),
27
+ redis: !!((defined?(ActionCable) && !defined?(SolidCable)) || (defined?(ActiveJob) && !defined?(SolidQueue))),
28
28
  system_test: File.exist?("test/application_system_test_case.rb"),
29
29
  node: File.exist?(".node-version"),
30
+ kamal: File.exist?("config/deploy.yml"),
30
31
  }
31
32
  end
32
33
 
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rails
4
+ module Command
5
+ class StatsCommand < Base # :nodoc:
6
+ desc "stats", "Report code statistics (KLOCs, etc) from the application or engine"
7
+ def perform
8
+ require "rails/code_statistics"
9
+ boot_application!
10
+
11
+ stat_directories = Rails::CodeStatistics.directories.map do |name, dir|
12
+ [name, Rails::Command.application_root.join(dir)]
13
+ end.select { |name, dir| File.directory?(dir) }
14
+
15
+ Rails::CodeStatistics.new(*stat_directories).to_s
16
+ end
17
+ end
18
+ end
19
+ end