Module: Mxrb::Progress

Defined in:
lib/mxrb/progress.rb

Overview

Terminal progress rendering shared by every long-running MXRB operation. It is enabled automatically only for an interactive terminal, writes to stderr, and therefore never contaminates command output or JSON on stdout.

Defined Under Namespace

Classes: NullTask, Task

Constant Summary collapse

THREAD_KEY =
:mxrb_progress_task
FALSE_VALUES =
%w[0 false no off].freeze

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.io=(value) ⇒ Object (writeonly)

Sets the attribute io

Parameters:

  • value

    the value to set the attribute io to.



199
200
201
# File 'lib/mxrb/progress.rb', line 199

def io=(value)
  @io = value
end

Class Method Details

.configure(enabled: nil, io: nil) ⇒ Object



201
202
203
204
# File 'lib/mxrb/progress.rb', line 201

def configure(enabled: nil, io: nil)
  @enabled = enabled unless enabled.nil?
  @io = io if io
end

.currentObject



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

def current = Thread.current[THREAD_KEY] || NullTask.instance

.enabled?Boolean

Returns:

  • (Boolean)


211
212
213
214
215
216
# File 'lib/mxrb/progress.rb', line 211

def enabled?
  return @enabled unless @enabled.nil?
  return false if FALSE_VALUES.include?(ENV.fetch('MXRB_PROGRESS', '').downcase)

  output.respond_to?(:tty?) && output.tty?
end

.reset!Object



206
207
208
209
# File 'lib/mxrb/progress.rb', line 206

def reset!
  @enabled = nil
  @io = nil
end

.with(label, total: nil) ⇒ Object

rubocop:disable Metrics/AbcSize, Metrics/MethodLength



218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# File 'lib/mxrb/progress.rb', line 218

def with(label, total: nil) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
  active = Thread.current[THREAD_KEY]
  return yield(active) if active
  return yield(NullTask.instance) unless enabled?

  task = Task.new(label, total:, io: output).start
  Thread.current[THREAD_KEY] = task
  result = yield(task)
  task.finish
  result
rescue StandardError => e
  task&.fail(e.message)
  raise
ensure
  Thread.current[THREAD_KEY] = nil if defined?(task) && task
end