deployml 0.4.0 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|