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

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

Defined Under Namespace

Classes: Task

Instance Method Summary collapse

Methods included from T::Sig

sig

Constructor Details

#initialize(auto_debrief: true) ⇒ SpinGroup

Returns a new instance of SpinGroup.



28
29
30
31
32
33
34
35
36
37
38
# File 'lib/cli/ui/spinner/spin_group.rb', line 28

def initialize(auto_debrief: true)
  @m = Mutex.new
  @consumed_lines = 0
  @tasks = []
  @auto_debrief = auto_debrief
  @start = Time.new
  if block_given?
    yield self
    wait
  end
end

Instance Method Details

#add(title, &block) ⇒ Object



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

def add(title, &block)
  @m.synchronize do
    @tasks << Task.new(title, &block)
  end
end

#all_succeeded?Boolean

Returns:

  • (Boolean)


287
288
289
290
291
# File 'lib/cli/ui/spinner/spin_group.rb', line 287

def all_succeeded?
  @m.synchronize do
    @tasks.all?(&:success)
  end
end

#debriefObject



296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
# File 'lib/cli/ui/spinner/spin_group.rb', line 296

def debrief
  @m.synchronize do
    @tasks.each do |task|
      title = task.title
      out = task.stdout
      err = task.stderr

      if task.success
        next @success_debrief&.call(title, out, err)
      end

      e = task.exception
      next @failure_debrief.call(title, e, out, err) if @failure_debrief

      CLI::UI::Frame.open('Task Failed: ' + title, color: :red, timing: Time.new - @start) do
        if e
          puts "#{e.class}: #{e.message}"
          puts "\tfrom #{e.backtrace.join("\n\tfrom ")}"
        end

        CLI::UI::Frame.divider('STDOUT')
        out = '(empty)' if out.nil? || out.strip.empty?
        puts out

        CLI::UI::Frame.divider('STDERR')
        err = '(empty)' if err.nil? || err.strip.empty?
        puts err
      end
    end
    @tasks.all?(&:success)
  end
end

#failure_debrief(&block) ⇒ Object



272
273
274
# File 'lib/cli/ui/spinner/spin_group.rb', line 272

def failure_debrief(&block)
  @failure_debrief = block
end

#success_debrief(&block) ⇒ Object



282
283
284
# File 'lib/cli/ui/spinner/spin_group.rb', line 282

def success_debrief(&block)
  @success_debrief = block
end

#waitObject



220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
# File 'lib/cli/ui/spinner/spin_group.rb', line 220

def wait
  idx = 0

  loop do
    all_done = T.let(true, T::Boolean)

    width = CLI::UI::Terminal.width

    @m.synchronize do
      CLI::UI.raw do
        @tasks.each.with_index do |task, int_index|
          nat_index = int_index + 1
          task_done = task.check
          all_done = false unless task_done

          if nat_index > @consumed_lines
            print(task.render(idx, true, width: width) + "\n")
            @consumed_lines += 1
          else
            offset = @consumed_lines - int_index
            move_to = CLI::UI::ANSI.cursor_up(offset) + "\r"
            move_from = "\r" + CLI::UI::ANSI.cursor_down(offset)

            print(move_to + task.render(idx, idx.zero?, width: width) + move_from)
          end
        end
      end
    end

    break if all_done

    idx = (idx + 1) % GLYPHS.size
    Spinner.index = idx
    sleep(PERIOD)
  end

  if @auto_debrief
    debrief
  else
    all_succeeded?
  end
rescue Interrupt
  @tasks.each(&:interrupt)
  raise
end