Class: Zenspec::ProgressLoader

Inherits:
Object
  • Object
show all
Defined in:
lib/zenspec/progress_loader.rb

Overview

Docker-style progress loader for displaying progress in terminal Displays progress bars similar to Docker's layer download progress

Examples:

Basic usage

loader = Zenspec::ProgressLoader.new(total: 10, description: "Running tests")
10.times do |i|
  loader.update(i + 1)
  sleep(0.1)
end
loader.finish

With custom width

loader = Zenspec::ProgressLoader.new(total: 100, width: 50)
loader.update(50, description: "Processing files 50/100")

Constant Summary collapse

DEFAULT_WIDTH =

Default width for the progress bar

40

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(total:, width: DEFAULT_WIDTH, description: nil, output: $stderr) ⇒ ProgressLoader

Returns a new instance of ProgressLoader.

Parameters:

  • total (Integer)

    Total number of items to process

  • width (Integer) (defaults to: DEFAULT_WIDTH)

    Width of the progress bar in characters

  • description (String) (defaults to: nil)

    Initial description text

  • output (IO) (defaults to: $stderr)

    Output stream (defaults to STDERR)



29
30
31
32
33
34
35
36
37
# File 'lib/zenspec/progress_loader.rb', line 29

def initialize(total:, width: DEFAULT_WIDTH, description: nil, output: $stderr)
  @total = total
  @width = width
  @current = 0
  @description = description
  @output = output
  @finished = false
  @start_time = Time.now
end

Instance Attribute Details

#currentObject (readonly)

Returns the value of attribute current.



20
21
22
# File 'lib/zenspec/progress_loader.rb', line 20

def current
  @current
end

#totalObject (readonly)

Returns the value of attribute total.



20
21
22
# File 'lib/zenspec/progress_loader.rb', line 20

def total
  @total
end

#widthObject (readonly)

Returns the value of attribute width.



20
21
22
# File 'lib/zenspec/progress_loader.rb', line 20

def width
  @width
end

Instance Method Details

#elapsed_timeFloat

Calculate elapsed time

Returns:

  • (Float)

    Elapsed time in seconds



74
75
76
# File 'lib/zenspec/progress_loader.rb', line 74

def elapsed_time
  Time.now - @start_time
end

#estimated_time_remainingFloat?

Calculate estimated time remaining

Returns:

  • (Float, nil)

    Estimated time remaining in seconds, or nil if cannot estimate



80
81
82
83
84
85
86
87
# File 'lib/zenspec/progress_loader.rb', line 80

def estimated_time_remaining
  return nil if @current.zero?

  elapsed = elapsed_time
  rate = @current.to_f / elapsed
  remaining_items = @total - @current
  remaining_items / rate
end

#finish(description: nil) ⇒ Object

Mark the progress as finished

Parameters:

  • description (String, nil) (defaults to: nil)

    Final description to display



56
57
58
59
60
61
62
# File 'lib/zenspec/progress_loader.rb', line 56

def finish(description: nil)
  @current = @total
  @description = description if description
  @finished = true
  render
  @output.puts # New line after completion
end

#format_time(seconds) ⇒ String

Format time duration

Parameters:

  • seconds (Float)

    Time in seconds

Returns:

  • (String)

    Formatted time string



92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/zenspec/progress_loader.rb', line 92

def format_time(seconds)
  return "0s" if seconds.nil? || seconds.zero?

  if seconds < 60
    "#{seconds.round}s"
  elsif seconds < 3600
    minutes = (seconds / 60).round
    "#{minutes}m"
  else
    hours = (seconds / 3600).round
    "#{hours}h"
  end
end

#increment(description: nil) ⇒ Object

Increment progress by one

Parameters:

  • description (String, nil) (defaults to: nil)

    Optional description to display



50
51
52
# File 'lib/zenspec/progress_loader.rb', line 50

def increment(description: nil)
  update(@current + 1, description: description)
end

#percentageInteger

Calculate current percentage

Returns:

  • (Integer)

    Percentage (0-100)



66
67
68
69
70
# File 'lib/zenspec/progress_loader.rb', line 66

def percentage
  return 100 if @total.zero?

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

#update(current, description: nil) ⇒ Object

Update the progress

Parameters:

  • current (Integer)

    Current progress value

  • description (String, nil) (defaults to: nil)

    Optional description to display



42
43
44
45
46
# File 'lib/zenspec/progress_loader.rb', line 42

def update(current, description: nil)
  @current = current
  @description = description if description
  render unless @finished
end