railties 7.2.0 → 8.0.0.beta1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +111 -254
- data/lib/minitest/rails_plugin.rb +1 -1
- data/lib/rails/application/configuration.rb +15 -2
- data/lib/rails/application/default_middleware_stack.rb +4 -0
- data/lib/rails/application/finisher.rb +2 -2
- data/lib/rails/application/routes_reloader.rb +11 -1
- data/lib/rails/application.rb +12 -0
- data/lib/rails/code_statistics.rb +128 -86
- data/lib/rails/code_statistics_calculator.rb +78 -76
- data/lib/rails/command/helpers/editor.rb +1 -1
- data/lib/rails/commands/app/update_command.rb +10 -9
- data/lib/rails/commands/console/irb_console.rb +1 -2
- data/lib/rails/commands/credentials/USAGE +4 -4
- data/lib/rails/commands/credentials/credentials_command.rb +5 -1
- data/lib/rails/commands/dev/dev_command.rb +1 -1
- data/lib/rails/commands/devcontainer/devcontainer_command.rb +1 -1
- data/lib/rails/commands/stats/stats_command.rb +19 -0
- data/lib/rails/dev_caching.rb +2 -2
- data/lib/rails/engine/configuration.rb +3 -1
- data/lib/rails/engine/lazy_route_set.rb +109 -0
- data/lib/rails/engine.rb +10 -5
- data/lib/rails/gem_version.rb +3 -3
- data/lib/rails/generators/app_base.rb +46 -24
- data/lib/rails/generators/database.rb +102 -68
- data/lib/rails/generators/erb/authentication/authentication_generator.rb +15 -0
- data/lib/rails/generators/erb/authentication/templates/views/passwords/edit.html.erb +9 -0
- data/lib/rails/generators/erb/authentication/templates/views/passwords/new.html.erb +8 -0
- data/lib/rails/generators/erb/authentication/templates/views/sessions/new.html.erb +11 -0
- data/lib/rails/generators/generated_attribute.rb +16 -11
- data/lib/rails/generators/rails/app/app_generator.rb +22 -32
- data/lib/rails/generators/rails/app/templates/Dockerfile.tt +12 -3
- data/lib/rails/generators/rails/app/templates/Gemfile.tt +23 -8
- data/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css.tt +6 -11
- data/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt +10 -3
- data/lib/rails/generators/rails/app/templates/app/views/pwa/service-worker.js +3 -3
- data/lib/rails/generators/rails/app/templates/bin/dev.tt +1 -0
- data/lib/rails/generators/rails/app/templates/bin/setup.tt +5 -7
- data/lib/rails/generators/rails/app/templates/bin/thrust.tt +4 -0
- data/lib/rails/generators/rails/app/templates/config/databases/mysql.yml.tt +23 -0
- data/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml.tt +23 -0
- data/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml.tt +40 -0
- data/lib/rails/generators/rails/app/templates/config/databases/trilogy.yml.tt +23 -0
- data/lib/rails/generators/rails/app/templates/config/deploy.yml.tt +124 -0
- data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +12 -23
- data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +34 -51
- data/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +5 -19
- data/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt +0 -7
- data/lib/rails/generators/rails/app/templates/config/initializers/filter_parameter_logging.rb.tt +1 -1
- data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_8_0.rb.tt +25 -0
- data/lib/rails/generators/rails/app/templates/config/puma.rb.tt +13 -3
- data/lib/rails/generators/rails/app/templates/config/routes.rb.tt +5 -3
- data/lib/rails/generators/rails/app/templates/docker-entrypoint.tt +4 -3
- data/lib/rails/generators/rails/app/templates/dockerignore.tt +1 -2
- data/lib/rails/generators/rails/app/templates/github/ci.yml.tt +1 -1
- data/lib/rails/generators/rails/app/templates/gitignore.tt +1 -2
- data/lib/rails/generators/rails/app/templates/kamal-secrets.tt +17 -0
- data/lib/rails/generators/rails/app/templates/public/400.html +114 -0
- data/lib/rails/generators/rails/app/templates/public/404.html +113 -66
- data/lib/rails/generators/rails/app/templates/public/406-unsupported-browser.html +113 -65
- data/lib/rails/generators/rails/app/templates/public/422.html +113 -66
- data/lib/rails/generators/rails/app/templates/public/500.html +113 -65
- data/lib/rails/generators/rails/app/templates/public/icon.png +0 -0
- data/lib/rails/generators/rails/app/templates/public/icon.svg +2 -2
- data/lib/rails/generators/rails/authentication/USAGE +6 -0
- data/lib/rails/generators/rails/authentication/authentication_generator.rb +54 -0
- data/lib/rails/generators/rails/authentication/templates/controllers/concerns/authentication.rb +55 -0
- data/lib/rails/generators/rails/authentication/templates/controllers/passwords_controller.rb +33 -0
- data/lib/rails/generators/rails/authentication/templates/controllers/sessions_controller.rb +21 -0
- data/lib/rails/generators/rails/authentication/templates/mailers/passwords_mailer.rb +6 -0
- data/lib/rails/generators/rails/authentication/templates/models/current.rb +4 -0
- data/lib/rails/generators/rails/authentication/templates/models/session.rb +3 -0
- data/lib/rails/generators/rails/authentication/templates/models/user.rb +6 -0
- data/lib/rails/generators/rails/authentication/templates/test/mailers/previews/passwords_mailer_preview.rb +7 -0
- data/lib/rails/generators/rails/authentication/templates/views/passwords_mailer/reset.html.erb +4 -0
- data/lib/rails/generators/rails/authentication/templates/views/passwords_mailer/reset.text.erb +2 -0
- data/lib/rails/generators/rails/credentials/templates/credentials.yml.tt +4 -0
- data/lib/rails/generators/rails/db/system/change/change_generator.rb +1 -1
- data/lib/rails/generators/rails/devcontainer/devcontainer_generator.rb +5 -3
- data/lib/rails/generators/rails/devcontainer/templates/devcontainer/devcontainer.json.tt +1 -1
- data/lib/rails/generators/rails/plugin/plugin_generator.rb +11 -11
- data/lib/rails/generators/rails/plugin/templates/github/ci.yml.tt +1 -1
- data/lib/rails/generators/rails/plugin/templates/test/test_helper.rb.tt +2 -2
- data/lib/rails/generators/rails/scaffold_controller/templates/api_controller.rb.tt +2 -2
- data/lib/rails/generators/rails/scaffold_controller/templates/controller.rb.tt +3 -3
- data/lib/rails/generators/rails/script/USAGE +18 -0
- data/lib/rails/generators/rails/script/script_generator.rb +18 -0
- data/lib/rails/generators/rails/script/templates/script.rb.tt +3 -0
- data/lib/rails/generators.rb +7 -2
- data/lib/rails/info_controller.rb +10 -2
- data/lib/rails/rack/silence_request.rb +33 -0
- data/lib/rails/rack.rb +1 -0
- data/lib/rails/railtie.rb +13 -13
- data/lib/rails/source_annotation_extractor.rb +31 -14
- data/lib/rails/tasks/statistics.rake +13 -28
- data/lib/rails/templates/rails/info/notes.html.erb +65 -0
- metadata +45 -25
- data/lib/rails/generators/rails/app/templates/app/assets/config/manifest.js.tt +0 -2
- data/lib/rails/generators/rails/app/templates/app/channels/application_cable/channel.rb.tt +0 -4
- data/lib/rails/generators/rails/app/templates/app/channels/application_cable/connection.rb.tt +0 -4
- data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_7_2.rb.tt +0 -70
- data/lib/rails/generators/rails/app/templates/config/initializers/permissions_policy.rb.tt +0 -13
- data/lib/rails/generators/rails/app/templates/test/channels/application_cable/connection_test.rb.tt +0 -13
- data/lib/rails/generators/rails/plugin/templates/rails/dummy_manifest.js.tt +0 -10
- data/lib/rails/generators/rails/plugin/templates/rails/engine_manifest.js.tt +0 -6
- data/lib/rails/generators/rails/plugin/templates/rails/javascripts.js.tt +0 -17
| @@ -3,115 +3,157 @@ | |
| 3 3 | 
             
            require "rails/code_statistics_calculator"
         | 
