interactive-logger 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 72a04135369c640aab4c63048eafb80e669ed895
4
- data.tar.gz: 8b983336a11ced1edbd6ff4624505c90e3801c32
3
+ metadata.gz: 0c5636a0534a2b4c303e9b6b3f83cdb0e1791dc6
4
+ data.tar.gz: f11583fe28d1b0757f8a73edeb82d52d0d8b8bf6
5
5
  SHA512:
6
- metadata.gz: 87f61383fff19a07ec26acaa805b3f05cfc10c283bdc9d68fdd85710f7c6a08b3760d0106724c280cdb423eeb0d36cbccece45ce759403f3b89df030f4a1ec4e
7
- data.tar.gz: 60fa6e6384f7d20ee5dde568723b90cb5a3102aaa5a942dc094ac0c7505ef736956ee4562db33eccc8e80e925cf677546aa3b6612cff170184c2809c9157625c
6
+ metadata.gz: 3156898ce2975d594b9799bcfe0abef48d68db309e7cc2b07345e61306c97994314e890ecb3ad72dcc447ef0e1df499525cf9ca21efc3b5e0e6730389ac5cc33
7
+ data.tar.gz: 4136d190ac320d7e5f9d60100d1ad84a9783fba4c7c053fcc5ba6c43499533e538c6e7ef8c54db4114b6de45079195e4de7451f45dc19c156943e6ed0b9c4a57
@@ -1,62 +1,99 @@
1
1
  # coding: utf-8
2
2
  require 'colorize'
3
3
  require 'ruby-duration'
4
+ require 'thread'
4
5
 
5
6
  # A logger that shows activity for each step without spamming to stdout.
6
7
  class InteractiveLogger
7
- class Step
8
- PROGRESS_SYMBOLS = %w(- \\ | /)
9
- FAILURE_SYMBOL = '✗'.red
10
- SUCCESS_SYMBOL = '✓'.green
11
- LB = '['.light_black
12
- RB = ']'.light_black
13
-
14
- def initialize(str, show_time: true)
15
- @orig_str = str
16
- @start = Time.now
17
- @show_time = show_time
18
- @pos = 0
19
- print_msg(in_progress_prefix << str)
20
- end
8
+ require_relative 'interactive_logger/step'
9
+ require_relative 'interactive_logger/threaded_step_interface'
21
10
 
22
- def continue(str = nil)
23
- @pos += 1
24
- print_msg("\r" << in_progress_prefix << (str || @orig_str))
25
- end
11
+ def initialize(debug: false)
12
+ @debug = debug
13
+ @current_step = nil
14
+ end
26
15
 
27
- def failure(str = nil)
28
- print_msg("\r" << prefix(FAILURE_SYMBOL) << (str || @orig_str))
29
- end
16
+ def debug?; @debug == true end
30
17
 
31
- def success(str = nil)
32
- print_msg("\r" << prefix(SUCCESS_SYMBOL) << (str || @orig_str))
33
- end
18
+ # Start a step.
19
+ def start(str)
20
+ @current_step = Step.new(str)
21
+ yield @current_step
22
+ print "\n"
23
+ rescue => e
24
+ @current_step.failure "Error while performing step: #{str}\n #{e.class}: #{e.message}"
25
+ print "\n"
26
+ raise
27
+ ensure
28
+ @current_step = nil
29
+ end
34
30
 
35
- private
31
+ # Use a threaded interface, to keep the UI updated even on a long-running
32
+ # process.
33
+ def start_threaded(str)
34
+ @current_step = Step.new(str)
35
+ queue = Queue.new
36
36
 
37
- def in_progress_prefix
38
- prefix(PROGRESS_SYMBOLS[@pos % PROGRESS_SYMBOLS.size].yellow)
37
+ Thread.abort_on_exception = true
38
+ child = Thread.new do
39
+ yield ThreadedStepInterface.new(queue)
39
40
  end
40
41
 
41
- def prefix(str)
42
- show_time = ''
43
- if @show_time
44
- show_time = Duration.new(Time.now.to_i - @start.to_i)
45
- .format(" #{LB} %tmm %ss #{RB}")
42
+ loop do
43
+ if queue.empty?
44
+ @current_step.continue # Keep the UI updating regardless of actual process.
45
+ else
46
+ until queue.empty?
47
+ msg = queue.pop
48
+ @current_step.send(msg.shift, *msg)
49
+ end
46
50
  end
47
- "#{LB} #{str} #{RB}#{show_time} "
48
- end
49
51
 
50
- def print_msg(str)
51
- @max_str = [str.uncolorize.size, @max_str || 0].max
52
- str << ' ' * (@max_str - str.uncolorize.size)
53
- print str
52
+ break unless child.alive?
53
+ sleep 0.5
54
54
  end
