Class: CLI::UI::ProgressReporter::Reporter

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

Overview

Progress reporter instance that manages the lifecycle of progress reporting

Constant Summary collapse

OSC =

OSC (Operating System Command) escape sequences

"\e]"
ST =

String Terminator (BEL)

"\a"
REMOVE =

Progress states

0
SET_PROGRESS =
1
ERROR =
2
INDETERMINATE =
3
PAUSED =
4

Instance Method Summary collapse

Methods included from T::Sig

sig

Constructor Details

#initialize(mode, to = $stdout, parent: nil, delay_start: false) ⇒ Reporter

Returns a new instance of Reporter.



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/cli/ui/progress_reporter.rb', line 31

def initialize(mode, to = $stdout, parent: nil, delay_start: false)
  @mode = mode
  @to = to
  @parent = parent
  @children = []
  @active = ProgressReporter.supports_progress? && @parent.nil?

  # Register with parent if nested
  @parent&.add_child(self)

  return unless @active
  return if delay_start # Don't emit initial OSC if delayed

  case mode
  when :indeterminate
    set_indeterminate
  when :progress
    set_progress(0)
  else
    raise ArgumentError, "Unknown progress mode: #{mode}"
  end
end

Instance Method Details

#add_child(child) ⇒ Object



55
56
57
# File 'lib/cli/ui/progress_reporter.rb', line 55

def add_child(child)
  @children << child
end

#cleanupObject



141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/cli/ui/progress_reporter.rb', line 141

def cleanup
  # Remove self from parent's children list
  @parent&.remove_child(self)

  # If parent exists and has no more children, restore its progress state
  if @parent && !@parent.has_active_children?
    case @parent.instance_variable_get(:@mode)
    when :indeterminate
      @parent.set_indeterminate
    when :progress
      # Parent progress bar should maintain its last state
      # The parent will handle re-emitting its progress on next tick
    end
  elsif !@parent
    # We're the root, clear progress
    clear
  end
end

#clearObject



132
133
134
135
136
137
138
# File 'lib/cli/ui/progress_reporter.rb', line 132

def clear
  # Only clear if we're the root reporter and have no active children
  return unless @active
  return if has_active_children?

  @to.print("#{OSC}9;4;#{REMOVE};#{ST}")
end

#force_set_indeterminateObject



103
104
105
106
107
108
# File 'lib/cli/ui/progress_reporter.rb', line 103

def force_set_indeterminate
  return unless @active

  @mode = :indeterminate
  @to.print("#{OSC}9;4;#{INDETERMINATE};#{ST}")
end

#force_set_progress(percentage) ⇒ Object



93
94
95
96
97
98
99
# File 'lib/cli/ui/progress_reporter.rb', line 93

def force_set_progress(percentage)
  return unless @active

  @mode = :progress
  percentage = percentage.clamp(0, 100)
  @to.print("#{OSC}9;4;#{SET_PROGRESS};#{percentage}#{ST}")
end

#has_active_children?Boolean

Returns:

  • (Boolean)


65
66
67
# File 'lib/cli/ui/progress_reporter.rb', line 65

def has_active_children?
  @children.any?
end

#remove_child(child) ⇒ Object



60
61
62
# File 'lib/cli/ui/progress_reporter.rb', line 60

def remove_child(child)
  @children.delete(child)
end

#set_errorObject



111
112
113
114
115
116
# File 'lib/cli/ui/progress_reporter.rb', line 111

def set_error
  # Error state can be set even with children
  return unless @active

  @to.print("#{OSC}9;4;#{ERROR};#{ST}")
end

#set_indeterminateObject



81
82
83
84
85
86
87
88
# File 'lib/cli/ui/progress_reporter.rb', line 81

def set_indeterminate
  # Don't emit progress if we have active children
  return if has_active_children?
  return unless @active

  @mode = :indeterminate # Update mode when switching to indeterminate
  @to.print("#{OSC}9;4;#{INDETERMINATE};#{ST}")
end

#set_paused(percentage = nil) ⇒ Object



119
120
121
122
123
124
125
126
127
128
129
# File 'lib/cli/ui/progress_reporter.rb', line 119

def set_paused(percentage = nil)
  return if has_active_children?
  return unless @active

  if percentage
    percentage = percentage.clamp(0, 100)
    @to.print("#{OSC}9;4;#{PAUSED};#{percentage}#{ST}")
  else
    @to.print("#{OSC}9;4;#{PAUSED};#{ST}")
  end
end

#set_progress(percentage) ⇒ Object

rubocop:disable Naming/AccessorMethodName



70
71
72
73
74
75
76
77
78
# File 'lib/cli/ui/progress_reporter.rb', line 70

def set_progress(percentage) # rubocop:disable Naming/AccessorMethodName
  # Don't emit progress if we have active children (they own the progress)
  return if has_active_children?
  return unless @active

  @mode = :progress # Update mode when switching to progress
  percentage = percentage.clamp(0, 100)
  @to.print("#{OSC}9;4;#{SET_PROGRESS};#{percentage}#{ST}")
end