| 4 4 | 
             
            require "active_support/core_ext/enumerable"
         | 
| 5 5 |  | 
| 6 | 
            -
             | 
| 7 | 
            -
               | 
| 8 | 
            -
             | 
| 9 | 
            -
             | 
| 10 | 
            -
             | 
| 11 | 
            -
             | 
| 12 | 
            -
             | 
| 13 | 
            -
             | 
| 14 | 
            -
             | 
| 15 | 
            -
             | 
| 16 | 
            -
             | 
| 17 | 
            -
             | 
| 18 | 
            -
             | 
| 19 | 
            -
             | 
| 20 | 
            -
             | 
| 21 | 
            -
             | 
| 22 | 
            -
             | 
| 23 | 
            -
             | 
| 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 | 
            -
             | 
| 26 | 
            -
             | 
| 27 | 
            -
             | 
| 28 | 
            -
             | 
| 60 | 
            +
                def initialize(*pairs)
         | 
| 61 | 
            +
                  @pairs      = pairs
         | 
| 62 | 
            +
                  @statistics = calculate_statistics
         | 
| 63 | 
            +
                  @total      = calculate_total if pairs.length > 1
         | 
| 64 | 
            +
                end
         | 
| 29 65 |  | 
| 30 | 
            -
                 | 
| 31 | 
            -
                   | 
