Class: CLI::UI::Spinner::SpinGroup::Task

Inherits:
Object
  • Object
show all
Defined in:
lib/cli/ui/spinner/spin_group.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(title, final_glyph:, merged_output:, duplicate_output_to:, work_queue:, &block) ⇒ Task

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

: (String title, final_glyph: ^(bool success) -> (Glyph | String), merged_output: bool, duplicate_output_to: IO, work_queue: WorkQueue) { (Task task) -> untyped } -> void



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/cli/ui/spinner/spin_group.rb', line 104

def initialize(title, final_glyph:, merged_output:, duplicate_output_to:, work_queue:, &block)
  @title = title
  @final_glyph = final_glyph
  @always_full_render = title =~ Formatter::SCAN_WIDGET
  @future = work_queue.enqueue do
    cap = CLI::UI::StdoutRouter::Capture.new(
      merged_output: merged_output, duplicate_output_to: duplicate_output_to,
    ) { block.call(self) }
    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
  @progress_percentage = nil
  @wants_progress_mode = false
end

Instance Attribute Details

#doneObject (readonly)

: bool



87
88
89
# File 'lib/cli/ui/spinner/spin_group.rb', line 87

def done
  @done
end

#exceptionObject (readonly)

: Exception?



90
91
92
# File 'lib/cli/ui/spinner/spin_group.rb', line 90

def exception
  @exception
end

#progress_percentageObject (readonly)

: Integer?



93
94
95
# File 'lib/cli/ui/spinner/spin_group.rb', line 93

def progress_percentage
  @progress_percentage
end

#stderrObject (readonly)

: String



81
82
83
# File 'lib/cli/ui/spinner/spin_group.rb', line 81

def stderr
  @stderr
end

#stdoutObject (readonly)

: String



81
82
83
# File 'lib/cli/ui/spinner/spin_group.rb', line 81

def stdout
  @stdout
end

#successObject (readonly)

: bool



84
85
86
# File 'lib/cli/ui/spinner/spin_group.rb', line 84

def success
  @success
end

#titleObject (readonly)

: String



81
82
83
# File 'lib/cli/ui/spinner/spin_group.rb', line 81

def title
  @title
end

Instance Method Details

#checkObject

Checks if a task is finished

: -> bool



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/cli/ui/spinner/spin_group.rb', line 137

def check
  return true if @done
  return false unless @future.completed?

  @done = true
  begin
    result = @future.value
    @success = true
    @success = false if result == TASK_FAILED
  rescue => exc
    @exception = exc
    @success = false
  end

  @on_done&.call(self)

  @done
end

#clear_progressObject

Switch back to indeterminate mode : -> void



213
214
215
216
217
218
# File 'lib/cli/ui/spinner/spin_group.rb', line 213

def clear_progress
  @m.synchronize do
    @progress_percentage = nil
    @wants_progress_mode = false
  end
end

#current_progressObject

Get current progress percentage : -> Integer?



228
229
230
# File 'lib/cli/ui/spinner/spin_group.rb', line 228

def current_progress
  @m.synchronize { @progress_percentage }
end

#on_done(&block) ⇒ Object

: { (Task task) -> void } -> void



130
131
132
# File 'lib/cli/ui/spinner/spin_group.rb', line 130

def on_done(&block)
  @on_done = block
end

#render(index, force = true, width: CLI::UI::Terminal.width) ⇒ Object

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

: (Integer index, ?bool force, ?width: Integer) -> String



175
176
177
178
179
180
181
182
183
184
185
# File 'lib/cli/ui/spinner/spin_group.rb', line 175

def render(index, force = true, width: CLI::UI::Terminal.width)
  @m.synchronize do
    if !CLI::UI.enable_cursor? || force || @always_full_render || @force_full_render
      full_render(index, width)
    else
      partial_render(index)
    end
  ensure
    @force_full_render = false
  end
end

#set_progress(percentage) ⇒ Object

Set progress percentage (0-100) and switch to progress mode : (Integer percentage) -> void



204
205
206
207
208
209
# File 'lib/cli/ui/spinner/spin_group.rb', line 204

def set_progress(percentage) # rubocop:disable Naming/AccessorMethodName
  @m.synchronize do
    @progress_percentage = percentage.clamp(0, 100)
    @wants_progress_mode = true
  end
end

#update_title(new_title) ⇒ Object

Update the spinner title

Attributes

  • title - title to change the spinner to

: (String new_title) -> void



194
195
196
197
198
199
200
# File 'lib/cli/ui/spinner/spin_group.rb', line 194

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

#wants_progress_mode?Boolean

Check if this task wants progress mode : -> bool

Returns:

  • (Boolean)


222
223
224
# File 'lib/cli/ui/spinner/spin_group.rb', line 222

def wants_progress_mode?
  @m.synchronize { @wants_progress_mode }
end