negroku 2.7.1 → 2.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -1
- data/docs/TASKS.md +47 -0
- data/lib/negroku/capistrano/tasks/env.rake +2 -0
- data/lib/negroku/capistrano/tasks/eye/delayed_job.rake +25 -29
- data/lib/negroku/capistrano/tasks/eye/puma.rake +10 -9
- data/lib/negroku/capistrano/tasks/eye/thinking_sphinx.rake +10 -9
- data/lib/negroku/capistrano/tasks/eye/unicorn.rake +10 -9
- data/lib/negroku/capistrano/tasks/eye.rake +36 -38
- data/lib/negroku/capistrano/templates/eye/_delayed_job.erb +9 -6
- data/lib/negroku/capistrano/templates/eye/_process.erb +8 -5
- data/lib/negroku/capistrano/templates/eye/_puma.erb +7 -2
- data/lib/negroku/capistrano/templates/eye/_sphinx.erb +7 -2
- data/lib/negroku/capistrano/templates/eye/_unicorn.erb +7 -2
- data/lib/negroku/templates/Capfile.erb +1 -0
- data/lib/negroku/version.rb +1 -1
- data/negroku.gemspec +2 -1
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c0754344fcb7eade9c733cf98caa26c6e8fb8b4d
|
4
|
+
data.tar.gz: 921c0b28575cc07474c1a20a93c0b9a51c74d726
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 832d8bb854c6f7df31038f23c1dd7e2ffdc3877acd40c90cc03ec2fcbf7b83d58585f9d21fdd8af31f82487ce64f0cc16320f1375aa48a2dde15706d82d60133
|
7
|
+
data.tar.gz: 71282695a9647abc0b938bb25e4c7a581542a97546cb4a93b92a60922f3bbd102bc80126b123b76758e214fe2bcdb5905ccfc4949b1cf34aa21f0ccf2fc2e036
|
data/CHANGELOG.md
CHANGED
@@ -4,7 +4,15 @@ Reverse Chronological Order:
|
|
4
4
|
|
5
5
|
## Unreleased
|
6
6
|
|
7
|
-
https://github.com/platanus/negroku/compare/v2.
|
7
|
+
https://github.com/platanus/negroku/compare/v2.8.0...HEAD
|
8
|
+
|
9
|
+
## `2.8.0`
|
10
|
+
|
11
|
+
https://github.com/platanus/negroku/compare/v2.7.1...2.8.0
|
12
|
+
|
13
|
+
FEAT:
|
14
|
+
- Adds some settings to process monitoring.
|
15
|
+
You can config timeouts and grace times.
|
8
16
|
|
9
17
|
## `2.7.1`
|
10
18
|
|
data/docs/TASKS.md
CHANGED
@@ -1,11 +1,58 @@
|
|
1
1
|
# Tasks
|
2
2
|
|
3
|
+
* [Eye](#eye)
|
3
4
|
* [Rails](#rails)
|
4
5
|
* [Remote Console](#remote-console)
|
5
6
|
* [Whenever](#whenever)
|
6
7
|
* [Config](#config)
|
7
8
|
* [Logs](#logs)
|
8
9
|
|
10
|
+
### Eye
|
11
|
+
|
12
|
+
Negroku support process monitoring via the [Eye gem](https://github.com/kostya/eye). Currently adds monitoring to
|
13
|
+
|
14
|
+
- unicorn
|
15
|
+
- puma
|
16
|
+
- thinking_sphinx
|
17
|
+
- delayed_job
|
18
|
+
|
19
|
+
Each monitor can be further customized using variables.
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
set: eye_<process>_<setting>, <value>
|
23
|
+
```
|
24
|
+
|
25
|
+
The main setting that can be customized are timeouts and grace times.
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
# delayed job timeouts
|
29
|
+
set: eye_delayed_job_start_timeout, 20.seconds
|
30
|
+
set: eye_delayed_job_stop_timeout, 1.minute
|
31
|
+
set: eye_delayed_job_restart_timeout, 1.minute
|
32
|
+
|
33
|
+
# For puma
|
34
|
+
set: eye_puma_start_grace, 45.seconds
|
35
|
+
set: eye_puma_stop_grace, 30.seconds
|
36
|
+
set: eye_puma_restart_grace, 2.minutes
|
37
|
+
```
|
38
|
+
|
39
|
+
#### Monitor custom processes
|
40
|
+
|
41
|
+
If you have other processes in your applicacion you can monitor them
|
42
|
+
using the `watch_process` method in your `deploy.rb` file
|
43
|
+
|
44
|
+
You'll need to setup the **start_command**, **stop_command** and **pid location**.
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
watch_process(:other_process, template: :process,
|
48
|
+
start_command: "process start",
|
49
|
+
stop_command: "process stop",
|
50
|
+
start_timeout: 50.seconds,
|
51
|
+
restart_grace: 1.minutes,
|
52
|
+
pid_file: "path/to/pid"
|
53
|
+
)
|
54
|
+
```
|
55
|
+
|
9
56
|
### Rails
|
10
57
|
|
11
58
|
##### Remote Console
|
@@ -1,42 +1,38 @@
|
|
1
1
|
#########
|
2
2
|
## Adds support to monitor delayed_job processes through eye
|
3
3
|
#########
|
4
|
-
def delayed_job_args
|
5
|
-
args = []
|
6
|
-
args << "--queues=#{fetch(:delayed_job_queues).join(',')}" unless fetch(:delayed_job_queues).nil?
|
7
|
-
args << "--prefix=#{fetch(:delayed_job_prefix)}" unless fetch(:delayed_job_prefix).nil?
|
8
|
-
args << fetch(:delayed_job_pools, {}).map {|k,v| "--pool=#{k}:#{v}"}.join(' ') unless fetch(:delayed_job_pools).nil?
|
9
|
-
args.join(' ')
|
10
|
-
end
|
11
4
|
|
12
|
-
|
13
|
-
|
14
|
-
|
5
|
+
# Watch the delayed_job processes using the build in template
|
6
|
+
namespace :delayed_job do
|
7
|
+
# Remove the multi process arg
|
8
|
+
def delayed_job_single_args
|
9
|
+
delayed_job_args.gsub(/-n\s\d\s*/, "")
|
10
|
+
end
|
15
11
|
|
16
|
-
def delayed_job_start_command
|
17
|
-
|
18
|
-
end
|
12
|
+
def delayed_job_start_command
|
13
|
+
"#{fetch(:rbenv_prefix)} bundle exec #{delayed_job_bin} #{delayed_job_single_args} -i \#{i} start"
|
14
|
+
end
|
19
15
|
|
20
|
-
def delayed_job_stop_command
|
21
|
-
|
22
|
-
end
|
16
|
+
def delayed_job_stop_command
|
17
|
+
"#{fetch(:rbenv_prefix)} bundle exec #{delayed_job_bin} #{delayed_job_single_args} -i \#{i} stop"
|
18
|
+
end
|
23
19
|
|
24
|
-
# Watch the delayed_job processes using the build in template
|
25
|
-
namespace :eye do
|
26
20
|
task :watch_process do
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
21
|
+
watch_process(:delayed_job, start_command: delayed_job_start_command,
|
22
|
+
stop_command: delayed_job_stop_command,
|
23
|
+
start_timeout: fetch(:eye_delayed_job_start_timeout, 60),
|
24
|
+
stop_timeout: fetch(:eye_delayed_job_stop_timeout, 30),
|
25
|
+
restart_timeout: fetch(:eye_delayed_job_restart_timeout, 30),
|
26
|
+
start_grace: fetch(:eye_delayed_job_start_grace, 100),
|
27
|
+
stop_grace: fetch(:eye_delayed_job_stop_grace, 30),
|
28
|
+
restart_grace: fetch(:eye_delayed_job_restart_grace, 30),
|
29
|
+
workers: fetch(:delayed_job_workers, 1)
|
30
|
+
)
|
33
31
|
end
|
34
|
-
end
|
35
32
|
|
36
|
-
# Override start, restart and stop delayed_job tasks to so they call
|
37
|
-
# the eye equivalents
|
38
|
-
|
39
|
-
['start','restart','stop'].each do |cmd|
|
33
|
+
# Override start, restart and stop delayed_job tasks to so they call
|
34
|
+
# the eye equivalents
|
35
|
+
['start', 'restart', 'stop'].each do |cmd|
|
40
36
|
if Rake::Task.task_defined?("delayed_job:#{cmd}")
|
41
37
|
Rake::Task["delayed_job:#{cmd}"].clear_actions
|
42
38
|
# Reload or restart delayed_job after the application is published
|
@@ -3,18 +3,19 @@
|
|
3
3
|
#########
|
4
4
|
|
5
5
|
# Watch the puma processes using the build in template
|
6
|
-
namespace :
|
6
|
+
namespace :puma do
|
7
7
|
task :watch_process do
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
watch_process(:puma, start_timeout: fetch(:eye_puma_start_timeout, 60),
|
9
|
+
stop_timeout: fetch(:eye_puma_stop_timeout, 30),
|
10
|
+
restart_timeout: fetch(:eye_puma_restart_timeout, 30),
|
11
|
+
start_grace: fetch(:eye_puma_start_grace, 100),
|
12
|
+
stop_grace: fetch(:eye_puma_stop_grace, 30),
|
13
|
+
restart_grace: fetch(:eye_puma_restart_grace, 30))
|
11
14
|
end
|
12
|
-
end
|
13
15
|
|
14
|
-
# Override start, restart and stop puma tasks to so they call
|
15
|
-
# the eye equivalents
|
16
|
-
|
17
|
-
['start','restart','stop'].each do |cmd|
|
16
|
+
# Override start, restart and stop puma tasks to so they call
|
17
|
+
# the eye equivalents
|
18
|
+
['start', 'restart', 'stop'].each do |cmd|
|
18
19
|
if Rake::Task.task_defined?("puma:#{cmd}")
|
19
20
|
Rake::Task["puma:#{cmd}"].clear_actions
|
20
21
|
# Reload or restart puma after the application is published
|
@@ -3,18 +3,19 @@
|
|
3
3
|
#########
|
4
4
|
|
5
5
|
# Watch the sphinx processes using the build in template
|
6
|
-
namespace :
|
6
|
+
namespace :thinking_sphinx do
|
7
7
|
task :watch_process do
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
watch_process(:sphinx, start_timeout: fetch(:eye_thinking_sphinx_start_timeout, 60),
|
9
|
+
stop_timeout: fetch(:eye_thinking_sphinx_stop_timeout, 30),
|
10
|
+
restart_timeout: fetch(:eye_thinking_sphinx_restart_timeout, 30),
|
11
|
+
start_grace: fetch(:eye_thinking_sphinx_start_grace, 100),
|
12
|
+
stop_grace: fetch(:eye_thinking_sphinx_stop_grace, 30),
|
13
|
+
restart_grace: fetch(:eye_thinking_sphinx_restart_grace, 30))
|
11
14
|
end
|
12
|
-
end
|
13
15
|
|
14
|
-
# Override start, restart and stop sphinx tasks to so they call
|
15
|
-
# the eye equivalents
|
16
|
-
|
17
|
-
['start','restart','stop'].each do |cmd|
|
16
|
+
# Override start, restart and stop sphinx tasks to so they call
|
17
|
+
# the eye equivalents
|
18
|
+
['start', 'restart', 'stop'].each do |cmd|
|
18
19
|
if Rake::Task.task_defined?("thinking_sphinx:#{cmd}")
|
19
20
|
Rake::Task["thinking_sphinx:#{cmd}"].clear_actions
|
20
21
|
# Reload or restart after the application is published
|
@@ -3,18 +3,19 @@
|
|
3
3
|
#########
|
4
4
|
|
5
5
|
# Watch the unicorn processes using the build in template
|
6
|
-
namespace :
|
6
|
+
namespace :unicorn do
|
7
7
|
task :watch_process do
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
watch_process(:unicorn, start_timeout: fetch(:eye_puma_start_timeout, 60),
|
9
|
+
stop_timeout: fetch(:eye_puma_stop_timeout, 30),
|
10
|
+
restart_timeout: fetch(:eye_puma_restart_timeout, 30),
|
11
|
+
start_grace: fetch(:eye_puma_start_grace, 100),
|
12
|
+
stop_grace: fetch(:eye_puma_stop_grace, 30),
|
13
|
+
restart_grace: fetch(:eye_puma_restart_grace, 30))
|
11
14
|
end
|
12
|
-
end
|
13
15
|
|
14
|
-
# Override start, restart and stop unicorn tasks to so they call
|
15
|
-
# the eye equivalents
|
16
|
-
|
17
|
-
['start','restart','stop'].each do |cmd|
|
16
|
+
# Override start, restart and stop unicorn tasks to so they call
|
17
|
+
# the eye equivalents
|
18
|
+
['start', 'restart', 'stop'].each do |cmd|
|
18
19
|
if Rake::Task.task_defined?("unicorn:#{cmd}")
|
19
20
|
Rake::Task["unicorn:#{cmd}"].clear_actions
|
20
21
|
# Reload or restart unicorn after the application is published
|
@@ -25,13 +25,14 @@ namespace :load do
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
-
namespace :env do
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
end
|
28
|
+
# namespace :env do
|
29
|
+
# desc 'Env variables changed'
|
30
|
+
# task :changed do
|
31
|
+
# end
|
32
|
+
# end
|
33
33
|
|
34
34
|
namespace :eye do
|
35
|
+
WATCHED_PROCESSES = %w[unicorn delayed_job thinking_sphinx puma]
|
35
36
|
|
36
37
|
desc "Loads eye config and starts monitoring"
|
37
38
|
task :load do
|
@@ -60,48 +61,45 @@ namespace :eye do
|
|
60
61
|
end
|
61
62
|
end
|
62
63
|
end
|
63
|
-
end
|
64
|
-
|
65
|
-
# Adds some task on complement the capistrano3-unicorn tasks
|
66
|
-
# This tasks are under the negroku namespace for easier identification
|
67
|
-
namespace :negroku do
|
68
|
-
|
69
|
-
namespace :eye do
|
70
64
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
65
|
+
desc "Upload eye configuration file"
|
66
|
+
task :setup do
|
67
|
+
WATCHED_PROCESSES.each do |task_name|
|
68
|
+
begin
|
69
|
+
Rake::Task["#{task_name}:watch_process"].invoke
|
70
|
+
rescue StandardError
|
71
|
+
end
|
72
|
+
end
|
78
73
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
end
|
74
|
+
on release_roles fetch(:eye_roles) do
|
75
|
+
within "#{shared_path}/config" do
|
76
|
+
processes = fetch(:eye_watched_processes, {})
|
83
77
|
|
84
|
-
|
85
|
-
upload! config, '/tmp/application.eye'
|
78
|
+
template_path = fetch(:eye_application_template)
|
86
79
|
|
87
|
-
|
80
|
+
# use a build in template if the template doesn't exists in the project
|
81
|
+
unless File.exists?(template_path)
|
82
|
+
template_path = "capistrano/templates/eye/application.eye.erb"
|
88
83
|
end
|
89
|
-
end
|
90
|
-
end
|
91
84
|
|
92
|
-
|
93
|
-
|
85
|
+
config = build_template(template_path, nil, binding)
|
86
|
+
upload! config, '/tmp/application.eye'
|
94
87
|
|
95
|
-
|
96
|
-
|
97
|
-
invoke 'eye:load'
|
98
|
-
invoke 'eye:start'
|
88
|
+
execute :mv, '/tmp/application.eye', 'eye.rb'
|
89
|
+
end
|
99
90
|
end
|
91
|
+
end
|
100
92
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
93
|
+
desc "Restart application by stoping, reloading and starting"
|
94
|
+
task :hard_restart do
|
95
|
+
invoke 'eye:stop'
|
96
|
+
sleep 5
|
97
|
+
invoke 'eye:load'
|
98
|
+
invoke 'eye:start'
|
105
99
|
end
|
106
100
|
|
101
|
+
before "deploy:published", "eye:setup"
|
102
|
+
after "eye:setup", "eye:load"
|
103
|
+
|
104
|
+
define_logs(:eye, app: 'eye.log')
|
107
105
|
end
|
@@ -1,13 +1,17 @@
|
|
1
1
|
group 'delayed-jobs' do
|
2
2
|
chain grace: 10.seconds
|
3
3
|
|
4
|
-
start_timeout <%= options[:start_timeout]
|
5
|
-
stop_timeout <%= options[:stop_timeout]
|
6
|
-
restart_timeout <%= options[:restart_timeout]
|
4
|
+
start_timeout <%= options[:start_timeout] %>.seconds
|
5
|
+
stop_timeout <%= options[:stop_timeout] %>.seconds
|
6
|
+
restart_timeout <%= options[:restart_timeout] %>.seconds
|
7
7
|
|
8
|
-
|
8
|
+
start_grace <%= options[:start_grace] %>.seconds
|
9
|
+
stop_grace <%= options[:stop_grace] %>.seconds
|
10
|
+
restart_grace <%= options[:restart_grace] %>.seconds
|
9
11
|
|
10
|
-
|
12
|
+
workers_count = <%= options[:workers] %>
|
13
|
+
|
14
|
+
(0 ... workers_count).each do |i|
|
11
15
|
|
12
16
|
process "worker-#{i}" do
|
13
17
|
pid_file "tmp/pids/delayed_job.#{i}.pid"
|
@@ -18,4 +22,3 @@
|
|
18
22
|
end
|
19
23
|
|
20
24
|
end
|
21
|
-
|
@@ -1,10 +1,13 @@
|
|
1
1
|
process "<%= options[:name] %>" do
|
2
|
-
start_timeout <%= options[:start_timeout] || "30.seconds" %>
|
3
|
-
stop_timeout <%= options[:stop_timeout] || "20.seconds" %>
|
4
|
-
restart_timeout <%= options[:restart_timeout] || "30.seconds" %>
|
5
|
-
|
6
2
|
pid_file "<%= options[:pid_file] %>"
|
7
3
|
start_command "<%= options[:start_command] %>"
|
8
4
|
stop_command "<%= options[:stop_command] %>"
|
9
|
-
end
|
10
5
|
|
6
|
+
start_timeout <%= options[:start_timeout] || 60 %>.seconds
|
7
|
+
stop_timeout <%= options[:stop_timeout] || 30 %>.seconds
|
8
|
+
restart_timeout <%= options[:restart_timeout] || 30 %>.seconds
|
9
|
+
|
10
|
+
start_grace <%= options[:start_grace] || 100 %>.seconds
|
11
|
+
stop_grace <%= options[:stop_grace] || 30 %>.seconds
|
12
|
+
restart_grace <%= options[:restart_grace] || 30 %>.seconds
|
13
|
+
end
|
@@ -14,6 +14,11 @@
|
|
14
14
|
<%= fetch(:puma_master_cpu_checks) %>
|
15
15
|
<%= fetch(:puma_master_memory_checks) %>
|
16
16
|
|
17
|
-
start_timeout
|
18
|
-
|
17
|
+
start_timeout <%= options[:start_timeout] %>.seconds
|
18
|
+
stop_timeout <%= options[:stop_timeout] %>.seconds
|
19
|
+
restart_timeout <%= options[:restart_timeout] %>.seconds
|
20
|
+
|
21
|
+
start_grace <%= options[:start_grace] %>.seconds
|
22
|
+
stop_grace <%= options[:stop_grace] %>.seconds
|
23
|
+
restart_grace <%= options[:restart_grace] %>.seconds
|
19
24
|
end
|
@@ -9,6 +9,11 @@
|
|
9
9
|
|
10
10
|
check :cpu, :every => 30, :below => 80, :times => 3
|
11
11
|
|
12
|
-
start_timeout
|
13
|
-
|
12
|
+
start_timeout <%= options[:start_timeout] %>.seconds
|
13
|
+
stop_timeout <%= options[:stop_timeout] %>.seconds
|
14
|
+
restart_timeout <%= options[:restart_timeout] %>.seconds
|
15
|
+
|
16
|
+
start_grace <%= options[:start_grace] %>.seconds
|
17
|
+
stop_grace <%= options[:stop_grace] %>.seconds
|
18
|
+
restart_grace <%= options[:restart_grace] %>.seconds
|
14
19
|
end
|
@@ -14,8 +14,13 @@
|
|
14
14
|
<%= fetch(:unicorn_master_cpu_checks) %>
|
15
15
|
<%= fetch(:unicorn_master_memory_checks) %>
|
16
16
|
|
17
|
-
start_timeout
|
18
|
-
|
17
|
+
start_timeout <%= options[:start_timeout] %>.seconds
|
18
|
+
stop_timeout <%= options[:stop_timeout] %>.seconds
|
19
|
+
restart_timeout <%= options[:restart_timeout] %>.seconds
|
20
|
+
|
21
|
+
start_grace <%= options[:start_grace] %>.seconds
|
22
|
+
stop_grace <%= options[:stop_grace] %>.seconds
|
23
|
+
restart_grace <%= options[:restart_grace] %>.seconds
|
19
24
|
|
20
25
|
monitor_children do
|
21
26
|
stop_command "kill -QUIT {PID}"
|
data/lib/negroku/version.rb
CHANGED
data/negroku.gemspec
CHANGED
@@ -22,7 +22,8 @@ spec = Gem::Specification.new do |s|
|
|
22
22
|
|
23
23
|
s.add_runtime_dependency('rake', '~> 10.1')
|
24
24
|
s.add_runtime_dependency('bundler', '~> 1.0')
|
25
|
-
s.add_runtime_dependency('
|
25
|
+
s.add_runtime_dependency('activesupport', '~> 3.0')
|
26
|
+
s.add_runtime_dependency('capistrano', '~> 3.4.0')
|
26
27
|
s.add_runtime_dependency('capistrano-rbenv', '~> 2.0.3')
|
27
28
|
s.add_runtime_dependency('capistrano-rails', '~> 1.1.3')
|
28
29
|
s.add_runtime_dependency('capistrano-bundler', '~> 1.1.4')
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: negroku
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Juan Ignacio Donoso
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-10-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rdoc
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - ~>
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '1.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: activesupport
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ~>
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '3.0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ~>
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '3.0'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
98
|
name: capistrano
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|