baton 0.4.10 → 0.5.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +1 -0
- data/baton.gemspec +1 -0
- data/lib/baton/configuration.rb +13 -5
- data/lib/baton/service.rb +59 -3
- data/lib/baton/templates/gem/bin/gem-monitor.tt +18 -1
- data/lib/baton/templates/gem/bin/gem.tt +22 -2
- data/lib/baton/templates/gem/config/gem.cfg.tt +3 -0
- data/lib/baton/version.rb +1 -1
- data/spec/baton/configuration_spec.rb +23 -2
- data/spec/fixtures/config.cfg +2 -1
- metadata +115 -34
data/README.md
CHANGED
@@ -62,6 +62,7 @@ Any baton extension should have an executable script that will start the extensi
|
|
62
62
|
### Service
|
63
63
|
|
64
64
|
The Service is the starting point of any baton extension. The idea of the service is to setup consumers for the input messages arriving from the API. By implementing `setup_consumers` one will allow the consumers to receive messages. [Here](https://github.com/digital-science/baton-ping/blob/master/lib/baton/baton-ping.rb) is an example.
|
65
|
+
The service also handles daemonizing for an extension. It will properly detach the process and take care of managing pid files and optionally log files. The configuration for pid and log files is commented out in the sample config.
|
65
66
|
|
66
67
|
### Consumer Manager
|
67
68
|
|
data/baton.gemspec
CHANGED
@@ -16,6 +16,7 @@ Gem::Specification.new do |gem|
|
|
16
16
|
gem.version = Baton::VERSION
|
17
17
|
|
18
18
|
gem.add_runtime_dependency "amqp", "~> 0.9.7"
|
19
|
+
gem.add_runtime_dependency "amq-client", "~> 0.9.9"
|
19
20
|
gem.add_runtime_dependency "eventmachine", "~> 1.0.0"
|
20
21
|
gem.add_runtime_dependency "em-http-request", "1.0.3"
|
21
22
|
gem.add_runtime_dependency "bunny", "~> 0.8.0"
|
data/lib/baton/configuration.rb
CHANGED
@@ -5,7 +5,7 @@ module Baton
|
|
5
5
|
class Configuration
|
6
6
|
include Baton::Logging
|
7
7
|
|
8
|
-
attr_accessor :config, :host, :vhost, :user, :password, :amqp_host_list
|
8
|
+
attr_accessor :config, :host, :vhost, :user, :password, :amqp_host_list, :heartbeat
|
9
9
|
|
10
10
|
def initialize
|
11
11
|
@config = {}
|
@@ -76,9 +76,10 @@ module Baton
|
|
76
76
|
self.host = rabbit_hosts[Kernel.rand(rabbit_hosts.size)]
|
77
77
|
self.amqp_host_list = rabbit_hosts
|
78
78
|
|
79
|
-
self.vhost
|
80
|
-
self.user
|
81
|
-
self.password
|
79
|
+
self.vhost = config["RABBIT_VHOST"]
|
80
|
+
self.user = config["RABBIT_USER"]
|
81
|
+
self.password = config["RABBIT_PASS"]
|
82
|
+
self.heartbeat = config.fetch("RABBIT_HEARTBEAT", 60).to_i
|
82
83
|
end
|
83
84
|
|
84
85
|
# Public: Defines the connection options for RabbitMQ as a Hash.
|
@@ -90,7 +91,14 @@ module Baton
|
|
90
91
|
#
|
91
92
|
# Returns a hash of RabbitMQ connection options.
|
92
93
|
def connection_opts
|
93
|
-
{
|
94
|
+
{
|
95
|
+
:host => host,
|
96
|
+
:vhost => vhost,
|
97
|
+
:user => user,
|
98
|
+
:password => password,
|
99
|
+
:pass => password,
|
100
|
+
:heartbeat => heartbeat
|
101
|
+
}.delete_if{|k,v| v.nil?}
|
94
102
|
end
|
95
103
|
end
|
96
104
|
end
|
data/lib/baton/service.rb
CHANGED
@@ -11,24 +11,80 @@ module Baton
|
|
11
11
|
class Service
|
12
12
|
include Baton::Logging
|
13
13
|
|
14
|
-
attr_accessor :server, :channel
|
14
|
+
attr_accessor :server, :channel, :daemonize
|
15
15
|
|
16
16
|
# Public: Initialize a Service. Sets up a new server for this service.
|
17
|
-
def initialize
|
17
|
+
def initialize(daemonize=false)
|
18
18
|
@server = Baton::Server.new
|
19
|
+
@daemonize = daemonize
|
20
|
+
@pid_file = Baton.configuration.pid_file || "/var/run/baton.pid"
|
21
|
+
Baton::Logging.logger = Baton.configuration.log_file || STDOUT
|
19
22
|
end
|
20
23
|
|
21
24
|
# Public: Method that starts the service.
|
22
25
|
#
|
23
26
|
# Returns nothing.
|
24
|
-
def
|
27
|
+
def go
|
25
28
|
logger.info "Starting Baton v#{Baton::VERSION}"
|
26
29
|
EM.run do
|
30
|
+
Signal.trap('INT') { stop }
|
31
|
+
Signal.trap('TERM'){ stop }
|
27
32
|
@channel = Baton::Channel.new
|
28
33
|
setup_consumers
|
29
34
|
end
|
30
35
|
end
|
31
36
|
|
37
|
+
def run
|
38
|
+
if @daemonize
|
39
|
+
pid = get_pid
|
40
|
+
|
41
|
+
if pid != 0
|
42
|
+
logger.error "Baton is already running! (PID: #{pid})"
|
43
|
+
exit -1
|
44
|
+
end
|
45
|
+
|
46
|
+
pid = fork { go }
|
47
|
+
|
48
|
+
begin
|
49
|
+
File.open(@pid_file, "w") { |f| f.write pid }
|
50
|
+
Process.detach(pid)
|
51
|
+
rescue => exc
|
52
|
+
Process.kill('TERM', pid)
|
53
|
+
logger.error "Couldn't daemonize: #{exc.message}"
|
54
|
+
end
|
55
|
+
else
|
56
|
+
go
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def stop
|
61
|
+
if @daemonize
|
62
|
+
pid = get_pid
|
63
|
+
begin
|
64
|
+
EM.stop
|
65
|
+
rescue
|
66
|
+
end
|
67
|
+
|
68
|
+
if pid != 0
|
69
|
+
Process.kill('HUP', pid.to_i)
|
70
|
+
File.delete(@pid_file)
|
71
|
+
logger.info "Stopped"
|
72
|
+
else
|
73
|
+
logger.warn "Daemon not running"
|
74
|
+
exit -1
|
75
|
+
end
|
76
|
+
else
|
77
|
+
EM.stop
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# Get the PID of the running daemon
|
82
|
+
#
|
83
|
+
# Returns the PID of the daemon
|
84
|
+
def get_pid
|
85
|
+
File.exists?(@pid_file) ? File.read(@pid_file).strip : 0
|
86
|
+
end
|
87
|
+
|
32
88
|
# Public: Method that allows implementations to setup new consumers
|
33
89
|
# depending on their needs. An example would be add a deploy consumer
|
34
90
|
# which will listen to deploy messages. For each consumer, add_consumer
|
@@ -1,9 +1,26 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require "baton/<%= config[:name] %>/<%= config[:name] %>-monitor"
|
4
|
+
require 'optparse'
|
5
|
+
|
6
|
+
cfg = File.expand_path("../../config/<%= config[:name] %>.cfg", __FILE__)
|
7
|
+
|
8
|
+
OptionParser.new do |opt|
|
9
|
+
opt.banner = "Usage: <%= config[:name] %> [OPTIONS]"
|
10
|
+
opt.separator ""
|
11
|
+
opt.separator "Specific options:"
|
12
|
+
opt.on("-c","--config-file [PATH]", "Path to a baton config file") do |o|
|
13
|
+
cfg = o
|
14
|
+
end
|
15
|
+
opt.on_tail("-h", "--help", "Show this message") do
|
16
|
+
puts opt
|
17
|
+
exit
|
18
|
+
end
|
19
|
+
end.parse!
|
4
20
|
|
5
21
|
Baton.configure do |c|
|
6
|
-
c.config_path =
|
22
|
+
c.config_path = cfg
|
23
|
+
c.exchange = "<%= config[:name] %>_in"
|
7
24
|
c.exchange_out = "<%= config[:name] %>_out"
|
8
25
|
end
|
9
26
|
|
@@ -1,11 +1,31 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require 'baton/<%= config[:name] %>'
|
4
|
+
require 'optparse'
|
5
|
+
|
6
|
+
cfg = File.expand_path("../../config/<%= config[:name] %>.cfg", __FILE__)
|
7
|
+
daemonize = false
|
8
|
+
|
9
|
+
OptionParser.new do |opt|
|
10
|
+
opt.banner = "Usage: <%= config[:name] %> [OPTIONS]"
|
11
|
+
opt.separator ""
|
12
|
+
opt.separator "Specific options:"
|
13
|
+
opt.on("-c","--config-file [PATH]", "Path to a baton config file") do |o|
|
14
|
+
cfg = o
|
15
|
+
end
|
16
|
+
opt.on("-d","--daemonize", "Should baton daemonize") do |o|
|
17
|
+
daemonize = o
|
18
|
+
end
|
19
|
+
opt.on_tail("-h", "--help", "Show this message") do
|
20
|
+
puts opt
|
21
|
+
exit
|
22
|
+
end
|
23
|
+
end.parse!
|
4
24
|
|
5
25
|
Baton.configure do |c|
|
6
|
-
c.config_path =
|
26
|
+
c.config_path = cfg
|
7
27
|
c.exchange = "<%= config[:name] %>_in"
|
8
28
|
c.exchange_out = "<%= config[:name] %>_out"
|
9
29
|
end
|
10
30
|
|
11
|
-
Baton::<%= config[:constant_array].last %>Service.new.run
|
31
|
+
Baton::<%= config[:constant_array].last %>Service.new(daemonize).run
|
data/lib/baton/version.rb
CHANGED
@@ -23,6 +23,10 @@ describe Baton::Configuration do
|
|
23
23
|
it "will set the password" do
|
24
24
|
subject.password.should eq("fromconfigpass")
|
25
25
|
end
|
26
|
+
|
27
|
+
it "will set the heartbeat" do
|
28
|
+
subject.heartbeat.should eq(666)
|
29
|
+
end
|
26
30
|
end
|
27
31
|
|
28
32
|
context "given a non existing file" do
|
@@ -40,14 +44,27 @@ describe Baton::Configuration do
|
|
40
44
|
|
41
45
|
context "give a config file" do
|
42
46
|
it "will return a config hash" do
|
43
|
-
subject.connection_opts.should eq({
|
47
|
+
subject.connection_opts.should eq({
|
48
|
+
:host=>"fromconfig.com",
|
49
|
+
:vhost=>"fromconfig",
|
50
|
+
:user=>"fromconfiguser",
|
51
|
+
:password=>"fromconfigpass",
|
52
|
+
:pass=>"fromconfigpass",
|
53
|
+
:heartbeat=>666
|
54
|
+
})
|
44
55
|
end
|
45
56
|
end
|
46
57
|
|
47
58
|
context "given one of the configuration options is nil" do
|
48
59
|
it "will not be returned in the config hash" do
|
49
60
|
subject.vhost = nil
|
50
|
-
subject.connection_opts.should eq({
|
61
|
+
subject.connection_opts.should eq({
|
62
|
+
:host=>"fromconfig.com",
|
63
|
+
:user=>"fromconfiguser",
|
64
|
+
:password=>"fromconfigpass",
|
65
|
+
:pass=>"fromconfigpass",
|
66
|
+
:heartbeat=>666
|
67
|
+
})
|
51
68
|
end
|
52
69
|
end
|
53
70
|
end
|
@@ -67,5 +84,9 @@ describe Baton::Configuration do
|
|
67
84
|
subject.amqp_host_list.should eq(["fromconfig.com", "moreconfig.com", "thirdconfig.com"])
|
68
85
|
end
|
69
86
|
|
87
|
+
it "will default the heartbeat to 60" do
|
88
|
+
subject.heartbeat.should eq(60)
|
89
|
+
end
|
90
|
+
|
70
91
|
end
|
71
92
|
end
|
data/spec/fixtures/config.cfg
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: baton
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,11 +10,11 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2013-01-11 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: amqp
|
17
|
-
requirement:
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
18
|
none: false
|
19
19
|
requirements:
|
20
20
|
- - ~>
|
@@ -22,10 +22,31 @@ dependencies:
|
|
22
22
|
version: 0.9.7
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
|
-
version_requirements:
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ~>
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: 0.9.7
|
31
|
+
- !ruby/object:Gem::Dependency
|
32
|
+
name: amq-client
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
34
|
+
none: false
|
35
|
+
requirements:
|
36
|
+
- - ~>
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: 0.9.9
|
39
|
+
type: :runtime
|
40
|
+
prerelease: false
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ~>
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 0.9.9
|
26
47
|
- !ruby/object:Gem::Dependency
|
27
48
|
name: eventmachine
|
28
|
-
requirement:
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
29
50
|
none: false
|
30
51
|
requirements:
|
31
52
|
- - ~>
|
@@ -33,21 +54,31 @@ dependencies:
|
|
33
54
|
version: 1.0.0
|
34
55
|
type: :runtime
|
35
56
|
prerelease: false
|
36
|
-
version_requirements:
|
57
|
+
version_requirements: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - ~>
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 1.0.0
|
37
63
|
- !ruby/object:Gem::Dependency
|
38
64
|
name: em-http-request
|
39
|
-
requirement:
|
65
|
+
requirement: !ruby/object:Gem::Requirement
|
40
66
|
none: false
|
41
67
|
requirements:
|
42
|
-
- - =
|
68
|
+
- - '='
|
43
69
|
- !ruby/object:Gem::Version
|
44
70
|
version: 1.0.3
|
45
71
|
type: :runtime
|
46
72
|
prerelease: false
|
47
|
-
version_requirements:
|
73
|
+
version_requirements: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - '='
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: 1.0.3
|
48
79
|
- !ruby/object:Gem::Dependency
|
49
80
|
name: bunny
|
50
|
-
requirement:
|
81
|
+
requirement: !ruby/object:Gem::Requirement
|
51
82
|
none: false
|
52
83
|
requirements:
|
53
84
|
- - ~>
|
@@ -55,10 +86,15 @@ dependencies:
|
|
55
86
|
version: 0.8.0
|
56
87
|
type: :runtime
|
57
88
|
prerelease: false
|
58
|
-
version_requirements:
|
89
|
+
version_requirements: !ruby/object:Gem::Requirement
|
90
|
+
none: false
|
91
|
+
requirements:
|
92
|
+
- - ~>
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: 0.8.0
|
59
95
|
- !ruby/object:Gem::Dependency
|
60
96
|
name: ohai
|
61
|
-
requirement:
|
97
|
+
requirement: !ruby/object:Gem::Requirement
|
62
98
|
none: false
|
63
99
|
requirements:
|
64
100
|
- - ~>
|
@@ -66,10 +102,15 @@ dependencies:
|
|
66
102
|
version: 0.6.12
|
67
103
|
type: :runtime
|
68
104
|
prerelease: false
|
69
|
-
version_requirements:
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
106
|
+
none: false
|
107
|
+
requirements:
|
108
|
+
- - ~>
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 0.6.12
|
70
111
|
- !ruby/object:Gem::Dependency
|
71
112
|
name: thor
|
72
|
-
requirement:
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
73
114
|
none: false
|
74
115
|
requirements:
|
75
116
|
- - ! '>='
|
@@ -77,10 +118,15 @@ dependencies:
|
|
77
118
|
version: '0'
|
78
119
|
type: :runtime
|
79
120
|
prerelease: false
|
80
|
-
version_requirements:
|
121
|
+
version_requirements: !ruby/object:Gem::Requirement
|
122
|
+
none: false
|
123
|
+
requirements:
|
124
|
+
- - ! '>='
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: '0'
|
81
127
|
- !ruby/object:Gem::Dependency
|
82
128
|
name: rspec
|
83
|
-
requirement:
|
129
|
+
requirement: !ruby/object:Gem::Requirement
|
84
130
|
none: false
|
85
131
|
requirements:
|
86
132
|
- - ~>
|
@@ -88,10 +134,15 @@ dependencies:
|
|
88
134
|
version: '2.7'
|
89
135
|
type: :development
|
90
136
|
prerelease: false
|
91
|
-
version_requirements:
|
137
|
+
version_requirements: !ruby/object:Gem::Requirement
|
138
|
+
none: false
|
139
|
+
requirements:
|
140
|
+
- - ~>
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: '2.7'
|
92
143
|
- !ruby/object:Gem::Dependency
|
93
144
|
name: moqueue
|
94
|
-
requirement:
|
145
|
+
requirement: !ruby/object:Gem::Requirement
|
95
146
|
none: false
|
96
147
|
requirements:
|
97
148
|
- - ~>
|
@@ -99,10 +150,15 @@ dependencies:
|
|
99
150
|
version: 0.1.4
|
100
151
|
type: :development
|
101
152
|
prerelease: false
|
102
|
-
version_requirements:
|
153
|
+
version_requirements: !ruby/object:Gem::Requirement
|
154
|
+
none: false
|
155
|
+
requirements:
|
156
|
+
- - ~>
|
157
|
+
- !ruby/object:Gem::Version
|
158
|
+
version: 0.1.4
|
103
159
|
- !ruby/object:Gem::Dependency
|
104
160
|
name: fakefs
|
105
|
-
requirement:
|
161
|
+
requirement: !ruby/object:Gem::Requirement
|
106
162
|
none: false
|
107
163
|
requirements:
|
108
164
|
- - ~>
|
@@ -110,10 +166,15 @@ dependencies:
|
|
110
166
|
version: 0.4.0
|
111
167
|
type: :development
|
112
168
|
prerelease: false
|
113
|
-
version_requirements:
|
169
|
+
version_requirements: !ruby/object:Gem::Requirement
|
170
|
+
none: false
|
171
|
+
requirements:
|
172
|
+
- - ~>
|
173
|
+
- !ruby/object:Gem::Version
|
174
|
+
version: 0.4.0
|
114
175
|
- !ruby/object:Gem::Dependency
|
115
176
|
name: rake
|
116
|
-
requirement:
|
177
|
+
requirement: !ruby/object:Gem::Requirement
|
117
178
|
none: false
|
118
179
|
requirements:
|
119
180
|
- - ~>
|
@@ -121,10 +182,15 @@ dependencies:
|
|
121
182
|
version: 0.9.2
|
122
183
|
type: :development
|
123
184
|
prerelease: false
|
124
|
-
version_requirements:
|
185
|
+
version_requirements: !ruby/object:Gem::Requirement
|
186
|
+
none: false
|
187
|
+
requirements:
|
188
|
+
- - ~>
|
189
|
+
- !ruby/object:Gem::Version
|
190
|
+
version: 0.9.2
|
125
191
|
- !ruby/object:Gem::Dependency
|
126
192
|
name: webmock
|
127
|
-
requirement:
|
193
|
+
requirement: !ruby/object:Gem::Requirement
|
128
194
|
none: false
|
129
195
|
requirements:
|
130
196
|
- - ~>
|
@@ -132,29 +198,44 @@ dependencies:
|
|
132
198
|
version: 1.8.7
|
133
199
|
type: :development
|
134
200
|
prerelease: false
|
135
|
-
version_requirements:
|
201
|
+
version_requirements: !ruby/object:Gem::Requirement
|
202
|
+
none: false
|
203
|
+
requirements:
|
204
|
+
- - ~>
|
205
|
+
- !ruby/object:Gem::Version
|
206
|
+
version: 1.8.7
|
136
207
|
- !ruby/object:Gem::Dependency
|
137
208
|
name: minitar
|
138
|
-
requirement:
|
209
|
+
requirement: !ruby/object:Gem::Requirement
|
139
210
|
none: false
|
140
211
|
requirements:
|
141
|
-
- - =
|
212
|
+
- - '='
|
142
213
|
- !ruby/object:Gem::Version
|
143
214
|
version: 0.5.3
|
144
215
|
type: :development
|
145
216
|
prerelease: false
|
146
|
-
version_requirements:
|
217
|
+
version_requirements: !ruby/object:Gem::Requirement
|
218
|
+
none: false
|
219
|
+
requirements:
|
220
|
+
- - '='
|
221
|
+
- !ruby/object:Gem::Version
|
222
|
+
version: 0.5.3
|
147
223
|
- !ruby/object:Gem::Dependency
|
148
224
|
name: simplecov
|
149
|
-
requirement:
|
225
|
+
requirement: !ruby/object:Gem::Requirement
|
150
226
|
none: false
|
151
227
|
requirements:
|
152
|
-
- - =
|
228
|
+
- - '='
|
153
229
|
- !ruby/object:Gem::Version
|
154
230
|
version: 0.6.4
|
155
231
|
type: :development
|
156
232
|
prerelease: false
|
157
|
-
version_requirements:
|
233
|
+
version_requirements: !ruby/object:Gem::Requirement
|
234
|
+
none: false
|
235
|
+
requirements:
|
236
|
+
- - '='
|
237
|
+
- !ruby/object:Gem::Version
|
238
|
+
version: 0.6.4
|
158
239
|
description: Baton
|
159
240
|
email:
|
160
241
|
- johnog@gmail.com
|
@@ -227,7 +308,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
227
308
|
version: '0'
|
228
309
|
segments:
|
229
310
|
- 0
|
230
|
-
hash:
|
311
|
+
hash: 1528221756626291784
|
231
312
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
232
313
|
none: false
|
233
314
|
requirements:
|
@@ -236,10 +317,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
236
317
|
version: '0'
|
237
318
|
segments:
|
238
319
|
- 0
|
239
|
-
hash:
|
320
|
+
hash: 1528221756626291784
|
240
321
|
requirements: []
|
241
322
|
rubyforge_project:
|
242
|
-
rubygems_version: 1.8.
|
323
|
+
rubygems_version: 1.8.24
|
243
324
|
signing_key:
|
244
325
|
specification_version: 3
|
245
326
|
summary: Baton
|