popro 0.1.2 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +4 -0
- data/lib/popro.rb +18 -2
- data/lib/popro/context.rb +30 -9
- data/lib/popro/formatter.rb +48 -1
- data/lib/popro/indicator.rb +36 -4
- data/lib/popro/progress.rb +7 -7
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fc8a91c38e9a66e7b5de492fe92f5def2d044fc118a3dfc25ef826ccadc8692c
|
4
|
+
data.tar.gz: 00fc035091657744a3bc7110b91f1cfb49192d07afce1a0866e20745b038c368
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f0c02a15ce252052573de441631e8665f8c2fde13e27162287a01739df908283514f8fa0eb98056e179c2d6ac139aac89bb4a603abd45ae1d9333d960f2de5e4
|
7
|
+
data.tar.gz: 989554d6b7dcf42c8db7a0a1b240b440acf07fd1b965e861486361fe7627fe4c65d37ae8df951daeae37445d689239397613a34f1e6231d11e5addbccdaf586a
|
data/CHANGELOG
CHANGED
data/lib/popro.rb
CHANGED
@@ -7,7 +7,9 @@ module Popro
|
|
7
7
|
|
8
8
|
require_relative 'popro/progress'
|
9
9
|
|
10
|
-
|
10
|
+
@_is_silenced = false
|
11
|
+
|
12
|
+
def self.new(total = 0, **options, &block)
|
11
13
|
raise ConfigError, 'using :total is not supported in new' if options.key?(:total) && (options[:total] != total)
|
12
14
|
|
13
15
|
options[:total] = total
|
@@ -15,7 +17,6 @@ module Popro
|
|
15
17
|
end
|
16
18
|
|
17
19
|
def self.each(obj, total = nil, **options, &block)
|
18
|
-
options[:step] = 0 unless options.key? :step
|
19
20
|
new(0, **options).each(obj, total, &block).done
|
20
21
|
end
|
21
22
|
|
@@ -23,6 +24,21 @@ module Popro
|
|
23
24
|
new(0, **options).each_will(obj, titler, total, &block).done
|
24
25
|
end
|
25
26
|
|
27
|
+
def self.each_gonna(obj, titler, total = nil, **options, &block)
|
28
|
+
new(0, **options).each_gonna(obj, titler, total, &block).done
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.silenced
|
32
|
+
prev_silenced = @_is_silenced
|
33
|
+
@_is_silenced = true
|
34
|
+
yield
|
35
|
+
@_is_silenced = prev_silenced
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.silenced?
|
39
|
+
@_is_silenced
|
40
|
+
end
|
41
|
+
|
26
42
|
def self.command_line(*_args)
|
27
43
|
raise 'TODO: implement a `ps` style progress indicator for command line'
|
28
44
|
end
|
data/lib/popro/context.rb
CHANGED
@@ -6,11 +6,13 @@ module Popro
|
|
6
6
|
WILL_CHECK_MARKS ||= ' ✔'
|
7
7
|
|
8
8
|
class Context
|
9
|
+
require_relative 'indicator'
|
10
|
+
|
9
11
|
def initialize(progress:, info:, indicator:, step: 1)
|
10
12
|
@progress = progress
|
11
|
-
@indicator = indicator
|
12
13
|
@info = info
|
13
14
|
@step = step
|
15
|
+
@_indicator = indicator
|
14
16
|
end
|
15
17
|
|
16
18
|
def each(obj, total = nil, &block)
|
@@ -39,31 +41,44 @@ module Popro
|
|
39
41
|
raise OutOfSyncError, 'done while not started' unless @info.running?
|
40
42
|
|
41
43
|
@info.finish
|
42
|
-
|
44
|
+
indicator.finish if indicator.respond_to? :finish
|
43
45
|
end
|
44
46
|
|
45
47
|
def formatter(&block)
|
46
|
-
unless @
|
47
|
-
raise ConfigError, "seems formatter is not available for #{@
|
48
|
+
unless @_indicator.respond_to?(:formatter=)
|
49
|
+
raise ConfigError, "seems formatter is not available for #{@_indicator.class}"
|
48
50
|
end
|
49
51
|
|
50
|
-
@
|
52
|
+
@_indicator.formatter = block
|
51
53
|
block
|
52
54
|
end
|
53
55
|
|
54
56
|
def did(yielded = nil, amount = nil)
|
55
57
|
@info.start unless @info.running?
|
56
58
|
amount = @step if amount.nil?
|
57
|
-
raise TypeError
|
59
|
+
raise TypeError, "amount: expected an integer, got #{amount.class}" unless amount.is_a? Integer
|
58
60
|
|
59
61
|
@info.current += amount unless amount.zero?
|
60
|
-
|
62
|
+
indicator.call(@info, yielded)
|
63
|
+
|
64
|
+
self
|
65
|
+
end
|
61
66
|
|
67
|
+
def gonna(title)
|
68
|
+
@info.start unless @info.running?
|
69
|
+
indicator.call(@info, title)
|
62
70
|
self
|
63
71
|
end
|
64
72
|
|
73
|
+
def each_gonna(obj, titler, total = nil, &block)
|
74
|
+
_each(obj, total) do |*args|
|
75
|
+
gonna(titler.call(*args))
|
76
|
+
block.call(*args, progress: @info)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
65
80
|
def will(title = nil, step = nil, &block)
|
66
|
-
|
81
|
+
gonna "#{WILL_CHECK_MARKS[0]} #{title}"
|
67
82
|
|
68
83
|
return self unless block_given?
|
69
84
|
|
@@ -79,9 +94,15 @@ module Popro
|
|
79
94
|
|
80
95
|
private
|
81
96
|
|
97
|
+
def indicator
|
98
|
+
return Indicator::Null if Popro.silenced?
|
99
|
+
|
100
|
+
@_indicator
|
101
|
+
end
|
102
|
+
|
82
103
|
def _each(obj, total = nil, &block)
|
83
104
|
total = obj.size if total.nil?
|
84
|
-
raise TypeError
|
105
|
+
raise TypeError, "total: expected an integer got #{total.class}" unless total.is_a?(Integer) || total.nil?
|
85
106
|
|
86
107
|
@info.total += total if total.positive?
|
87
108
|
# block = proc { |d| d } unless block_given?
|
data/lib/popro/formatter.rb
CHANGED
@@ -30,7 +30,7 @@ module Popro
|
|
30
30
|
def call(info, *args)
|
31
31
|
result = @formatter.call(info, *args)
|
32
32
|
@longest = [@longest, result.size].max
|
33
|
-
"\r
|
33
|
+
"\r#{result.ljust(@longest, ' ')}"
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
@@ -43,6 +43,53 @@ module Popro
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
+
class Estimate
|
47
|
+
# TODO: cleaner implementation/formatstring
|
48
|
+
attr_reader :info
|
49
|
+
|
50
|
+
def initialize
|
51
|
+
@start_time = current_time
|
52
|
+
@info = nil
|
53
|
+
end
|
54
|
+
|
55
|
+
def call(info, *_args)
|
56
|
+
@info = info
|
57
|
+
|
58
|
+
[
|
59
|
+
"estimated time left: #{format_duration(estimated_left)}",
|
60
|
+
"[#{format_duration(elapsed)}/#{format_duration(estimated_total)}]"
|
61
|
+
].join(', ')
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def elapsed
|
67
|
+
current_time - @start_time
|
68
|
+
end
|
69
|
+
|
70
|
+
def estimated_total
|
71
|
+
return nil if info.current.zero? || info.total.zero?
|
72
|
+
|
73
|
+
elapsed + (info.total / info.current) * elapsed
|
74
|
+
end
|
75
|
+
|
76
|
+
def estimated_left
|
77
|
+
return nil if info.current.zero? || info.total.zero?
|
78
|
+
|
79
|
+
(info.total / info.current) * elapsed
|
80
|
+
end
|
81
|
+
|
82
|
+
def format_duration(secs)
|
83
|
+
return '??d??h??m??s' if secs.nil?
|
84
|
+
|
85
|
+
format('%02dd%02dh%02dm%02ds', secs / 86_400, secs / 3600 % 24, secs / 60 % 60, secs % 60)
|
86
|
+
end
|
87
|
+
|
88
|
+
def current_time
|
89
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
46
93
|
class Sprintf
|
47
94
|
def initialize(format_string = nil)
|
48
95
|
@format_string = format_string
|
data/lib/popro/indicator.rb
CHANGED
@@ -1,9 +1,25 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'popro'
|
4
|
+
|
3
5
|
module Popro
|
4
6
|
module Indicator
|
5
7
|
require_relative 'formatter'
|
6
8
|
|
9
|
+
class Null
|
10
|
+
def self.new
|
11
|
+
self
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.initialize
|
15
|
+
self
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.call(*_args); end
|
19
|
+
|
20
|
+
def self.finish; end
|
21
|
+
end
|
22
|
+
|
7
23
|
class Aggregate
|
8
24
|
def initialize(*indicators)
|
9
25
|
@indicators = indicators
|
@@ -27,7 +43,7 @@ module Popro
|
|
27
43
|
formatter = self.class.default_formatter(formatter) if formatter.nil? || formatter.is_a?(String)
|
28
44
|
|
29
45
|
@formatter = formatter
|
30
|
-
@stream = stream ||
|
46
|
+
@stream = stream || $stdout
|
31
47
|
end
|
32
48
|
|
33
49
|
def call(*args)
|
@@ -45,11 +61,27 @@ module Popro
|
|
45
61
|
end
|
46
62
|
end
|
47
63
|
|
48
|
-
|
64
|
+
class Callback
|
65
|
+
def initialize(finish = nil, &block)
|
66
|
+
@finish = finish
|
67
|
+
@callback = block
|
68
|
+
end
|
69
|
+
|
70
|
+
def call(*args)
|
71
|
+
@callback.call(*args)
|
72
|
+
end
|
73
|
+
|
74
|
+
def finish
|
75
|
+
@finish&.call
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.default_formatter(*extra_formatters)
|
49
80
|
::Popro::Formatter::RewriteLine.new(
|
50
81
|
::Popro::Formatter::Concat.new(
|
51
82
|
::Popro::Formatter::Spinner.new(:dots, bounce: true),
|
52
83
|
::Popro::Formatter::Sprintf.new,
|
84
|
+
*extra_formatters,
|
53
85
|
(proc do |_, yielded = nil|
|
54
86
|
yielded if yielded.is_a?(String) || yielded.is_a?(Numeric)
|
55
87
|
end),
|
@@ -58,8 +90,8 @@ module Popro
|
|
58
90
|
)
|
59
91
|
end
|
60
92
|
|
61
|
-
def self.default
|
62
|
-
Stream.new(formatter: default_formatter)
|
93
|
+
def self.default(*extra_formatters)
|
94
|
+
Stream.new(formatter: default_formatter(*extra_formatters))
|
63
95
|
end
|
64
96
|
end
|
65
97
|
end
|
data/lib/popro/progress.rb
CHANGED
@@ -9,21 +9,21 @@ module Popro
|
|
9
9
|
DEFAULT_OPTIONS ||= {
|
10
10
|
total: 0,
|
11
11
|
current: 0,
|
12
|
+
indicator: Indicator.default
|
12
13
|
}.freeze
|
13
14
|
|
14
15
|
attr_reader :context
|
15
16
|
|
16
17
|
def initialize(**options)
|
17
|
-
options.merge!(DEFAULT_OPTIONS)
|
18
|
-
|
19
18
|
@started = false
|
20
19
|
|
21
|
-
|
20
|
+
options = DEFAULT_OPTIONS
|
21
|
+
.merge(step: block_given? ? 0 : 1)
|
22
|
+
.merge(options)
|
22
23
|
|
23
|
-
|
24
|
-
indicator = Indicator.default unless options.key? :indicator
|
24
|
+
@info = Info.new(total: options.delete(:total), current: options.delete(:current))
|
25
25
|
|
26
|
-
options.merge!(progress: self, info: @info
|
26
|
+
options.merge!(progress: self, info: @info)
|
27
27
|
@context = Context.new(**options)
|
28
28
|
|
29
29
|
register_aliases
|
@@ -43,7 +43,7 @@ module Popro
|
|
43
43
|
|
44
44
|
def register_aliases
|
45
45
|
class << self
|
46
|
-
%i[each each_will to_proc
|
46
|
+
%i[each each_will each_gonna to_proc gonna will did formatter start done].each do |method_name|
|
47
47
|
define_method method_name do |*args, &block|
|
48
48
|
@context.public_send(method_name, *args, &block)
|
49
49
|
end
|
metadata
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: popro
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- MikeSmithEU
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-09-16 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: The Poor-Man's Progress Indicator
|
14
|
-
email:
|
14
|
+
email:
|
15
15
|
executables: []
|
16
16
|
extensions: []
|
17
17
|
extra_rdoc_files: []
|
@@ -31,7 +31,7 @@ homepage: https://rubygems.org/gems/popro
|
|
31
31
|
licenses:
|
32
32
|
- MIT
|
33
33
|
metadata: {}
|
34
|
-
post_install_message:
|
34
|
+
post_install_message:
|
35
35
|
rdoc_options: []
|
36
36
|
require_paths:
|
37
37
|
- lib
|
@@ -39,7 +39,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
39
39
|
requirements:
|
40
40
|
- - ">="
|
41
41
|
- !ruby/object:Gem::Version
|
42
|
-
version: '
|
42
|
+
version: '2.7'
|
43
43
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - ">="
|
@@ -47,7 +47,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
47
47
|
version: '0'
|
48
48
|
requirements: []
|
49
49
|
rubygems_version: 3.1.2
|
50
|
-
signing_key:
|
50
|
+
signing_key:
|
51
51
|
specification_version: 4
|
52
52
|
summary: Po'Pro
|
53
53
|
test_files: []
|