lib/gdk/diagnostic/ruby_gems.rb (80 lines of code) (raw):
# frozen_string_literal: true
module GDK
module Diagnostic
class RubyGems < Base
TITLE = 'Ruby Gems'
GEM_REQUIRE_MAPPING = {
'charlock_holmes' => 'charlock_holmes',
'ffi' => 'ffi',
'gpgme' => 'gpgme',
'pg' => 'pg',
'oj' => 'oj'
}.freeze
GITLAB_GEMS_WITH_C_CODE_TO_CHECK = GEM_REQUIRE_MAPPING.keys
def initialize(allow_gem_not_installed: false)
@allow_gem_not_installed = allow_gem_not_installed
super()
end
def success?
return false unless bundle_check_ok?
failed_to_load_gitlab_gems.empty?
end
def detail
return if success?
return bundle_check_error_message unless bundle_check_ok?
gitlab_error_message
end
private
def bundle_check_ok?
exec_cmd("#{bundle_exec_cmd} bundle check") || allow_gem_not_installed?
end
def allow_gem_not_installed?
@allow_gem_not_installed == true
end
def failed_to_load_gitlab_gems
@failed_to_load_gitlab_gems ||= failed_to_load_gitlab_gems_parallel(GITLAB_GEMS_WITH_C_CODE_TO_CHECK)
end
def failed_to_load_gitlab_gems_parallel(names)
names
.map { |name| Thread.new { Thread.current[:name] = name unless gem_ok?(name) } }
.filter_map { |thread| thread.join[:name] }
end
def gem_ok?(name)
# We need to support the situation where it's OK if a Ruby gem is not
# installed because we could be about to install the GDK for the very
# first time and the Ruby gem won't be installed.
gem_installed?(name) ? gem_loads_ok?(name) : allow_gem_not_installed?
end
def bundle_exec_cmd
@bundle_exec_cmd ||= config.gdk_root.join('support', 'bundle-exec')
end
def gem_installed?(name)
exec_cmd("#{bundle_exec_cmd} gem list -i #{name}")
end
def gem_loads_ok?(name)
gem_name = GEM_REQUIRE_MAPPING[name]
command = -> { exec_cmd("#{bundle_exec_cmd} ruby -r #{gem_name} -e 'nil'") }
if GDK::Dependencies.bundler_loaded?
::Bundler.with_unbundled_env do
command.call
end
else
command.call
end
end
def exec_cmd(cmd)
GDK::Output.debug("cmd=[#{cmd}]")
Shellout.new(cmd, chdir: config.gitlab.dir.to_s).execute(display_output: false, display_error: false).success?
end
def bundle_check_error_message
<<~MESSAGE
There are Ruby gems missing that need to be installed. Try running the following to fix:
(cd #{config.gitlab.dir} && bundle install)
MESSAGE
end
def gitlab_error_message
<<~MESSAGE
The following Ruby Gems appear to have issues:
#{@failed_to_load_gitlab_gems.join("\n")}
Try running the following to fix:
(cd #{config.gitlab.dir} && bundle pristine #{@failed_to_load_gitlab_gems.join(' ')})
MESSAGE
end
end
end
end