lib/gdk/command/doctor.rb (94 lines of code) (raw):

# frozen_string_literal: true module GDK module Command class Doctor < BaseCommand def initialize(diagnostics: GDK::Diagnostic.all, **args) @diagnostics = diagnostics @unexpected_error = false @should_autocorrect = false super(**args) end def run(args = []) unless installed? out.warn("GDK has not been installed so cannot run 'gdk doctor'. Try running `gem install gitlab-development-kit` again.") return false end @should_autocorrect = args.intersect?(['--correct', '-correct', '-C']) return false unless start_necessary_services show_results(diagnostic_results) return 2 if @unexpected_error handle_correctable_results(correctable_results) return 2 if @unexpected_error diagnostic_results.empty? end private attr_reader :diagnostics def installed? # TODO: Eventually, the Procfile will no longer exists so we need a better # way to determine this, but this will be OK for now. GDK.root.join('Procfile').exist? end def diagnostic_results @diagnostic_results ||= jobs.filter_map { |x| x.join[:results] } end def correctable_results @correctable_results ||= diagnostic_results.reject(&:unexpected_error).select(&:correctable?) end def jobs diagnostics.map do |diagnostic| Thread.new do Thread.current[:results] = perform_diagnosis_for(diagnostic) out.print(output_dot, stderr: true) end end end def perform_diagnosis_for(diagnostic) diagnostic unless diagnostic.success? rescue StandardError => e @unexpected_error = true diagnostic.unexpected_error = e diagnostic end def perform_corrections correctable_results.map do |diagnostic| perform_correction_for(diagnostic) end end def perform_correction_for(diagnostic) out.print("Performing correction for '#{diagnostic.title}' ") diagnostic.correct! out.success(out.wrap_in_color('success', Output::COLOR_CODE_GREEN)) rescue StandardError => e @unexpected_error = true out.error(e.message, e) end def handle_correctable_results(correctable_results) out.puts("\n") if correctable_results.any? if @should_autocorrect out.divider perform_corrections else out.info("You may autocorrect #{correctable_results.size} #{correctable_results.size == 1 ? 'problem' : 'problems'} by running `gdk doctor --correct` or `gdk doctor -C`") end elsif @should_autocorrect out.warn('No problems to autocorrect.') end end def start_necessary_services postgresql = Postgresql.new return true if postgresql.ready?(try_times: 1, quiet: true) Runit.start('postgresql', quiet: true) postgresql.ready?(try_times: 20, interval: 0.5) end def show_results(results) out.puts("\n") return out.success('Your GDK is healthy.') unless results.any? out.warn('Your GDK may need attention.') results.each { |diagnostic| out.puts(diagnostic.message) } end def output_dot return out.wrap_in_color('E', Output::COLOR_CODE_RED) if Thread.current[:results]&.unexpected_error return out.wrap_in_color('W', Output::COLOR_CODE_YELLOW) if Thread.current[:results] out.wrap_in_color('.', Output::COLOR_CODE_GREEN) end end end end