Method: CLI::UI::Frame.open

Defined in:
lib/cli/ui/frame.rb

.open(text, color: DEFAULT_FRAME_COLOR, failure_text: nil, success_text: nil, timing: block_given?, , frame_style: self.frame_style, to: $stdout, &block) ⇒ Object

Opens a new frame. Can be nested Can be invoked in two ways: block and blockless

  • In block form, the frame is closed automatically when the block returns

  • In blockless form, caller MUST call Frame.close when the frame is logically done

  • Blockless form is strongly discouraged in cases where block form can be made to work

The return value of the block determines if the block is a “success” or a “failure”

Attributes

  • text - (required) the text/title to output in the frame

Options

  • :color - The color of the frame. Defaults to DEFAULT_FRAME_COLOR

  • :failure_text - If the block failed, what do we output? Defaults to nil

  • :success_text - If the block succeeds, what do we output? Defaults to nil

  • :timing - How long did the frame content take? Invalid for blockless. Defaults to true for the block form

  • frame_style - The frame style to use for this frame

  • :to - Target stream, like $stdout or $stderr. Can be anything with print and puts methods, or under Sorbet, IO or StringIO. Defaults to $stdout.

Example

Block Form (Assumes CLI::UI::StdoutRouter.enable has been called)
CLI::UI::Frame.open('Open') { puts 'hi' }

Default Output:

Blockless Form
CLI::UI::Frame.open('Open')

Default Output:

: [T] (String text, ?color: colorable, ?failure_text: String?, ?success_text: String?, ?timing: (Numeric | bool), ?frame_style: frame_stylable, ?to: io_like) ?{ -> T } -> T?



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
123
124
125
126
127
128
129
130
131
# File 'lib/cli/ui/frame.rb', line 77

def open(
  text,
  color: DEFAULT_FRAME_COLOR,
  failure_text: nil,
  success_text: nil,
  timing: block_given?,
  frame_style: self.frame_style,
  to: $stdout,
  &block
)
  frame_style = CLI::UI.resolve_style(frame_style)
  color = CLI::UI.resolve_color(color)

  unless block_given?
    if failure_text
      raise ArgumentError, 'failure_text is not compatible with blockless invocation'
    elsif success_text
      raise ArgumentError, 'success_text is not compatible with blockless invocation'
    elsif timing
      raise ArgumentError, 'timing is not compatible with blockless invocation'
    end
  end

  t_start = Time.now
  CLI::UI.raw do
    to.print(prefix.chop)
    to.puts(frame_style.start(text, color: color))
  end
  FrameStack.push(color: color, style: frame_style)

  return unless block_given?

  closed = false
  begin
    success = false #: untyped
    success = yield
  rescue
    closed = true
    t_diff = elapsed(t_start, timing)
    close(failure_text, color: :red, elapsed: t_diff, to: to)
    raise
  else
    success
  ensure
    unless closed
      t_diff = elapsed(t_start, timing)
      success_bool = success #: as untyped
      if success_bool != false
        close(success_text, color: color, elapsed: t_diff, to: to)
      else
        close(failure_text, color: :red, elapsed: t_diff, to: to)
      end
    end
  end
end