class Spinner
Constants
- VERSION
Attributes
queue[R]
Public Class Methods
new(*tasks)
click to toggle source
# File lib/spinner.rb, line 9 def initialize(*tasks) @queue = tasks @width = 0 @chars = %w{ | / - \\ } end
Public Instance Methods
spin!()
click to toggle source
Starts executing the queued tasks.
# File lib/spinner.rb, line 44 def spin! # Handle no tasks in the queue. return unless @queue.any? # Mark the current time in order to calculate the total duration. start_time = Time.now # Pluralize the number of tasks in the queue. task_counter = "#{@queue.size} task" << (@queue.size == 1 ? '' : 's') # Update the print width. @width = (@width + (@queue.size.to_s.length + 2) * 2) + 1 # Execute each task in sequence. @queue.each_with_index do |task, i| run_task(task, i+1) end # Reset this spinner instance so that it can be reused. reset! # Mark the completion time and calculate the duration. end_time = Time.now time_taken = distance_of_time_in_words(start_time, end_time) # Print the completion message. print("Done! #{task_counter} completed in #{time_taken} :-)\n") end
task(title=nil, task_name=nil, &block)
click to toggle source
Injects a new task into the queue.
# File lib/spinner.rb, line 16 def task(title=nil, task_name=nil, &block) # Handle no task being supplied. return @queue.map(&:title) unless block_given? || task_name # Set default title. title = 'Executing' unless title # Tasks can be given a block to evaluate or # a rake task name to invoke. if block_given? task_block = block elsif task_name task_block = Rake::Task[task_name] end # Inject the task into the queue. @queue << [ title, task_block ] # Amend the output width if necessary. if @width < title.length @width = title.length end # Return the new list of tasks. @queue.map(&:first) end
Private Instance Methods
clear()
click to toggle source
Clears the current printed output.
# File lib/spinner.rb, line 81 def clear print("\r") print(" ".ljust(@width + 5)) print("\r") end
distance_of_time_in_words(from_time, to_time)
click to toggle source
Simplified extraction from ActionView.
# File lib/spinner.rb, line 129 def distance_of_time_in_words(from_time, to_time) distance_in_minutes = ((to_time - from_time) / 60.0).round distance_in_seconds = (to_time - from_time).round case distance_in_minutes when 0..1 case distance_in_seconds when 0..4 then "less than 5 seconds" when 5..9 then "less than 10 seconds" when 10..19 then "less than 20 seconds" when 20..39 then "about half a minute" when 40..59 then "less than one minute" else "one minute" end when 2...45 then "about #{distance_in_minutes} minutes" when 45...90 then "about an hour" else "over an hour" end end
print(*args)
click to toggle source
Outputs to the console.
# File lib/spinner.rb, line 76 def print(*args) STDOUT.print(*args) end
reset!()
click to toggle source
Reset this spinner instance to defaults.
# File lib/spinner.rb, line 88 def reset! @width = 0 @queue = [] end
run_task(item, counter)
click to toggle source
Executes a single task.
# File lib/spinner.rb, line 94 def run_task(item, counter) # Extract the title & task block. title, task = *item # Print the task counter and title. print("#{counter}/#{queue.size}: #{title}".ljust(@width, '.') + '... ') # Begin a new thread to update the printed output while # the task runs. t = Thread.new { # Suppress $stdout during the task's execution. $stdout = StringIO.new if task.respond_to?(:invoke) task.invoke else task.call end } # Run the spinner for the duration of the task, # then clear the output. spin while t.alive? t.join clear end
spin()
click to toggle source
Update the position of the spinner.
# File lib/spinner.rb, line 121 def spin print(@chars[0]) # Print the next character... sleep(0.1) # ...wait 100ms... print("\b") # ...move the cursor back by one... @chars.push(@chars.shift) # ...rotate the characters array. end