| 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 | 
            -
             | 
| 36 | 
            -
             | 
| 71 | 
            +
                  if @total
         | 
| 72 | 
            +
                    print_line("Total", @total)
         | 
| 73 | 
            +
                    print_splitter
         | 
| 74 | 
            +
                  end
         | 
| 37 75 |  | 
| 38 | 
            -
             | 
| 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 | 
            -
                 | 
| 44 | 
            -
                   | 
| 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 | 
            -
             | 
| 47 | 
            -
             | 
| 87 | 
            +
                    Dir.foreach(directory) do |file_name|
         | 
| 88 | 
            +
                      path = "#{directory}/#{file_name}"
         | 
| 48 89 |  | 
| 49 | 
            -
             | 
| 50 | 
            -
             | 
| 51 | 
            -
             | 
| 52 | 
            -
             | 
| 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 | 
            -
             | 
| 57 | 
            -
             | 
| 97 | 
            +
                    stats
         | 
| 98 | 
            +
                  end
         | 
| 58 99 |  | 
| 59 | 
            -
             | 
| 60 | 
            -
             | 
| 61 | 
            -
             | 
| 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 | 
            -
             | 
| 66 | 
            -
             | 
| 67 | 
            -
             | 
| 68 | 
            -
             | 
| 69 | 
            -
             | 
| 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 | 
            -
             | 
| 72 | 
            -
             | 
| 73 | 
            -
             | 
| 74 | 
            -
             | 
| 75 | 
            -
             | 
| 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 | 
            -
             | 
| 78 | 
            -
             | 
| 79 | 
            -
             | 
| 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 | 
            -
             | 
| 82 | 
            -
             | 
| 83 | 
            -
             | 
| 84 | 
            -
             | 
| 85 | 
            -
             | 
| 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 | 
            -
             | 
| 92 | 
            -
             | 
| 93 | 
            -
             | 
| 94 | 
            -
             | 
| 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 | 
            -
             | 
| 100 | 
            -
             | 
| 101 | 
            -
             | 
| 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 | 
            -
             | 
| 104 | 
            -
             | 
| 105 | 
            -
             | 
| 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 | 
            -
             | 
| 111 | 
            -
             | 
| 112 | 
            -
             | 
| 151 | 
            +
                  def print_code_test_stats
         | 
| 152 | 
            +
                    code  = calculate_code
         | 
| 153 | 
            +
                    tests = calculate_tests
         | 
| 113 154 |  | 
| 114 | 
            -
             | 
| 115 | 
            -
             | 
| 116 | 
            -
             | 
| 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 | 
            -
             | 
| 4 | 
            -
               | 
| 3 | 
            +
            module Rails
         | 
| 4 | 
            +
              class CodeStatisticsCalculator # :nodoc:
         | 
| 5 | 
            +
                attr_reader :lines, :code_lines, :classes, :methods
         | 
| 5 6 |  | 
| 6 | 
            -
             | 
