Class: Philiprehberger::Progress::Bar

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

Constant Summary collapse

FILL_CHAR =
"\u2588"
EMPTY_CHAR =
"\u2591"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(total:, width: 30, output: $stderr, fill: '=', empty: ' ', tip: '>') ⇒ Bar

Returns a new instance of Bar.



13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/philiprehberger/progress/bar.rb', line 13

def initialize(total:, width: 30, output: $stderr, fill: '=', empty: ' ', tip: '>')
  @total = [total, 0].max
  @width = width
  @output = output
  @current = 0
  @start_time = now
  @finished = false
  @paused = false
  @pause_elapsed = 0.0
  @pause_start = nil
  @fill = fill
  @empty = empty
  @tip = tip
end

Instance Attribute Details

#currentObject (readonly)

Returns the value of attribute current.



11
12
13
# File 'lib/philiprehberger/progress/bar.rb', line 11

def current
  @current
end

#totalObject (readonly)

Returns the value of attribute total.



11
12
13
# File 'lib/philiprehberger/progress/bar.rb', line 11

def total
  @total
end

Instance Method Details

#advance(n = 1) ⇒ Object



28
29
30
31
32
33
34
# File 'lib/philiprehberger/progress/bar.rb', line 28

def advance(n = 1)
  return self if @finished

  @current = [@current + n, @total].min
  render_to_output
  self
end

#elapsedObject



106
107
108
109
110
# File 'lib/philiprehberger/progress/bar.rb', line 106

def elapsed
  raw = now - @start_time - @pause_elapsed
  raw -= (now - @pause_start) if @paused
  raw
end

#etaObject



112
113
114
115
116
117
118
119
# File 'lib/philiprehberger/progress/bar.rb', line 112

def eta
  return 0.0 if @current >= @total
  return nil if @current.zero?

  elapsed_time = elapsed
  items_per_sec = @current.to_f / elapsed_time
  (@total - @current) / items_per_sec
end

#finishObject



88
89
90
91
92
93
94
# File 'lib/philiprehberger/progress/bar.rb', line 88

def finish
  @current = @total
  @finished = true
  render_to_output
  @output.write("\n") if tty?
  self
end

#finished?Boolean

Returns:

  • (Boolean)


96
97
98
# File 'lib/philiprehberger/progress/bar.rb', line 96

def finished?
  @finished
end

#pauseself

Pause the progress bar, freezing elapsed time calculation.

Returns:

  • (self)


64
65
66
67
68
69
70
# File 'lib/philiprehberger/progress/bar.rb', line 64

def pause
  return self if @paused || @finished

  @paused = true
  @pause_start = now
  self
end

#paused?Boolean

Returns:

  • (Boolean)


84
85
86
# File 'lib/philiprehberger/progress/bar.rb', line 84

def paused?
  @paused
end

#percentageObject



100
101
102
103
104
# File 'lib/philiprehberger/progress/bar.rb', line 100

def percentage
  return 100.0 if @total.zero?

  (@current.to_f / @total * 100).round(1)
end

#resetself

Reset the bar to 0, preserving total and width. Restarts the timer.

Returns:

  • (self)


51
52
53
54
55
56
57
58
59
# File 'lib/philiprehberger/progress/bar.rb', line 51

def reset
  @current = 0
  @finished = false
  @paused = false
  @pause_elapsed = 0.0
  @pause_start = nil
  @start_time = now
  self
end

#resumeself

Resume after pause.

Returns:

  • (self)


75
76
77
78
79
80
81
82
# File 'lib/philiprehberger/progress/bar.rb', line 75

def resume
  return self unless @paused

  @pause_elapsed += now - @pause_start
  @pause_start = nil
  @paused = false
  self
end

#set(n) ⇒ self

Set absolute progress position.

Parameters:

  • n (Integer)

    the new current value (clamped to 0..total)

Returns:

  • (self)


40
41
42
43
44
45
46
# File 'lib/philiprehberger/progress/bar.rb', line 40

def set(n)
  return self if @finished

  @current = [[n, 0].max, @total].min
  render_to_output
  self
end

#throughputObject



121
122
123
124
125
126
# File 'lib/philiprehberger/progress/bar.rb', line 121

def throughput
  elapsed_time = elapsed
  return 0.0 if elapsed_time.zero?

  @current.to_f / elapsed_time
end

#to_hObject



128
129
130
131
132
133
134
135
136
137
# File 'lib/philiprehberger/progress/bar.rb', line 128

def to_h
  {
    percentage: percentage,
    elapsed: elapsed,
    eta: eta,
    throughput: throughput,
    current: @current,
    total: @total
  }
end

#to_sObject



139
140
141
142
143
144
145
146
147
148
# File 'lib/philiprehberger/progress/bar.rb', line 139

def to_s
  return to_h.to_json if Philiprehberger::Progress.json_mode?

  bar_str = render_bar
  pct = format('%<p>5.1f%%', p: percentage)
  eta_str = format_eta(eta)
  tput = format('%<t>.1f/s', t: throughput)

  "[#{bar_str}] #{pct} | #{@current}/#{@total} | ETA: #{eta_str} | #{tput}"
end