capistrano-tools 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +19 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +57 -0
- data/Rakefile +1 -0
- data/capistrano-tools.gemspec +23 -0
- data/lib/capistrano-tools/templater.rb +43 -0
- data/lib/capistrano-tools/unicorn.rb +194 -0
- data/lib/capistrano-tools/version.rb +5 -0
- data/lib/capistrano-tools.rb +15 -0
- data/lib/templates/database.yml.erb +9 -0
- data/lib/templates/mailer.yml.erb +9 -0
- data/lib/templates/unicorn.rb.erb +27 -0
- metadata +90 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Arturs Kreipans
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
# Capistrano::Tools
|
2
|
+
|
3
|
+
It is a collection of scripts for capistrano
|
4
|
+
* unicorn deploy script
|
5
|
+
* script to manage config yml fails (prompt paswords on deploy:setup)
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem 'capistrano-tools', :git => 'git@github.com:fragallia/capistrano-tools.git'
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
## Usage
|
18
|
+
### Unicorn
|
19
|
+
Require the gem in your deploy script
|
20
|
+
~~~
|
21
|
+
require 'capistrano-tools'
|
22
|
+
~~~
|
23
|
+
add deploy restart after callback for unicorn
|
24
|
+
~~~
|
25
|
+
after 'deploy:restart', 'unicorn:reload'
|
26
|
+
~~~
|
27
|
+
|
28
|
+
You can set following variables for unicorn:
|
29
|
+
|
30
|
+
- unicorn\_env : unicron environment, defaults to **rails_env** or **env**.
|
31
|
+
- unicorn\_pid : location of unicron pid file, defaults to **shared/pids** folder
|
32
|
+
- unicorn\_bundle : path to bundle library, defaults to **bundle\_cmd** or "bundle"
|
33
|
+
- unicorn\_bin : path to unicron library, defaults to 'unicron'
|
34
|
+
|
35
|
+
** If your are using unicron with unix socket file, do not locate it in to current directory. **
|
36
|
+
|
37
|
+
### Templater
|
38
|
+
Require the gem in your deploy script
|
39
|
+
~~~
|
40
|
+
require 'capistrano-tools'
|
41
|
+
~~~
|
42
|
+
Create template and set templater variable:
|
43
|
+
~~~
|
44
|
+
set :templater, :template_dir => "lib/capistrano/templates", :templates => ['database']
|
45
|
+
~~~
|
46
|
+
|
47
|
+
## TODO
|
48
|
+
|
49
|
+
* create generator to create default files (config/unicorn/production.rb, config/deploy.rb, config/deploy/production.rb, Capfile)
|
50
|
+
|
51
|
+
## Contributing
|
52
|
+
|
53
|
+
1. Fork it
|
54
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
55
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
56
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
57
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'capistrano-tools/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "capistrano-tools"
|
8
|
+
gem.version = Capistrano::Tools::VERSION
|
9
|
+
gem.authors = ["Arturs Kreipans"]
|
10
|
+
gem.email = ["arturs.kreipans@gmail.com"]
|
11
|
+
gem.description = %q{Integration scripts for Capistrano}
|
12
|
+
gem.summary = %q{Integration scripts for Capistrano}
|
13
|
+
gem.homepage = ""
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_development_dependency 'rake'
|
21
|
+
|
22
|
+
gem.add_runtime_dependency 'capistrano'
|
23
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Capistrano::Tools
|
2
|
+
class Templater
|
3
|
+
TASKS = [
|
4
|
+
'templater:setup',
|
5
|
+
'templater:symlink'
|
6
|
+
]
|
7
|
+
def self.load_into(capistrano_config)
|
8
|
+
capistrano_config.load do
|
9
|
+
namespace :templater do
|
10
|
+
task :setup, :except => { :no_release => true } do
|
11
|
+
templater = fetch(:templater, {})
|
12
|
+
location = templater.fetch(:template_dir, "templates")
|
13
|
+
|
14
|
+
templater.fetch(:templates, []).each do | template |
|
15
|
+
path_to_template = File.join(File.expand_path('../../', __FILE__), "#{location}/#{template}.yml.erb")
|
16
|
+
if File.file?(path_to_template)
|
17
|
+
config = ERB.new(File.read(path_to_template))
|
18
|
+
|
19
|
+
run "mkdir -p #{shared_path}/config"
|
20
|
+
put config.result(binding), "#{shared_path}/config/#{template}.yml"
|
21
|
+
else
|
22
|
+
puts "[WARNING] template #{path_to_template} not found"
|
23
|
+
next
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
task :symlink, :except => { :no_release => true } do
|
29
|
+
templater = fetch(:templater, {})
|
30
|
+
templater.fetch(:templates, []).each do | template |
|
31
|
+
run "ln -nfs #{shared_path}/config/#{template}.yml #{release_path}/config/#{template}.yml"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
after "deploy:setup", "templater:setup" unless fetch(:skip_templater_setup, false)
|
38
|
+
after "deploy:finalize_update", "templater:symlink"
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,194 @@
|
|
1
|
+
require 'capistrano'
|
2
|
+
require 'capistrano/version'
|
3
|
+
|
4
|
+
module Capistrano::Tools
|
5
|
+
class Unicorn
|
6
|
+
TASKS = [
|
7
|
+
'unicorn:start',
|
8
|
+
'unicorn:stop',
|
9
|
+
'unicorn:restart',
|
10
|
+
'unicorn:reload',
|
11
|
+
'unicorn:shutdown',
|
12
|
+
'unicorn:add_worker',
|
13
|
+
'unicorn:remove_worker'
|
14
|
+
]
|
15
|
+
|
16
|
+
def self.load_into(capistrano_config)
|
17
|
+
capistrano_config.load do
|
18
|
+
before(Capistrano::Tools::Unicorn::TASKS) do
|
19
|
+
_cset(:unicorn_pid) { fetch(:unicorn_pid, "#{shared_path}/pids/unicorn.pid") }
|
20
|
+
_cset(:unicorn_env) { fetch(:unicorn_env, fetch(:rails_env, fetch(:env, 'production'))) }
|
21
|
+
_cset(:unicorn_bin) { fetch(:unicorn_bin, "unicorn") }
|
22
|
+
_cset(:unicorn_bundle) { fetch(:unicorn_bundle, fetch(:bundle_cmd, 'bundle')) }
|
23
|
+
end
|
24
|
+
|
25
|
+
# Check if a remote process exists using its pid file
|
26
|
+
#
|
27
|
+
def remote_process_exists?(pid_file)
|
28
|
+
"[ -e #{pid_file} ] && kill -0 `cat #{pid_file}` > /dev/null 2>&1"
|
29
|
+
end
|
30
|
+
|
31
|
+
# Stale Unicorn process pid file
|
32
|
+
#
|
33
|
+
def old_unicorn_pid
|
34
|
+
"#{unicorn_pid}.oldbin"
|
35
|
+
end
|
36
|
+
|
37
|
+
# Command to check if Unicorn is running
|
38
|
+
#
|
39
|
+
def unicorn_is_running?
|
40
|
+
remote_process_exists?(unicorn_pid)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Command to check if stale Unicorn is running
|
44
|
+
#
|
45
|
+
def old_unicorn_is_running?
|
46
|
+
remote_process_exists?(old_unicorn_pid)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Get unicorn master process PID (using the shell)
|
50
|
+
#
|
51
|
+
def get_unicorn_pid(pid_file=unicorn_pid)
|
52
|
+
"`cat #{pid_file}`"
|
53
|
+
end
|
54
|
+
|
55
|
+
# Get unicorn master (old) process PID
|
56
|
+
#
|
57
|
+
def get_old_unicorn_pid
|
58
|
+
get_unicorn_pid(old_unicorn_pid)
|
59
|
+
end
|
60
|
+
|
61
|
+
# Send a signal to a unicorn master processes
|
62
|
+
#
|
63
|
+
def unicorn_send_signal(signal, pid=get_unicorn_pid)
|
64
|
+
"#{try_sudo} kill -s #{signal} #{pid}"
|
65
|
+
end
|
66
|
+
|
67
|
+
# Kill Unicorns in multiple ways O_O
|
68
|
+
#
|
69
|
+
def kill_unicorn(signal)
|
70
|
+
script = <<-END
|
71
|
+
if #{unicorn_is_running?}; then
|
72
|
+
echo "Stopping Unicorn...";
|
73
|
+
#{unicorn_send_signal(signal)};
|
74
|
+
else
|
75
|
+
echo "Unicorn is not running.";
|
76
|
+
fi;
|
77
|
+
END
|
78
|
+
|
79
|
+
script
|
80
|
+
end
|
81
|
+
|
82
|
+
# Start the Unicorn server
|
83
|
+
#
|
84
|
+
def start_unicorn
|
85
|
+
primary_config_path = "#{current_path}/config/unicorn.rb"
|
86
|
+
secondary_config_path = "#{current_path}/config/unicorn/#{unicorn_env}.rb"
|
87
|
+
|
88
|
+
script = <<-END
|
89
|
+
if [ -e #{primary_config_path} ]; then
|
90
|
+
UNICORN_CONFIG_PATH=#{primary_config_path};
|
91
|
+
else
|
92
|
+
if [ -e #{secondary_config_path} ]; then
|
93
|
+
UNICORN_CONFIG_PATH=#{secondary_config_path};
|
94
|
+
else
|
95
|
+
echo "Config file for \"#{unicorn_env}\" environment was not found at either \"#{primary_config_path}\" or \"#{secondary_config_path}\"";
|
96
|
+
exit 1;
|
97
|
+
fi;
|
98
|
+
fi;
|
99
|
+
|
100
|
+
if [ -e #{unicorn_pid} ]; then
|
101
|
+
if kill -0 `cat #{unicorn_pid}` > /dev/null 2>&1; then
|
102
|
+
echo "Unicorn is already running!";
|
103
|
+
exit 0;
|
104
|
+
fi;
|
105
|
+
|
106
|
+
rm #{unicorn_pid};
|
107
|
+
fi;
|
108
|
+
|
109
|
+
echo "Starting Unicorn...";
|
110
|
+
cd #{current_path} && BUNDLE_GEMFILE=#{current_path}/Gemfile #{unicorn_bundle} exec #{unicorn_bin} -c $UNICORN_CONFIG_PATH -E #{unicorn_env} -D;
|
111
|
+
END
|
112
|
+
|
113
|
+
script
|
114
|
+
end
|
115
|
+
|
116
|
+
#
|
117
|
+
# Unicorn cap tasks
|
118
|
+
#
|
119
|
+
namespace :unicorn do
|
120
|
+
desc 'Start Unicorn master process'
|
121
|
+
task :start, :roles => :app, :except => {:no_release => true} do
|
122
|
+
run start_unicorn
|
123
|
+
end
|
124
|
+
|
125
|
+
desc 'Stop Unicorn'
|
126
|
+
task :stop, :roles => :app, :except => {:no_release => true} do
|
127
|
+
run kill_unicorn('QUIT')
|
128
|
+
end
|
129
|
+
|
130
|
+
desc 'Immediately shutdown Unicorn'
|
131
|
+
task :shutdown, :roles => :app, :except => {:no_release => true} do
|
132
|
+
run kill_unicorn('TERM')
|
133
|
+
end
|
134
|
+
|
135
|
+
desc 'Restart Unicorn'
|
136
|
+
task :restart, :roles => :app, :except => {:no_release => true} do
|
137
|
+
run <<-END
|
138
|
+
if #{unicorn_is_running?}; then
|
139
|
+
echo "Restarting Unicorn...";
|
140
|
+
#{unicorn_send_signal('USR2')};
|
141
|
+
else
|
142
|
+
#{start_unicorn}
|
143
|
+
fi;
|
144
|
+
|
145
|
+
sleep 2; # in order to wait for the (old) pidfile to show up
|
146
|
+
|
147
|
+
if #{old_unicorn_is_running?}; then
|
148
|
+
#{unicorn_send_signal('QUIT', get_old_unicorn_pid)};
|
149
|
+
fi;
|
150
|
+
END
|
151
|
+
end
|
152
|
+
|
153
|
+
desc 'Reload Unicorn'
|
154
|
+
task :reload, :roles => :app, :except => {:no_release => true} do
|
155
|
+
run <<-END
|
156
|
+
if #{unicorn_is_running?}; then
|
157
|
+
echo "Reloading Unicorn...";
|
158
|
+
#{unicorn_send_signal('HUP')};
|
159
|
+
else
|
160
|
+
#{start_unicorn}
|
161
|
+
fi;
|
162
|
+
END
|
163
|
+
end
|
164
|
+
|
165
|
+
desc 'Add a new worker'
|
166
|
+
task :add_worker, :roles => :app, :except => {:no_release => true} do
|
167
|
+
run <<-END
|
168
|
+
if #{unicorn_is_running?}; then
|
169
|
+
echo "Adding a new Unicorn worker...";
|
170
|
+
#{unicorn_send_signal('TTIN')};
|
171
|
+
else
|
172
|
+
echo "Unicorn is not running.";
|
173
|
+
fi;
|
174
|
+
END
|
175
|
+
end
|
176
|
+
|
177
|
+
desc 'Remove amount of workers'
|
178
|
+
task :remove_worker, :roles => :app, :except => {:no_release => true} do
|
179
|
+
run <<-END
|
180
|
+
if #{unicorn_is_running?}; then
|
181
|
+
echo "Removing a Unicorn worker...";
|
182
|
+
#{unicorn_send_signal('TTOU')};
|
183
|
+
else
|
184
|
+
echo "Unicorn is not running.";
|
185
|
+
fi;
|
186
|
+
END
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require "capistrano-tools/version"
|
2
|
+
|
3
|
+
module Capistrano
|
4
|
+
module Tools
|
5
|
+
unless Capistrano::Configuration.respond_to?(:instance)
|
6
|
+
abort "This extension requires Capistrano 2"
|
7
|
+
end
|
8
|
+
|
9
|
+
require 'capistrano-tools/unicorn'
|
10
|
+
require 'capistrano-tools/templater'
|
11
|
+
|
12
|
+
Capistrano::Tools::Unicorn.load_into(Capistrano::Configuration.instance)
|
13
|
+
Capistrano::Tools::Templater.load_into(Capistrano::Configuration.instance)
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
production:
|
2
|
+
adapter: <%= Capistrano::CLI.ui.ask("Enter database adapter: ") %>
|
3
|
+
database: <%= Capistrano::CLI.ui.ask("Enter database name: ") %>
|
4
|
+
username: <%= Capistrano::CLI.ui.ask("Enter database username: ") %>
|
5
|
+
password: <%= Capistrano::CLI.ui.ask("Enter database password: ") %>
|
6
|
+
host: <%= Capistrano::CLI.ui.ask("Enter database host: ") %>
|
7
|
+
encoding: utf8
|
8
|
+
timeout: 5000
|
9
|
+
|
@@ -0,0 +1,9 @@
|
|
1
|
+
production:
|
2
|
+
address: <%= Capistrano::CLI.ui.ask("Enter SMTP option address: ") %>
|
3
|
+
port: <%= Capistrano::CLI.ui.ask("Enter SMTP option port: ") %>
|
4
|
+
domain: <%= Capistrano::CLI.ui.ask("Enter SMTP option domain: ") %>
|
5
|
+
user_name: <%= Capistrano::CLI.ui.ask("Enter SMTP option user_name: ") %>
|
6
|
+
password: <%= Capistrano::CLI.ui.ask("Enter SMTP option password: ") %>
|
7
|
+
authentication: <%= Capistrano::CLI.ui.ask("Enter SMTP option authentication: ") %>
|
8
|
+
enable_starttls_auto: <%= Capistrano::CLI.ui.ask("Enter SMTP option enable_starttls_auto: ") %>
|
9
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# Set your full path to application.
|
2
|
+
app_path = "<%= fetch(:deploy_to, "/var/www/#{fetch(:application, "app")}") %>/current"
|
3
|
+
|
4
|
+
# Set unicorn options
|
5
|
+
worker_processes 2
|
6
|
+
|
7
|
+
timeout 30
|
8
|
+
|
9
|
+
# socket for nginx
|
10
|
+
listen "/tmp/#{fetch(:application, 'app')}.unicorn.sock", :backlog => 64
|
11
|
+
|
12
|
+
# Spawn unicorn master worker for user deploy (group: deploy)
|
13
|
+
user 'deploy', 'deploy'
|
14
|
+
|
15
|
+
# Fill path to your app
|
16
|
+
working_directory app_path
|
17
|
+
|
18
|
+
# Should be 'production' by default, otherwise use other env
|
19
|
+
rails_env = ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'production'
|
20
|
+
|
21
|
+
# Set the path of the log files inside the log folder of the testapp
|
22
|
+
stderr_path "#{app_path}/log/unicorn.stderr.log"
|
23
|
+
stdout_path "#{app_path}/log/unicorn.stdout.log"
|
24
|
+
|
25
|
+
pid "#{app_path}/tmp/pids/unicorn.pid"
|
26
|
+
|
27
|
+
|
metadata
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: capistrano-tools
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Arturs Kreipans
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-04-10 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: capistrano
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
description: Integration scripts for Capistrano
|
47
|
+
email:
|
48
|
+
- arturs.kreipans@gmail.com
|
49
|
+
executables: []
|
50
|
+
extensions: []
|
51
|
+
extra_rdoc_files: []
|
52
|
+
files:
|
53
|
+
- .gitignore
|
54
|
+
- Gemfile
|
55
|
+
- LICENSE.txt
|
56
|
+
- README.md
|
57
|
+
- Rakefile
|
58
|
+
- capistrano-tools.gemspec
|
59
|
+
- lib/capistrano-tools.rb
|
60
|
+
- lib/capistrano-tools/templater.rb
|
61
|
+
- lib/capistrano-tools/unicorn.rb
|
62
|
+
- lib/capistrano-tools/version.rb
|
63
|
+
- lib/templates/database.yml.erb
|
64
|
+
- lib/templates/mailer.yml.erb
|
65
|
+
- lib/templates/unicorn.rb.erb
|
66
|
+
homepage: ''
|
67
|
+
licenses: []
|
68
|
+
post_install_message:
|
69
|
+
rdoc_options: []
|
70
|
+
require_paths:
|
71
|
+
- lib
|
72
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
79
|
+
none: false
|
80
|
+
requirements:
|
81
|
+
- - ! '>='
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
requirements: []
|
85
|
+
rubyforge_project:
|
86
|
+
rubygems_version: 1.8.24
|
87
|
+
signing_key:
|
88
|
+
specification_version: 3
|
89
|
+
summary: Integration scripts for Capistrano
|
90
|
+
test_files: []
|