Read about our upcoming Code of Conduct on this issue

Commit 6b7586c0 authored by Heinrich Lee Yu's avatar Heinrich Lee Yu
Browse files

Upgrade to Rails 5.2

Updates changed method names and fixes spec failures
parent 8c5a9dddc494
#!/usr/bin/env ruby
APP_ROOT = File.expand_path('..', __dir__)
Dir.chdir(APP_ROOT) do
begin
exec "yarnpkg", *ARGV
rescue Errno::ENOENT
$stderr.puts "Yarn executable was not detected in the system."
$stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install"
exit 1
end
end
require File.expand_path('boot', __dir__)
require_relative 'boot'
require 'rails/all'
# Based on https://github.com/rails/rails/blob/v5.2.3/railties/lib/rails/all.rb
# Only load the railties we need instead of loading everything
require 'active_record/railtie'
require 'action_controller/railtie'
require 'action_view/railtie'
require 'action_mailer/railtie'
require 'rails/test_unit/railtie'
Bundler.require(:default, Rails.env)
Bundler.require(*Rails.groups)
module Gitlab
class Application < Rails::Application
......@@ -25,6 +31,8 @@ class Application < Rails::Application
# Application configuration should go into files in config/initializers
# -- all .rb files in that directory are automatically loaded.
config.active_record.sqlite3.represent_boolean_as_integer = true
# Sidekiq uses eager loading, but directories not in the standard Rails
# directories must be added to the eager load paths:
# https://github.com/mperham/sidekiq/wiki/FAQ#why-doesnt-sidekiq-autoload-my-rails-application-code
......@@ -86,13 +94,6 @@ class Application < Rails::Application
# Configure the default encoding used in templates for Ruby 1.9.
config.encoding = "utf-8"
# ActionCable mount point.
# The default Rails' mount point is `/cable` which may conflict with existing
# namespaces/users.
# https://github.com/rails/rails/blob/5-0-stable/actioncable/lib/action_cable.rb#L38
# Please change this value when configuring ActionCable for real usage.
config.action_cable.mount_path = "/-/cable"
# Configure sensitive parameters which will be filtered from the log file.
#
# Parameters filtered:
......@@ -272,5 +273,10 @@ class Application < Rails::Application
Gitlab::Routing.add_helpers(project_url_helpers)
Gitlab::Routing.add_helpers(MilestonesRoutingHelper)
end
# This makes generated cookies to be compatible with Rails 5.1 and older
# We can remove this when we're confident that there are no issues with the Rails 5.2 upgrade
# and we won't need to rollback to older versions
config.action_dispatch.use_authenticated_cookie_encryption = false
end
end
......@@ -7,6 +7,7 @@
config.cache_classes = false
# Show full error reports and disable caching
config.active_record.verbose_query_logs = true
config.consider_all_requests_local = true
config.action_controller.perform_caching = false
......
......@@ -23,6 +23,7 @@
config.public_file_server.headers = { 'Cache-Control' => 'public, max-age=3600' }
# Show full error reports and disable caching
config.active_record.verbose_query_logs = true
config.consider_all_requests_local = true
config.action_controller.perform_caching = false
......
......@@ -22,7 +22,7 @@ module RegisterDateTimeWithTimeZone
#
# When schema dumping, `timestamptz` columns will be output as
# `t.datetime_with_timezone`.
def initialize_type_map(mapping)
def initialize_type_map(mapping = type_map)
super mapping
mapping.register_type 'timestamptz' do |_, _, sql_type|
......@@ -51,7 +51,7 @@ module RegisterDateTimeWithTimeZone
#
# When schema dumping, `timestamp` columns will be output as
# `t.datetime_with_timezone`.
def initialize_type_map(mapping)
def initialize_type_map(mapping = type_map)
super mapping
mapping.register_type(/timestamp/i) do |sql_type|
......
module ActiveRecord
module Associations
class Preloader
class NullPreloader
def self.new(klass, owners, reflection, preload_scope)
self
end
def self.run(preloader)
end
def self.preloaded_records
[]
end
end
module NoCommitPreloader
def preloader_for(reflection, owners, rhs_klass)
return NullPreloader if rhs_klass == ::Commit
def preloader_for(reflection, owners)
return NullPreloader if owners.first.association(reflection.name).klass == ::Commit
super
end
......
# frozen_string_literal: true
# This is backport of https://github.com/rails/rails/pull/26815/files
# Enabled by default for every non-production environment
module ActiveRecord
class LogSubscriber
module VerboseQueryLogs
def debug(progname = nil, &block)
return unless super
log_query_source
end
def log_query_source
source_line, line_number = extract_callstack(caller_locations)
if source_line
if defined?(::Rails.root)
app_root = "#{::Rails.root}/".freeze
source_line = source_line.sub(app_root, "")
end
logger.debug(" ↳ #{source_line}:#{line_number}")
end
end
def extract_callstack(callstack)
line = callstack.find do |frame|
frame.absolute_path && !ignored_callstack(frame.absolute_path)
end
offending_line = line || callstack.first
[
offending_line.path,
offending_line.lineno,
offending_line.label
]
end
LOG_SUBSCRIBER_FILE = ActiveRecord::LogSubscriber.method(:logger).source_location.first
RAILS_GEM_ROOT = File.expand_path("../../../..", LOG_SUBSCRIBER_FILE) + "/"
APP_CONFIG_ROOT = File.expand_path("..", __dir__) + "/"
def ignored_callstack(path)
path.start_with?(APP_CONFIG_ROOT, RAILS_GEM_ROOT, RbConfig::CONFIG["rubylibdir"])
end
end
if Rails.version.start_with?("5.2")
raise "Remove this monkey patch: #{__FILE__}"
else
prepend(VerboseQueryLogs) unless Rails.env.production?
end
end
end
......@@ -2,17 +2,14 @@
require 'active_record/migration'
module ActiveRecord
class Migrator
class << self
alias_method :migrations_unmemoized, :migrations
class MigrationContext
alias_method :migrations_unmemoized, :migrations
# This method is called a large number of times per rspec example, and
# it reads + parses `db/migrate/*` each time. Memoizing it can save 0.5
# seconds per spec.
def migrations(paths)
@migrations ||= {}
(@migrations[paths] ||= migrations_unmemoized(paths)).dup
end
# This method is called a large number of times per rspec example, and
# it reads + parses `db/migrate/*` each time. Memoizing it can save 0.5
# seconds per spec.
def migrations
@migrations ||= migrations_unmemoized
end
end
end
......
......@@ -22,10 +22,11 @@ def _update_row(attribute_names, attempted_action = "update")
# Patched because when `lock_version` is read as `0`, it may actually be `NULL` in the DB.
possible_previous_lock_value = previous_lock_value.to_i == 0 ? [nil, 0] : previous_lock_value
affected_rows = self.class.unscoped._update_record(
arel_attributes_with_values(attribute_names),
self.class.primary_key => id_in_database,
locking_column => possible_previous_lock_value
affected_rows = self.class.unscoped.where(
locking_column => possible_previous_lock_value,
self.class.primary_key => id_in_database
).update_all(
attributes_with_values_for_update(attribute_names)
)
if affected_rows != 1
......
......@@ -18,7 +18,7 @@
.map { |k, v| { key: k, value: v } }
payload = {
time: event.time.utc.iso8601(3),
time: Time.now.utc.iso8601(3),
params: params,
remote_ip: event.payload[:remote_ip],
user_id: event.payload[:user_id],
......
......@@ -15,7 +15,6 @@ module ActiveRecord
module ConnectionAdapters
class Mysql2Adapter < AbstractMysqlAdapter
alias_method :__gitlab_add_index, :add_index
alias_method :__gitlab_add_index_sql, :add_index_sql
alias_method :__gitlab_add_index_options, :add_index_options
def add_index(table_name, column_name, options = {})
......@@ -24,12 +23,6 @@ def add_index(table_name, column_name, options = {})
end
end
def add_index_sql(table_name, column_name, options = {})
unless options[:opclasses]
__gitlab_add_index_sql(table_name, column_name, options)
end
end
def add_index_options(table_name, column_name, options = {})
if options[:using] && options[:using] == :gin
options = options.dup
......
......@@ -94,8 +94,8 @@ def with!(opts = :chain, *rest) # :nodoc:
end
end
def build_arel
arel = super()
def build_arel(aliases)
arel = super
build_with(arel) if @values[:with]
......
......@@ -10,11 +10,11 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20190703130053) do
ActiveRecord::Schema.define(version: 2019_07_03_130053) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
enable_extension "pg_trgm"
enable_extension "plpgsql"
create_table "abuse_reports", id: :serial, force: :cascade do |t|
t.integer "reporter_id"
......
......@@ -205,7 +205,9 @@ def paginate_with_limit_optimization(relation)
limited_total_count = pagination_data.total_count_with_limit
if limited_total_count > Kaminari::ActiveRecordRelationMethods::MAX_COUNT_LIMIT
pagination_data.without_count
# The call to `total_count_with_limit` memoizes `@arel` because of a call to `references_eager_loaded_tables?`
# We need to call `reset` because `without_count` relies on `@arel` being unmemoized
pagination_data.reset.without_count
else
pagination_data
end
......
......@@ -7,8 +7,7 @@ module Runner
JOB_TOKEN_PARAM = :token
def runner_registration_token_valid?
ActiveSupport::SecurityUtils.variable_size_secure_compare(params[:token],
Gitlab::CurrentSettings.runners_registration_token)
ActiveSupport::SecurityUtils.secure_compare(params[:token], Gitlab::CurrentSettings.runners_registration_token)
end
def authenticate_runner!
......
......@@ -45,7 +45,7 @@ def uncached_application_settings
# need to be added to the application settings. To prevent Rake tasks
# and other callers from failing, use any loaded settings and return
# defaults for missing columns.
if ActiveRecord::Migrator.needs_migration?
if ActiveRecord::Base.connection.migration_context.needs_migration?
db_attributes = current_settings&.attributes || {}
fake_application_settings(db_attributes)
elsif current_settings.present?
......
......@@ -128,7 +128,7 @@ def self.nulls_last_order(field, direction = 'ASC')
order = "#{field} IS NULL, #{order}" if direction == 'ASC'
end
order
Arel.sql(order)
end
def self.nulls_first_order(field, direction = 'ASC')
......@@ -142,7 +142,7 @@ def self.nulls_first_order(field, direction = 'ASC')
order = "#{field} IS NULL, #{order}" if direction == 'DESC'
end
order
Arel.sql(order)
end
def self.random
......
......@@ -24,7 +24,7 @@ def self.create_and_execute_trigger?(table)
begin
from(nil)
.pluck("has_table_privilege(#{quoted_table}, 'TRIGGER')")
.pluck(Arel.sql("has_table_privilege(#{quoted_table}, 'TRIGGER')"))
.first
rescue ActiveRecord::StatementInvalid
# This error is raised when using a non-existing table name. In this
......
......@@ -23,10 +23,11 @@
control_count = ActiveRecord::QueryRecorder.new { get :index }.count
create(:ci_runner, :tagged_only)
create_list(:ci_runner, 5, :tagged_only)
# There is still an N+1 query for `runner.builds.count`
expect { get :index }.not_to exceed_query_limit(control_count + 1)
# We also need to add 1 because it takes 2 queries to preload tags
expect { get :index }.not_to exceed_query_limit(control_count + 6)
expect(response).to have_gitlab_http_status(200)
expect(response.body).to have_content('tag1')
......
......@@ -16,7 +16,7 @@
shared_examples 'resource with a custom avatar' do |source_type|
it 'returns a custom avatar image' do
expect(public_send("#{source_type}_icon", *helper_args))
.to eq "<img src=\"#{resource.avatar.url}\" alt=\"Banana sample\" />"
.to eq "<img src=\"#{resource.avatar.url}\" />"
end
end
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment