DEV: Upgrade Discourse to Rails 6 (#8083)

* Adjustments to pass specs on Rails 6.0.0
* Use classic autoloader instead of Zeitwerk
* Update Rails 6.0.0 deprecated methods
* Rails 6.0.0 not allowing column with integer name
* Drop freedom_patches/rails6.rb
* Default value for trigger_transactional_callbacks? is true
* Bump rspec-rails version to 4.0.0.beta2
This commit is contained in:
Krzysztof Kotlarek 2019-09-12 10:41:50 +10:00 committed by Sam
parent eeb84806bc
commit 32b8a2ccff
17 changed files with 80 additions and 185 deletions

16
Gemfile
View File

@ -16,13 +16,13 @@ if rails_master?
else
# until rubygems gives us optional dependencies we are stuck with this
# bundle update actionmailer actionpack actionview activemodel activerecord activesupport railties
gem 'actionmailer', '5.2.3'
gem 'actionpack', '5.2.3'
gem 'actionview', '5.2.3'
gem 'activemodel', '5.2.3'
gem 'activerecord', '5.2.3'
gem 'activesupport', '5.2.3'
gem 'railties', '5.2.3'
gem 'actionmailer', '6.0.0'
gem 'actionpack', '6.0.0'
gem 'actionview', '6.0.0'
gem 'activemodel', '6.0.0'
gem 'activerecord', '6.0.0'
gem 'activesupport', '6.0.0'
gem 'railties', '6.0.0'
gem 'sprockets-rails'
end
@ -140,7 +140,7 @@ group :test, :development do
gem 'mocha', require: false
gem 'rb-fsevent', require: RUBY_PLATFORM =~ /darwin/i ? 'rb-fsevent' : false
gem 'rb-inotify', '~> 0.9', require: RUBY_PLATFORM =~ /linux/i ? 'rb-inotify' : false
gem 'rspec-rails', require: false
gem 'rspec-rails', '4.0.0.beta2', require: false
gem 'shoulda-matchers', '~> 3.1', '>= 3.1.3', require: false
gem 'rspec-html-matchers'
gem 'pry-nav'

View File

@ -1,47 +1,46 @@
GEM
remote: https://rubygems.org/
specs:
actionmailer (5.2.3)
actionpack (= 5.2.3)
actionview (= 5.2.3)
activejob (= 5.2.3)
actionmailer (6.0.0)
actionpack (= 6.0.0)
actionview (= 6.0.0)
activejob (= 6.0.0)
mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 2.0)
actionpack (5.2.3)
actionview (= 5.2.3)
activesupport (= 5.2.3)
actionpack (6.0.0)
actionview (= 6.0.0)
activesupport (= 6.0.0)
rack (~> 2.0)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.2)
actionview (5.2.3)
activesupport (= 5.2.3)
rails-html-sanitizer (~> 1.0, >= 1.2.0)
actionview (6.0.0)
activesupport (= 6.0.0)
builder (~> 3.1)
erubi (~> 1.4)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.3)
rails-html-sanitizer (~> 1.1, >= 1.2.0)
active_model_serializers (0.8.4)
activemodel (>= 3.0)
activejob (5.2.3)
activesupport (= 5.2.3)
activejob (6.0.0)
activesupport (= 6.0.0)
globalid (>= 0.3.6)
activemodel (5.2.3)
activesupport (= 5.2.3)
activerecord (5.2.3)
activemodel (= 5.2.3)
activesupport (= 5.2.3)
arel (>= 9.0)
activesupport (5.2.3)
activemodel (6.0.0)
activesupport (= 6.0.0)
activerecord (6.0.0)
activemodel (= 6.0.0)
activesupport (= 6.0.0)
activesupport (6.0.0)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2)
minitest (~> 5.1)
tzinfo (~> 1.1)
zeitwerk (~> 2.1, >= 2.1.8)
addressable (2.5.2)
public_suffix (>= 2.0.2, < 4.0)
annotate (2.7.5)
activerecord (>= 3.2, < 7.0)
rake (>= 10.4, < 13.0)
arel (9.0.0)
ast (2.4.0)
aws-eventstream (1.0.3)
aws-partitions (1.154.0)
@ -183,7 +182,7 @@ GEM
rack (>= 1.1.3)
metaclass (0.0.4)
method_source (0.9.2)
mini_mime (1.0.1)
mini_mime (1.0.2)
mini_portile2 (2.4.0)
mini_racer (0.2.6)
libv8 (>= 6.9.411)
@ -282,20 +281,20 @@ GEM
rails-dom-testing (2.0.3)
activesupport (>= 4.2.0)
nokogiri (>= 1.6)
rails-html-sanitizer (1.0.4)
rails-html-sanitizer (1.2.0)
loofah (~> 2.2, >= 2.2.2)
rails_multisite (2.0.7)
activerecord (> 4.2, < 7)
railties (> 4.2, < 7)
railties (5.2.3)
actionpack (= 5.2.3)
activesupport (= 5.2.3)
railties (6.0.0)
actionpack (= 6.0.0)
activesupport (= 6.0.0)
method_source
rake (>= 0.8.7)
thor (>= 0.19.0, < 2.0)
thor (>= 0.20.3, < 2.0)
rainbow (3.0.0)
raindrops (0.19.0)
rake (12.3.2)
rake (12.3.3)
rake-compiler (1.0.7)
rake
rb-fsevent (0.10.3)
@ -330,14 +329,14 @@ GEM
rspec-mocks (3.8.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.8.0)
rspec-rails (3.8.2)
actionpack (>= 3.0)
activesupport (>= 3.0)
railties (>= 3.0)
rspec-core (~> 3.8.0)
rspec-expectations (~> 3.8.0)
rspec-mocks (~> 3.8.0)
rspec-support (~> 3.8.0)
rspec-rails (4.0.0.beta2)
actionpack (>= 4.2)
activesupport (>= 4.2)
railties (>= 4.2)
rspec-core (~> 3.8)
rspec-expectations (~> 3.8)
rspec-mocks (~> 3.8)
rspec-support (~> 3.8)
rspec-support (3.8.0)
rtlit (0.0.5)
rubocop (0.69.0)
@ -417,18 +416,19 @@ GEM
hkdf (~> 0.2)
jwt (~> 2.0)
yaml-lint (0.0.10)
zeitwerk (2.1.10)
PLATFORMS
ruby
DEPENDENCIES
actionmailer (= 5.2.3)
actionpack (= 5.2.3)
actionview (= 5.2.3)
actionmailer (= 6.0.0)
actionpack (= 6.0.0)
actionview (= 6.0.0)
active_model_serializers (~> 0.8.3)
activemodel (= 5.2.3)
activerecord (= 5.2.3)
activesupport (= 5.2.3)
activemodel (= 6.0.0)
activerecord (= 6.0.0)
activesupport (= 6.0.0)
annotate
aws-sdk-s3
aws-sdk-sns
@ -504,7 +504,7 @@ DEPENDENCIES
rack-mini-profiler
rack-protection
rails_multisite
railties (= 5.2.3)
railties (= 6.0.0)
rake
rb-fsevent
rb-inotify (~> 0.9)
@ -517,7 +517,7 @@ DEPENDENCIES
rqrcode
rspec
rspec-html-matchers
rspec-rails
rspec-rails (= 4.0.0.beta2)
rtlit
rubocop
ruby-prof

