Class: CLI::UI::Spinner::SpinGroup
- Inherits:
-
Object
- Object
- CLI::UI::Spinner::SpinGroup
- Extended by:
- T::Sig
- Defined in:
- lib/cli/ui/spinner/spin_group.rb
Defined Under Namespace
Classes: Task
Constant Summary collapse
Class Attribute Summary collapse
-
.pause_mutex ⇒ Object
readonly
Returns the value of attribute pause_mutex.
Class Method Summary collapse
Instance Method Summary collapse
- #add(title, final_glyph: DEFAULT_FINAL_GLYPH, merged_output: false, duplicate_output_to: File.new(File::NULL, 'w'), &block) ⇒ Object
- #all_succeeded? ⇒ Boolean
- #debrief ⇒ Object
- #failure_debrief(&block) ⇒ Object
-
#initialize(auto_debrief: true) ⇒ SpinGroup
constructor
A new instance of SpinGroup.
- #success_debrief(&block) ⇒ Object
- #wait ⇒ Object
Methods included from T::Sig
Constructor Details
#initialize(auto_debrief: true) ⇒ SpinGroup
Returns a new instance of SpinGroup.
63 64 65 66 67 68 69 70 71 72 |
# File 'lib/cli/ui/spinner/spin_group.rb', line 63 def initialize(auto_debrief: true) @m = Mutex.new @tasks = [] @auto_debrief = auto_debrief @start = Time.new if block_given? yield self wait end end |
Class Attribute Details
.pause_mutex ⇒ Object (readonly)
Returns the value of attribute pause_mutex.
13 14 15 |
# File 'lib/cli/ui/spinner/spin_group.rb', line 13 def pause_mutex @pause_mutex end |
Class Method Details
.pause_spinners(&block) ⇒ Object
25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/cli/ui/spinner/spin_group.rb', line 25 def pause_spinners(&block) previous_paused = T.let(nil, T.nilable(T::Boolean)) @pause_mutex.synchronize do previous_paused = @paused @paused = true end block.call ensure @pause_mutex.synchronize do @paused = previous_paused end end |
.paused? ⇒ Boolean
16 17 18 |
# File 'lib/cli/ui/spinner/spin_group.rb', line 16 def paused? @paused end |
Instance Method Details
#add(title, final_glyph: DEFAULT_FINAL_GLYPH, merged_output: false, duplicate_output_to: File.new(File::NULL, 'w'), &block) ⇒ Object
273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 |
# File 'lib/cli/ui/spinner/spin_group.rb', line 273 def add( title, final_glyph: DEFAULT_FINAL_GLYPH, merged_output: false, duplicate_output_to: File.new(File::NULL, 'w'), &block ) @m.synchronize do @tasks << Task.new( title, final_glyph: final_glyph, merged_output: merged_output, duplicate_output_to: duplicate_output_to, &block ) end end |
#all_succeeded? ⇒ Boolean
382 383 384 385 386 |
# File 'lib/cli/ui/spinner/spin_group.rb', line 382 def all_succeeded? @m.synchronize do @tasks.all?(&:success) end end |
#debrief ⇒ Object
391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 |
# File 'lib/cli/ui/spinner/spin_group.rb', line 391 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.}" 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
367 368 369 |
# File 'lib/cli/ui/spinner/spin_group.rb', line 367 def failure_debrief(&block) @failure_debrief = block end |
#success_debrief(&block) ⇒ Object
377 378 379 |
# File 'lib/cli/ui/spinner/spin_group.rb', line 377 def success_debrief(&block) @success_debrief = block end |
#wait ⇒ Object
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 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 |
# File 'lib/cli/ui/spinner/spin_group.rb', line 299 def wait idx = 0 consumed_lines = 0 tasks_seen = @tasks.map { false } tasks_seen_done = @tasks.map { false } loop do done_count = 0 width = CLI::UI::Terminal.width self.class.pause_mutex.synchronize do next if self.class.paused? @m.synchronize do CLI::UI.raw do @tasks.each.with_index do |task, int_index| nat_index = int_index + 1 task_done = task.check done_count += 1 if task_done if CLI::UI.enable_cursor? 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 elsif !tasks_seen[int_index] || (task_done && !tasks_seen_done[int_index]) print(task.render(idx, true, width: width) + "\n") end tasks_seen[int_index] = true tasks_seen_done[int_index] ||= task_done end end end end break if done_count == @tasks.size 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 |