gem_velocity 0.0.8 → 0.0.9
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.
- data/.gitignore +1 -1
- data/README.md +18 -49
- data/TODO +7 -5
- data/examples/README.md +1 -0
- data/examples/generate_images.rb +48 -0
- data/examples/public/images/AggregatedVelocitator-haml-i18n-extractor-0.4.x.png +0 -0
- data/examples/public/images/Multiplexer-haml-i18n-extractor-0.0.17-0.0.16-0.4.x.png +0 -0
- data/examples/public/images/Multiplexer-haml-i18n-extractor-0.4.x-0.3.x.png +0 -0
- data/examples/public/images/SingleVelocitator-haml-i18n-extractor-0.0.16.png +0 -0
- data/examples/public/images/SingleVelocitator-haml-i18n-extractor-0.0.17.png +0 -0
- data/lib/gem_velocity/gem_data.rb +1 -1
- data/lib/gem_velocity/gruff_builder.rb +16 -13
- data/lib/gem_velocity/helpers.rb +26 -0
- data/lib/gem_velocity/velocitators/aggregated_velocitator.rb +24 -16
- data/lib/gem_velocity/velocitators/base_velocitator.rb +45 -39
- data/lib/gem_velocity/velocitators/factory.rb +52 -0
- data/lib/gem_velocity/velocitators/multiplexer.rb +65 -0
- data/lib/gem_velocity/velocitators/single_velocitator.rb +22 -14
- data/lib/gem_velocity/version.rb +1 -1
- data/lib/gem_velocity.rb +8 -1
- data/spec/aggregated_velocitor_spec.rb +53 -0
- data/spec/factory_spec.rb +54 -0
- data/spec/gruff_builder_spec.rb +0 -3
- data/spec/multiplexer_spec.rb +73 -0
- data/spec/no_time_cop_spec.rb +12 -28
- data/spec/single_velocitator_spec.rb +92 -0
- data/spec/spec_helper.rb +4 -0
- metadata +21 -11
- data/examples/rails-4.0.0-3.2.14-0.9.1.png +0 -0
- data/examples/rails-4.0.0-3.2.14-2.3.5.png +0 -0
- data/examples/rails-4.0.1.rc1-4.0.0-4.0.0.rc2-4.0.0.rc1-4.0.0.beta1.png +0 -0
- data/lib/gem_velocity/velocitators/all.rb +0 -4
- data/lib/gem_velocity/velocitators/multiple_velocitator.rb +0 -34
- data/spec/velocitator_spec.rb +0 -189
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -1,18 +1,22 @@
|
|
1
1
|
# GemVelocity
|
2
2
|
|
3
|
-
A way to see gem velocity. There are
|
3
|
+
A way to see gem velocity. There are two ways you can view graphs.
|
4
|
+
|
5
|
+
`SingleVelocitator`
|
6
|
+
|
7
|
+
This is a single line graph of a single version.
|
4
8
|
|
5
9
|
`AggregatedVelocitator`
|
6
10
|
|
7
|
-
|
11
|
+
This is a signle line graph that has an aggregated view of a major version (or bunch of single minor versions, etc).
|
8
12
|
|
9
|
-
|
13
|
+
See specs and examples for more info.
|
10
14
|
|
11
|
-
|
15
|
+
There is also the `Multiplexer`, this is a wrapper around being able to draw multiple lines at once. You pass it any number of the above and it will graph multiple lines together in one graph.
|
12
16
|
|
13
17
|
## Note
|
14
18
|
|
15
|
-
There may be some inconstancies. These are outlined in:
|
19
|
+
There may be some inconstancies due to bad data coming back from the api. These are outlined in:
|
16
20
|
|
17
21
|
[https://gist.github.com/shaiguitar/d2af997b7f58e24fd305](https://gist.github.com/shaiguitar/d2af997b7f58e24fd305)
|
18
22
|
|
@@ -20,60 +24,25 @@ It seems it happens with older data. I'm investigating though with the help of t
|
|
20
24
|
|
21
25
|
## Requirements
|
22
26
|
|
23
|
-
It draws graphs. So
|
27
|
+
It draws graphs. So you'll need imagemagick/rmagick. Any problems with installation let me know and I'll try to help out.
|
24
28
|
|
25
|
-
|
29
|
+
`brew install imagemagick && brew link imagemagick && gem install gem_velocity`
|
26
30
|
|
27
31
|
# Example
|
28
32
|
|
29
|
-
|
30
|
-
velocitator = MultipleVelocitator.new("rails", ["4.0.0","3.2.14","2.3.5"])
|
31
|
-
file = velocitator.graph("/tmp")
|
32
|
-
</pre>
|
33
|
-
|
34
|
-
Produces:
|
35
|
-
|
36
|
-

|
37
|
-
|
38
|
-
Notice the date range:
|
39
|
-
|
40
|
-
<pre>
|
41
|
-
velocitator = MultipleVelocitator.new("rails", ["4.0.0","3.2.14","0.9.1"])
|
42
|
-
file = velocitator.graph("/tmp", [3.months.ago, Time.now])
|
43
|
-
</pre>
|
44
|
-
|
45
|
-
Produces:
|
33
|
+
See [examples](examples/) for pictures. The specs have more examples as well.
|
46
34
|
|
47
|
-
|
35
|
+
Important to note, you should be able to pass in specific start time, end time, max and min values.
|
48
36
|
|
49
|
-
|
50
|
-
velocitator = AggregatedVelocitator.new("rails", "4")
|
51
|
-
# matches any version /^4.\d/ etc
|
52
|
-
file = velocitator.graph("/tmp")
|
53
|
-
</pre>
|
54
|
-
|
55
|
-
Produces:
|
56
|
-
|
57
|
-

|
58
|
-
|
59
|
-
Another: [celluloid](https://gist.github.com/shaiguitar/7e6d95971c5254fa3665)
|
60
|
-
|
61
|
-
You could do the same with a `SingleVelocitator` as well:
|
62
|
-
|
63
|
-
<pre>
|
64
|
-
velocitator = SingleVelocitator.new("rails", "4.0.0")
|
65
|
-
file = velocitator.graph("/tmp")
|
66
|
-
</pre>
|
67
|
-
|
68
|
-
That image is left as an excerise to the reader. Actually it's late. But try it and see.
|
69
|
-
|
70
|
-
Also, you should be able to pass in max,min values which completes you being able to manipulate the boundries of the graph in question.
|
37
|
+
This essentially completes you being able to manipulate the boundries of the graph in question.
|
71
38
|
|
72
39
|
## Web UI
|
73
40
|
|
74
|
-
Do you want to see this with ease (Hey, the api is easy. Whatever) on the web at `http://rubygems-velocity.org/gem/rails/4.0.0,3.2.14` or something similar?
|
41
|
+
Do you want to see this with ease (Hey, the api is easy. Whatever) on the web at `http://rubygems-velocity.org/gem/rails/4.0.0,3.2.14` or something similar?
|
42
|
+
|
43
|
+
[Work](https://github.com/shaiguitar/gem_velocity_web) has been started to put it on a UI, but your feedback in necessary for it to be useful:
|
75
44
|
|
76
|
-
|
45
|
+
So if you have any idea of how you'd like to use it, please put your thoughts on the [issue](https://github.com/shaiguitar/gem_velocities/issues/3)
|
77
46
|
|
78
47
|
Lemme know.
|
79
48
|
|
data/TODO
CHANGED
@@ -1,11 +1,7 @@
|
|
1
|
-
Web ui/embeddable links with those images.
|
2
|
-
can't remove images
|
3
|
-
have uniq name: hash the date_range,max,min,name,versions. (and time?)
|
4
|
-
shard the directories of where the image goes so it doesn't bomb out?
|
5
|
-
|
6
1
|
Add a Version?
|
7
2
|
|
8
3
|
currently, the versions in the base class are single versions, but they are essentially used for representing a specific line
|
4
|
+
|
9
5
|
in default_line_datas.
|
10
6
|
(and then used for titles, abd bs).
|
11
7
|
|
@@ -14,3 +10,9 @@ if rubygems 606 isn't solved, why not just put a total on there and let the inco
|
|
14
10
|
rename time_format_str_small alias
|
15
11
|
|
16
12
|
swap out gruff_builder to some other composing object of a builder, that can mash up the various velocitators?
|
13
|
+
|
14
|
+
consolidate velocitator fixtrues or at least repeatable generators in specs.
|
15
|
+
|
16
|
+
cassandra says to have an option to have the multiplexer start them from the same data (to see curve/adoption rate). I see it.
|
17
|
+
|
18
|
+
hardcode a time limit of earliest_time since historical data is not reliable.
|
data/examples/README.md
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
See generated images for the script here in [the images directory](public/images)
|
@@ -0,0 +1,48 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
examples_dir = File.expand_path(File.dirname(__FILE__))
|
6
|
+
images_dir = File.join(examples_dir, "public","images")
|
7
|
+
project_root = File.join(examples_dir, "..")
|
8
|
+
project_lib = File.join(project_root,"lib")
|
9
|
+
|
10
|
+
$:.unshift(project_root)
|
11
|
+
$:.unshift(project_lib)
|
12
|
+
require 'lib/gem_velocity'
|
13
|
+
|
14
|
+
puts "Cleaning images directory before generating again."
|
15
|
+
FileUtils.rm_rf(images_dir)
|
16
|
+
|
17
|
+
puts "SINGLE VELOCITATOR"
|
18
|
+
@v1 = SingleVelocitator.new("haml-i18n-extractor", "0.0.17")
|
19
|
+
@v1.max_value = 800
|
20
|
+
file = @v1.graph
|
21
|
+
|
22
|
+
puts "SINGLE VELOCITATOR"
|
23
|
+
# these are basically equivalet:
|
24
|
+
# BaseVelocitator.create(:gem_name => "haml-i18n-extractor", :version => "0.0.16")
|
25
|
+
# BaseVelocitator.create(:full_name => "haml-i18n-extractor-0.0.16")
|
26
|
+
@v2 = SingleVelocitator.new("haml-i18n-extractor", "0.0.16")
|
27
|
+
@v2.max_value = 800
|
28
|
+
file = @v2.graph
|
29
|
+
|
30
|
+
puts "AGGREGATED VELOCITATOR"
|
31
|
+
# these are basically equivalet:
|
32
|
+
# BaseVelocitator.create(:gem_name => "haml-i18n-extractor", :version => "0.4.x")
|
33
|
+
# BaseVelocitator.create(:full_name => "haml-i18n-extractor-0.4.x")
|
34
|
+
@v3 = AggregatedVelocitator.new("haml-i18n-extractor", "0.4.x")
|
35
|
+
@v3.max_value = 800
|
36
|
+
file = @v3.graph
|
37
|
+
|
38
|
+
puts "MULTIPLEXING"
|
39
|
+
@velocitators = [@v1,@v2,@v3]
|
40
|
+
@multiplexer = Multiplexer.new(@velocitators)
|
41
|
+
file = @multiplexer.graph
|
42
|
+
|
43
|
+
puts "MULIPLEXING AGAIN"
|
44
|
+
@velocitators = []
|
45
|
+
@velocitators << BaseVelocitator.create(:gem_name => "haml-i18n-extractor", :version => "0.4.x")
|
46
|
+
@velocitators << BaseVelocitator.create(:full_name => "haml-i18n-extractor-0.3.x")
|
47
|
+
@multiplexer = Multiplexer.new(@velocitators)
|
48
|
+
file = @multiplexer.graph
|
Binary file
|
@@ -24,7 +24,7 @@ class GemData
|
|
24
24
|
# it should be a hash
|
25
25
|
if @versions_metadata.is_a?(String)
|
26
26
|
if @versions_metadata.match(/This rubygem could not be found/)
|
27
|
-
raise(NoSuchGem, "This rubygem could not be found")
|
27
|
+
raise(NoSuchGem, "This rubygem #{gem_name} could not be found")
|
28
28
|
end
|
29
29
|
end
|
30
30
|
@versions_metadata
|
@@ -14,16 +14,18 @@ class GruffBuilder
|
|
14
14
|
attr_accessor :title, :labels, :line_datas, :min_value, :max_value, :hide_legend
|
15
15
|
|
16
16
|
def initialize(root, relative_path, versions, gem_name, gruff_options = {})
|
17
|
-
|
18
|
-
@
|
19
|
-
@
|
20
|
-
@
|
21
|
-
@
|
22
|
-
@
|
23
|
-
@
|
24
|
-
@
|
25
|
-
@
|
26
|
-
@
|
17
|
+
# just pass it in all in gruff_options?
|
18
|
+
@root = root || raise(ArgumentError,"you must set a root. default is root/public/images")
|
19
|
+
@relative_path = relative_path || "public/images/"
|
20
|
+
@versions = versions.is_a?(Array) ? versions : raise(ArgumentError,"versions must be an array")
|
21
|
+
@gem_name = gem_name
|
22
|
+
@title = gruff_options[:title] || ""
|
23
|
+
@labels = gruff_options[:labels] || {}
|
24
|
+
@line_datas = gruff_options[:line_datas]
|
25
|
+
@min_value = gruff_options[:min_value] || MIN_VALUE
|
26
|
+
@max_value = gruff_options[:max_value] || MAX_VALUE
|
27
|
+
@hide_legend = gruff_options[:hide_legend] || false
|
28
|
+
@type = gruff_options[:type]
|
27
29
|
end
|
28
30
|
|
29
31
|
def relative_filename
|
@@ -31,7 +33,7 @@ class GruffBuilder
|
|
31
33
|
end
|
32
34
|
|
33
35
|
def filename
|
34
|
-
"#{graph_name(versions.join("-"))}.png"
|
36
|
+
"#{graph_name(@type, versions.join("-"))}.png"
|
35
37
|
end
|
36
38
|
|
37
39
|
def absolute_filename
|
@@ -63,9 +65,10 @@ class GruffBuilder
|
|
63
65
|
FileUtils.mkdir_p(File.expand_path(absolute_destination))
|
64
66
|
end
|
65
67
|
|
66
|
-
def graph_name(append_text = nil)
|
68
|
+
def graph_name(prepend_text = nil, append_text = nil)
|
69
|
+
prepend_text = prepend_text.nil? ? "" : "#{prepend_text}-"
|
67
70
|
append_text = append_text.nil? ? "" : "-#{append_text}"
|
68
|
-
"#{gem_name}"+ append_text
|
71
|
+
prepend_text + "#{gem_name}"+ append_text
|
69
72
|
end
|
70
73
|
|
71
74
|
def gruff
|
data/lib/gem_velocity/helpers.rb
CHANGED
@@ -10,4 +10,30 @@ module Helpers
|
|
10
10
|
Date.parse(whatever.to_s).strftime("%Y-%m-%d")
|
11
11
|
end
|
12
12
|
|
13
|
+
def earliest_for(whatevers)
|
14
|
+
whatevers = whatevers.map{|s| Date.parse(s) } if whatevers.first.is_a?(String)
|
15
|
+
time_format_str(whatevers.sort.first)
|
16
|
+
end
|
17
|
+
|
18
|
+
def latest_for(whatevers)
|
19
|
+
whatevers = whatevers.map{|s| Date.parse(s) } if whatevers.first.is_a?(String)
|
20
|
+
time_format_str(whatevers.sort.last)
|
21
|
+
end
|
22
|
+
|
23
|
+
def compute_day_range_from_start_end(s,e)
|
24
|
+
all_days = []
|
25
|
+
s = Date.parse(s)
|
26
|
+
e = Date.parse(e)
|
27
|
+
i = s
|
28
|
+
while (i <= e )
|
29
|
+
all_days << i
|
30
|
+
i += 1.day
|
31
|
+
end
|
32
|
+
all_days.map{|d| time_format_str_small(d)}
|
33
|
+
end
|
34
|
+
|
35
|
+
def remove_trailing_x(str)
|
36
|
+
str.gsub(/[xX]$/,"")
|
37
|
+
end
|
38
|
+
|
13
39
|
end
|
@@ -1,10 +1,18 @@
|
|
1
1
|
class AggregatedVelocitator < BaseVelocitator
|
2
2
|
|
3
|
+
# TODO can probably get rid of this
|
3
4
|
attr_reader :aggregated_versions
|
5
|
+
|
6
|
+
# the one with the wildcard
|
7
|
+
attr_reader :version
|
8
|
+
|
9
|
+
# all of the ones matched, aggregated_versions
|
10
|
+
attr_reader :versions
|
11
|
+
|
4
12
|
def initialize(gem_name, top_level_ver)
|
5
13
|
@gem_name = gem_name
|
6
|
-
@
|
7
|
-
@aggregated_versions = gem_data.versions.select{|v| v.match(/^#{Regexp.escape(top_level_ver)}/) }
|
14
|
+
@version = top_level_ver #with a wildcard/x
|
15
|
+
@versions = @aggregated_versions = gem_data.versions.select{|v| v.match(/^#{Regexp.escape(remove_trailing_x(top_level_ver))}/) }
|
8
16
|
super(gem_name, @aggregated_versions)
|
9
17
|
end
|
10
18
|
|
@@ -16,29 +24,29 @@ class AggregatedVelocitator < BaseVelocitator
|
|
16
24
|
base_max_for(@aggregated_versions) * @aggregated_versions.size
|
17
25
|
end
|
18
26
|
|
19
|
-
def
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
:hide_legend => true
|
27
|
-
}
|
28
|
-
end
|
27
|
+
def line_data(start_t = nil, end_t = nil)
|
28
|
+
range = nil
|
29
|
+
if start_t && end_t
|
30
|
+
range = compute_day_range_from_start_end(start_t,end_t)
|
31
|
+
else
|
32
|
+
range = effective_days_in_range
|
33
|
+
end
|
29
34
|
|
30
|
-
def line_datas
|
31
35
|
ret = Hash.new(0)
|
32
36
|
@aggregated_versions.each do |v|
|
33
|
-
|
37
|
+
range.each do |d|
|
34
38
|
ret[d] += downloads_per_day(v)[d] || 0
|
35
39
|
end
|
36
40
|
end
|
37
|
-
|
41
|
+
range.map{|d| ret[d] }
|
38
42
|
end
|
39
43
|
|
40
44
|
def title
|
41
|
-
"#{@gem_name}: #{@
|
45
|
+
"#{@gem_name}: #{@version}\n(downloads: #{num_downloads})"
|
46
|
+
end
|
47
|
+
|
48
|
+
def hide_legend?
|
49
|
+
true
|
42
50
|
end
|
43
51
|
|
44
52
|
end
|
@@ -10,9 +10,27 @@ class BaseVelocitator
|
|
10
10
|
|
11
11
|
attr_accessor :gem_name, :versions
|
12
12
|
|
13
|
-
def
|
13
|
+
def self.create(options)
|
14
|
+
Factory.new(options).velocitator
|
15
|
+
end
|
16
|
+
|
17
|
+
def graph(root_arg = root, range = effective_date_range, min = effective_min_value, max = effective_max_value)
|
14
18
|
set_overwritable_attrs(root_arg,range,min,max)
|
15
|
-
gruff_builder.write
|
19
|
+
file = gruff_builder(root, graph_options).write
|
20
|
+
puts "Wrote graph to #{file}"
|
21
|
+
file
|
22
|
+
end
|
23
|
+
|
24
|
+
def graph_options
|
25
|
+
opts = {
|
26
|
+
:title => title,
|
27
|
+
:labels => ({1 => time_format_str_small(effective_start_time), (line_datas.first.size-2) => time_format_str_small(effective_end_time) }),
|
28
|
+
:max_value => effective_max_value,
|
29
|
+
:min_value => effective_min_value,
|
30
|
+
:line_datas => line_datas,
|
31
|
+
:hide_legend => hide_legend?,
|
32
|
+
:type => self.class.to_s
|
33
|
+
}
|
16
34
|
end
|
17
35
|
|
18
36
|
# modifiers on the end result image being rendered. Essentially these are the boundries
|
@@ -25,6 +43,13 @@ class BaseVelocitator
|
|
25
43
|
|
26
44
|
def effective_date_range
|
27
45
|
@passed_date_range || default_date_range
|
46
|
+
end
|
47
|
+
# some sugar
|
48
|
+
def effective_start_time; effective_date_range.first ;end
|
49
|
+
def effective_end_time; effective_date_range.last ;end
|
50
|
+
|
51
|
+
def effective_days_in_range
|
52
|
+
compute_day_range_from_start_end(effective_start_time,effective_end_time)
|
28
53
|
end
|
29
54
|
|
30
55
|
def effective_max_value
|
@@ -46,6 +71,11 @@ class BaseVelocitator
|
|
46
71
|
ActiveSupport::NumberHelper.number_to_delimited(sum)
|
47
72
|
end
|
48
73
|
|
74
|
+
def time_built(version)
|
75
|
+
gem_data.versions_built_at[version]
|
76
|
+
end
|
77
|
+
alias :built_at :time_built
|
78
|
+
|
49
79
|
private
|
50
80
|
|
51
81
|
def initialize(gem_name, versions)
|
@@ -57,7 +87,7 @@ class BaseVelocitator
|
|
57
87
|
|
58
88
|
def validate_correct_versions
|
59
89
|
versions.each do |v|
|
60
|
-
gem_data.versions.include?(v) || raise(NoSuchVersion,"version not found for #{
|
90
|
+
gem_data.versions.include?(v) || raise(NoSuchVersion,"version #{v} not found for #{gem_name}.")
|
61
91
|
end
|
62
92
|
end
|
63
93
|
|
@@ -85,12 +115,14 @@ class BaseVelocitator
|
|
85
115
|
0
|
86
116
|
end
|
87
117
|
|
88
|
-
def
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
118
|
+
def line_datas
|
119
|
+
# aggregated and single are both just one, just line_data, but default to this
|
120
|
+
# because of the multiplexer, since it does have line_datas
|
121
|
+
[line_data]
|
122
|
+
end
|
123
|
+
|
124
|
+
def versions_for_legends
|
125
|
+
[version]
|
94
126
|
end
|
95
127
|
|
96
128
|
def base_earliest_time_for(verzionz)
|
@@ -106,11 +138,7 @@ class BaseVelocitator
|
|
106
138
|
totals.flatten.compact.max
|
107
139
|
end
|
108
140
|
|
109
|
-
|
110
|
-
# returns # "2013-10-10" => 45
|
111
|
-
accumulated_downloads_per_day(version)
|
112
|
-
end
|
113
|
-
|
141
|
+
# returns # "2013-10-10" => 45
|
114
142
|
def accumulated_downloads_per_day(version)
|
115
143
|
# downloads_metadata comes back ordered by date
|
116
144
|
ret = Hash.new(0)
|
@@ -123,37 +151,15 @@ class BaseVelocitator
|
|
123
151
|
end
|
124
152
|
ret
|
125
153
|
end
|
126
|
-
|
127
|
-
# a little sugar
|
128
|
-
def effective_start_time; effective_date_range.first ;end
|
129
|
-
def effective_end_time; effective_date_range.last ;end
|
130
|
-
|
131
|
-
# helper method to convert [start,end] into a
|
132
|
-
# start..end range of days like "2013-10-10"
|
133
|
-
def effective_days_in_range
|
134
|
-
all_days = []
|
135
|
-
s = Date.parse(effective_start_time)
|
136
|
-
e = Date.parse(effective_end_time)
|
137
|
-
i = s
|
138
|
-
while (i <= e )
|
139
|
-
all_days << i
|
140
|
-
i += 1.day
|
141
|
-
end
|
142
|
-
all_days.map{|d| time_format_str_small(d)}
|
143
|
-
end
|
154
|
+
alias :downloads_per_day :accumulated_downloads_per_day
|
144
155
|
|
145
156
|
def gem_data
|
146
157
|
# need this memoized so the gem_data memoization works for the same instance
|
147
158
|
@gem_data ||= GemData.new(@gem_name)
|
148
159
|
end
|
149
160
|
|
150
|
-
def gruff_builder
|
151
|
-
GruffBuilder.new(
|
161
|
+
def gruff_builder(path,graph_opts)
|
162
|
+
GruffBuilder.new(path || Dir.pwd, nil, versions_for_legends, gem_name, graph_opts)
|
152
163
|
end
|
153
164
|
|
154
|
-
# it's just shorter syntax
|
155
|
-
def time_built(version)
|
156
|
-
gem_data.versions_built_at[version]
|
157
|
-
end
|
158
|
-
|
159
165
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
class Factory
|
2
|
+
|
3
|
+
include Helpers
|
4
|
+
|
5
|
+
attr_reader :gem_name, :version, :versions, :type
|
6
|
+
|
7
|
+
def initialize(options)
|
8
|
+
|
9
|
+
# one ver passed
|
10
|
+
if options[:gem_name] && options[:version]
|
11
|
+
@gem_name = options[:gem_name]
|
12
|
+
@version = options[:version]
|
13
|
+
@type = type_from_version(@version)
|
14
|
+
@versions = self.velocitator.versions
|
15
|
+
elsif options[:full_name]
|
16
|
+
@gem_name = name_from_full_name(options[:full_name])
|
17
|
+
@version = version_from_full_name(options[:full_name])
|
18
|
+
@type = type_from_version(@version)
|
19
|
+
@versions = self.velocitator.versions
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def velocitator
|
24
|
+
if @type == :aggregated
|
25
|
+
AggregatedVelocitator.new(@gem_name, @version)
|
26
|
+
elsif @type == :single
|
27
|
+
SingleVelocitator.new(@gem_name, @version)
|
28
|
+
else
|
29
|
+
raise 'no velocitor found to generate!'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def name_from_full_name(str)
|
36
|
+
str.split("-")[0..-2].join("-")
|
37
|
+
end
|
38
|
+
|
39
|
+
def version_from_full_name(str)
|
40
|
+
str.split("-").last
|
41
|
+
end
|
42
|
+
|
43
|
+
def type_from_version(str)
|
44
|
+
if str.last.downcase == "x"
|
45
|
+
:aggregated
|
46
|
+
else
|
47
|
+
:single
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
@@ -0,0 +1,65 @@
|
|
1
|
+
class Multiplexer < BaseVelocitator
|
2
|
+
|
3
|
+
include ::Helpers
|
4
|
+
attr_reader :velocitators
|
5
|
+
|
6
|
+
def initialize(velocitators)
|
7
|
+
@velocitators = velocitators
|
8
|
+
# TODO what if there are multiple gem_names being multiplexed?
|
9
|
+
super(velocitators.first.gem_name, velocitators.map(&:versions).flatten)
|
10
|
+
end
|
11
|
+
|
12
|
+
def version
|
13
|
+
raise "The multiplexer does not have a single version. try @versions."
|
14
|
+
end
|
15
|
+
|
16
|
+
def root
|
17
|
+
velocitator_with_root = velocitators.detect{|v| v.root }
|
18
|
+
if velocitator_with_root
|
19
|
+
velocitator_with_root.root
|
20
|
+
else
|
21
|
+
Dir.pwd
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def default_start
|
26
|
+
earliest_for(velocitators.map(&:effective_start_time))
|
27
|
+
end
|
28
|
+
|
29
|
+
def effective_end_time
|
30
|
+
latest_for(velocitators.map(&:effective_end_time))
|
31
|
+
end
|
32
|
+
|
33
|
+
def effective_min_value
|
34
|
+
velocitators.map(&:effective_min_value).min
|
35
|
+
end
|
36
|
+
|
37
|
+
def effective_max_value
|
38
|
+
velocitators.map(&:effective_max_value).max
|
39
|
+
end
|
40
|
+
|
41
|
+
def line_datas
|
42
|
+
velocitators.map do |velocitator|
|
43
|
+
velocitator.line_data(effective_start_time, effective_end_time)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def hide_legend?
|
48
|
+
false
|
49
|
+
end
|
50
|
+
|
51
|
+
def versions_for_legends
|
52
|
+
velocitators.map(&:version)
|
53
|
+
end
|
54
|
+
|
55
|
+
def title
|
56
|
+
"Composite: #{gem_names}"
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def gem_names
|
62
|
+
velocitators.map(&:gem_name).sort.uniq.join(" ")
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
class SingleVelocitator < BaseVelocitator
|
2
2
|
|
3
|
+
# the one passed in
|
4
|
+
# for :versions, it's just [version]
|
3
5
|
attr_reader :version
|
4
6
|
|
5
7
|
def initialize(gem_name, version)
|
@@ -19,24 +21,30 @@ class SingleVelocitator < BaseVelocitator
|
|
19
21
|
accumulated_downloads_per_day(@version).map {|day,total| total}.max
|
20
22
|
end
|
21
23
|
|
22
|
-
def
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
def line_datas
|
35
|
-
default_line_datas
|
24
|
+
def line_data(start_t = nil, end_t = nil)
|
25
|
+
range = nil
|
26
|
+
if start_t && end_t
|
27
|
+
range = compute_day_range_from_start_end(start_t,end_t)
|
28
|
+
else
|
29
|
+
range = effective_days_in_range
|
30
|
+
end
|
31
|
+
|
32
|
+
range.map do |d|
|
33
|
+
downloads_per_day(version)[d] || 0
|
34
|
+
end
|
36
35
|
end
|
37
36
|
|
38
37
|
def title
|
39
38
|
"#{gem_name}-#{version}\n(downloads: #{num_downloads})"
|
40
39
|
end
|
41
40
|
|
41
|
+
def time_built
|
42
|
+
super(@version)
|
43
|
+
end
|
44
|
+
|
45
|
+
def hide_legend?
|
46
|
+
true
|
47
|
+
end
|
48
|
+
|
49
|
+
|
42
50
|
end
|
data/lib/gem_velocity/version.rb
CHANGED