View File

@ -1,5 +1,5 @@
<div class="user-crawler">
<img src='<%= UrlHelper.local_cdn_url(get_absolute_image_url(@user.small_avatar_url)) %>' alt='<%= @user.username %>' title='<%= @user.username %>' />
<img src='<%= ::UrlHelper.local_cdn_url(get_absolute_image_url(@user.small_avatar_url)) %>' alt='<%= @user.username %>' title='<%= @user.username %>' />
<h2 class='username'><%= @user.username %></h2>
</div>

View File

@ -93,6 +93,8 @@ module Discourse
# issue is image_optim crashes on missing dependencies
config.assets.image_optim = false
config.autoloader = :classic
# Custom directories with classes and modules you want to be autoloadable.
config.autoload_paths += Dir["#{config.root}/app/serializers"]
config.autoload_paths += Dir["#{config.root}/lib/validators/"]

View File

@ -4,8 +4,8 @@ class AddTopicAllowedGroups < ActiveRecord::Migration[4.2]
def change
create_table :topic_allowed_groups, force: true do |t|
# oops
t.integer :group_id, :integer, null: false
t.integer :topic_id, :integer, null: false
t.integer :group_id, null: false
t.integer :topic_id, null: false
end
add_index :topic_allowed_groups, [:group_id, :topic_id], unique: true

View File

@ -3,6 +3,6 @@
class FixTopicAllowedGroups < ActiveRecord::Migration[4.2]
def change
# big oops
remove_column :topic_allowed_groups, :integer
remove_column :topic_allowed_groups, :integer if column_exists?(:topic_allowed_groups, :integer)
end
end

View File

