railties 5.2.3 → 6.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +306 -126
- data/MIT-LICENSE +1 -1
- data/RDOC_MAIN.rdoc +38 -31
- data/README.rdoc +2 -2
- data/lib/minitest/rails_plugin.rb +7 -11
- data/lib/rails.rb +5 -0
- data/lib/rails/all.rb +4 -0
- data/lib/rails/api/generator.rb +2 -1
- data/lib/rails/api/task.rb +16 -0
- data/lib/rails/app_loader.rb +2 -2
- data/lib/rails/app_updater.rb +3 -1
- data/lib/rails/application.rb +71 -29
- data/lib/rails/application/bootstrap.rb +2 -10
- data/lib/rails/application/configuration.rb +113 -13
- data/lib/rails/application/default_middleware_stack.rb +3 -0
- data/lib/rails/application/dummy_erb_compiler.rb +18 -0
- data/lib/rails/application/finisher.rb +54 -0
- data/lib/rails/autoloaders.rb +48 -0
- data/lib/rails/backtrace_cleaner.rb +5 -17
- data/lib/rails/code_statistics.rb +3 -3
- data/lib/rails/command.rb +11 -10
- data/lib/rails/command/base.rb +12 -4
- data/lib/rails/command/behavior.rb +7 -48
- data/lib/rails/command/environment_argument.rb +8 -15
- data/lib/rails/command/spellchecker.rb +58 -0
- data/lib/rails/commands/console/console_command.rb +6 -0
- data/lib/rails/commands/credentials/USAGE +19 -1
- data/lib/rails/commands/credentials/credentials_command.rb +52 -19
- data/lib/rails/commands/db/system/change/change_command.rb +20 -0
- data/lib/rails/commands/dbconsole/dbconsole_command.rb +20 -8
- data/lib/rails/commands/dev/dev_command.rb +19 -0
- data/lib/rails/commands/encrypted/USAGE +1 -1
- data/lib/rails/commands/encrypted/encrypted_command.rb +2 -2
- data/lib/rails/commands/help/help_command.rb +1 -1
- data/lib/rails/commands/initializers/initializers_command.rb +23 -0
- data/lib/rails/commands/new/new_command.rb +2 -2
- data/lib/rails/commands/notes/notes_command.rb +39 -0
- data/lib/rails/commands/plugin/plugin_command.rb +1 -1
- data/lib/rails/commands/routes/routes_command.rb +37 -0
- data/lib/rails/commands/runner/runner_command.rb +13 -9
- data/lib/rails/commands/secrets/USAGE +3 -3
- data/lib/rails/commands/secrets/secrets_command.rb +3 -3
- data/lib/rails/commands/server/server_command.rb +113 -50
- data/lib/rails/configuration.rb +1 -7
- data/lib/rails/engine.rb +32 -18
- data/lib/rails/engine/configuration.rb +5 -2
- data/lib/rails/gem_version.rb +3 -3
- data/lib/rails/generators.rb +11 -10
- data/lib/rails/generators/actions.rb +52 -39
- data/lib/rails/generators/app_base.rb +59 -97
- data/lib/rails/generators/app_name.rb +50 -0
- data/lib/rails/generators/database.rb +58 -0
- data/lib/rails/generators/erb/mailer/mailer_generator.rb +1 -1
- data/lib/rails/generators/erb/scaffold/templates/_form.html.erb.tt +6 -3
- data/lib/rails/generators/erb/scaffold/templates/index.html.erb.tt +1 -1
- data/lib/rails/generators/erb/scaffold/templates/show.html.erb.tt +9 -1
- data/lib/rails/generators/generated_attribute.rb +53 -27
- data/lib/rails/generators/migration.rb +1 -2
- data/lib/rails/generators/model_helpers.rb +8 -1
- data/lib/rails/generators/named_base.rb +1 -5
- data/lib/rails/generators/rails/app/app_generator.rb +37 -71
- data/lib/rails/generators/rails/app/templates/Gemfile.tt +7 -10
- data/lib/rails/generators/rails/app/templates/app/assets/config/manifest.js.tt +0 -3
- data/lib/rails/generators/rails/app/templates/app/{assets/javascripts/cable.js.tt → javascript/channels/consumer.js} +2 -9
- data/lib/rails/generators/rails/app/templates/app/javascript/channels/index.js +5 -0
- data/lib/rails/generators/rails/app/templates/app/javascript/packs/application.js.tt +23 -0
- data/lib/rails/generators/rails/app/templates/app/jobs/application_job.rb.tt +5 -0
- data/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt +4 -4
- data/lib/rails/generators/rails/app/templates/bin/setup.tt +7 -7
- data/lib/rails/generators/rails/app/templates/config/application.rb.tt +2 -0
- data/lib/rails/generators/rails/app/templates/config/cable.yml.tt +1 -1
- data/lib/rails/generators/rails/app/templates/config/databases/frontbase.yml.tt +2 -2
- data/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml.tt +2 -2
- data/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml.tt +2 -2
- data/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml.tt +3 -3
- data/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml.tt +3 -3
- data/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml.tt +1 -1
- data/lib/rails/generators/rails/app/templates/config/databases/mysql.yml.tt +4 -4
- data/lib/rails/generators/rails/app/templates/config/databases/oracle.yml.tt +2 -2
- data/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml.tt +6 -6
- data/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml.tt +1 -1
- data/lib/rails/generators/rails/app/templates/config/databases/sqlserver.yml.tt +2 -2
- data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +5 -2
- data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +28 -12
- data/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +13 -7
- data/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt +1 -1
- data/lib/rails/generators/rails/app/templates/config/initializers/content_security_policy.rb.tt +7 -0
- data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_6_0.rb.tt +45 -0
- data/lib/rails/generators/rails/app/templates/config/locales/en.yml +1 -1
- data/lib/rails/generators/rails/app/templates/config/puma.rb.tt +7 -3
- data/lib/rails/generators/rails/app/templates/config/routes.rb.tt +1 -1
- data/lib/rails/generators/rails/app/templates/config/spring.rb.tt +6 -6
- data/lib/rails/generators/rails/app/templates/gitignore.tt +2 -7
- data/lib/rails/generators/rails/app/templates/package.json.tt +7 -1
- data/lib/rails/generators/rails/app/templates/public/robots.txt +1 -1
- data/lib/rails/generators/rails/app/templates/ruby-version.tt +1 -1
- data/lib/rails/generators/rails/app/templates/test/channels/application_cable/connection_test.rb.tt +11 -0
- data/lib/rails/generators/rails/app/templates/test/test_helper.rb.tt +7 -0
- data/lib/rails/generators/rails/assets/USAGE +1 -4
- data/lib/rails/generators/rails/assets/assets_generator.rb +0 -1
- data/lib/rails/generators/rails/controller/controller_generator.rb +11 -1
- data/lib/rails/generators/rails/credentials/credentials_generator.rb +7 -8
- data/lib/rails/generators/rails/db/system/change/change_generator.rb +65 -0
- data/lib/rails/generators/rails/encrypted_file/encrypted_file_generator.rb +4 -5
- data/lib/rails/generators/rails/helper/helper_generator.rb +5 -0
- data/lib/rails/generators/rails/plugin/plugin_generator.rb +9 -33
- data/lib/rails/generators/rails/plugin/templates/app/controllers/%namespaced_name%/application_controller.rb.tt +1 -1
- data/lib/rails/generators/rails/plugin/templates/app/helpers/%namespaced_name%/application_helper.rb.tt +1 -1
- data/lib/rails/generators/rails/plugin/templates/app/jobs/%namespaced_name%/application_job.rb.tt +1 -1
- data/lib/rails/generators/rails/plugin/templates/app/mailers/%namespaced_name%/application_mailer.rb.tt +1 -1
- data/lib/rails/generators/rails/plugin/templates/app/models/%namespaced_name%/application_record.rb.tt +1 -1
- data/lib/rails/generators/rails/plugin/templates/gitignore.tt +1 -1
- data/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/engine.rb.tt +1 -1
- data/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/railtie.rb.tt +1 -1
- data/lib/rails/generators/rails/plugin/templates/test/test_helper.rb.tt +1 -2
- data/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb +14 -0
- data/lib/rails/generators/rails/scaffold_controller/templates/api_controller.rb.tt +1 -1
- data/lib/rails/generators/rails/scaffold_controller/templates/controller.rb.tt +1 -1
- data/lib/rails/generators/resource_helpers.rb +1 -6
- data/lib/rails/generators/test_unit/integration/integration_generator.rb +6 -0
- data/lib/rails/generators/test_unit/job/job_generator.rb +5 -0
- data/lib/rails/generators/test_unit/mailer/mailer_generator.rb +1 -1
- data/lib/rails/generators/test_unit/model/templates/fixtures.yml.tt +2 -2
- data/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb +8 -3
- data/lib/rails/generators/test_unit/system/system_generator.rb +5 -0
- data/lib/rails/generators/testing/behaviour.rb +3 -0
- data/lib/rails/info.rb +2 -2
- data/lib/rails/info_controller.rb +1 -1
- data/lib/rails/mailers_controller.rb +7 -4
- data/lib/rails/paths.rb +19 -9
- data/lib/rails/railtie.rb +1 -1
- data/lib/rails/ruby_version_check.rb +3 -3
- data/lib/rails/secrets.rb +0 -1
- data/lib/rails/source_annotation_extractor.rb +138 -117
- data/lib/rails/tasks.rb +1 -0
- data/lib/rails/tasks/annotations.rake +9 -9
- data/lib/rails/tasks/dev.rake +5 -4
- data/lib/rails/tasks/framework.rake +5 -1
- data/lib/rails/tasks/initializers.rake +5 -4
- data/lib/rails/tasks/log.rake +0 -1
- data/lib/rails/tasks/routes.rake +4 -26
- data/lib/rails/tasks/statistics.rake +4 -0
- data/lib/rails/tasks/yarn.rake +1 -1
- data/lib/rails/tasks/zeitwerk.rake +66 -0
- data/lib/rails/templates/rails/welcome/index.html.erb +2 -2
- data/lib/rails/test_help.rb +11 -9
- data/lib/rails/test_unit/reporter.rb +1 -1
- data/lib/rails/test_unit/runner.rb +5 -5
- data/lib/rails/test_unit/testing.rake +1 -1
- metadata +31 -22
- data/lib/rails/generators/js/assets/assets_generator.rb +0 -15
- data/lib/rails/generators/js/assets/templates/javascript.js +0 -2
- data/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt +0 -22
- data/lib/rails/generators/rails/app/templates/bin/bundle.tt +0 -2
- data/lib/rails/generators/rails/app/templates/bin/update.tt +0 -34
- data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_5_2.rb.tt +0 -38
- data/lib/rails/generators/rails/assets/templates/javascript.js +0 -2
@@ -10,8 +10,7 @@ ActiveRecord::Migrator.migrations_paths << File.expand_path('../db/migrate', __d
|
|
10
10
|
<% end -%>
|
11
11
|
require "rails/test_help"
|
12
12
|
|
13
|
-
# Filter out
|
14
|
-
# to be shown.
|
13
|
+
# Filter out the backtrace from minitest while preserving the one from other libraries.
|
15
14
|
Minitest.backtrace_filter = Minitest::BacktraceFilter.new
|
16
15
|
|
17
16
|
<% unless engine? -%>
|
@@ -32,6 +32,20 @@ module Rails
|
|
32
32
|
hook_for :helper, as: :scaffold do |invoked|
|
33
33
|
invoke invoked, [ controller_name ]
|
34
34
|
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def permitted_params
|
39
|
+
attachments, others = attributes_names.partition { |name| attachments?(name) }
|
40
|
+
params = others.map { |name| ":#{name}" }
|
41
|
+
params += attachments.map { |name| "#{name}: []" }
|
42
|
+
params.join(", ")
|
43
|
+
end
|
44
|
+
|
45
|
+
def attachments?(name)
|
46
|
+
attribute = attributes.find { |attr| attr.name == name }
|
47
|
+
attribute&.attachments?
|
48
|
+
end
|
35
49
|
end
|
36
50
|
end
|
37
51
|
end
|
@@ -54,7 +54,7 @@ class <%= controller_class_name %>Controller < ApplicationController
|
|
54
54
|
<%- if attributes_names.empty? -%>
|
55
55
|
params.fetch(:<%= singular_table_name %>, {})
|
56
56
|
<%- else -%>
|
57
|
-
params.require(:<%= singular_table_name %>).permit(<%=
|
57
|
+
params.require(:<%= singular_table_name %>).permit(<%= permitted_params %>)
|
58
58
|
<%- end -%>
|
59
59
|
end
|
60
60
|
end
|
@@ -61,7 +61,7 @@ class <%= controller_class_name %>Controller < ApplicationController
|
|
61
61
|
<%- if attributes_names.empty? -%>
|
62
62
|
params.fetch(:<%= singular_table_name %>, {})
|
63
63
|
<%- else -%>
|
64
|
-
params.require(:<%= singular_table_name %>).permit(<%=
|
64
|
+
params.require(:<%= singular_table_name %>).permit(<%= permitted_params %>)
|
65
65
|
<%- end -%>
|
66
66
|
end
|
67
67
|
end
|
@@ -25,13 +25,8 @@ module Rails
|
|
25
25
|
assign_controller_names!(controller_name.pluralize)
|
26
26
|
end
|
27
27
|
|
28
|
-
# TODO Change this to private once we've dropped Ruby 2.2 support.
|
29
|
-
# Workaround for Ruby 2.2 "private attribute?" warning.
|
30
|
-
protected
|
31
|
-
|
32
|
-
attr_reader :controller_name, :controller_file_name
|
33
|
-
|
34
28
|
private
|
29
|
+
attr_reader :controller_name, :controller_file_name
|
35
30
|
|
36
31
|
def controller_class_path
|
37
32
|
if options[:model_name]
|
@@ -10,6 +10,12 @@ module TestUnit # :nodoc:
|
|
10
10
|
def create_test_files
|
11
11
|
template "integration_test.rb", File.join("test/integration", class_path, "#{file_name}_test.rb")
|
12
12
|
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def file_name
|
17
|
+
@_file_name ||= super.sub(/_test\z/i, "")
|
18
|
+
end
|
13
19
|
end
|
14
20
|
end
|
15
21
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Read about fixtures at
|
1
|
+
# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
|
2
2
|
<% unless attributes.empty? -%>
|
3
3
|
<% %w(one two).each do |name| %>
|
4
4
|
<%= name %>:
|
@@ -7,7 +7,7 @@
|
|
7
7
|
password_digest: <%%= BCrypt::Password.create('secret') %>
|
8
8
|
<%- elsif attribute.reference? -%>
|
9
9
|
<%= yaml_key_value(attribute.column_name.sub(/_id$/, ''), attribute.default || name) %>
|
10
|
-
<%-
|
10
|
+
<%- elsif !attribute.virtual? -%>
|
11
11
|
<%= yaml_key_value(attribute.column_name, attribute.default) %>
|
12
12
|
<%- end -%>
|
13
13
|
<%- if attribute.polymorphic? -%>
|
@@ -49,15 +49,20 @@ module TestUnit # :nodoc:
|
|
49
49
|
attributes_names.map do |name|
|
50
50
|
if %w(password password_confirmation).include?(name) && attributes.any?(&:password_digest?)
|
51
51
|
["#{name}", "'secret'"]
|
52
|
-
|
52
|
+
elsif !virtual?(name)
|
53
53
|
["#{name}", "@#{singular_table_name}.#{name}"]
|
54
54
|
end
|
55
|
-
end.sort.to_h
|
55
|
+
end.compact.sort.to_h
|
56
56
|
end
|
57
57
|
|
58
58
|
def boolean?(name)
|
59
59
|
attribute = attributes.find { |attr| attr.name == name }
|
60
|
-
attribute
|
60
|
+
attribute&.type == :boolean
|
61
|
+
end
|
62
|
+
|
63
|
+
def virtual?(name)
|
64
|
+
attribute = attributes.find { |attr| attr.name == name }
|
65
|
+
attribute&.virtual?
|
61
66
|
end
|
62
67
|
end
|
63
68
|
end
|
@@ -67,6 +67,9 @@ module Rails
|
|
67
67
|
def run_generator(args = default_arguments, config = {})
|
68
68
|
capture(:stdout) do
|
69
69
|
args += ["--skip-bundle"] unless args.include? "--dev"
|
70
|
+
args |= ["--skip-bootsnap"] unless args.include? "--no-skip-bootsnap"
|
71
|
+
args |= ["--skip-webpack-install"] unless args.include? "--no-skip-webpack-install"
|
72
|
+
|
70
73
|
generator_class.start(args, config.reverse_merge(destination_root: destination_root))
|
71
74
|
end
|
72
75
|
end
|
data/lib/rails/info.rb
CHANGED
@@ -41,7 +41,7 @@ module Rails
|
|
41
41
|
alias inspect to_s
|
42
42
|
|
43
43
|
def to_html
|
44
|
-
"<table>".
|
44
|
+
(+"<table>").tap do |table|
|
45
45
|
properties.each do |(name, value)|
|
46
46
|
table << %(<tr><td class="name">#{CGI.escapeHTML(name.to_s)}</td>)
|
47
47
|
formatted_value = if value.kind_of?(Array)
|
@@ -63,7 +63,7 @@ module Rails
|
|
63
63
|
|
64
64
|
# The Ruby version and platform, e.g. "2.0.0-p247 (x86_64-darwin12.4.0)".
|
65
65
|
property "Ruby version" do
|
66
|
-
|
66
|
+
RUBY_DESCRIPTION
|
67
67
|
end
|
68
68
|
|
69
69
|
# The RubyGems version, if it's installed.
|
@@ -4,7 +4,7 @@ require "rails/application_controller"
|
|
4
4
|
require "action_dispatch/routing/inspector"
|
5
5
|
|
6
6
|
class Rails::InfoController < Rails::ApplicationController # :nodoc:
|
7
|
-
prepend_view_path ActionDispatch::
|
7
|
+
prepend_view_path ActionDispatch::DebugView::RESCUES_TEMPLATE_PATH
|
8
8
|
layout -> { request.xhr? ? false : "application" }
|
9
9
|
|
10
10
|
before_action :require_local!
|
@@ -3,10 +3,11 @@
|
|
3
3
|
require "rails/application_controller"
|
4
4
|
|
5
5
|
class Rails::MailersController < Rails::ApplicationController # :nodoc:
|
6
|
-
prepend_view_path ActionDispatch::
|
6
|
+
prepend_view_path ActionDispatch::DebugView::RESCUES_TEMPLATE_PATH
|
7
7
|
|
8
|
+
around_action :set_locale, only: :preview
|
9
|
+
before_action :find_preview, only: :preview
|
8
10
|
before_action :require_local!, unless: :show_previews?
|
9
|
-
before_action :find_preview, :set_locale, only: :preview
|
10
11
|
|
11
12
|
helper_method :part_query, :locale_query
|
12
13
|
|
@@ -38,7 +39,7 @@ class Rails::MailersController < Rails::ApplicationController # :nodoc:
|
|
38
39
|
end
|
39
40
|
else
|
40
41
|
@part = find_preferred_part(request.format, Mime[:html], Mime[:text])
|
41
|
-
render action: "email", layout: false, formats:
|
42
|
+
render action: "email", layout: false, formats: [:html]
|
42
43
|
end
|
43
44
|
else
|
44
45
|
raise AbstractController::ActionNotFound, "Email '#{@email_action}' not found in #{@preview.name}"
|
@@ -92,6 +93,8 @@ class Rails::MailersController < Rails::ApplicationController # :nodoc:
|
|
92
93
|
end
|
93
94
|
|
94
95
|
def set_locale
|
95
|
-
I18n.
|
96
|
+
I18n.with_locale(params[:locale] || I18n.default_locale) do
|
97
|
+
yield
|
98
|
+
end
|
96
99
|
end
|
97
100
|
end
|
data/lib/rails/paths.rb
CHANGED
@@ -113,10 +113,11 @@ module Rails
|
|
113
113
|
attr_accessor :glob
|
114
114
|
|
115
115
|
def initialize(root, current, paths, options = {})
|
116
|
-
@paths
|
117
|
-
@current
|
118
|
-
@root
|
119
|
-
@glob
|
116
|
+
@paths = paths
|
117
|
+
@current = current
|
118
|
+
@root = root
|
119
|
+
@glob = options[:glob]
|
120
|
+
@exclude = options[:exclude]
|
120
121
|
|
121
122
|
options[:autoload_once] ? autoload_once! : skip_autoload_once!
|
122
123
|
options[:eager_load] ? eager_load! : skip_eager_load!
|
@@ -189,13 +190,11 @@ module Rails
|
|
189
190
|
raise "You need to set a path root" unless @root.path
|
190
191
|
result = []
|
191
192
|
|
192
|
-
each do |
|
193
|
-
path = File.expand_path(
|
193
|
+
each do |path|
|
194
|
+
path = File.expand_path(path, @root.path)
|
194
195
|
|
195
196
|
if @glob && File.directory?(path)
|
196
|
-
|
197
|
-
result.concat(Dir.glob(@glob).map { |file| File.join path, file }.sort)
|
198
|
-
end
|
197
|
+
result.concat files_in(path)
|
199
198
|
else
|
200
199
|
result << path
|
201
200
|
end
|
@@ -222,6 +221,17 @@ module Rails
|
|
222
221
|
end
|
223
222
|
|
224
223
|
alias to_a expanded
|
224
|
+
|
225
|
+
private
|
226
|
+
|
227
|
+
def files_in(path)
|
228
|
+
Dir.chdir(path) do
|
229
|
+
files = Dir.glob(@glob)
|
230
|
+
files -= @exclude if @exclude
|
231
|
+
files.map! { |file| File.join(path, file) }
|
232
|
+
files.sort
|
233
|
+
end
|
234
|
+
end
|
225
235
|
end
|
226
236
|
end
|
227
237
|
end
|
data/lib/rails/railtie.rb
CHANGED
@@ -224,7 +224,7 @@ module Rails
|
|
224
224
|
end
|
225
225
|
|
226
226
|
def railtie_namespace #:nodoc:
|
227
|
-
@railtie_namespace ||= self.class.
|
227
|
+
@railtie_namespace ||= self.class.module_parents.detect { |n| n.respond_to?(:railtie_namespace) }
|
228
228
|
end
|
229
229
|
|
230
230
|
protected
|
@@ -1,15 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.
|
3
|
+
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.5.0") && RUBY_ENGINE == "ruby"
|
4
4
|
desc = defined?(RUBY_DESCRIPTION) ? RUBY_DESCRIPTION : "ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE})"
|
5
5
|
abort <<-end_message
|
6
6
|
|
7
|
-
Rails
|
7
|
+
Rails 6 requires Ruby 2.5.0 or newer.
|
8
8
|
|
9
9
|
You're running
|
10
10
|
#{desc}
|
11
11
|
|
12
|
-
Please upgrade to Ruby 2.
|
12
|
+
Please upgrade to Ruby 2.5.0 or newer to continue.
|
13
13
|
|
14
14
|
end_message
|
15
15
|
end
|
data/lib/rails/secrets.rb
CHANGED
@@ -1,141 +1,162 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
#
|
5
|
-
# rails notes
|
6
|
-
# rails notes:optimize
|
7
|
-
#
|
8
|
-
# and friends. See <tt>rails -T notes</tt> and <tt>railties/lib/rails/tasks/annotations.rake</tt>.
|
9
|
-
#
|
10
|
-
# Annotation objects are triplets <tt>:line</tt>, <tt>:tag</tt>, <tt>:text</tt> that
|
11
|
-
# represent the line where the annotation lives, its tag, and its text. Note
|
12
|
-
# the filename is not stored.
|
13
|
-
#
|
14
|
-
# Annotations are looked for in comments and modulus whitespace they have to
|
15
|
-
# start with the tag optionally followed by a colon. Everything up to the end
|
16
|
-
# of the line (or closing ERB comment tag) is considered to be their text.
|
17
|
-
class SourceAnnotationExtractor
|
18
|
-
Annotation = Struct.new(:line, :tag, :text) do
|
19
|
-
def self.directories
|
20
|
-
@@directories ||= %w(app config db lib test) + (ENV["SOURCE_ANNOTATION_DIRECTORIES"] || "").split(",")
|
21
|
-
end
|
3
|
+
require "active_support/deprecation"
|
22
4
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
5
|
+
module Rails
|
6
|
+
# Implements the logic behind <tt>Rails::Command::NotesCommand</tt>. See <tt>rails notes --help</tt> for usage information.
|
7
|
+
#
|
8
|
+
# Annotation objects are triplets <tt>:line</tt>, <tt>:tag</tt>, <tt>:text</tt> that
|
9
|
+
# represent the line where the annotation lives, its tag, and its text. Note
|
10
|
+
# the filename is not stored.
|
11
|
+
#
|
12
|
+
# Annotations are looked for in comments and modulus whitespace they have to
|
13
|
+
# start with the tag optionally followed by a colon. Everything up to the end
|
14
|
+
# of the line (or closing ERB comment tag) is considered to be their text.
|
15
|
+
class SourceAnnotationExtractor
|
16
|
+
class Annotation < Struct.new(:line, :tag, :text)
|
17
|
+
def self.directories
|
18
|
+
@@directories ||= %w(app config db lib test)
|
19
|
+
end
|
28
20
|
|
29
|
-
|
30
|
-
|
31
|
-
|
21
|
+
# Registers additional directories to be included
|
22
|
+
# Rails::SourceAnnotationExtractor::Annotation.register_directories("spec", "another")
|
23
|
+
def self.register_directories(*dirs)
|
24
|
+
directories.push(*dirs)
|
25
|
+
end
|
32
26
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
extensions[/\.(#{exts.join("|")})$/] = block
|
37
|
-
end
|
27
|
+
def self.tags
|
28
|
+
@@tags ||= %w(OPTIMIZE FIXME TODO)
|
29
|
+
end
|
38
30
|
|
39
|
-
|
40
|
-
|
41
|
-
|
31
|
+
# Registers additional tags
|
32
|
+
# Rails::SourceAnnotationExtractor::Annotation.register_tags("TESTME", "DEPRECATEME")
|
33
|
+
def self.register_tags(*additional_tags)
|
34
|
+
tags.push(*additional_tags)
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.extensions
|
38
|
+
@@extensions ||= {}
|
39
|
+
end
|
42
40
|
|
43
|
-
|
41
|
+
# Registers new Annotations File Extensions
|
42
|
+
# Rails::SourceAnnotationExtractor::Annotation.register_extensions("css", "scss", "sass", "less", "js") { |tag| /\/\/\s*(#{tag}):?\s*(.*)$/ }
|
43
|
+
def self.register_extensions(*exts, &block)
|
44
|
+
extensions[/\.(#{exts.join("|")})$/] = block
|
45
|
+
end
|
46
|
+
|
47
|
+
register_extensions("builder", "rb", "rake", "yml", "yaml", "ruby") { |tag| /#\s*(#{tag}):?\s*(.*)$/ }
|
48
|
+
register_extensions("css", "js") { |tag| /\/\/\s*(#{tag}):?\s*(.*)$/ }
|
49
|
+
register_extensions("erb") { |tag| /<%\s*#\s*(#{tag}):?\s*(.*?)\s*%>/ }
|
50
|
+
|
51
|
+
# Returns a representation of the annotation that looks like this:
|
52
|
+
#
|
53
|
+
# [126] [TODO] This algorithm is simple and clearly correct, make it faster.
|
54
|
+
#
|
55
|
+
# If +options+ has a flag <tt>:tag</tt> the tag is shown as in the example above.
|
56
|
+
# Otherwise the string contains just line and text.
|
57
|
+
def to_s(options = {})
|
58
|
+
s = +"[#{line.to_s.rjust(options[:indent])}] "
|
59
|
+
s << "[#{tag}] " if options[:tag]
|
60
|
+
s << text
|
61
|
+
end
|
62
|
+
|
63
|
+
# Used in annotations.rake
|
64
|
+
#:nodoc:
|
65
|
+
def self.notes_task_deprecation_warning
|
66
|
+
ActiveSupport::Deprecation.warn("This rake task is deprecated and will be removed in Rails 6.1. \nRefer to `rails notes --help` for more information.\n")
|
67
|
+
puts "\n"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# Prints all annotations with tag +tag+ under the root directories +app+,
|
72
|
+
# +config+, +db+, +lib+, and +test+ (recursively).
|
73
|
+
#
|
74
|
+
# If +tag+ is <tt>nil</tt>, annotations with either default or registered tags are printed.
|
75
|
+
#
|
76
|
+
# Specific directories can be explicitly set using the <tt>:dirs</tt> key in +options+.
|
77
|
+
#
|
78
|
+
# Rails::SourceAnnotationExtractor.enumerate 'TODO|FIXME', dirs: %w(app lib), tag: true
|
79
|
+
#
|
80
|
+
# If +options+ has a <tt>:tag</tt> flag, it will be passed to each annotation's +to_s+.
|
44
81
|
#
|
45
|
-
#
|
82
|
+
# See <tt>#find_in</tt> for a list of file extensions that will be taken into account.
|
46
83
|
#
|
47
|
-
#
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
84
|
+
# This class method is the single entry point for the `rails notes` command.
|
85
|
+
def self.enumerate(tag = nil, options = {})
|
86
|
+
tag ||= Annotation.tags.join("|")
|
87
|
+
extractor = new(tag)
|
88
|
+
dirs = options.delete(:dirs) || Annotation.directories
|
89
|
+
extractor.display(extractor.find(dirs), options)
|
53
90
|
end
|
54
|
-
end
|
55
91
|
|
56
|
-
|
57
|
-
# +config+, +db+, +lib+, and +test+ (recursively).
|
58
|
-
#
|
59
|
-
# Additional directories may be added using a comma-delimited list set using
|
60
|
-
# <tt>ENV['SOURCE_ANNOTATION_DIRECTORIES']</tt>.
|
61
|
-
#
|
62
|
-
# Directories may also be explicitly set using the <tt>:dirs</tt> key in +options+.
|
63
|
-
#
|
64
|
-
# SourceAnnotationExtractor.enumerate 'TODO|FIXME', dirs: %w(app lib), tag: true
|
65
|
-
#
|
66
|
-
# If +options+ has a <tt>:tag</tt> flag, it will be passed to each annotation's +to_s+.
|
67
|
-
#
|
68
|
-
# See <tt>#find_in</tt> for a list of file extensions that will be taken into account.
|
69
|
-
#
|
70
|
-
# This class method is the single entry point for the rake tasks.
|
71
|
-
def self.enumerate(tag, options = {})
|
72
|
-
extractor = new(tag)
|
73
|
-
dirs = options.delete(:dirs) || Annotation.directories
|
74
|
-
extractor.display(extractor.find(dirs), options)
|
75
|
-
end
|
76
|
-
|
77
|
-
attr_reader :tag
|
78
|
-
|
79
|
-
def initialize(tag)
|
80
|
-
@tag = tag
|
81
|
-
end
|
92
|
+
attr_reader :tag
|
82
93
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
dirs.inject({}) { |h, dir| h.update(find_in(dir)) }
|
87
|
-
end
|
94
|
+
def initialize(tag)
|
95
|
+
@tag = tag
|
96
|
+
end
|
88
97
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
results = {}
|
95
|
-
|
96
|
-
Dir.glob("#{dir}/*") do |item|
|
97
|
-
next if File.basename(item)[0] == ?.
|
98
|
-
|
99
|
-
if File.directory?(item)
|
100
|
-
results.update(find_in(item))
|
101
|
-
else
|
102
|
-
extension = Annotation.extensions.detect do |regexp, _block|
|
103
|
-
regexp.match(item)
|
104
|
-
end
|
98
|
+
# Returns a hash that maps filenames under +dirs+ (recursively) to arrays
|
99
|
+
# with their annotations.
|
100
|
+
def find(dirs)
|
101
|
+
dirs.inject({}) { |h, dir| h.update(find_in(dir)) }
|
102
|
+
end
|
105
103
|
|
106
|
-
|
107
|
-
|
108
|
-
|
104
|
+
# Returns a hash that maps filenames under +dir+ (recursively) to arrays
|
105
|
+
# with their annotations. Files with extensions registered in
|
106
|
+
# <tt>Rails::SourceAnnotationExtractor::Annotation.extensions</tt> are
|
107
|
+
# taken into account. Only files with annotations are included.
|
108
|
+
def find_in(dir)
|
109
|
+
results = {}
|
110
|
+
|
111
|
+
Dir.glob("#{dir}/*") do |item|
|
112
|
+
next if File.basename(item)[0] == ?.
|
113
|
+
|
114
|
+
if File.directory?(item)
|
115
|
+
results.update(find_in(item))
|
116
|
+
else
|
117
|
+
extension = Annotation.extensions.detect do |regexp, _block|
|
118
|
+
regexp.match(item)
|
119
|
+
end
|
120
|
+
|
121
|
+
if extension
|
122
|
+
pattern = extension.last.call(tag)
|
123
|
+
results.update(extract_annotations_from(item, pattern)) if pattern
|
124
|
+
end
|
109
125
|
end
|
110
126
|
end
|
111
|
-
end
|
112
127
|
|
113
|
-
|
114
|
-
|
128
|
+
results
|
129
|
+
end
|
115
130
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
131
|
+
# If +file+ is the filename of a file that contains annotations this method returns
|
132
|
+
# a hash with a single entry that maps +file+ to an array of its annotations.
|
133
|
+
# Otherwise it returns an empty hash.
|
134
|
+
def extract_annotations_from(file, pattern)
|
135
|
+
lineno = 0
|
136
|
+
result = File.readlines(file, encoding: Encoding::BINARY).inject([]) do |list, line|
|
137
|
+
lineno += 1
|
138
|
+
next list unless line =~ pattern
|
139
|
+
list << Annotation.new(lineno, $1, $2)
|
140
|
+
end
|
141
|
+
result.empty? ? {} : { file => result }
|
125
142
|
end
|
126
|
-
result.empty? ? {} : { file => result }
|
127
|
-
end
|
128
143
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
144
|
+
# Prints the mapping from filenames to annotations in +results+ ordered by filename.
|
145
|
+
# The +options+ hash is passed to each annotation's +to_s+.
|
146
|
+
def display(results, options = {})
|
147
|
+
options[:indent] = results.flat_map { |f, a| a.map(&:line) }.max.to_s.size
|
148
|
+
results.keys.sort.each do |file|
|
149
|
+
puts "#{file}:"
|
150
|
+
results[file].each do |note|
|
151
|
+
puts " * #{note.to_s(options)}"
|
152
|
+
end
|
153
|
+
puts
|
137
154
|
end
|
138
|
-
puts
|
139
155
|
end
|
140
156
|
end
|
141
157
|
end
|
158
|
+
|
159
|
+
# Remove this deprecated class in the next minor version
|
160
|
+
#:nodoc:
|
161
|
+
SourceAnnotationExtractor = ActiveSupport::Deprecation::DeprecatedConstantProxy.
|
162
|
+
new("SourceAnnotationExtractor", "Rails::SourceAnnotationExtractor")
|