unhappychoice/circleci-cli

View on GitHub
lib/circleci/cli/command/watch_command/build_watcher.rb

Summary

Maintainability
A
1 hr
Test Coverage
# frozen_string_literal: true

module CircleCI
  module CLI
    module Command
      class BuildWatcher
        attr_reader :build

        def initialize(build, verbose: false)
          @build = build
          @verbose = verbose
          @messages = Hash.new { |h, k| h[k] = [] }
        end

        def start
          bind_event_handling @build.channel_name
          notify_started
        end

        def stop(status)
          client.unsubscribe("#{@build.channel_name}@0")
          notify_stopped(status)
        end

        private

        def bind_event_handling(channel) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
          client.bind_event_json(channel, 'newAction') do |json|
            if @verbose
              print_bordered json['log']['name']
            else
              print json['log']['name']
            end
          end

          client.bind_event_json(channel, 'appendAction') do |json|
            if @verbose
              Thor::Shell::Basic.new.say(json['out']['message'], nil, false)
            else
              @messages[json['step']] << json['out']['message']
            end
          end

          client.bind_event_json(channel, 'updateAction') do |json|
            next if @verbose

            case json['log']['status']
            when 'success'
              puts "\e[2K\r#{Printer.colorize_green(json['log']['name'])}"
            when 'failed'
              puts "\e[2K\r#{Printer.colorize_red(json['log']['name'])}"
              @messages[json['step']].each(&method(:say))
            end
          end
        end

        def notify_started
          say Printer::BuildPrinter.header_for(
            @build,
            "👀 Start watching #{@build.project_name} ##{@build.build_number}"
          )
        end

        def notify_stopped(status)
          text = case status
                 when 'success'
                   Printer.colorize_green("🎉 #{@build.project_name} ##{@build.build_number} has succeeded!")
                 when 'failed'
                   Printer.colorize_red("😥 #{@build.project_name} ##{@build.build_number} has failed...")
                 end

          @verbose ? print_bordered(text) : say(text)
        end

        def print_bordered(text)
          say Terminal::Table.new(rows: [[text]], style: { width: 120 }).to_s
        end

        def client
          @client ||= Networking::CircleCIPusherClient.new.tap(&:connect)
        end
      end
    end
  end
end