@ -1,110 +0,0 @@
# frozen_string_literal: true
# this is a quick backport of a new method introduced in Rails 6
# to be removed after we upgrade to Rails 6
if ! defined? ActionView::Base.with_view_paths
class ActionView::Base
class << self
alias with_view_paths new
end
end
end
# backport of https://github.com/rails/rails/commit/890485cfce4c361c03a41ec23b0ba187007818cc
if !defined? ActionDispatch::Http::ContentDisposition
module ActionDispatch
module Http
class ContentDisposition
def self.format(disposition:, filename:)
new(disposition: disposition, filename: filename).to_s
end
attr_reader :disposition, :filename
def initialize(disposition:, filename:)
@disposition = disposition
@filename = filename
end
TRADITIONAL_ESCAPED_CHAR = /[^ A-Za-z0-9!#$+.^_`|~-]/
def ascii_filename
'filename="' + percent_escape(I18n.transliterate(filename), TRADITIONAL_ESCAPED_CHAR) + '"'
end
RFC_5987_ESCAPED_CHAR = /[^A-Za-z0-9!#$&+.^_`|~-]/
def utf8_filename
"filename*=UTF-8''" + percent_escape(filename, RFC_5987_ESCAPED_CHAR)
end
def to_s
if filename
"#{disposition}; #{ascii_filename}; #{utf8_filename}"
else
"#{disposition}"
end
end
private
def percent_escape(string, pattern)
string.gsub(pattern) do |char|
char.bytes.map { |byte| "%%%02X" % byte }.join
end
end
end
end
end
module ActionController
module DataStreaming
private
def send_file_headers!(options)
type_provided = options.has_key?(:type)
content_type = options.fetch(:type, DEFAULT_SEND_FILE_TYPE)
self.content_type = content_type
response.sending_file = true
raise ArgumentError, ":type option required" if content_type.nil?
if content_type.is_a?(Symbol)
extension = Mime[content_type]
raise ArgumentError, "Unknown MIME type #{options[:type]}" unless extension
self.content_type = extension
else
if !type_provided && options[:filename]
# If type wasn't provided, try guessing from file extension.
content_type = Mime::Type.lookup_by_extension(File.extname(options[:filename]).downcase.delete(".")) || content_type
end
self.content_type = content_type
end
disposition = options.fetch(:disposition, DEFAULT_SEND_FILE_DISPOSITION)
if disposition
headers["Content-Disposition"] = ActionDispatch::Http::ContentDisposition.format(disposition: disposition, filename: options[:filename])
end
headers["Content-Transfer-Encoding"] = "binary"
# Fix a problem with IE 6.0 on opening downloaded files:
# If Cache-Control: no-cache is set (which Rails does by default),
# IE removes the file it just downloaded from its cache immediately
# after it displays the "open/save" dialog, which means that if you
# hit "open" the file isn't there anymore when the application that
# is called for handling the download is run, so let's workaround that
response.cache_control[:public] ||= false
end
end
end
module ActiveStorage
class Service
private
def content_disposition_with(type: "inline", filename:)
disposition = (type.to_s.presence_in(%w( attachment inline )) || "inline")
ActionDispatch::Http::ContentDisposition.format(disposition: disposition, filename: filename.sanitized)
end
end
end
end

View File

@ -36,6 +36,9 @@ class MiniSqlMultisiteConnection < MiniSql::Postgres::Connection
def before_committed!(*); end
def rolledback!(*); end
def trigger_transactional_callbacks?
true
end
end
# Allows running arbitrary code after the current transaction has been committed.

View File

@ -14,8 +14,8 @@ describe Migration::SafeMigrate do
end
def migrate_up(path)
migrations = ActiveRecord::MigrationContext.new(path).migrations
ActiveRecord::Migrator.new(:up, migrations, migrations.first.version).run
migrations = ActiveRecord::MigrationContext.new(path, ActiveRecord::SchemaMigration).migrations
ActiveRecord::Migrator.new(:up, migrations, ActiveRecord::SchemaMigration, migrations.first.version).run
end
it "bans all table removal" do

View File

@ -734,7 +734,7 @@ describe PostRevisor do
let(:bumped_at) { 1.day.ago }
before do
topic.update_attributes!(bumped_at: bumped_at)
topic.update!(bumped_at: bumped_at)
create_hidden_tags(['important', 'secret'])
topic = post.topic
topic.tags = [Fabricate(:tag, name: "super"), Tag.where(name: "important").first, Fabricate(:tag, name: "stuff")]

View File

@ -344,7 +344,7 @@ describe UserNotifications do
]
SiteSetting.post_excerpts_in_emails = true
SiteSetting.post_excerpt_maxlength = paragraphs.first.length
response.update_attributes!(raw: paragraphs.join("\n\n"))
response.update!(raw: paragraphs.join("\n\n"))
mail = UserNotifications.user_replied(
user,
post: response,

View File

@ -39,7 +39,7 @@ describe BadgesController do
it 'renders rss feed of a badge' do
get "/badges/#{badge.id}.rss"
expect(response.status).to eq(200)
expect(response.content_type).to eq('application/rss+xml')
expect(response.media_type).to eq('application/rss+xml')
end
end
end

View File

@ -426,7 +426,7 @@ describe GroupsController do
get "/groups/#{group.name}/posts.rss"
expect(response.status).to eq(200)
expect(response.content_type).to eq('application/rss+xml')
expect(response.media_type).to eq('application/rss+xml')
end
end
@ -435,7 +435,7 @@ describe GroupsController do
get "/groups/#{group.name}/mentions.rss"
expect(response.status).to eq(200)
expect(response.content_type).to eq('application/rss+xml')
expect(response.media_type).to eq('application/rss+xml')
end
it 'fails when disabled' do

View File

@ -320,7 +320,7 @@ RSpec.describe ListController do
it 'renders latest RSS' do
get "/latest.rss"
expect(response.status).to eq(200)
expect(response.content_type).to eq('application/rss+xml')
expect(response.media_type).to eq('application/rss+xml')
end
it 'renders links correctly with subfolder' do
@ -337,14 +337,14 @@ RSpec.describe ListController do
it 'renders top RSS' do
get "/top.rss"
expect(response.status).to eq(200)
expect(response.content_type).to eq('application/rss+xml')
expect(response.media_type).to eq('application/rss+xml')
end
TopTopic.periods.each do |period|
it "renders #{period} top RSS" do
get "/top/#{period}.rss"
expect(response.status).to eq(200)
expect(response.content_type).to eq('application/rss+xml')
expect(response.media_type).to eq('application/rss+xml')
end
end
end
@ -433,7 +433,7 @@ RSpec.describe ListController do
it 'renders RSS' do
get "/c/#{category.slug}.rss"
expect(response.status).to eq(200)
expect(response.content_type).to eq('application/rss+xml')
expect(response.media_type).to eq('application/rss+xml')
end
it "renders RSS in subfolder correctly" do

View File

@ -20,7 +20,7 @@ RSpec.describe MetadataController do
get "/manifest.webmanifest"
expect(response.status).to eq(200)
expect(response.content_type).to eq('application/manifest+json')
expect(response.media_type).to eq('application/manifest+json')
manifest = JSON.parse(response.body)
expect(manifest["name"]).to eq(title)
@ -98,7 +98,7 @@ RSpec.describe MetadataController do
expect(response.body).to include("/search?q={searchTerms}")
expect(response.body).to include('image/png')
expect(response.body).to include(UrlHelper.absolute(upload.url))
expect(response.content_type).to eq('application/xml')
expect(response.media_type).to eq('application/xml')
end
end
@ -121,7 +121,7 @@ RSpec.describe MetadataController do
expect(response.status).to eq(200)
expect(response.body).to include("hash_of_app_certificate")
expect(response.body).to include("com.example.app")
expect(response.content_type).to eq('application/json')
expect(response.media_type).to eq('application/json')
end
end
@ -143,7 +143,7 @@ RSpec.describe MetadataController do
expect(response.status).to eq(200)
expect(response.body).to include("applinks")
expect(response.content_type).to eq('application/json')
expect(response.media_type).to eq('application/json')
get "/apple-app-site-association.json"
expect(response.status).to eq(404)

View File

@ -26,7 +26,7 @@ describe StaticController do
get '/favicon/proxied'
expect(response.status).to eq(200)
expect(response.content_type).to eq('image/png')
expect(response.media_type).to eq('image/png')
expect(response.body.bytesize).to eq(SiteIconManager.favicon.filesize)
end
@ -36,7 +36,7 @@ describe StaticController do
get '/favicon/proxied'
expect(response.status).to eq(200)
expect(response.content_type).to eq('image/png')
expect(response.media_type).to eq('image/png')
expect(response.body.bytesize).to eq(upload.filesize)
end
end
@ -66,7 +66,7 @@ describe StaticController do
get '/favicon/proxied'
expect(response.status).to eq(200)
expect(response.content_type).to eq('image/png')
expect(response.media_type).to eq('image/png')
expect(response.body.bytesize).to eq(upload.filesize)
end
end

View File

@ -1998,7 +1998,7 @@ RSpec.describe TopicsController do
it 'renders rss of the topic' do
get "/t/foo/#{topic.id}.rss"
expect(response.status).to eq(200)
expect(response.content_type).to eq('application/rss+xml')
expect(response.media_type).to eq('application/rss+xml')
end
it 'renders rss of the topic correctly with subfolder' do