Class: RVGP::Application::StatusOutputRake

Inherits:
Object
  • Object
show all
Defined in:
lib/rvgp/application/status_output.rb

Overview

These methods output ‘pretty’ indications of the build process, and is used by both the rvgp standalone bin, as well as the rake processes themselves. This class manages colors, icons, indentation and thread syncronization concerns, relating to status display. NOTE: This class doesn’t know if it wants to be a logger or something else… Let’s see where it ends up

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}) ⇒ StatusOutputRake

Create a new STDOUT status output logger

Parameters:

  • opts (Hash) (defaults to: {})

    what options to configure this registry with

Options Hash (opts):

  • :pastel (Pastel)

    A pastel object to use, for formatting output



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/rvgp/application/status_output.rb', line 24

def initialize(opts = {})
  @semaphore = Mutex.new
  @pastel = opts[:pastel] || Pastel.new

  @last_header_outputted = nil

  begin
    @tty_cols = TTY::Screen.width
  rescue Errno::ENOENT
    @tty_cols = 0
  end

  # NOTE: This is the smallest width I bothered testing on. I don't think
  # we really care to support this code path in general. If you're this
  # narrow, umm, fix that.
  @tty_cols = 40 if @tty_cols < 40

  @complete = I18n.t 'status.indicators.complete'
  @indent = I18n.t 'status.indicators.indent'
  @fill = I18n.t 'status.indicators.fill'
  @attention1 = I18n.t 'status.indicators.attention1'
  @attention2 = I18n.t 'status.indicators.attention2'
  @truncated = I18n.t 'status.indicators.truncated'
end

Instance Attribute Details

#tty_colsInteger (readonly)

The width of the terminal, in characters - This number is calculated at the time of Object instantiation.

Returns:

  • (Integer)

    the current value of tty_cols



18
19
20
# File 'lib/rvgp/application/status_output.rb', line 18

def tty_cols
  @tty_cols
end

Instance Method Details

#info(cmd, desc) {|void| ... } ⇒ void

This method returns an undefined value.

This is the only public interface, at this time, for use in outputting status. This is the only method that RVGP needs implemented, on a status output object, should you choose to write your own.

Parameters:

  • cmd (String)

    The command that’s emmitting this status message

  • desc (String)

    The I18n key, appended to ‘status.commands.’, that contains the message you wish to output

Yields:

  • (void)

    A block that contains the execution of this message, and which will return an execution status.

Yield Returns:

  • (Hash<Symbol, Array>)

    A hash, with the keys :errors, and :warnings, each of which contains a list of errors and warnings that occurred, during the execution of this block. These will be stylized and output to the user.



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/rvgp/application/status_output.rb', line 59

def info(cmd, desc, &block)
  icon, header, prefix = *%w[icon header prefix].map do |attr|
    I18n.t format('status.commands.%<cmd>s.%<attr>s', cmd: cmd.to_s, attr: attr)
  end

  @semaphore.synchronize do
    unless @last_header_outputted == cmd
      puts ["\n", icon, ' ', @pastel.bold(header)].join
      @last_header_outputted = cmd
    end
  end

  ret = block.call || {}

  has_warn = ret.key?(:warnings) && !ret[:warnings].empty?
  has_fail = ret.key?(:errors) && !ret[:errors].empty?

  status_length = (if has_warn && has_fail
                     I18n.t 'status.indicators.complete_and', left: @complete, right: @complete
                   else
                     @complete
                   end).length

  status = if has_warn && has_fail
             I18n.t 'status.indicators.complete_and',
                    left: @pastel.yellow(@complete),
                    right: @pastel.red(@complete)
           elsif has_warn
             @pastel.yellow(@complete)
           elsif has_fail
             @pastel.red(@complete)
           else
             @pastel.green(@complete)
           end

  fixed_element_width = ([@indent, prefix, ' ', @indent, ' ', ' '].join.length + status_length)

  available_width = tty_cols - fixed_element_width

  # If the description is gigantic, we need to constrain it. That's our
  # variable-length column, so to speak:
  fill = if available_width <= desc.length
           # The plus one is due to the compact'd nil below, which, removes a space
           # character, that would have otherwise been placed next to the @fill
           desc = desc[0...available_width - @truncated.length - 1] + @truncated
           ' '
         elsif (available_width - desc.length) > 1
           [' ', @fill * (available_width - desc.length - 2), ' '].join
         elsif (available_width - desc.length) == 1
           ' '
         else # This should only be zero
           ''
         end

  @semaphore.synchronize do
    puts [
      [@indent, @pastel.bold(prefix), ' ', @pastel.blue(desc), fill, status].join,
      has_warn ? status_tree(:yellow, ret[:warnings]) : nil,
      has_fail ? status_tree(:red, ret[:errors]) : nil
    ].compact.flatten.join("\n")
  end

  ret
end