Class: Bolt::Outputter::Rainbow

Inherits:
Human show all
Defined in:
lib/bolt/outputter/rainbow.rb

Constant Summary

Constants inherited from Human

Human::COLORS

Instance Method Summary collapse

Methods inherited from Human

#duration_to_string, #enabled?, #fatal_error, #format_log, #format_table, #handle_event, #plan_logging?, #print_action_error, #print_action_step, #print_apply_result, #print_bolt_error, #print_container_finish, #print_container_result, #print_container_start, #print_error, #print_groups, #print_head, #print_module_info, #print_module_list, #print_new_plan, #print_new_policy, #print_plan_finish, #print_plan_info, #print_plan_lookup, #print_plan_result, #print_plan_start, #print_plans, #print_plugin_list, #print_policy_list, #print_prompt, #print_prompt_error, #print_puppetfile_result, #print_result, #print_result_set, #print_start, #print_step_finish, #print_step_start, #print_target_info, #print_targets, #print_task_info, #print_tasks, #remove_trail, #stop_spin, #truncate, #wrap

Methods inherited from Bolt::Outputter

for_format, #indent, #print_error, #spin, #stop_spin

Constructor Details

#initialize(color, verbose, trace, spin, stream = $stdout) ⇒ Rainbow

Returns a new instance of Rainbow.


8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/bolt/outputter/rainbow.rb', line 8

def initialize(color, verbose, trace, spin, stream = $stdout)
  begin
    require 'paint'
    if Bolt::Util.windows?
      # the Paint gem thinks that windows does not support ansi colors
      # but windows 10 or later does
      # we can display colors if we force mode to TRUE_COLOR
      Paint.mode = 0xFFFFFF
    end
  rescue LoadError
    raise "The 'paint' gem is required to use the rainbow outputter."
  end
  super
  @line_color = 0
  @color = 0
  @state = :normal
end

Instance Method Details

#colorize(color, string) ⇒ Object


36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/bolt/outputter/rainbow.rb', line 36

def colorize(color, string)
  if @color && @stream.isatty
    if %i[green rainbow].include?(color)
      a = string.chars.map do |c|
        case @state
        when :normal
          case c
          when "\e"
            @state = :ansi
          when "\n"
            @line_color += 1
            @color = @line_color
            c
          else
            Paint[c, rainbow]
          end
        when :ansi
          @state = :normal if c == 'm'
        end
      end
      a.join
    else
      "\033[#{COLORS[color]}m#{string}\033[0m"
    end
  else
    string
  end
end

101
102
103
# File 'lib/bolt/outputter/rainbow.rb', line 101

def print_guide(guide, _topic)
  @stream.puts colorize(:rainbow, guide)
end

112
113
114
# File 'lib/bolt/outputter/rainbow.rb', line 112

def print_message(message)
  @stream.puts colorize(:rainbow, message)
end

76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/bolt/outputter/rainbow.rb', line 76

def print_summary(results, elapsed_time = nil)
  ok_set = results.ok_set
  unless ok_set.empty?
    @stream.puts colorize(:rainbow, format('Successful on %<size>d target%<plural>s: %<names>s',
                                           size: ok_set.size,
                                           plural: ok_set.size == 1 ? '' : 's',
                                           names: ok_set.targets.map(&:safe_name).join(',')))
  end

  error_set = results.error_set
  unless error_set.empty?
    @stream.puts colorize(:red,
                          format('Failed on %<size>d target%<plural>s: %<names>s',
                                 size: error_set.size,
                                 plural: error_set.size == 1 ? '' : 's',
                                 names: error_set.targets.map(&:safe_name).join(',')))
  end

  total_msg = format('Ran on %<size>d target%<plural>s',
                     size: results.size,
                     plural: results.size == 1 ? '' : 's')
  total_msg << " in #{duration_to_string(elapsed_time)}" unless elapsed_time.nil?
  @stream.puts colorize(:rainbow, total_msg)
end

105
106
107
108
109
110
# File 'lib/bolt/outputter/rainbow.rb', line 105

def print_topics(topics)
  content  = String.new("Available topics are:\n")
  content += topics.join("\n")
  content += "\n\nUse `bolt guide <topic>` to view a specific guide."
  @stream.puts colorize(:rainbow, content)
end

#rainbowObject

The algorithm is from lolcat (github.com/busyloop/lolcat) lolcat is released with WTFPL


28
29
30
31
32
33
34
# File 'lib/bolt/outputter/rainbow.rb', line 28

def rainbow
  red = Math.sin(0.3 * @color + 0) * 127 + 128
  green = Math.sin(0.3 * @color + 2 * Math::PI / 3) * 127 + 128
  blue  = Math.sin(0.3 * @color + 4 * Math::PI / 3) * 127 + 128
  @color += 1 / 8.0
  format("%<red>02X%<green>02X%<blue>02X", red: red, green: green, blue: blue)
end

#start_spinObject


65
66
67
68
69
70
71
72
73
74
# File 'lib/bolt/outputter/rainbow.rb', line 65

def start_spin
  return unless @spin && @stream.isatty && !@spinning
  @spinning = true
  @spin_thread = Thread.new do
    loop do
      sleep(0.1)
      @stream.print(colorize(:rainbow, @pinwheel.rotate!.first + "\b"))
    end
  end
end