interactive-logger 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/interactive-logger.rb +78 -41
- data/lib/interactive_logger/step.rb +68 -0
- data/lib/interactive_logger/threaded_step_interface.rb +23 -0
- metadata +3 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0c5636a0534a2b4c303e9b6b3f83cdb0e1791dc6
|
4
|
+
data.tar.gz: f11583fe28d1b0757f8a73edeb82d52d0d8b8bf6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3156898ce2975d594b9799bcfe0abef48d68db309e7cc2b07345e61306c97994314e890ecb3ad72dcc447ef0e1df499525cf9ca21efc3b5e0e6730389ac5cc33
|
7
|
+
data.tar.gz: 4136d190ac320d7e5f9d60100d1ad84a9783fba4c7c053fcc5ba6c43499533e538c6e7ef8c54db4114b6de45079195e4de7451f45dc19c156943e6ed0b9c4a57
|
data/lib/interactive-logger.rb
CHANGED
@@ -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
|
-
|
8
|
-
|
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
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
11
|
+
def initialize(debug: false)
|
12
|
+
@debug = debug
|
13
|
+
@current_step = nil
|
14
|
+
end
|
26
15
|
|
27
|
-
|
28
|
-
print_msg("\r" << prefix(FAILURE_SYMBOL) << (str || @orig_str))
|
29
|
-
end
|
16
|
+
def debug?; @debug == true end
|
30
17
|
|
31
|
-
|
32
|
-
|
33
|
-
|
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
|
-
|
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
|
-
|
38
|
-
|
37
|
+
Thread.abort_on_exception = true
|
38
|
+
child = Thread.new do
|
39
|
+
yield ThreadedStepInterface.new(queue)
|
39
40
|
end
|
40
41
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
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
|
-
|
51
|
-
|
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
|
-
#
|
58
|
-
def
|
59
|
-
|
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.
|
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
|