neutrino_client 0.0.3 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/neutrino/metric.rb +7 -4
- data/lib/neutrino/munin_metric.rb +21 -5
- data/lib/neutrino/reporter.rb +12 -30
- data/lib/neutrino/shell_metric.rb +14 -6
- data/lib/neutrino/version.rb +1 -1
- data/test/cli_test.rb +1 -1
- data/test/config_test.rb +1 -1
- data/test/metric_test.rb +42 -15
- data/test/munin_metric_test.rb +41 -4
- data/test/reporter_test.rb +5 -10
- data/test/shell_metric_test.rb +29 -8
- metadata +4 -4
data/lib/neutrino/metric.rb
CHANGED
@@ -10,11 +10,10 @@ module Neutrino
|
|
10
10
|
property :group
|
11
11
|
property :type
|
12
12
|
property :name
|
13
|
-
property :
|
13
|
+
property :values
|
14
14
|
property :display_options
|
15
15
|
|
16
16
|
def metric_id
|
17
|
-
raise StandardError.new("Requires name and hostname") unless name && hostname
|
18
17
|
Digest::MD5.hexdigest("#{name}#{hostname}")
|
19
18
|
end
|
20
19
|
|
@@ -23,15 +22,19 @@ module Neutrino
|
|
23
22
|
end
|
24
23
|
|
25
24
|
def to_h
|
25
|
+
raise StandardError.new("Requires name") unless name
|
26
|
+
raise StandardError.new("Requires values") unless values
|
27
|
+
raise StandardError.new("Requires hostname") unless hostname
|
26
28
|
{
|
27
29
|
:metadata => (base_metadata || {}).merge({
|
28
30
|
:name => self.name,
|
29
31
|
:group => self.group,
|
30
|
-
:type => self.type
|
32
|
+
:type => self.type,
|
33
|
+
:hostname => self.hostname
|
31
34
|
}),
|
32
35
|
:display_options => self.display_options,
|
33
36
|
:name => self.metric_id,
|
34
|
-
:
|
37
|
+
:values => self.values || {}
|
35
38
|
}
|
36
39
|
end
|
37
40
|
end
|
@@ -8,7 +8,7 @@ module Neutrino
|
|
8
8
|
def initialize(opts={})
|
9
9
|
super(opts)
|
10
10
|
configure
|
11
|
-
|
11
|
+
query
|
12
12
|
end
|
13
13
|
|
14
14
|
def self.execute_and_parse(command)
|
@@ -16,9 +16,16 @@ module Neutrino
|
|
16
16
|
stdout.read.strip
|
17
17
|
end
|
18
18
|
result = {}
|
19
|
-
|
19
|
+
Log.debug("#{command} outputs #{output}")
|
20
|
+
output.to_s.split("\n").each do |line|
|
20
21
|
whole_line, key, value = line.match(/(\S*) (.*)/).to_a
|
21
|
-
|
22
|
+
key = line.strip if key.nil? # Can be nil if no value is specified
|
23
|
+
key_parts = nil
|
24
|
+
if key.match("graph_")
|
25
|
+
key_parts = key.split(/_/)
|
26
|
+
else
|
27
|
+
key_parts = key.split(/\./)
|
28
|
+
end
|
22
29
|
if key_parts.length == 2
|
23
30
|
result[key_parts.first] ||= {}
|
24
31
|
result[key_parts.first][key_parts.last] = value
|
@@ -26,6 +33,7 @@ module Neutrino
|
|
26
33
|
result[key_parts.first] = value
|
27
34
|
end
|
28
35
|
end
|
36
|
+
Log.debug("#{command} output is parsed as #{result.inspect}")
|
29
37
|
result
|
30
38
|
end
|
31
39
|
|
@@ -44,14 +52,22 @@ module Neutrino
|
|
44
52
|
self.base_metadata["group"] = plugin_configuration["graph"]["category"]
|
45
53
|
self.base_metadata["type"] = plugin_configuration["graph"]["vlabel"]
|
46
54
|
self.base_metadata["name"] = plugin_configuration["graph"]["title"]
|
55
|
+
self.name = plugin_configuration["graph"]["title"]
|
47
56
|
end
|
48
57
|
end
|
49
58
|
|
50
59
|
def query
|
51
60
|
plugin_query = MuninMetric.query_plugin(self.munin_plugin_path)
|
52
61
|
begin
|
53
|
-
|
54
|
-
|
62
|
+
values_hash = {}
|
63
|
+
plugin_query.to_a.each do |metric|
|
64
|
+
name = metric[0]
|
65
|
+
val = metric[1]["value"]
|
66
|
+
values_hash[name] = val.nil? ? nil : val.to_f
|
67
|
+
end
|
68
|
+
self.values = values_hash
|
69
|
+
rescue => e
|
70
|
+
Log.debug("Error querying munin: #{e}")
|
55
71
|
end
|
56
72
|
end
|
57
73
|
|
data/lib/neutrino/reporter.rb
CHANGED
@@ -6,60 +6,46 @@ module Neutrino
|
|
6
6
|
|
7
7
|
def self.record(metric)
|
8
8
|
Log.info("Recording: #{metric.to_json}")
|
9
|
-
HTTParty.post('http://neutrino2.heroku.com/record', :body => metric.
|
10
|
-
|
9
|
+
response = HTTParty.post('http://neutrino2.heroku.com/record', :body => metric.to_h)
|
10
|
+
Log.debug "Response: body=#{response.body} code=#{response.code} message=#{response.message} headers=#{response.headers.inspect}"
|
11
11
|
end
|
12
12
|
|
13
13
|
def self.get_metrics
|
14
14
|
ms = [
|
15
|
-
ShellMetric.new({
|
16
|
-
:name => "CPU Steal",
|
17
|
-
:command => "iostat | grep -A1 avg-cpu | tail -1 | awk '{print $5}'",
|
18
|
-
:group => "system",
|
19
|
-
:type => "CPU"
|
20
|
-
}),
|
21
15
|
ShellMetric.new({
|
22
16
|
:name => "User CPU",
|
23
|
-
:
|
17
|
+
:commands => {:user => "iostat | grep -A1 avg-cpu | tail -1 | awk '{print $1}'"},
|
24
18
|
:group => "system",
|
25
19
|
:type => "CPU",
|
26
20
|
:display_options => {:min => 0, :max => 1}
|
27
21
|
}),
|
28
22
|
ShellMetric.new({
|
29
23
|
:name => "Idle CPU",
|
30
|
-
:
|
24
|
+
:commands => {:idle => "iostat | grep -A1 avg-cpu | tail -1 | awk '{print $6}'"},
|
31
25
|
:group => "system",
|
32
26
|
:type => "CPU",
|
33
27
|
:display_options => {:min => 0, :max => 100}
|
34
28
|
}),
|
35
29
|
ShellMetric.new({
|
36
30
|
:name => "Free Memory",
|
37
|
-
:
|
31
|
+
:commands => {:free => "cat /proc/meminfo | grep 'MemFree' | awk '{print $2}'"},
|
38
32
|
:group => "system",
|
39
33
|
:type => 'memory'
|
40
34
|
# :display_options => {:min => 0, :max => ShellMetric.execute("cat /proc/meminfo | grep 'MemTotal' | awk '{print $2}'")}
|
41
35
|
}),
|
42
|
-
ShellMetric.new({
|
43
|
-
:name => "Load Avg (1m)",
|
44
|
-
:command => "cat /proc/loadavg | awk '{print $1}'",
|
45
|
-
:group => "system",
|
46
|
-
:type => 'load'
|
47
|
-
}),
|
48
|
-
ShellMetric.new({
|
49
|
-
:name => "Load Avg (5m)",
|
50
|
-
:command => "cat /proc/loadavg | awk '{print $2}'",
|
51
|
-
:group => "system",
|
52
|
-
:type => 'load'
|
53
|
-
}),
|
54
36
|
ShellMetric.new({
|
55
37
|
:name => "Load Avg (15m)",
|
56
|
-
:
|
38
|
+
:commands => {
|
39
|
+
"1_min" => "cat /proc/loadavg | awk '{print $1}'",
|
40
|
+
"5_min" => "cat /proc/loadavg | awk '{print $2}'",
|
41
|
+
"15_min" => "cat /proc/loadavg | awk '{print $3}'",
|
42
|
+
},
|
57
43
|
:group => "system",
|
58
44
|
:type => 'load'
|
59
45
|
}),
|
60
46
|
ShellMetric.new({
|
61
47
|
:name => "Process Count",
|
62
|
-
:
|
48
|
+
:commands => {:processes => "ps aux | wc -l"},
|
63
49
|
:group => "system",
|
64
50
|
:type => 'process'
|
65
51
|
})
|
@@ -72,11 +58,7 @@ module Neutrino
|
|
72
58
|
get_metrics.each do |m|
|
73
59
|
m.hostname = `hostname`.strip
|
74
60
|
m.base_metadata = Config.metadata
|
75
|
-
|
76
|
-
Reporter.record(m)
|
77
|
-
rescue StandardError => e
|
78
|
-
Log.warn("Error running '#{m.name}': #{e}")
|
79
|
-
end
|
61
|
+
Reporter.record(m)
|
80
62
|
end
|
81
63
|
end
|
82
64
|
end
|
@@ -3,20 +3,28 @@ require 'open3'
|
|
3
3
|
module Neutrino
|
4
4
|
module Client
|
5
5
|
class ShellMetric < Metric
|
6
|
-
property :
|
6
|
+
property :commands
|
7
|
+
|
8
|
+
def initialize(opts={})
|
9
|
+
super(opts)
|
10
|
+
query
|
11
|
+
end
|
7
12
|
|
8
13
|
def self.execute(command)
|
9
14
|
parsed_value = Open3.popen3(command) do |stdin, stdout, stderr, wait_thr|
|
10
15
|
stdout.read.strip
|
11
16
|
end
|
12
|
-
|
17
|
+
Log.debug("'#{command}' outputs '#{parsed_value}'")
|
18
|
+
Log.warn("'#{command}' outputs '#{parsed_value}'") if parsed_value.nil? || parsed_value.empty?
|
13
19
|
return parsed_value
|
14
20
|
end
|
15
21
|
|
16
|
-
def
|
17
|
-
|
18
|
-
|
19
|
-
|
22
|
+
def query
|
23
|
+
values_hash = {}
|
24
|
+
self.commands.each_pair do |name, cmd|
|
25
|
+
values_hash[name] = ShellMetric.execute(cmd)
|
26
|
+
end
|
27
|
+
self.values = values_hash
|
20
28
|
end
|
21
29
|
end
|
22
30
|
end
|
data/lib/neutrino/version.rb
CHANGED
data/test/cli_test.rb
CHANGED
data/test/config_test.rb
CHANGED
data/test/metric_test.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require "neutrino/client"
|
1
|
+
require "lib/neutrino/client"
|
2
2
|
require "test/unit"
|
3
3
|
require 'mocha'
|
4
4
|
|
@@ -17,7 +17,7 @@ module Neutrino
|
|
17
17
|
def test_metric_attributes
|
18
18
|
attrs = {
|
19
19
|
:name => "Load Avg (15m)",
|
20
|
-
:
|
20
|
+
:values => {:myval => 747},
|
21
21
|
:group => "system",
|
22
22
|
:type => 'load',
|
23
23
|
:display_options => {:width => 100}
|
@@ -26,7 +26,8 @@ module Neutrino
|
|
26
26
|
assert_equal metric.group, attrs[:group]
|
27
27
|
assert_equal metric.type, attrs[:type]
|
28
28
|
assert_equal metric.name, attrs[:name]
|
29
|
-
assert_equal metric.
|
29
|
+
assert_equal metric.values, attrs[:values]
|
30
|
+
assert_equal metric.values[:myval], attrs[:values][:myval]
|
30
31
|
assert_equal metric.display_options, attrs[:display_options]
|
31
32
|
end
|
32
33
|
|
@@ -51,16 +52,6 @@ module Neutrino
|
|
51
52
|
assert_equal metric.metric_id, Digest::MD5.hexdigest("#{name}#{hostname}")
|
52
53
|
end
|
53
54
|
|
54
|
-
def test_metric_id_raises_without_hostname
|
55
|
-
metric = Metric.new(:name => "a_metric")
|
56
|
-
assert_raises(StandardError){ metric.metric_id }
|
57
|
-
end
|
58
|
-
|
59
|
-
def test_metric_id_raises_without_hostname
|
60
|
-
metric = Metric.new(:hostname => "a_metric.com")
|
61
|
-
assert_raises(StandardError){ metric.metric_id }
|
62
|
-
end
|
63
|
-
|
64
55
|
def test_to_json_calls_to_h
|
65
56
|
metric = Metric.new(:hostname => "a_metric.com", :name => "asdf")
|
66
57
|
metric.expects(:to_h)
|
@@ -70,7 +61,7 @@ module Neutrino
|
|
70
61
|
def test_metric_to_h
|
71
62
|
attrs = {
|
72
63
|
:name => "Load Avg (15m)",
|
73
|
-
:
|
64
|
+
:values => {:bval => 0.11},
|
74
65
|
:group => "system",
|
75
66
|
:type => 'load',
|
76
67
|
:display_options => {:width => 100}
|
@@ -84,10 +75,46 @@ module Neutrino
|
|
84
75
|
assert_equal result[:metadata][:name], attrs[:name]
|
85
76
|
assert_equal result[:metadata][:group], attrs[:group]
|
86
77
|
assert_equal result[:metadata][:type], attrs[:type]
|
78
|
+
assert_equal result[:metadata][:hostname], metric.hostname
|
87
79
|
assert_equal result[:display_options], attrs[:display_options]
|
88
|
-
assert_equal result[:
|
80
|
+
assert_equal result[:values][:bval], 0.11
|
89
81
|
assert_equal result[:name], metric.metric_id
|
90
82
|
end
|
83
|
+
|
84
|
+
def test_metric_to_h_raises_without_hostname
|
85
|
+
attrs = {
|
86
|
+
:name => "Load Avg (15m)",
|
87
|
+
:values => {:bval => 0.11},
|
88
|
+
:group => "system",
|
89
|
+
:type => 'load',
|
90
|
+
:display_options => {:width => 100}
|
91
|
+
}
|
92
|
+
metric = Metric.new(attrs)
|
93
|
+
assert_raises(StandardError){ metric.to_h }
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_metric_to_h_raises_without_name
|
97
|
+
attrs = {
|
98
|
+
:values => {:bval => 0.11},
|
99
|
+
:group => "system",
|
100
|
+
:type => 'load',
|
101
|
+
:display_options => {:width => 100}
|
102
|
+
}
|
103
|
+
metric = Metric.new(attrs)
|
104
|
+
assert_raises(StandardError){ metric.to_h }
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_metric_to_h_raises_without_values
|
108
|
+
attrs = {
|
109
|
+
:name => "Load Avg (15m)",
|
110
|
+
:group => "system",
|
111
|
+
:type => 'load',
|
112
|
+
:display_options => {:width => 100}
|
113
|
+
}
|
114
|
+
metric = Metric.new(attrs)
|
115
|
+
assert_raises(StandardError){ metric.to_h }
|
116
|
+
end
|
117
|
+
|
91
118
|
end
|
92
119
|
end
|
93
120
|
end
|
data/test/munin_metric_test.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require "neutrino/client"
|
1
|
+
require "lib/neutrino/client"
|
2
2
|
require "test/unit"
|
3
3
|
require 'mocha'
|
4
4
|
|
@@ -11,6 +11,7 @@ module Neutrino
|
|
11
11
|
|
12
12
|
def test_properties
|
13
13
|
path = "/path/to/plugin"
|
14
|
+
Open3.stubs(:popen3)
|
14
15
|
m = MuninMetric.new(:munin_plugin_path => path)
|
15
16
|
assert_equal m.munin_plugin_path, path
|
16
17
|
end
|
@@ -42,8 +43,9 @@ module Neutrino
|
|
42
43
|
assert_equal m["load"]["value"], "0.17"
|
43
44
|
end
|
44
45
|
|
45
|
-
def
|
46
|
+
def test_configuring_sets_base_metadata
|
46
47
|
path = "/some_plugin"
|
48
|
+
Open3.stubs(:popen3).with("#{path}")
|
47
49
|
Open3.expects(:popen3).with("#{path} config").returns("graph_title Load average\ngraph_args --base 1000 -l 0\ngraph_vlabel load\ngraph_scale no\ngraph_category system\nload.label load\nload.warning 10\nload.critical 120\ngraph_info The load average of the machine describes how many processes are in the run-queue (scheduled to run \"immediately\").\nload.info Average load for the five minutes.\n")
|
48
50
|
m = MuninMetric.new(:munin_plugin_path => path)
|
49
51
|
assert_equal m.base_metadata["group"], "system"
|
@@ -51,13 +53,48 @@ module Neutrino
|
|
51
53
|
assert_equal m.base_metadata["name"], "Load average"
|
52
54
|
end
|
53
55
|
|
56
|
+
def test_can_handle_memory_output
|
57
|
+
path = "/some_plugin"
|
58
|
+
output = "swap_cache.value 0\nswap.value 0\n"
|
59
|
+
Open3.stubs(:popen3).with("#{path} config").returns("")
|
60
|
+
Open3.stubs(:popen3).with("#{path}").returns(output)
|
61
|
+
m = MuninMetric.new(:munin_plugin_path => path)
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_can_handle_multiple_values
|
65
|
+
path = "/some_plugin"
|
66
|
+
output = "swap_cache.value 33\nswap.value 44\n"
|
67
|
+
Open3.stubs(:popen3).with("#{path} config").returns("")
|
68
|
+
Open3.stubs(:popen3).with("#{path}").returns(output)
|
69
|
+
m = MuninMetric.new(:munin_plugin_path => path)
|
70
|
+
assert_equal m.values["swap_cache"], 33
|
71
|
+
assert_equal m.values["swap"], 44
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_can_handle_no_values
|
75
|
+
path = "/some_plugin"
|
76
|
+
output = "swap_cache.value\nswap.value 44\n"
|
77
|
+
Open3.stubs(:popen3).with("#{path} config").returns("")
|
78
|
+
Open3.stubs(:popen3).with("#{path}").returns(output)
|
79
|
+
m = MuninMetric.new(:munin_plugin_path => path)
|
80
|
+
assert_equal m.values["swap_cache"], nil
|
81
|
+
assert m.values.keys.include? "swap_cache"
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_instanciation_configures_and_queries
|
85
|
+
path = "/some_plugin"
|
86
|
+
Open3.stubs(:popen3).with("#{path}")
|
87
|
+
Open3.expects(:popen3).with("#{path} config")
|
88
|
+
MuninMetric.new(:munin_plugin_path => path)
|
89
|
+
end
|
90
|
+
|
54
91
|
def test_query
|
55
92
|
path = "/some_plugin"
|
56
93
|
Open3.expects(:popen3).with("#{path} config").returns("")
|
57
94
|
Open3.expects(:popen3).with(path).returns("load.value 123\n")
|
58
95
|
m = MuninMetric.new(:munin_plugin_path => path)
|
59
|
-
m.
|
60
|
-
assert_equal m.
|
96
|
+
assert m.values.keys.include? "load"
|
97
|
+
assert_equal m.values["load"], 123
|
61
98
|
end
|
62
99
|
end
|
63
100
|
end
|
data/test/reporter_test.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require "neutrino/client"
|
1
|
+
require "lib/neutrino/client"
|
2
2
|
require "test/unit"
|
3
3
|
require 'mocha'
|
4
4
|
require 'fakeweb'
|
@@ -12,6 +12,7 @@ module Neutrino
|
|
12
12
|
ShellMetric.stubs(:execute).returns(3.14159)
|
13
13
|
|
14
14
|
FakeWeb.allow_net_connect = false
|
15
|
+
FakeWeb.register_uri(:post, %r|neutrino2\.heroku\.com/|, :body => "{ok:1}")
|
15
16
|
end
|
16
17
|
|
17
18
|
def test_reporter_should_call_record_one_per_metric
|
@@ -20,17 +21,11 @@ module Neutrino
|
|
20
21
|
Reporter.report
|
21
22
|
end
|
22
23
|
|
23
|
-
def test_reporter_swallows_errors_and_logs_warnings
|
24
|
-
Open3.stubs(:popen3).returns('')
|
25
|
-
metrics = Reporter.get_metrics
|
26
|
-
Log.expects(:warn).times(metrics.length)
|
27
|
-
Reporter.report
|
28
|
-
end
|
29
|
-
|
30
24
|
def test_reporter_adds_munin_plugins
|
25
|
+
dummy_metric = Metric.new(:name => "a", :hostname => 'asdf', :values => {:a => 1})
|
31
26
|
Dir.expects(:glob).with("/somedir/*").returns(["/path1", "/path2"])
|
32
|
-
MuninMetric.expects(:new).with(:munin_plugin_path => "/path1").returns(
|
33
|
-
MuninMetric.expects(:new).with(:munin_plugin_path => "/path2").returns(
|
27
|
+
MuninMetric.expects(:new).with(:munin_plugin_path => "/path1").returns(dummy_metric)
|
28
|
+
MuninMetric.expects(:new).with(:munin_plugin_path => "/path2").returns(dummy_metric)
|
34
29
|
Config.munin_plugin_globs "/somedir/*"
|
35
30
|
Reporter.report
|
36
31
|
end
|
data/test/shell_metric_test.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require "neutrino/client"
|
1
|
+
require "lib/neutrino/client"
|
2
2
|
require "test/unit"
|
3
3
|
require 'mocha'
|
4
4
|
|
@@ -9,22 +9,43 @@ module Neutrino
|
|
9
9
|
Config.defaults!
|
10
10
|
end
|
11
11
|
|
12
|
+
def test_initialization_calls_query
|
13
|
+
ShellMetric.expects(:execute).with("somecmd").returns(100)
|
14
|
+
m = ShellMetric.new(:commands => {:myval => "somecmd"})
|
15
|
+
end
|
16
|
+
|
12
17
|
def test_execute_calculates_value
|
13
18
|
cmd = "ps aux | wc -l"
|
14
|
-
m = ShellMetric.new(:command => cmd)
|
15
19
|
ShellMetric.expects(:execute).with(cmd)
|
16
|
-
m.
|
20
|
+
m = ShellMetric.new(:commands => {:myval => cmd})
|
17
21
|
end
|
18
22
|
|
19
|
-
def
|
23
|
+
def test_creates_values_hash
|
24
|
+
ShellMetric.stubs(:execute).with("somecmd").returns(100)
|
25
|
+
ShellMetric.stubs(:execute).with("othercmd").returns(150)
|
26
|
+
m = ShellMetric.new(:commands => {:myval => "somecmd", :bval => "othercmd"})
|
27
|
+
assert_equal m.values[:myval], 100
|
28
|
+
assert_equal m.values[:bval], 150
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_reporter_logs_warnings_for_empty_output
|
32
|
+
cmd = "ps aux | wc -l"
|
33
|
+
Open3.stubs(:popen3).with(cmd).returns("")
|
34
|
+
Log.expects(:warn)
|
35
|
+
ShellMetric.execute(cmd)
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_reporter_logs_debugs
|
20
39
|
cmd = "ps aux | wc -l"
|
21
|
-
Open3.
|
40
|
+
Open3.stubs(:popen3).with(cmd).returns("100")
|
41
|
+
Log.expects(:debug)
|
22
42
|
ShellMetric.execute(cmd)
|
23
43
|
end
|
24
44
|
|
25
|
-
def
|
26
|
-
|
27
|
-
|
45
|
+
def test_executes_command
|
46
|
+
cmd = "ps aux | wc -l"
|
47
|
+
Open3.expects(:popen3).with(cmd).returns("100")
|
48
|
+
ShellMetric.execute(cmd)
|
28
49
|
end
|
29
50
|
end
|
30
51
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: neutrino_client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 21
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 5
|
10
|
+
version: 0.0.5
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Nick Stielau
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-02-
|
18
|
+
date: 2011-02-25 00:00:00 -08:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|