class CLI::UI::Spinner::SpinGroup::Task

Attributes

exception[R]
stderr[R]
stdout[R]
success[R]
title[R]

Public Class Methods

new(title, &block) click to toggle source

Initializes a new Task This is managed entirely internally by SpinGroup

Attributes

  • title - Title of the task

  • block - Block for the task, will be provided with an instance of the spinner

# File lib/cli/ui/spinner/spin_group.rb, line 42
def initialize(title, &block)
  @title = title
  @always_full_render = title =~ Formatter::SCAN_WIDGET
  @thread = Thread.new do
    cap = CLI::UI::StdoutRouter::Capture.new(self, with_frame_inset: false, &block)
    begin
      cap.run
    ensure
      @stdout = cap.stdout
      @stderr = cap.stderr
    end
  end

  @m = Mutex.new
  @force_full_render = false
  @done = false
  @exception = nil
  @success   = false
end

Public Instance Methods

check() click to toggle source

Checks if a task is finished

# File lib/cli/ui/spinner/spin_group.rb, line 64
def check
  return true if @done
  return false if @thread.alive?

  @done = true
  begin
    status = @thread.join.status
    @success = (status == false)
    @success = false if @thread.value == TASK_FAILED
  rescue => exc
    @exception = exc
    @success = false
  end

  @done
end
render(index, force = true, width: CLI::UI::Terminal.width) click to toggle source

Re-renders the task if required:

We try to be as lazy as possible in re-rendering the full line. The spinner rune will change on each render for the most part, but the body text will rarely have changed. If the body text has changed, we set @force_full_render.

Further, if the title string includes any CLI::UI::Widgets, we assume that it may change from render to render, since those evaluate more dynamically than the rest of our format codes, which are just text formatters. This is controlled by @always_full_render.

Attributes

  • index - index of the task

  • force - force rerender of the task

  • width - current terminal width to format for

# File lib/cli/ui/spinner/spin_group.rb, line 99
def render(index, force = true, width: CLI::UI::Terminal.width)
  @m.synchronize do
    if force || @always_full_render || @force_full_render
      full_render(index, width)
    else
      partial_render(index)
    end
  ensure
    @force_full_render = false
  end
end
update_title(new_title) click to toggle source

Update the spinner title

Attributes

  • title - title to change the spinner to

# File lib/cli/ui/spinner/spin_group.rb, line 117
def update_title(new_title)
  @m.synchronize do
    @always_full_render = new_title =~ Formatter::SCAN_WIDGET
    @title = new_title
    @force_full_render = true
  end
end

Private Instance Methods

full_render(index, terminal_width) click to toggle source
# File lib/cli/ui/spinner/spin_group.rb, line 127
def full_render(index, terminal_width)
  prefix = inset +
    glyph(index) +
    CLI::UI::Color::RESET.code +
    ' '

  truncation_width = terminal_width - CLI::UI::ANSI.printing_width(prefix)

  prefix +
    CLI::UI.resolve_text(title, truncate_to: truncation_width) +
    "\e[K"
end
glyph(index) click to toggle source
# File lib/cli/ui/spinner/spin_group.rb, line 144
def glyph(index)
  if @done
    @success ? CLI::UI::Glyph::CHECK.to_s : CLI::UI::Glyph::X.to_s
  else
    GLYPHS[index]
  end
end
inset() click to toggle source
# File lib/cli/ui/spinner/spin_group.rb, line 152
def inset
  @inset ||= CLI::UI::Frame.prefix
end
inset_width() click to toggle source
# File lib/cli/ui/spinner/spin_group.rb, line 156
def inset_width
  @inset_width ||= CLI::UI::ANSI.printing_width(inset)
end
partial_render(index) click to toggle source
# File lib/cli/ui/spinner/spin_group.rb, line 140
def partial_render(index)
  CLI::UI::ANSI.cursor_forward(inset_width) + glyph(index) + CLI::UI::Color::RESET.code
end