ke 0.0.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 +7 -0
- data/.gitignore +14 -0
- data/.travis.yml +3 -0
- data/Gemfile +2 -0
- data/LICENSE +22 -0
- data/README.md +67 -0
- data/Rakefile +8 -0
- data/ke.gemspec +22 -0
- data/lib/ke.rb +6 -0
- data/lib/ke/capped_sample.rb +36 -0
- data/lib/ke/determinate_task.rb +13 -0
- data/lib/ke/indeterminate_task.rb +46 -0
- data/lib/ke/reporters/multi_line_reporter.rb +29 -0
- data/lib/ke/reporters/single_line_reporter.rb +29 -0
- data/lib/ke/version.rb +3 -0
- data/test/ke_test.rb +26 -0
- data/test/test_helper.rb +2 -0
- metadata +90 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4fbfaca5a83423f479bc2a76e0b7903397b5fdd0
|
4
|
+
data.tar.gz: eff7b260a09a7ae6c2c5e4d7c8d58ac37843c1be
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9bb0ebe5335d9f3b31c2a21aa71bfb7c4e67c65f102a76d5be0818e84fd25b904902f6a32b4e035adefb7f9060dc02b04214daad3356713ad857c1b383da3d9b
|
7
|
+
data.tar.gz: c5718d042ff068d8dd43520ab670d6b5478ed91aab5934c47cd44dc7696cd882c4573d1374c6c804d0450a1e6cefd50bff77707d1142ee713b5a1edda5cd768d
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Mark Dodwell
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
# Ke [](https://travis-ci.org/mkdynamic/ke)
|
2
|
+
|
3
|
+
Measure progress of Ruby code with the ability to provide estimates for time until completion.
|
4
|
+
|
5
|
+
Supports tasks with a known (determinate) and unknown (indeterminate) number of iterations. For indeterminate tasks it's only possible to provide a rate. For determinate tasks it's possible to provide both a rate and an estimated remaining time.
|
6
|
+
|
7
|
+
## Usage
|
8
|
+
|
9
|
+
Install them gem with `gem install ke`. If you're using Bundler then add it to your Gemfile with `gem ke` and run `bundle install`. Usage examples below:
|
10
|
+
|
11
|
+
### Example 1: An indeterminate task with a multi line reporting output
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
require 'ke'
|
15
|
+
|
16
|
+
task = Ke::IndeterminateTask.new
|
17
|
+
reporter = Ke::MultiLineReporter.new(task, "indeterminate task")
|
18
|
+
task.start
|
19
|
+
reporter.print_start
|
20
|
+
loop do
|
21
|
+
break if rand(200) == 50
|
22
|
+
sleep 0.1
|
23
|
+
task.tick
|
24
|
+
reporter.print_tick if task.tick_count % 10 == 0
|
25
|
+
end
|
26
|
+
task.complete
|
27
|
+
reporter.print_complete
|
28
|
+
```
|
29
|
+
|
30
|
+
### Example 2: A determinate task with a single line reporting output
|
31
|
+
|
32
|
+
```ruby
|
33
|
+
require 'ke'
|
34
|
+
|
35
|
+
task = Ke::DeterminateTask.new(total_ticks: 50)
|
36
|
+
reporter = Ke::SingleLineReporter.new(task, "determinate task")
|
37
|
+
task.start
|
38
|
+
reporter.print_start
|
39
|
+
50.times do
|
40
|
+
sleep 0.1
|
41
|
+
task.tick
|
42
|
+
reporter.print_tick if task.tick_count % 10 == 0
|
43
|
+
end
|
44
|
+
task.complete
|
45
|
+
reporter.print_complete
|
46
|
+
```
|
47
|
+
|
48
|
+
## Custom reporters
|
49
|
+
|
50
|
+
You can add your own reporters as needed. Scope the existing reporters to learn the interface.
|
51
|
+
|
52
|
+
## TODO
|
53
|
+
|
54
|
+
- Provide some syntactic sugar for the API, it's a bit rough at present
|
55
|
+
- Provide some pleasant looking default reporters (the current 2 work, but are ugly)
|
56
|
+
- Add some real tests
|
57
|
+
- Add more Ruby versions to Travis CI (anything 1.9+ compat should work)
|
58
|
+
- Measure the performanc impact
|
59
|
+
- Use other averages than SMA. WMA, EMA etc.
|
60
|
+
|
61
|
+
## Contributing
|
62
|
+
|
63
|
+
1. Fork it
|
64
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
65
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
66
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
67
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/ke.gemspec
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
lib = File.expand_path('../lib', __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require 'ke/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "ke"
|
7
|
+
spec.version = Ke::VERSION
|
8
|
+
spec.authors = ["Mark Dodwell"]
|
9
|
+
spec.email = ["mark@madeofcode.com"]
|
10
|
+
spec.description = "Measure progress of Ruby code."
|
11
|
+
spec.summary = "Measure progress of Ruby code."
|
12
|
+
spec.homepage = "https://github.com/mkdynamic/ke"
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
spec.files = `git ls-files`.split($/)
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^test/})
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
|
20
|
+
spec.add_development_dependency "rake"
|
21
|
+
spec.add_development_dependency "minitest"
|
22
|
+
end
|
data/lib/ke.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
module Ke
|
2
|
+
class CappedSample
|
3
|
+
def initialize(limit)
|
4
|
+
@array = []
|
5
|
+
@limit = limit
|
6
|
+
end
|
7
|
+
|
8
|
+
def push(element)
|
9
|
+
@array << element
|
10
|
+
@array.shift if @array.size > @limit
|
11
|
+
self
|
12
|
+
end
|
13
|
+
alias :<< :push
|
14
|
+
|
15
|
+
def size
|
16
|
+
@array.size
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_a
|
20
|
+
@array.dup
|
21
|
+
end
|
22
|
+
alias :to_ary :to_a
|
23
|
+
|
24
|
+
def mean
|
25
|
+
if @array.size > 0
|
26
|
+
@array.inject(:+) / @array.size.to_f
|
27
|
+
else
|
28
|
+
0
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_s
|
33
|
+
"#<CappedSample: #{@array.inspect}>"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Ke
|
2
|
+
class DeterminateTask < IndeterminateTask
|
3
|
+
def initialize(opts = {})
|
4
|
+
super
|
5
|
+
@total_ticks = opts[:total_ticks]
|
6
|
+
end
|
7
|
+
|
8
|
+
def estimated_duration_until_complete
|
9
|
+
ticks_remaining = [@total_ticks - @tick_count, 0].max
|
10
|
+
ticks_remaining * duration_per_tick
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Ke
|
2
|
+
class IndeterminateTask
|
3
|
+
attr_reader :tick_count, :complete_time
|
4
|
+
|
5
|
+
def initialize(opts = {})
|
6
|
+
@tick_count = 0
|
7
|
+
@duration_per_tick = 0
|
8
|
+
@duration_per_tick_history = CappedSample.new(100)
|
9
|
+
@mutex = Mutex.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def start_time
|
13
|
+
@start_time
|
14
|
+
end
|
15
|
+
|
16
|
+
def elapsed_duration
|
17
|
+
Time.now - @start_time
|
18
|
+
end
|
19
|
+
|
20
|
+
def total_duration
|
21
|
+
@complete_time - @start_time
|
22
|
+
end
|
23
|
+
|
24
|
+
def start
|
25
|
+
@start_time = Time.now
|
26
|
+
end
|
27
|
+
|
28
|
+
def duration_per_tick
|
29
|
+
@duration_per_tick_history.mean
|
30
|
+
end
|
31
|
+
|
32
|
+
def tick
|
33
|
+
@mutex.synchronize do
|
34
|
+
this_tick_time = Time.now
|
35
|
+
duration_this_tick = this_tick_time - (@last_tick_time || start_time)
|
36
|
+
@duration_per_tick_history << duration_this_tick
|
37
|
+
@last_tick_time = this_tick_time
|
38
|
+
@tick_count += 1
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def complete
|
43
|
+
@complete_time = Time.now
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Ke
|
2
|
+
class MultiLineReporter
|
3
|
+
def initialize(task, label, io = STDOUT)
|
4
|
+
@task = task
|
5
|
+
@label = label
|
6
|
+
@io = io
|
7
|
+
end
|
8
|
+
|
9
|
+
def print_start
|
10
|
+
@io.puts "Starting #{@label}"
|
11
|
+
end
|
12
|
+
|
13
|
+
def print_tick
|
14
|
+
ticks_per_second = (1 / @task.duration_per_tick).round(2)
|
15
|
+
elapsed_time = (@task.elapsed_duration / 60.0).round(2)
|
16
|
+
|
17
|
+
if @task.respond_to?(:estimated_duration_until_complete)
|
18
|
+
estimated_duration_until_complete = (@task.estimated_duration_until_complete / 60.0).round(2)
|
19
|
+
@io.puts "Running #{@label}, #{elapsed_time} minutes elapsed, #{estimated_duration_until_complete} minutes remaining"
|
20
|
+
else
|
21
|
+
@io.puts "Running #{@label}, #{elapsed_time} minutes elapsed, #{ticks_per_second} ticks/second"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def print_complete
|
26
|
+
@io.puts "Completed #{@label}, #{@task.total_duration} total duration"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Ke
|
2
|
+
class SingleLineReporter
|
3
|
+
def initialize(task, label, io = STDOUT)
|
4
|
+
@task = task
|
5
|
+
@label = label
|
6
|
+
@io = io
|
7
|
+
end
|
8
|
+
|
9
|
+
def print_start
|
10
|
+
@io.print "Starting #{@label}"
|
11
|
+
end
|
12
|
+
|
13
|
+
def print_tick
|
14
|
+
ticks_per_second = (1 / @task.duration_per_tick).round(2)
|
15
|
+
elapsed_time = (@task.elapsed_duration / 60.0).round(2)
|
16
|
+
|
17
|
+
if @task.respond_to?(:estimated_duration_until_complete)
|
18
|
+
estimated_duration_until_complete = (@task.estimated_duration_until_complete / 60.0).round(2)
|
19
|
+
@io.print "{#{elapsed_time}/#{estimated_duration_until_complete} mins}"
|
20
|
+
else
|
21
|
+
@io.print "{#{elapsed_time} mins, #{ticks_per_second} ticks/sec}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def print_complete
|
26
|
+
@io.puts "complete."
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/ke/version.rb
ADDED
data/test/ke_test.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
task = Ke::IndeterminateTask.new
|
4
|
+
reporter = Ke::MultiLineReporter.new(task, "indeterminate task")
|
5
|
+
task.start
|
6
|
+
reporter.print_start
|
7
|
+
loop do
|
8
|
+
break if rand(200) == 50
|
9
|
+
sleep 0.1
|
10
|
+
task.tick
|
11
|
+
reporter.print_tick if task.tick_count % 10 == 0
|
12
|
+
end
|
13
|
+
task.complete
|
14
|
+
reporter.print_complete
|
15
|
+
|
16
|
+
task = Ke::DeterminateTask.new(total_ticks: 50)
|
17
|
+
reporter = Ke::SingleLineReporter.new(task, "determinate task")
|
18
|
+
task.start
|
19
|
+
reporter.print_start
|
20
|
+
50.times do
|
21
|
+
sleep 0.1
|
22
|
+
task.tick
|
23
|
+
reporter.print_tick if task.tick_count % 10 == 0
|
24
|
+
end
|
25
|
+
task.complete
|
26
|
+
reporter.print_complete
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ke
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Mark Dodwell
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-07-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: minitest
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: Measure progress of Ruby code.
|
42
|
+
email:
|
43
|
+
- mark@madeofcode.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- .gitignore
|
49
|
+
- .travis.yml
|
50
|
+
- Gemfile
|
51
|
+
- LICENSE
|
52
|
+
- README.md
|
53
|
+
- Rakefile
|
54
|
+
- ke.gemspec
|
55
|
+
- lib/ke.rb
|
56
|
+
- lib/ke/capped_sample.rb
|
57
|
+
- lib/ke/determinate_task.rb
|
58
|
+
- lib/ke/indeterminate_task.rb
|
59
|
+
- lib/ke/reporters/multi_line_reporter.rb
|
60
|
+
- lib/ke/reporters/single_line_reporter.rb
|
61
|
+
- lib/ke/version.rb
|
62
|
+
- test/ke_test.rb
|
63
|
+
- test/test_helper.rb
|
64
|
+
homepage: https://github.com/mkdynamic/ke
|
65
|
+
licenses:
|
66
|
+
- MIT
|
67
|
+
metadata: {}
|
68
|
+
post_install_message:
|
69
|
+
rdoc_options: []
|
70
|
+
require_paths:
|
71
|
+
- lib
|
72
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - '>='
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
requirements: []
|
83
|
+
rubyforge_project:
|
84
|
+
rubygems_version: 2.2.2
|
85
|
+
signing_key:
|
86
|
+
specification_version: 4
|
87
|
+
summary: Measure progress of Ruby code.
|
88
|
+
test_files:
|
89
|
+
- test/ke_test.rb
|
90
|
+
- test/test_helper.rb
|