deployml 0.4.0 → 0.4.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.
- data/ChangeLog.md +10 -0
- data/README.md +1 -0
- data/Rakefile +1 -1
- data/gemspec.yml +3 -1
- data/lib/deployml/configuration.rb +10 -0
- data/lib/deployml/environment.rb +20 -29
- data/lib/deployml/frameworks/rails2.rb +4 -0
- data/lib/deployml/frameworks/rails3.rb +9 -17
- data/lib/deployml/local_shell.rb +3 -0
- data/lib/deployml/project.rb +45 -18
- data/lib/deployml/remote_shell.rb +44 -4
- data/lib/deployml/servers/apache.rb +12 -0
- data/lib/deployml/servers/mongrel.rb +16 -1
- data/lib/deployml/servers/thin.rb +16 -1
- data/lib/deployml/version.rb +1 -1
- data/spec/spec_helper.rb +1 -2
- metadata +9 -7
data/ChangeLog.md
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
### 0.4.1 / 2010-12-08
|
2
|
+
|
3
|
+
* Added support for Ruby 1.8.6.
|
4
|
+
* Added {DeploYML::Configuration#bundler}.
|
5
|
+
* Auto-detect usage of [Bundler](http://gembundler.com/) by checking for a
|
6
|
+
`Gemfile` in project directories.
|
7
|
+
* Fixed a Ruby 1.8.x specific bug where non-Strings were being passed to
|
8
|
+
`Kernel.system`.
|
9
|
+
* Only print status messages if the mixin is enabled.
|
10
|
+
|
1
11
|
### 0.4.0 / 2010-11-29
|
2
12
|
|
3
13
|
* Require addressable ~> 2.2.0.
|
data/README.md
CHANGED
@@ -115,6 +115,7 @@ List available tasks:
|
|
115
115
|
|
116
116
|
## Requirements
|
117
117
|
|
118
|
+
* [ruby](http://www.ruby-lang.org/) >= 1.8.6
|
118
119
|
* [addressable](http://addressable.rubyforge.org/) ~> 2.2.0
|
119
120
|
* [rprogram](http://github.com/postmodern/rprogram) ~> 0.2.0
|
120
121
|
* [thor](http://github.com/wycats/thor) ~> 0.14.3
|
data/Rakefile
CHANGED
data/gemspec.yml
CHANGED
@@ -10,6 +10,8 @@ email: postmodern.mod3@gmail.com
|
|
10
10
|
homepage: http://github.com/postmodern/deployml
|
11
11
|
has_yard: true
|
12
12
|
|
13
|
+
required_ruby_version: >= 1.8.6
|
14
|
+
|
13
15
|
dependencies:
|
14
16
|
addressable: ~> 2.2.0
|
15
17
|
rprogram: ~> 0.2.0
|
@@ -17,5 +19,5 @@ dependencies:
|
|
17
19
|
|
18
20
|
development_dependencies:
|
19
21
|
ore-tasks: ~> 0.3.0
|
20
|
-
rspec: ~> 2.
|
22
|
+
rspec: ~> 2.2.0
|
21
23
|
yard: ~> 0.6.0
|
@@ -24,6 +24,9 @@ module DeploYML
|
|
24
24
|
# The destination URI to upload the project to.
|
25
25
|
attr_reader :dest
|
26
26
|
|
27
|
+
# Whether the project uses Bundler.
|
28
|
+
attr_reader :bundler
|
29
|
+
|
27
30
|
# The framework used by the project
|
28
31
|
attr_reader :framework
|
29
32
|
|
@@ -48,6 +51,10 @@ module DeploYML
|
|
48
51
|
# @option config [String, Hash] :dest
|
49
52
|
# The destination URI to upload the project to.
|
50
53
|
#
|
54
|
+
# @option config [Boolean] :bundler
|
55
|
+
# Specifies whether the projects dependencies are controlled by
|
56
|
+
# [Bundler](http://gembundler.com).
|
57
|
+
#
|
51
58
|
# @option config [Symbol] :framework
|
52
59
|
# The framework used by the project.
|
53
60
|
#
|
@@ -70,6 +77,7 @@ module DeploYML
|
|
70
77
|
@server_name = nil
|
71
78
|
@server_options = {}
|
72
79
|
|
80
|
+
@bundler = false
|
73
81
|
@framework = nil
|
74
82
|
@orm = nil
|
75
83
|
|
@@ -78,6 +86,8 @@ module DeploYML
|
|
78
86
|
|
79
87
|
config = normalize_hash(config)
|
80
88
|
|
89
|
+
@bundler = config[:bundler]
|
90
|
+
|
81
91
|
if config[:framework]
|
82
92
|
@framework = config[:framework].to_sym
|
83
93
|
end
|
data/lib/deployml/environment.rb
CHANGED
@@ -158,7 +158,11 @@ module DeploYML
|
|
158
158
|
# @since 0.3.0
|
159
159
|
#
|
160
160
|
def setup(shell)
|
161
|
+
shell.status "Cloning #{@source} ..."
|
162
|
+
|
161
163
|
shell.run 'git', 'clone', '--depth', 1, @source, @dest.path
|
164
|
+
|
165
|
+
shell.status "Cloned."
|
162
166
|
end
|
163
167
|
|
164
168
|
#
|
@@ -170,12 +174,16 @@ module DeploYML
|
|
170
174
|
# @since 0.3.0
|
171
175
|
#
|
172
176
|
def update(shell)
|
177
|
+
shell.status "Updating #{@dest.path} ..."
|
178
|
+
|
173
179
|
shell.run 'git', 'reset', '--hard', 'HEAD'
|
174
180
|
shell.run 'git', 'pull', '-f'
|
181
|
+
|
182
|
+
shell.status "Updated."
|
175
183
|
end
|
176
184
|
|
177
185
|
#
|
178
|
-
#
|
186
|
+
# Installs any additional dependencies.
|
179
187
|
#
|
180
188
|
# @param [RemoteShell] shell
|
181
189
|
# The remote shell to execute commands through.
|
@@ -183,6 +191,13 @@ module DeploYML
|
|
183
191
|
# @since 0.3.0
|
184
192
|
#
|
185
193
|
def install(shell)
|
194
|
+
if @bundler
|
195
|
+
shell.status "Bundling dependencies ..."
|
196
|
+
|
197
|
+
shell.run 'bundle', 'install', '--deployment'
|
198
|
+
|
199
|
+
shell.status "Dependencies bundled."
|
200
|
+
end
|
186
201
|
end
|
187
202
|
|
188
203
|
#
|
@@ -254,52 +269,28 @@ module DeploYML
|
|
254
269
|
def invoke(tasks)
|
255
270
|
remote_shell do |shell|
|
256
271
|
# setup the deployment repository
|
257
|
-
if tasks.include?(:setup)
|
258
|
-
shell.status "Cloning #{@source} ..."
|
259
|
-
setup(shell)
|
260
|
-
shell.status "Cloned."
|
261
|
-
end
|
272
|
+
setup(shell) if tasks.include?(:setup)
|
262
273
|
|
263
274
|
# cd into the deployment repository
|
264
275
|
shell.cd @dest.path
|
265
276
|
|
266
277
|
# update the deployment repository
|
267
|
-
if tasks.include?(:update)
|
268
|
-
shell.status "Updating #{@dest.path} ..."
|
269
|
-
update(shell)
|
270
|
-
shell.status "Updated."
|
271
|
-
end
|
278
|
+
update(shell) if tasks.include?(:update)
|
272
279
|
|
273
280
|
# framework tasks
|
274
|
-
if tasks.include?(:install)
|
275
|
-
shell.status "Installing additional dependencies ..."
|
276
|
-
install(shell)
|
277
|
-
shell.status "Dependencies installed."
|
278
|
-
end
|
281
|
+
install(shell) if tasks.include?(:install)
|
279
282
|
|
280
|
-
if tasks.include?(:migrate)
|
281
|
-
shell.status "Migrating database ..."
|
282
|
-
migrate(shell)
|
283
|
-
shell.status "Database migrated."
|
284
|
-
end
|
283
|
+
migrate(shell) if tasks.include?(:migrate)
|
285
284
|
|
286
285
|
# server tasks
|
287
286
|
if tasks.include?(:config)
|
288
|
-
shell.status "Configuring server ..."
|
289
287
|
server_config(shell)
|
290
|
-
shell.status "Server configured."
|
291
288
|
elsif tasks.include?(:start)
|
292
|
-
shell.status "Starting server ..."
|
293
289
|
server_start(shell)
|
294
|
-
shell.status "Server started."
|
295
290
|
elsif tasks.include?(:stop)
|
296
|
-
shell.status "Stopping server ..."
|
297
291
|
server_stop(shell)
|
298
|
-
shell.status "Server stopped."
|
299
292
|
elsif tasks.include?(:restart)
|
300
|
-
shell.status "Restarting server ..."
|
301
293
|
server_restart(shell)
|
302
|
-
shell.status "Server restarted."
|
303
294
|
end
|
304
295
|
end
|
305
296
|
|
@@ -15,7 +15,11 @@ module DeploYML
|
|
15
15
|
# The shell to execute commands in.
|
16
16
|
#
|
17
17
|
def migrate(shell)
|
18
|
+
shell.status "Migrating the ActiveRecord Database ..."
|
19
|
+
|
18
20
|
shell.run 'rake', 'db:migrate', "RAILS_ENV=#{@environment}"
|
21
|
+
|
22
|
+
shell.status "ActiveRecord Database migrated."
|
19
23
|
end
|
20
24
|
end
|
21
25
|
end
|
@@ -8,16 +8,6 @@ module DeploYML
|
|
8
8
|
module Rails3
|
9
9
|
include Rails
|
10
10
|
|
11
|
-
#
|
12
|
-
# Installs any dependencies using `bundle install --deployment`.
|
13
|
-
#
|
14
|
-
# @param [LocalShell, RemoteShell] shell
|
15
|
-
# The shell to execute commands in.
|
16
|
-
#
|
17
|
-
def install(shell)
|
18
|
-
shell.run 'bundle', 'install', '--deployment'
|
19
|
-
end
|
20
|
-
|
21
11
|
#
|
22
12
|
# Migrates the database using the `db:autoupgrade` if
|
23
13
|
# [DataMapper](http://datamapper.org) is being used, or the typical
|
@@ -27,14 +17,16 @@ module DeploYML
|
|
27
17
|
# The shell to execute commands in.
|
28
18
|
#
|
29
19
|
def migrate(shell)
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
20
|
+
case @orm
|
21
|
+
when :datamapper
|
22
|
+
shell.status "Running DataMapper auto-upgrades ..."
|
23
|
+
shell.run 'rake', 'db:autoupgrade', "RAILS_ENV=#{@environment}"
|
24
|
+
else
|
25
|
+
shell.status "Running ActiveRecord migrations ..."
|
26
|
+
shell.run 'rake', 'db:migrate', "RAILS_ENV=#{@environment}"
|
27
|
+
end
|
36
28
|
|
37
|
-
shell.
|
29
|
+
shell.status "Database migrated."
|
38
30
|
end
|
39
31
|
end
|
40
32
|
end
|
data/lib/deployml/local_shell.rb
CHANGED
data/lib/deployml/project.rb
CHANGED
@@ -262,41 +262,68 @@ module DeploYML
|
|
262
262
|
protected
|
263
263
|
|
264
264
|
#
|
265
|
-
#
|
265
|
+
# Infers the configuration from the project root directory.
|
266
266
|
#
|
267
|
-
# @
|
268
|
-
# The
|
267
|
+
# @return [Hash{Symbol => Object}]
|
268
|
+
# The infered configuration.
|
269
269
|
#
|
270
|
-
# @
|
271
|
-
# The `source` or `dest` options were not specified.
|
270
|
+
# @since 0.4.1
|
272
271
|
#
|
273
|
-
|
272
|
+
def infer_configuration
|
273
|
+
config = {}
|
274
|
+
|
275
|
+
# check for Bundler
|
276
|
+
if File.file?(File.join(@root,'Gemfile'))
|
277
|
+
config[:bundler] = true
|
278
|
+
end
|
279
|
+
|
280
|
+
return config
|
281
|
+
end
|
282
|
+
|
274
283
|
#
|
275
|
-
|
276
|
-
|
284
|
+
# Loads configuration from a YAML file.
|
285
|
+
#
|
286
|
+
# @param [String] path
|
287
|
+
# The path to the configuration file.
|
288
|
+
#
|
289
|
+
# @return [Hash]
|
290
|
+
# The loaded configuration.
|
291
|
+
#
|
292
|
+
# @raise [InvalidConfig]
|
293
|
+
# The configuration file did not contain a YAML Hash.
|
294
|
+
#
|
295
|
+
# @since 0.4.1
|
296
|
+
#
|
297
|
+
def load_configuration(path)
|
298
|
+
config = YAML.load_file(path)
|
277
299
|
|
278
|
-
|
279
|
-
|
300
|
+
unless config.kind_of?(Hash)
|
301
|
+
raise(InvalidConfig,"DeploYML file #{path.dump} does not contain a Hash")
|
302
|
+
end
|
280
303
|
|
281
|
-
|
282
|
-
|
283
|
-
end
|
304
|
+
return config
|
305
|
+
end
|
284
306
|
|
285
|
-
|
286
|
-
|
307
|
+
#
|
308
|
+
# Loads the project configuration.
|
309
|
+
#
|
310
|
+
# @since 0.3.0
|
311
|
+
#
|
312
|
+
def load_environments!
|
313
|
+
base_config = infer_configuration
|
287
314
|
|
288
315
|
if File.file?(@config_file)
|
289
|
-
base_config.merge!(
|
316
|
+
base_config.merge!(load_configuration(@config_file))
|
290
317
|
end
|
291
318
|
|
292
319
|
@environments = {}
|
293
320
|
|
294
321
|
if File.directory?(@environments_dir)
|
295
322
|
Dir.glob(File.join(@environments_dir,'*.yml')) do |path|
|
296
|
-
|
323
|
+
config = base_config.merge(load_configuration(path))
|
297
324
|
name = File.basename(path).sub(/\.yml$/,'').to_sym
|
298
325
|
|
299
|
-
@environments[name] = Environment.new(name,
|
326
|
+
@environments[name] = Environment.new(name,config)
|
300
327
|
end
|
301
328
|
else
|
302
329
|
@environments[:production] = Environment.new(:production,base_config)
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'deployml/shell'
|
2
2
|
|
3
3
|
require 'addressable/uri'
|
4
|
-
require 'shellwords'
|
5
4
|
|
6
5
|
module DeploYML
|
7
6
|
#
|
@@ -10,7 +9,6 @@ module DeploYML
|
|
10
9
|
class RemoteShell
|
11
10
|
|
12
11
|
include Shell
|
13
|
-
include Shellwords
|
14
12
|
|
15
13
|
# The URI of the remote shell
|
16
14
|
attr_reader :uri
|
@@ -96,7 +94,7 @@ module DeploYML
|
|
96
94
|
#
|
97
95
|
def join
|
98
96
|
@history.map { |command|
|
99
|
-
command.map { |word| shellescape(word) }.join(' ')
|
97
|
+
command.map { |word| shellescape(word.to_s) }.join(' ')
|
100
98
|
}.join(' && ')
|
101
99
|
end
|
102
100
|
|
@@ -127,8 +125,11 @@ module DeploYML
|
|
127
125
|
options += ['-p', @uri.port.to_s]
|
128
126
|
end
|
129
127
|
|
128
|
+
# append the SSH URI
|
130
129
|
options << ssh_uri
|
131
|
-
|
130
|
+
|
131
|
+
# append the additional arguments
|
132
|
+
args.each { |arg| options << arg.to_s }
|
132
133
|
|
133
134
|
return system('ssh',*options)
|
134
135
|
end
|
@@ -140,5 +141,44 @@ module DeploYML
|
|
140
141
|
ssh(self.join) unless @history.empty?
|
141
142
|
end
|
142
143
|
|
144
|
+
protected
|
145
|
+
|
146
|
+
#
|
147
|
+
# Escapes a string so that it can be safely used in a Bourne shell
|
148
|
+
# command line.
|
149
|
+
#
|
150
|
+
# Note that a resulted string should be used unquoted and is not
|
151
|
+
# intended for use in double quotes nor in single quotes.
|
152
|
+
#
|
153
|
+
# @param [String] str
|
154
|
+
# The string to escape.
|
155
|
+
#
|
156
|
+
# @return [String]
|
157
|
+
# The shell-escaped string.
|
158
|
+
#
|
159
|
+
# @example
|
160
|
+
# open("| grep #{Shellwords.escape(pattern)} file") { |pipe|
|
161
|
+
# # ...
|
162
|
+
# }
|
163
|
+
#
|
164
|
+
# @note Vendored from `shellwords.rb` line 72 from Ruby 1.9.2.
|
165
|
+
#
|
166
|
+
def shellescape(str)
|
167
|
+
# An empty argument will be skipped, so return empty quotes.
|
168
|
+
return "''" if str.empty?
|
169
|
+
|
170
|
+
str = str.dup
|
171
|
+
|
172
|
+
# Process as a single byte sequence because not all shell
|
173
|
+
# implementations are multibyte aware.
|
174
|
+
str.gsub!(/([^A-Za-z0-9_\-.,:\/@\n])/n, "\\\\\\1")
|
175
|
+
|
176
|
+
# A LF cannot be escaped with a backslash because a backslash + LF
|
177
|
+
# combo is regarded as line continuation and simply ignored.
|
178
|
+
str.gsub!(/\n/, "'\n'")
|
179
|
+
|
180
|
+
return str
|
181
|
+
end
|
182
|
+
|
143
183
|
end
|
144
184
|
end
|
@@ -14,7 +14,11 @@ module DeploYML
|
|
14
14
|
# The shell to execute commands in.
|
15
15
|
#
|
16
16
|
def server_start(shell)
|
17
|
+
shell.status "Starting Apache ..."
|
18
|
+
|
17
19
|
shell.run 'apachectl', 'start'
|
20
|
+
|
21
|
+
shell.status "Apache started."
|
18
22
|
end
|
19
23
|
|
20
24
|
#
|
@@ -24,7 +28,11 @@ module DeploYML
|
|
24
28
|
# The shell to execute commands in.
|
25
29
|
#
|
26
30
|
def server_restart(shell)
|
31
|
+
shell.status "Restarting Apache ..."
|
32
|
+
|
27
33
|
shell.run 'apachectl', 'restart'
|
34
|
+
|
35
|
+
shell.status "Apache restarted."
|
28
36
|
end
|
29
37
|
|
30
38
|
#
|
@@ -34,7 +42,11 @@ module DeploYML
|
|
34
42
|
# The shell to execute commands in.
|
35
43
|
#
|
36
44
|
def server_stop(shell)
|
45
|
+
shell.status "Stopping Apache ..."
|
46
|
+
|
37
47
|
shell.run 'apachectl', 'stop'
|
48
|
+
|
49
|
+
shell.status "Apache stoped."
|
38
50
|
end
|
39
51
|
end
|
40
52
|
end
|
@@ -46,9 +46,12 @@ module DeploYML
|
|
46
46
|
raise(MissingOption,"No 'config' option specified under server options",caller)
|
47
47
|
end
|
48
48
|
|
49
|
-
|
49
|
+
shell.status "Configuring Mongrel ..."
|
50
50
|
|
51
|
+
options = ['-c', dest.path] + @mongrel.arguments
|
51
52
|
shell.run 'mongrel_rails', 'cluster::configure', *options
|
53
|
+
|
54
|
+
shell.status "Mongrel configured."
|
52
55
|
end
|
53
56
|
|
54
57
|
#
|
@@ -58,7 +61,11 @@ module DeploYML
|
|
58
61
|
# The shell to execute commands in.
|
59
62
|
#
|
60
63
|
def server_start(shell)
|
64
|
+
shell.status "Starting Mongrel(s) ..."
|
65
|
+
|
61
66
|
mongrel_cluster 'cluster::start'
|
67
|
+
|
68
|
+
shell.status "Mongrel(s) started."
|
62
69
|
end
|
63
70
|
|
64
71
|
#
|
@@ -68,7 +75,11 @@ module DeploYML
|
|
68
75
|
# The shell to execute commands in.
|
69
76
|
#
|
70
77
|
def server_stop(shell)
|
78
|
+
shell.status "Stopping Mongrel(s) ..."
|
79
|
+
|
71
80
|
mongrel_cluster 'cluster::stop'
|
81
|
+
|
82
|
+
shell.status "Mongrel(s) stopped."
|
72
83
|
end
|
73
84
|
|
74
85
|
#
|
@@ -78,7 +89,11 @@ module DeploYML
|
|
78
89
|
# The shell to execute commands in.
|
79
90
|
#
|
80
91
|
def server_restart(shell)
|
92
|
+
shell.status "Restarting Mongrel(s) ..."
|
93
|
+
|
81
94
|
mongrel_cluster 'cluster::restart'
|
95
|
+
|
96
|
+
shell.status "Mongrel(s) restarted."
|
82
97
|
end
|
83
98
|
end
|
84
99
|
end
|
@@ -46,9 +46,12 @@ module DeploYML
|
|
46
46
|
raise(MissingOption,"No 'config' option specified under the server options",caller)
|
47
47
|
end
|
48
48
|
|
49
|
-
|
49
|
+
shell.status "Configuring Thin ..."
|
50
50
|
|
51
|
+
options = ['-c', dest.path] + @thin.arguments
|
51
52
|
shell.run 'thin', 'config', *options
|
53
|
+
|
54
|
+
shell.status "Thin configured."
|
52
55
|
end
|
53
56
|
|
54
57
|
#
|
@@ -58,7 +61,11 @@ module DeploYML
|
|
58
61
|
# The shell to execute commands in.
|
59
62
|
#
|
60
63
|
def server_start(shell)
|
64
|
+
shell.status "Starting Thin ..."
|
65
|
+
|
61
66
|
thin shell, 'start'
|
67
|
+
|
68
|
+
shell.status "Thin started."
|
62
69
|
end
|
63
70
|
|
64
71
|
#
|
@@ -68,7 +75,11 @@ module DeploYML
|
|
68
75
|
# The shell to execute commands in.
|
69
76
|
#
|
70
77
|
def server_stop(shell)
|
78
|
+
shell.status "Stopping Thin ..."
|
79
|
+
|
71
80
|
thin shell, 'stop'
|
81
|
+
|
82
|
+
shell.status "Thin stopped."
|
72
83
|
end
|
73
84
|
|
74
85
|
#
|
@@ -78,7 +89,11 @@ module DeploYML
|
|
78
89
|
# The shell to execute commands in.
|
79
90
|
#
|
80
91
|
def server_restart(shell)
|
92
|
+
shell.status "Restarting Thin ..."
|
93
|
+
|
81
94
|
thin shell, 'restart'
|
95
|
+
|
96
|
+
shell.status "Thin restarted."
|
82
97
|
end
|
83
98
|
end
|
84
99
|
end
|
data/lib/deployml/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 4
|
8
|
-
-
|
9
|
-
version: 0.4.
|
8
|
+
- 1
|
9
|
+
version: 0.4.1
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Postmodern
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-
|
17
|
+
date: 2010-12-08 00:00:00 -08:00
|
18
18
|
default_executable: deployml
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -87,9 +87,9 @@ dependencies:
|
|
87
87
|
- !ruby/object:Gem::Version
|
88
88
|
segments:
|
89
89
|
- 2
|
90
|
-
-
|
90
|
+
- 2
|
91
91
|
- 0
|
92
|
-
version: 2.
|
92
|
+
version: 2.2.0
|
93
93
|
type: :development
|
94
94
|
version_requirements: *id005
|
95
95
|
- !ruby/object:Gem::Dependency
|
@@ -185,8 +185,10 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
185
185
|
- - ">="
|
186
186
|
- !ruby/object:Gem::Version
|
187
187
|
segments:
|
188
|
-
-
|
189
|
-
|
188
|
+
- 1
|
189
|
+
- 8
|
190
|
+
- 6
|
191
|
+
version: 1.8.6
|
190
192
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
191
193
|
none: false
|
192
194
|
requirements:
|