| 7 | 
            -
             | 
| 8 | 
            -
             | 
| 9 | 
            -
             | 
| 10 | 
            -
             | 
| 11 | 
            -
             | 
| 12 | 
            -
             | 
| 13 | 
            -
             | 
| 14 | 
            -
             | 
| 15 | 
            -
             | 
| 16 | 
            -
             | 
| 17 | 
            -
             | 
| 18 | 
            -
             | 
| 19 | 
            -
             | 
| 20 | 
            -
             | 
| 21 | 
            -
             | 
| 22 | 
            -
             | 
| 23 | 
            -
             | 
| 24 | 
            -
             | 
| 25 | 
            -
             | 
| 26 | 
            -
             | 
| 27 | 
            -
             | 
| 28 | 
            -
             | 
| 29 | 
            -
             | 
| 30 | 
            -
             | 
| 31 | 
            -
             | 
| 32 | 
            -
             | 
| 33 | 
            -
             | 
| 34 | 
            -
             | 
| 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 | 
            -
             | 
| 39 | 
            -
             | 
| 39 | 
            +
                PATTERNS[:minitest] = PATTERNS[:rb].merge method: /^\s*(def|test)\s+['"_a-z]/
         | 
| 40 | 
            +
                PATTERNS[:rake] = PATTERNS[:rb]
         | 
| 40 41 |  | 
| 41 | 
            -
             | 
| 42 | 
            -
             | 
| 43 | 
            -
             | 
| 44 | 
            -
             | 
| 45 | 
            -
             | 
| 46 | 
            -
             | 
| 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 | 
            -
             | 
| 49 | 
            -
             | 
| 50 | 
            -
             | 
| 51 | 
            -
             | 
| 52 | 
            -
             | 
| 53 | 
            -
             | 
| 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 | 
            -
             | 
| 56 | 
            -
             | 
| 57 | 
            -
             | 
| 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 | 
            -
             | 
| 62 | 
            -
             | 
| 62 | 
            +
                def add_by_io(io, file_type)
         | 
| 63 | 
            +
                  patterns = PATTERNS[file_type] || {}
         | 
| 63 64 |  | 
| 64 | 
            -
             | 
| 65 | 
            +
                  comment_started = false
         | 
| 65 66 |  | 
| 66 | 
            -
             | 
| 67 | 
            -
             | 
| 67 | 
            +
                  while line = io.gets
         | 
| 68 | 
            +
                    @lines += 1
         | 
| 68 69 |  | 
| 69 | 
            -
             | 
| 70 | 
            -
             | 
| 71 | 
            -
             | 
| 72 | 
            -
             | 
| 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 | 
            -
             | 
| 82 | 
            -
             | 
| 83 | 
            -
             | 
| 84 | 
            -
             | 
| 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 | 
            -
             | 
| 90 | 
            -
             | 
| 91 | 
            -
             | 
| 92 | 
            -
             | 
| 93 | 
            -
             | 
| 94 | 
            -
             | 
| 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 | 
            -
             | 
| 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=" | 
| 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."
         | 
| @@ -69,23 +69,24 @@ module Rails | |
| 69 69 | 
             
                          skip_action_mailbox: !defined?(ActionMailbox::Engine),
         | 
| 70 70 | 
             
                          skip_action_text:    !defined?(ActionText::Engine),
         | 
| 71 71 | 
             
                          skip_action_cable:   !defined?(ActionCable::Engine),
         | 
| 72 | 
            +
                          skip_brakeman:       skip_gem?("brakeman"),
         | 
| 73 | 
            +
                          skip_rubocop:        skip_gem?("rubocop"),
         | 
| 72 74 | 
             
                          skip_test:           !defined?(Rails::TestUnitRailtie),
         | 
| 73 75 | 
             
                          skip_system_test:    Rails.application.config.generators.system_tests.nil?,
         | 
| 74 | 
            -
                          asset_pipeline:      asset_pipeline,
         | 
| 75 76 | 
             
                          skip_asset_pipeline: asset_pipeline.nil?,
         | 
| 76 77 | 
             
                          skip_bootsnap:       !defined?(Bootsnap),
         | 
| 77 78 | 
             
                        }.merge(options)
         | 