55
+
56
+ puts
57
+ child.join
58
+
59
+ @current_step.nil?
60
+ rescue => e
61
+ @current_step.failure "Error while performing step: #{str}\n #{e.class}: #{e.message}"
62
+ print "\n"
63
+ raise
64
+ ensure
65
+ @current_step = nil
55
66
  end
56
67
 
57
- # Start a step.
58
- def start(str)
59
- yield Step.new(str)
68
+ # Post a debug message above the current step output, if debugging is enabled.
69
+ def debug(str)
70
+ return unless debug?
71
+
72
+ @current_step.blank if @current_step
73
+ print '--> '.yellow
74
+ puts str
75
+ @current_step.repaint if @current_step
76
+ end
77
+ # Post an informative message above the current step output.
78
+ def info(str)
79
+ @current_step.blank if @current_step
80
+ print '--> '.green
81
+ puts str
82
+ @current_step.repaint if @current_step
83
+ end
84
+
85
+ # Post an error message above the current step output.
86
+ def error(str)
87
+ @current_step.blank if @current_step
88
+ print '--> '.red
89
+ puts str
90
+ @current_step.repaint if @current_step
91
+ end
92
+
93
+ # Post a single message, without any progress tracking.
94
+ def msg(str)
95
+ c = Step.new(str)
96
+ c.success
60
97
  print "\n"
61
98
  end
62
99
  end
@@ -0,0 +1,68 @@
1
+ # coding: utf-8
2
+ class InteractiveLogger
3
+ class Step
4
+ PROGRESS_SYMBOLS = %w(- \\ | /)
5
+ FAILURE_SYMBOL = '✗'.red
6
+ SUCCESS_SYMBOL = '✓'.green
7
+ LB = '['.light_black
8
+ RB = ']'.light_black
9
+
10
+ def initialize(str, show_time: true)
11
+ @last_str = str
12
+ @start = Time.now
13
+ @show_time = show_time
14
+ @pos = 0
15
+ print_msg(in_progress_prefix << str)
16
+ end
17
+
18
+ def continue(str = nil)
19
+ @pos += 1
20
+ @last_str = str if str
21
+ print_msg(in_progress_prefix << @last_str)
22
+ end
23
+
24
+ def failure(str = nil)
25
+ @last_str = str if str
26
+ print_msg(prefix(FAILURE_SYMBOL) << @last_str)
27
+ end
28
+
29
+ def success(str = nil)
30
+ @last_str = str if str
31
+ print_msg(prefix(SUCCESS_SYMBOL) << @last_str)
32
+ end
33
+
34
+ # Blank out the current line.
35
+ def blank
36
+ print "\r"
37
+ if @last_print_msg
38
+ print ' ' * @last_print_msg.uncolorize.size
39
+ end
40
+ print "\r"
41
+ end
42
+
43
+ def repaint
44
+ print @last_print_msg
45
+ end
46
+
47
+ private
48
+
49
+ def in_progress_prefix
50
+ prefix(PROGRESS_SYMBOLS[@pos % PROGRESS_SYMBOLS.size].yellow)
51
+ end
52
+
53
+ def prefix(str)
54
+ show_time = ''
55
+ if @show_time
56
+ show_time = Duration.new(Time.now.to_i - @start.to_i)
57
+ .format(" #{LB} %tmm %ss #{RB}")
58
+ end
59
+ "#{LB} #{str} #{RB}#{show_time} "
60
+ end
61
+
62
+ def print_msg(str)
63
+ blank
64
+ @last_print_msg = str
65
+ print str
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,23 @@
1
+ require 'thread'
2
+
3
+ class InteractiveLogger
4
+ # A interface-match for Step, but used simply to communicate with the main
5
+ # thread, which actually manipulates the Step.
6
+ class ThreadedStepInterface
7
+ def initialize(queue)
8
+ @queue = queue
9
+ end
10
+
11
+ def continue(str = nil)
12
+ @queue.push([:continue, str])
13
+ end
14
+
15
+ def failure(str = nil)
16
+ @queue.push([:failure, str])
17
+ end
18
+
19
+ def success(str = nil)
20
+ @queue.push([:success, str])
21
+ end
22
+ end
23
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: interactive-logger
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kyle Smith <askreet@gmail.com>
@@ -51,6 +51,8 @@ extensions: []
51
51
  extra_rdoc_files: []
52
52
  files:
53
53
  - lib/interactive-logger.rb
54
+ - lib/interactive_logger/step.rb
55
+ - lib/interactive_logger/threaded_step_interface.rb
54
56
  homepage: https://github.com/askreet/interactive-logger
55
57
  licenses:
56
58
  - MIT