Class: Mxrb::Progress::Task

Inherits:
Object
  • Object
show all
Defined in:
lib/mxrb/progress.rb

Overview

Thread-safe terminal renderer for a single operation.

Constant Summary collapse

SPINNER =

rubocop:disable Metrics/ClassLength

%w[| / - \\].freeze
BAR_WIDTH =
28
REFRESH_INTERVAL =
0.08

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(label, total: nil, io: $stderr) ⇒ Task

Returns a new instance of Task.



35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/mxrb/progress.rb', line 35

def initialize(label, total: nil, io: $stderr)
  @label = label.to_s
  @total = normalize_total(total)
  @io = io
  @current = 0
  @detail = nil
  @started_at = Process.clock_gettime(Process::CLOCK_MONOTONIC)
  @last_rendered_at = 0.0
  @spinner_index = 0
  @mutex = Mutex.new
  @finished = false
end

Instance Attribute Details

#currentObject (readonly)

Returns the value of attribute current.



33
34
35
# File 'lib/mxrb/progress.rb', line 33

def current
  @current
end

#labelObject (readonly)

Returns the value of attribute label.



33
34
35
# File 'lib/mxrb/progress.rb', line 33

def label
  @label
end

#totalObject (readonly)

Returns the value of attribute total.



33
34
35
# File 'lib/mxrb/progress.rb', line 33

def total
  @total
end

Instance Method Details

#add_total(amount) ⇒ Object



79
80
81
82
83
# File 'lib/mxrb/progress.rb', line 79

def add_total(amount)
  @mutex.synchronize { @total = (@total || 0) + Integer(amount) }
  render(force: true)
  self
end

#advance(amount = 1, detail: nil, force: false) ⇒ Object



69
70
71
72
73
74
75
76
77
# File 'lib/mxrb/progress.rb', line 69

def advance(amount = 1, detail: nil, force: false)
  @mutex.synchronize do
    @current += amount
    @current = [@current, @total].min if @total
    @detail = detail.to_s unless detail.nil?
  end
  render(force:)
  self
end

#enabled?Boolean

Returns:

  • (Boolean)


48
# File 'lib/mxrb/progress.rb', line 48

def enabled? = true

#fail(message = nil) ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
# File 'lib/mxrb/progress.rb', line 98

def fail(message = nil)
  stop_spinner
  @mutex.synchronize do
    return self if @finished

    @detail = message.to_s unless message.to_s.empty?
    @finished = true
  end
  render(force: true, final: true, failed: true)
  self
end

#finish(detail = nil) ⇒ Object



85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/mxrb/progress.rb', line 85

def finish(detail = nil)
  stop_spinner
  @mutex.synchronize do
    return self if @finished

    @detail = detail.to_s if detail
    @current = @total if @total
    @finished = true
  end
  render(force: true, final: true)
  self
end

#startObject



50
51
52
53
54
# File 'lib/mxrb/progress.rb', line 50

def start
  render(force: true)
  start_spinner unless determinate?
  self
end

#update(current: nil, total: nil, detail: nil, force: false) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/mxrb/progress.rb', line 56

def update(current: nil, total: nil, detail: nil, force: false)
  became_determinate = false
  @mutex.synchronize do
    became_determinate = @total.nil? && !total.nil?
    @total = normalize_total(total) unless total.nil?
    @current = [[Integer(current), 0].max, @total || Float::INFINITY].min unless current.nil?
    @detail = detail.to_s unless detail.nil?
  end
  stop_spinner if became_determinate
  render(force:)
  self
end