| 78 79 | 
             
                      end
         | 
| 79 80 |  | 
| 80 81 | 
             
                      def asset_pipeline
         | 
| 81 | 
            -
                         | 
| 82 | 
            -
             | 
| 83 | 
            -
             | 
| 84 | 
            -
             | 
| 85 | 
            -
             | 
| 86 | 
            -
                         | 
| 87 | 
            -
             | 
| 88 | 
            -
                         | 
| 82 | 
            +
                        "propshaft" if defined?(Propshaft::Railtie)
         | 
| 83 | 
            +
                      end
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                      def skip_gem?(gem_name)
         | 
| 86 | 
            +
                        gem gem_name
         | 
| 87 | 
            +
                        false
         | 
| 88 | 
            +
                      rescue LoadError
         | 
| 89 | 
            +
                        true
         | 
| 89 90 | 
             
                      end
         | 
| 90 91 | 
             
                  end
         | 
| 91 92 | 
             
                end
         | 
| @@ -89,9 +89,8 @@ module Rails | |
| 89 89 | 
             
                    end
         | 
| 90 90 |  | 
| 91 91 | 
             
                    env = colorized_env
         | 
| 92 | 
            -
                    app_name = @app.class.module_parent_name.underscore.dasherize
         | 
| 93 92 | 
             
                    prompt_prefix = "%N(#{env})"
         | 
| 94 | 
            -
                    IRB.conf[:IRB_NAME] =  | 
| 93 | 
            +
                    IRB.conf[:IRB_NAME] = @app.name
         | 
| 95 94 |  | 
| 96 95 | 
             
                    IRB.conf[:PROMPT][:RAILS_PROMPT] = {
         | 
| 97 96 | 
             
                      PROMPT_I: "#{prompt_prefix}> ",
         | 
| @@ -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 | 
            -
                 | 
| 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,7 +24,7 @@ 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 30 | 
             
                      }
         | 
| @@ -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
         | 
    
        data/lib/rails/dev_caching.rb
    CHANGED
    
    | @@ -12,10 +12,10 @@ module Rails | |
| 12 12 |  | 
| 13 13 | 
             
                    if File.exist?(FILE)
         | 
| 14 14 | 
             
                      delete_cache_file
         | 
| 15 | 
            -
                      puts " | 
| 15 | 
            +
                      puts "Action Controller caching disabled for development mode."
         | 
| 16 16 | 
             
                    else
         | 
| 17 17 | 
             
                      create_cache_file
         | 
| 18 | 
            -
                      puts " | 
| 18 | 
            +
                      puts "Action Controller caching enabled for development mode."
         | 
| 19 19 | 
             
                    end
         | 
| 20 20 |  | 
| 21 21 | 
             
                    FileUtils.touch "tmp/restart.txt"
         | 
| @@ -6,7 +6,7 @@ module Rails | |
| 6 6 | 
             
              class Engine
         | 
| 7 7 | 
             
                class Configuration < ::Rails::Railtie::Configuration
         | 
| 8 8 | 
             
                  attr_reader :root
         | 
| 9 | 
            -
                  attr_accessor :middleware, :javascript_path
         | 
| 9 | 
            +
                  attr_accessor :middleware, :javascript_path, :route_set_class, :default_scope
         | 
| 10 10 | 
             
                  attr_writer :eager_load_paths, :autoload_once_paths, :autoload_paths
         | 
| 11 11 |  | 
| 12 12 | 
             
                  # An array of custom autoload paths to be added to the ones defined
         | 
| @@ -44,6 +44,8 @@ module Rails | |
| 44 44 | 
             
                    @generators = app_generators.dup
         | 
| 45 45 | 
             
                    @middleware = Rails::Configuration::MiddlewareStackProxy.new
         | 
| 46 46 | 
             
                    @javascript_path = "javascript"
         | 
| 47 | 
            +
                    @route_set_class = ActionDispatch::Routing::RouteSet
         | 
| 48 | 
            +
                    @default_scope = nil
         | 
| 47 49 |  | 
| 48 50 | 
             
                    @autoload_paths = []
         | 
| 49 51 | 
             
                    @autoload_once_paths = []
         |