erCapistranoDrupal 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in erCapistranoDrupal.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 everright.chen
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,178 @@
1
+ erCapistranoDrupal
2
+ ==================
3
+
4
+ erCapistranoDrupal is a drupal deploy file for Capistrano. Includes site install, database migration; support subsites.
5
+
6
+ ## Requirements
7
+ * [Drush](http://drush.ws)
8
+ * [Capistrano](https://github.com/capistrano/capistrano)
9
+ * [Capistrano-ext](https://github.com/neerajkumar/capistrano-ext)
10
+
11
+ ## Versions
12
+ * Drupal 7
13
+ * Drupal 6 will be support on next version
14
+
15
+ ## Installation
16
+
17
+ $ gem install erCapistranoDrupal
18
+
19
+ ## Usage
20
+
21
+ Open your application's `Capfile` and make it begins like this:
22
+
23
+ require 'rubygems'
24
+ require 'erCapistranoDrupal'
25
+ load 'config/deploy'
26
+
27
+ Taking care to remove the original `require 'deploy'` as this is where all the standard tasks are defined.
28
+
29
+ You should then be able to proceed as you would usually, you may want to familiarise yourself with the truncated list of tasks, you can get a full list with:
30
+
31
+ $ cap -T
32
+
33
+ ## Special Files
34
+ ### .htaccess
35
+ * /htaccess-[dev|staging|production]
36
+ * /htaccess
37
+
38
+ ### robots.txt
39
+ * /robots-[dev|staging|production].txt
40
+
41
+ ### settings.php
42
+ * /sites/[default]/settings.[dev|staging|production].php
43
+ * [shared_path]/sites/[default]/settings.php
44
+
45
+ ### database migrations
46
+ * /migration/[default]/[yyyymmdd]/[hhiiss]_task.sql
47
+ * /migration/[default]/[yyyymmdd]/[hhiiss]_task.drush
48
+
49
+ #### SQL File
50
+ # add user (2) to role (3)
51
+ insert into users_roles (uid, rid) values (2, 3);
52
+
53
+ #### Drush File
54
+ # create new user 'everright'
55
+ user-create everright --mail="everright@example.com" --password="123456"
56
+ # enable token module
57
+ en token
58
+
59
+ ## Default Variables
60
+
61
+ ### Where to save the download resources
62
+ * :dp_local_backup, '/backup'
63
+
64
+ ### Directories under shared_path: drupal sites, database backup, files backup, migration history
65
+ * :dp_sites, 'sites'
66
+ * :dp_migration, 'migration'
67
+ * :dp_released_files, 'released_files'
68
+ * :dp_released_db, 'released_db'
69
+
70
+ ### Domains, virtualhosts
71
+ * :dp_domains, ['default']
72
+ * :dp_default_domain, 'default'
73
+ * :dp_virtual_hosts, []
74
+
75
+ ### Share files when use multiple web servers
76
+ * :dp_shared_files, false
77
+ * :dp_shared_path, '/nfs'
78
+
79
+ ### Drush tool
80
+ * :drush, '/usr/bin/drush'
81
+
82
+ ### Drush site install info
83
+ If you want to install the drupal when first deploy, then you need to change these variables.
84
+ * :dp_site_install, false
85
+ * :dp_site_db_url, nil
86
+ * :dp_site_profile, 'standard'
87
+ * :dp_site_name, 'Drupal 7 Demo'
88
+ * :dp_site_admin_user, 'admin'
89
+ * :dp_site_admin_pass, 'admin'
90
+
91
+ ### Maintainance key
92
+ * :dp_maintainance_keys, {'default' => 'maintenance_mode'}
93
+
94
+ Support "[Read Only Mode](https://drupal.org/project/readonlymode)" module.
95
+
96
+ System will be auto set the maintainance key to "site_readonly" when "Read Only Mode" module enabled.
97
+
98
+ ## Deploy Example
99
+ ### deploy.rb
100
+
101
+ # application name
102
+ set :application, 'd7demo_deploy'
103
+
104
+ # remote server user
105
+ set :user, 'deploy'
106
+ set :use_sudo, false
107
+
108
+ # set multiple environments
109
+ set :stages, ['dev', 'staging', 'production']
110
+ set :default_stage, 'dev'
111
+
112
+ require 'capistrano/ext/multistage'
113
+
114
+ # set scm
115
+ set :scm, :git
116
+ set :repository, 'git@github.com:everright/d7demo.git'
117
+ set :branch, 'master'
118
+ set :deploy_via, :copy
119
+ set :copy_cache, true
120
+ set :copy_exclude, %w(.git .gitignore)
121
+
122
+ ### deploy/dev.rb
123
+ # define servers, must be set primary web.
124
+ server 'dev_server', :web, :primary => true
125
+
126
+ # deploy to
127
+ set :deploy_to, "/var/www/sites/dev.d7demo.local"
128
+
129
+ # site install info
130
+ set :dp_site_install, true
131
+ set :dp_site_db_url, "mysql://drupal_all:123456@dbserver/d7_demo_dev"
132
+ set :dp_site_profile, "standard"
133
+ set :dp_site_name, "D7 Demo"
134
+ set :dp_site_admin_user, "admin"
135
+ set :dp_site_admin_pass, "admin"
136
+
137
+ ### deploy/staging.rb
138
+ # define servers, must be set primary web.
139
+ server 'staging_server', :web, :primary => true
140
+
141
+ # deploy to
142
+ set :deploy_to, "/var/www/sites/staging.d7demo.local"
143
+
144
+ # site install info
145
+ set :site_install, true
146
+ set :site_db_url, "mysql://drupal_all:123456@dbserver/d7_demo_staging"
147
+ set :site_profile, "standard"
148
+ set :site_name, "D7 Demo"
149
+ set :site_admin_user, "admin"
150
+ set :site_admin_pass, "admin"
151
+
152
+ ### deploy/production.rb
153
+
154
+ # define servers, must be set primary web.
155
+ server 'production_server1', :web, :primary => true
156
+ server 'production_server2', :web
157
+ server 'production_server3', :web, {
158
+ :user => 'other_deploy_user'
159
+ }
160
+
161
+ # deploy to
162
+ set :deploy_to, "/var/www/sites/www.d7demo.local"
163
+
164
+ # site install info
165
+ set :dp_site_install, true
166
+ set :dp_site_db_url, "mysql://drupal_all:123456@dbserver/d7_demo"
167
+ set :dp_site_profile, "standard"
168
+ set :dp_site_name, "D7 Demo"
169
+ set :dp_site_admin_user, "admin"
170
+ set :dp_site_admin_pass, "admin"
171
+
172
+ # If have multiple webservers, enable share files
173
+ set :dp_shared_files, true
174
+
175
+ ## Changelog:
176
+
177
+ ### Version 0.1.0 - June 17 2013
178
+ * First release
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'erCapistranoDrupal/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "erCapistranoDrupal"
8
+ spec.version = ErCapistranoDrupal::VERSION
9
+ spec.authors = ["everright.chen"]
10
+ spec.email = ["everright.chen@gmail.com"]
11
+ spec.description = %q{A Drupal Deploy File for Capistrano. Includes site install, database migration; support multiple subsites.}
12
+ spec.summary = %q{A Drupal Deploy File for Capistrano.}
13
+ spec.homepage = %q{http://github.com/everright/erCapistranoDrupal}
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_runtime_dependency "capistrano"
22
+ spec.add_runtime_dependency "capistrano-ext"
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.3"
25
+ spec.add_development_dependency "rake"
26
+ end
@@ -0,0 +1,3 @@
1
+ module ErCapistranoDrupal
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,833 @@
1
+ Capistrano::Configuration.instance(:must_exist).load do
2
+
3
+ require 'capistrano/recipes/deploy/scm'
4
+ require 'capistrano/recipes/deploy/strategy'
5
+
6
+ def _cset(name, *args, &block)
7
+ unless exists?(name)
8
+ set(name, *args, &block)
9
+ end
10
+ end
11
+
12
+ # =========================================================================
13
+ # These variables MUST be set in the client capfiles. If they are not set,
14
+ # the deploy will fail with an error.
15
+ # =========================================================================
16
+
17
+ _cset(:application) { abort "Please specify the name of your application, set :application, 'foo'" }
18
+ _cset(:repository) { abort "Please specify the repository that houses your application's code, set :repository, 'foo'" }
19
+
20
+ # =========================================================================
21
+ # These variables may be set in the client capfile if their default values
22
+ # are not sufficient.
23
+ # =========================================================================
24
+
25
+ _cset(:scm) { scm_default }
26
+ _cset :deploy_via, :checkout
27
+
28
+ _cset(:deploy_to) { "/u/apps/#{application}" }
29
+ _cset(:revision) { source.head }
30
+
31
+ # =========================================================================
32
+ # These variables should NOT be changed unless you are very confident in
33
+ # what you are doing. Make sure you understand all the implications of your
34
+ # changes if you do decide to muck with these!
35
+ # =========================================================================
36
+
37
+ _cset(:source) { Capistrano::Deploy::SCM.new(scm, self) }
38
+ _cset(:real_revision) { source.local.query_revision(revision) { |cmd| with_env("LC_ALL", "C") { run_locally(cmd) } } }
39
+
40
+ _cset(:strategy) { Capistrano::Deploy::Strategy.new(deploy_via, self) }
41
+
42
+ _cset(:release_name) { set :deploy_timestamped, true; Time.now.utc.strftime("%Y%m%d%H%M%S") }
43
+
44
+ _cset :version_dir, "releases"
45
+ _cset :shared_dir, "shared"
46
+ _cset :shared_children, []
47
+ _cset :current_dir, "current"
48
+
49
+ _cset(:releases_path) { File.join(deploy_to, version_dir) }
50
+ _cset(:shared_path) { File.join(deploy_to, shared_dir) }
51
+ _cset(:current_path) { File.join(deploy_to, current_dir) }
52
+ _cset(:release_path) { File.join(releases_path, release_name) }
53
+
54
+ _cset(:releases) { capture("#{try_sudo} ls -x #{releases_path}", :except => { :no_release => true }).split.sort }
55
+ _cset(:current_release) { releases.any? ? File.join(releases_path, releases.last) : nil }
56
+ _cset(:previous_release) { releases.length > 1 ? File.join(releases_path, releases[-2]) : nil }
57
+
58
+ _cset(:current_revision) { capture("#{try_sudo} cat #{current_path}/REVISION", :except => { :no_release => true }).chomp }
59
+ _cset(:latest_revision) { capture("#{try_sudo} cat #{current_release}/REVISION", :except => { :no_release => true }).chomp }
60
+ _cset(:previous_revision) { capture("#{try_sudo} cat #{previous_release}/REVISION", :except => { :no_release => true }).chomp if previous_release }
61
+
62
+ _cset(:run_method) { fetch(:use_sudo, true) ? :sudo : :run }
63
+
64
+ # some tasks, like create_symlink, need to always point at the latest release, but
65
+ # they can also (occassionally) be called standalone. In the standalone case,
66
+ # the timestamped release_path will be inaccurate, since the directory won't
67
+ # actually exist. This variable lets tasks like create_symlink work either in the
68
+ # standalone case, or during deployment.
69
+ _cset(:latest_release) { exists?(:deploy_timestamped) ? release_path : current_release }
70
+
71
+ # Where to save the download resources
72
+ _cset :dp_local_backup, '/backup'
73
+
74
+ # define release backup db and files, migration
75
+ _cset :dp_sites, 'sites'
76
+ _cset :dp_migration, 'migration'
77
+ _cset :dp_released_files, 'released_files'
78
+ _cset :dp_released_db, 'released_db'
79
+
80
+ # Domains, virtualhosts
81
+ _cset :dp_domains, ['default']
82
+ _cset :dp_default_domain, 'default'
83
+ _cset :dp_virtual_hosts, []
84
+
85
+ # Share files when use multiple web servers
86
+ _cset :dp_shared_files, false
87
+ _cset :dp_shared_path, '/nfs'
88
+
89
+ # Drush tool
90
+ _cset :drush, '/usr/bin/drush'
91
+
92
+ # Drush site install info
93
+ _cset :dp_site_install, false
94
+ _cset :dp_site_db_url, nil
95
+ _cset :dp_site_profile, 'standard'
96
+ _cset :dp_site_name, 'Drupal 7 Demo'
97
+ _cset :dp_site_admin_user, 'admin'
98
+ _cset :dp_site_admin_pass, 'admin'
99
+
100
+ # =========================================================================
101
+ # If "Read Only Mode" enabled, then set maintainance key to 'site_readonly'
102
+ # else set maintainance key to 'maintenance_mode'
103
+ # =========================================================================
104
+ _cset :dp_maintainance_keys, {'default' => 'maintenance_mode'}
105
+
106
+ # =========================================================================
107
+ # These are helper methods that will be available to your recipes.
108
+ # =========================================================================
109
+
110
+ # Checks known version control directories to intelligently set the version
111
+ # # control in-use. For example, if a .svn directory exists in the project,
112
+ # # it will set the :scm variable to :subversion, if a .git directory exists
113
+ # # in the project, it will set the :scm variable to :git and so on. If no
114
+ # # directory is found, it will default to :git.
115
+ def scm_default
116
+ if File.exist? '.git'
117
+ :git
118
+ elsif File.exist? '.accurev'
119
+ :accurev
120
+ elsif File.exist? '.bzr'
121
+ :bzr
122
+ elsif File.exist? '.cvs'
123
+ :cvs
124
+ elsif File.exist? '_darcs'
125
+ :darcs
126
+ elsif File.exist? '.hg'
127
+ :mercurial
128
+ elsif File.exist? '.perforce'
129
+ :perforce
130
+ elsif File.exist? '.svn'
131
+ :subversion
132
+ else
133
+ :none
134
+ end
135
+ end
136
+
137
+ # Auxiliary helper method for the `deploy:check' task. Lets you set up your
138
+ # own dependencies.
139
+ def depend(location, type, *args)
140
+ deps = fetch(:dependencies, {})
141
+ deps[location] ||= {}
142
+ deps[location][type] ||= []
143
+ deps[location][type] << args
144
+ set :dependencies, deps
145
+ end
146
+
147
+ # Temporarily sets an environment variable, yields to a block, and restores
148
+ # the value when it is done.
149
+ def with_env(name, value)
150
+ saved, ENV[name] = ENV[name], value
151
+ yield
152
+ ensure
153
+ ENV[name] = saved
154
+ end
155
+
156
+ # logs the command then executes it locally.
157
+ # returns the command output as a string
158
+ def run_locally(cmd)
159
+ if dry_run
160
+ return logger.debug "executing locally: #{cmd.inspect}"
161
+ end
162
+ logger.trace "executing locally: #{cmd.inspect}" if logger
163
+ output_on_stdout = nil
164
+ elapsed = Benchmark.realtime do
165
+ output_on_stdout = `#{cmd}`
166
+ end
167
+ if $?.to_i > 0 # $? is command exit code (posix style)
168
+ raise Capistrano::LocalArgumentError, "Command #{cmd} returned status code #{$?}"
169
+ end
170
+ logger.trace "command finished in #{(elapsed * 1000).round}ms" if logger
171
+ output_on_stdout
172
+ end
173
+
174
+ # If a command is given, this will try to execute the given command, as
175
+ # described below. Otherwise, it will return a string for use in embedding in
176
+ # another command, for executing that command as described below.
177
+ #
178
+ # If :run_method is :sudo (or :use_sudo is true), this executes the given command
179
+ # via +sudo+. Otherwise is uses +run+. If :as is given as a key, it will be
180
+ # passed as the user to sudo as, if using sudo. If the :as key is not given,
181
+ # it will default to whatever the value of the :admin_runner variable is,
182
+ # which (by default) is unset.
183
+ #
184
+ # THUS, if you want to try to run something via sudo, and what to use the
185
+ # root user, you'd just to try_sudo('something'). If you wanted to try_sudo as
186
+ # someone else, you'd just do try_sudo('something', :as => "bob"). If you
187
+ # always wanted sudo to run as a particular user, you could do
188
+ # set(:admin_runner, "bob").
189
+ def try_sudo(*args)
190
+ options = args.last.is_a?(Hash) ? args.pop : {}
191
+ command = args.shift
192
+ raise ArgumentError, "too many arguments" if args.any?
193
+
194
+ as = options.fetch(:as, fetch(:admin_runner, nil))
195
+ via = fetch(:run_method, :sudo)
196
+ if command
197
+ invoke_command(command, :via => via, :as => as)
198
+ elsif via == :sudo
199
+ sudo(:as => as)
200
+ else
201
+ ""
202
+ end
203
+ end
204
+
205
+ # Same as sudo, but tries sudo with :as set to the value of the :runner
206
+ # variable (which defaults to "app").
207
+ def try_runner(*args)
208
+ options = args.last.is_a?(Hash) ? args.pop : {}
209
+ args << options.merge(:as => fetch(:runner, "app"))
210
+ try_sudo(*args)
211
+ end
212
+
213
+ # =========================================================================
214
+ # Check the remote file or directory exist
215
+ # =========================================================================
216
+ def remote_file_exists?(path)
217
+ results = []
218
+ invoke_command("if [ -e '#{path}' ]; then echo -n 'true'; fi") do |ch, stream, out|
219
+ results << (out == 'true')
220
+ end
221
+
222
+ results == [true]
223
+ end
224
+
225
+ # =========================================================================
226
+ # These are the tasks that are available to help with deploying web apps,
227
+ # and specifically, Rails applications. You can have cap give you a summary
228
+ # of them with `cap -T'.
229
+ # =========================================================================
230
+ namespace :deploy do
231
+ desc <<-DESC
232
+ Deploys your project. This calls both `update' and `restart'. Note that \
233
+ this will generally only work for applications that have already been deployed \
234
+ once. For a "cold" deploy, you'll want to take a look at the `deploy:cold' \
235
+ task, which handles the cold start specifically.
236
+ DESC
237
+ task :default do
238
+ update
239
+ cleanup
240
+ end
241
+
242
+ desc <<-DESC
243
+ Prepares one or more servers for deployment. Before you can use any \
244
+ of the Capistrano deployment tasks with your project, you will need to \
245
+ make sure all of your servers have been prepared with `cap deploy:setup'. When \
246
+ you add a new server to your cluster, you can easily run the setup task \
247
+ on just that server by specifying the HOSTS environment variable:
248
+
249
+ $ cap HOSTS=new.server.com deploy:setup
250
+
251
+ It is safe to run this task on servers that have already been set up; it \
252
+ will not destroy any deployed revisions or data.
253
+ DESC
254
+ task :setup do
255
+ dirs = [deploy_to, releases_path, shared_path]
256
+ dirs += shared_children.map { |d| File.join(shared_path, d.split('/').last) }
257
+
258
+ commands = []
259
+ commands << "#{try_sudo} mkdir -p #{dirs.join(' ')}"
260
+ commands << "#{try_sudo} chmod g+w #{dirs.join(' ')}" if fetch(:group_writable, true)
261
+
262
+ dirs = [dp_sites, dp_migration, dp_released_files, dp_released_db]
263
+
264
+ dp_domains.each do |domain|
265
+ dirs += ["#{dp_sites}/#{domain}", "#{dp_sites}/#{domain}/files", "#{dp_released_files}/#{domain}", "#{dp_released_db}/#{domain}", "#{dp_migration}/#{domain}"]
266
+ end
267
+
268
+ if dp_shared_files
269
+ dirs = dirs.map { |d| File.join(dp_shared_path, d) }
270
+ else
271
+ dirs = dirs.map { |d| File.join(shared_path, d) }
272
+ end
273
+
274
+ commands << "#{try_sudo} mkdir -p #{dirs.join(' ')}"
275
+ commands << "#{try_sudo} chmod g+w #{dirs.join(' ')}" if fetch(:group_writable, true)
276
+
277
+ if dp_shared_files
278
+ commands << "#{try_sudo} ln -nfs #{dp_shared_path}/#{dp_sites} #{shared_path}/#{dp_sites}"
279
+ commands << "#{try_sudo} ln -nfs #{dp_shared_path}/#{dp_released_files} #{shared_path}/#{dp_released_files}"
280
+ commands << "#{try_sudo} ln -nfs #{dp_shared_path}/#{dp_released_db} #{shared_path}/#{dp_released_db}"
281
+ commands << "#{try_sudo} ln -nfs #{dp_shared_path}/#{dp_migration} #{shared_path}/#{dp_migration}"
282
+ end
283
+
284
+ run commands.join('; ') if commands.any?
285
+ end
286
+
287
+ desc <<-DESC
288
+ Copies your project and updates the symlink. It does this in a \
289
+ transaction, so that if either `update_code' or `create_symlink' fail, all \
290
+ changes made to the remote servers will be rolled back, leaving your \
291
+ system in the same state it was in before `update' was invoked. Usually, \
292
+ you will want to call `deploy' instead of `update', but `update' can be \
293
+ handy if you want to deploy, but not immediately restart your application.
294
+ DESC
295
+ task :update do
296
+ transaction do
297
+ update_code
298
+ create_symlink
299
+ web.default
300
+ end
301
+ end
302
+
303
+ desc <<-DESC
304
+ Copies your project to the remote servers. This is the first stage \
305
+ of any deployment; moving your updated code and assets to the deployment \
306
+ servers. You will rarely call this task directly, however; instead, you \
307
+ should call the `deploy' task (to do a complete deploy) or the `update' \
308
+ task (if you want to perform the `restart' task separately).
309
+
310
+ You will need to make sure you set the :scm variable to the source \
311
+ control software you are using (it defaults to :subversion), and the \
312
+ :deploy_via variable to the strategy you want to use to deploy (it \
313
+ defaults to :checkout).
314
+ DESC
315
+ task :update_code, :except => { :no_release => true } do
316
+ on_rollback { run "rm -rf #{release_path}; true" }
317
+ strategy.deploy!
318
+ finalize_update
319
+ maintainance_keys
320
+ end
321
+
322
+ desc <<-DESC
323
+ [internal] Touches up the released code. This is called by update_code \
324
+ after the basic deploy finishes. It assumes a Rails project was deployed, \
325
+ so if you are deploying something else, you may want to override this \
326
+ task with your own environment's requirements.
327
+
328
+ This task will make the release group-writable (if the :group_writable \
329
+ variable is set to true, which is the default). It will then set up \
330
+ symlinks to the shared directory for the log, system, and tmp/pids \
331
+ directories, and will lastly touch all assets in public/images, \
332
+ public/stylesheets, and public/javascripts so that the times are \
333
+ consistent (so that asset timestamping works). This touch process \
334
+ is only carried out if the :normalize_asset_timestamps variable is \
335
+ set to true, which is the default.
336
+ DESC
337
+ task :finalize_update, :except => { :no_release => true } do
338
+ escaped_release = latest_release.to_s.shellescape
339
+ commands = []
340
+ commands << "chmod -R -- g+w #{escaped_release}" if fetch(:group_writable, true)
341
+
342
+ # mkdir -p is making sure that the directories are there for some SCM's that don't
343
+ # save empty folders
344
+ shared_children.map do |dir|
345
+ d = dir.shellescape
346
+ if (dir.rindex('/')) then
347
+ commands += ["rm -rf -- #{escaped_release}/#{d}", "mkdir -p -- #{escaped_release}/#{dir.slice(0..(dir.rindex('/'))).shellescape}"]
348
+ else
349
+ commands << "rm -rf -- #{escaped_release}/#{d}"
350
+ end
351
+ commands << "ln -s -- #{shared_path}/#{dir.split('/').last.shellescape} #{escaped_release}/#{d}"
352
+ end
353
+
354
+ run commands.join(' && ') if commands.any?
355
+ end
356
+
357
+ desc "Set the site maintainance keys"
358
+ task :maintainance_keys, :roles => [:web], :only => { :primary => true }, :except => { :no_release => true } do
359
+ if previous_release
360
+ tmp_keys = {}
361
+
362
+ dp_domains.each do |domain|
363
+ tmp_keys[domain] = capture("#{drush} pml --status='enabled' --root=#{current_path} --uri=#{domain} -y | grep 'Read Only Mode (readonlymode)' > /dev/null; if [ $? = 0 ]; then echo -n 'site_readonly'; else echo -n 'maintenance_mode'; fi")
364
+ end
365
+
366
+ set :dp_maintainance_keys, tmp_keys
367
+ end
368
+ end
369
+
370
+ desc <<-DESC
371
+ Updates the symlink to the most recently deployed version. Capistrano works \
372
+ by putting each new release of your application in its own directory. When \
373
+ you deploy a new version, this task's job is to update the `current' symlink \
374
+ to point at the new version. You will rarely need to call this task \
375
+ directly; instead, use the `deploy' task (which performs a complete \
376
+ deploy, including `restart') or the 'update' task (which does everything \
377
+ except `restart').
378
+ DESC
379
+ task :create_symlink, :except => { :no_release => true } do
380
+ on_rollback do
381
+ run "rm -f #{current_path}"
382
+ if previous_release
383
+ run "ln -s #{previous_release} #{current_path}; true"
384
+ else
385
+ logger.important "no previous release to rollback to, rollback of symlink skipped"
386
+ end
387
+ end
388
+
389
+ run "rm -f #{current_path} && ln -s #{latest_release} #{current_path}"
390
+ end
391
+
392
+ desc <<-DESC
393
+ Deprecated API. This has become deploy:create_symlink, please update your recipes
394
+ DESC
395
+ task :symlink, :except => { :no_release => true } do
396
+ Kernel.warn "[Deprecation Warning] This API has changed, please hook `deploy:create_symlink` instead of `deploy:symlink`."
397
+ create_symlink
398
+ end
399
+
400
+ desc <<-DESC
401
+ Copy files to the currently deployed version. This is useful for updating \
402
+ files piecemeal, such as when you need to quickly deploy only a single \
403
+ file. Some files, such as updated templates, images, or stylesheets, \
404
+ might not require a full deploy, and especially in emergency situations \
405
+ it can be handy to just push the updates to production, quickly.
406
+
407
+ To use this task, specify the files and directories you want to copy as a \
408
+ comma-delimited list in the FILES environment variable. All directories \
409
+ will be processed recursively, with all files being pushed to the \
410
+ deployment servers.
411
+
412
+ $ cap deploy:upload FILES=templates,controller.rb
413
+
414
+ Dir globs are also supported:
415
+
416
+ $ cap deploy:upload FILES='config/apache/*.conf'
417
+ DESC
418
+ task :upload, :except => { :no_release => true } do
419
+ files = (ENV["FILES"] || "").split(",").map { |f| Dir[f.strip] }.flatten
420
+ abort "Please specify at least one file or directory to update (via the FILES environment variable)" if files.empty?
421
+
422
+ files.each { |file| top.upload(file, File.join(current_path, file)) }
423
+ end
424
+
425
+ namespace :rollback do
426
+ desc <<-DESC
427
+ [internal] Points the current symlink at the previous revision.
428
+ This is called by the rollback sequence, and should rarely (if
429
+ ever) need to be called directly.
430
+ DESC
431
+ task :revision, :except => { :no_release => true } do
432
+ if previous_release
433
+ run "#{try_sudo} rm #{current_path}; #{try_sudo} ln -s #{previous_release} #{current_path}"
434
+ else
435
+ abort "could not rollback the code because there is no prior release"
436
+ end
437
+ end
438
+
439
+ desc <<-DESC
440
+ [internal] Removes the most recently deployed release.
441
+ This is called by the rollback sequence, and should rarely
442
+ (if ever) need to be called directly.
443
+ DESC
444
+ task :cleanup, :except => { :no_release => true } do
445
+ run "if [ `readlink #{current_path}` != #{current_release} ]; then #{try_sudo} rm -rf #{current_release}; fi"
446
+ end
447
+
448
+ desc <<-DESC
449
+ Rolls back to the previously deployed version. The `current' symlink will \
450
+ be updated to point at the previously deployed version, and then the \
451
+ current release will be removed from the servers. You'll generally want \
452
+ to call `rollback' instead, as it performs a `restart' as well.
453
+ DESC
454
+ task :code, :except => { :no_release => true } do
455
+ revision
456
+ deploy.web.rollback
457
+ cleanup
458
+ end
459
+
460
+ desc <<-DESC
461
+ Rolls back to a previous version and restarts. This is handy if you ever \
462
+ discover that you've deployed a lemon; `cap rollback' and you're right \
463
+ back where you were, on the previously deployed version.
464
+ DESC
465
+ task :default do
466
+ revision
467
+ deploy.web.rollback
468
+ cleanup
469
+ end
470
+ end
471
+
472
+ desc <<-DESC
473
+ Clean up old releases. By default, the last 5 releases are kept on each \
474
+ server (though you can change this with the keep_releases variable). All \
475
+ other deployed revisions are removed from the servers. By default, this \
476
+ will use sudo to clean up the old releases, but if sudo is not available \
477
+ for your environment, set the :use_sudo variable to false instead.
478
+ DESC
479
+ task :cleanup, :except => { :no_release => true } do
480
+ count = fetch(:keep_releases, 5).to_i
481
+ if count < releases.length
482
+ deploy.web.cleanup
483
+ run "#{try_sudo} ls -1dt #{releases_path}/* | tail -n +#{count + 1} | #{try_sudo} xargs rm -rf"
484
+ end
485
+ end
486
+
487
+ desc <<-DESC
488
+ Test deployment dependencies. Checks things like directory permissions, \
489
+ necessary utilities, and so forth, reporting on the things that appear to \
490
+ be incorrect or missing. This is good for making sure a deploy has a \
491
+ chance of working before you actually run `cap deploy'.
492
+
493
+ You can define your own dependencies, as well, using the `depend' method:
494
+
495
+ depend :remote, :gem, "tzinfo", ">=0.3.3"
496
+ depend :local, :command, "svn"
497
+ depend :remote, :directory, "/u/depot/files"
498
+ DESC
499
+ task :check, :except => { :no_release => true } do
500
+ dependencies = strategy.check!
501
+
502
+ other = fetch(:dependencies, {})
503
+ other.each do |location, types|
504
+ types.each do |type, calls|
505
+ if type == :gem
506
+ dependencies.send(location).command(fetch(:gem_command, "gem")).or("`gem' command could not be found. Try setting :gem_command")
507
+ end
508
+
509
+ calls.each do |args|
510
+ dependencies.send(location).send(type, *args)
511
+ end
512
+ end
513
+ end
514
+
515
+ if dependencies.pass?
516
+ puts "You appear to have all necessary dependencies installed"
517
+ else
518
+ puts "The following dependencies failed. Please check them and try again:"
519
+ dependencies.reject { |d| d.pass? }.each do |d|
520
+ puts "--> #{d.message}"
521
+ end
522
+ abort
523
+ end
524
+ end
525
+
526
+ desc <<-DESC
527
+ Deploys and starts a `cold' application. This is useful if you have not \
528
+ deployed your application before, or if your application is (for some \
529
+ other reason) not currently running. It will deploy the code, run any \
530
+ pending migrations, and then instead of invoking `deploy:restart', it will \
531
+ invoke `deploy:start' to fire up the application servers.
532
+ DESC
533
+ task :cold do
534
+ update
535
+ end
536
+
537
+ namespace :pending do
538
+ desc <<-DESC
539
+ Displays the `diff' since your last deploy. This is useful if you want \
540
+ to examine what changes are about to be deployed. Note that this might \
541
+ not be supported on all SCM's.
542
+ DESC
543
+ task :diff, :except => { :no_release => true } do
544
+ system(source.local.diff(current_revision))
545
+ end
546
+
547
+ desc <<-DESC
548
+ Displays the commits since your last deploy. This is good for a summary \
549
+ of the changes that have occurred since the last deploy. Note that this \
550
+ might not be supported on all SCM's.
551
+ DESC
552
+ task :default, :except => { :no_release => true } do
553
+ from = source.next_revision(current_revision)
554
+ system(source.local.log(from))
555
+ end
556
+ end
557
+
558
+ namespace :web do
559
+ desc <<-DESC
560
+ Run website install, files and database backup,
561
+ Fix htaccess and robots, Database migration.
562
+ DESC
563
+ task :default, :except => { :no_release => true } do
564
+ htaccess
565
+ robots
566
+ virtualhost
567
+ install
568
+ symlink
569
+ backup_files
570
+ backup_database
571
+ disable
572
+ migrate
573
+ clear_cache
574
+ enable
575
+ end
576
+
577
+ desc "Symlink files dir from shared path to latest release path"
578
+ task :symlink, :except => { :no_release => true } do
579
+ commands = []
580
+
581
+ dp_domains.each do |domain|
582
+ domain_path = "#{release_path}/#{dp_sites}/#{domain}"
583
+
584
+ if remote_file_exists?("#{domain_path}/settings.#{stage}.php")
585
+ commands << "#{try_sudo} ln -nfs #{domain_path}/settings.#{stage}.php #{domain_path}/settings.php"
586
+ elsif remote_file_exists?("#{shared_path}/#{dp_sites}/#{domain}/settings.php")
587
+ commands << "#{try_sudo} ln -nfs #{shared_path}/#{dp_sites}/#{domain}/settings.php #{domain_path}/settings.php"
588
+ end
589
+
590
+ if remote_file_exists?(domain_path)
591
+ commands << "#{try_sudo} ln -nfs #{shared_path}/#{dp_sites}/#{domain}/files #{domain_path}/files"
592
+ end
593
+ end
594
+
595
+ run commands.join('; ') if commands.any?
596
+ end
597
+
598
+ task :htaccess, :except => { :no_release => true } do
599
+ if remote_file_exists?("#{current_path}/htaccess-#{stage}")
600
+ run "#{try_sudo} mv #{current_path}/htaccess-#{stage} #{current_path}/.htaccess && #{try_sudo} rm -rf #{current_path}/htaccess-*"
601
+ elsif remote_file_exists?("#{current_path}/htaccess")
602
+ run "#{try_sudo} mv #{current_path}/htaccess #{current_path}/.htaccess"
603
+ end
604
+ end
605
+
606
+ task :robots, :except => { :no_release => true } do
607
+ if remote_file_exists?("#{current_path}/robots-#{stage}.txt")
608
+ run "#{try_sudo} mv #{current_path}/robots-#{stage}.txt #{current_path}/robots.txt; #{try_sudo} rm -rf #{current_path}/robots-*.txt"
609
+ end
610
+ end
611
+
612
+ task :virtualhost, :except => { :no_release => true } do
613
+ if not dp_virtual_hosts.empty? and not dp_default_domain.empty?
614
+ commands = []
615
+
616
+ dp_virtual_hosts.each do |alias_domain|
617
+ commands << "#{try_sudo} ln -nfs #{release_path}/#{dp_sites}/#{default_domain} #{release_path}/#{dp_sites}/#{alias_domain}"
618
+ end
619
+
620
+ run commands.join('; ') if commands.any?
621
+ end
622
+ end
623
+
624
+ desc "Install site on first deploy if site_install is true."
625
+ task :install, :roles => [:web], :only => { :primary => true }, :except => { :no_release => true } do
626
+ if dp_site_install and not previous_release
627
+ abort "Please specify the database url of your drupal install, set :dp_site_db_url, 'mysql://root:123456@localhost/drupal7_demo" if not dp_site_db_url
628
+
629
+ default_shared_path = "#{shared_path}/#{dp_sites}/#{dp_default_domain}"
630
+ default_current_path = "#{current_path}/#{dp_sites}/#{dp_default_domain}"
631
+ run "#{drush} si #{dp_site_profile} --root=#{current_path} --db-url=#{dp_site_db_url} --site-name=\"#{dp_site_name}\" --account-name=\"#{dp_site_admin_user}\" --account-pass=\"#{dp_site_admin_pass}\" -y && #{try_sudo} cp #{default_current_path}/settings.php #{default_shared_path}/settings.php && chmod 444 #{default_shared_path}/settings.php && #{try_sudo} chmod -R ug+w #{default_current_path}; #{try_sudo} rm -rf #{default_current_path}/settings.php #{default_current_path}/files"
632
+ end
633
+ end
634
+
635
+ desc "Deactive drupal maintainance mode."
636
+ task :enable, :roles => [:web], :only => { :primary => true }, :except => { :no_release => true } do
637
+ commands = []
638
+
639
+ dp_domains.each do |domain|
640
+ commands << "#{drush} vset #{dp_maintainance_keys[domain]} 0 --root=#{current_path} --uri=#{domain} -y"
641
+ end
642
+
643
+ run commands.join('; ') if commands.any?
644
+ end
645
+
646
+ desc "Active drupal maintainance mode."
647
+ task :disable, :roles => [:web], :only => { :primary => true }, :except => { :no_release => true } do
648
+ commands = []
649
+
650
+ dp_domains.each do |domain|
651
+ commands << "#{drush} vset #{dp_maintainance_keys[domain]} 1 --root=#{current_path} --uri=#{domain} -y"
652
+ end
653
+
654
+ run commands.join('; ') if commands.any?
655
+ end
656
+
657
+ desc "Run drupal database update migrations if required"
658
+ task :migrate, :roles => [:web], :only => {:primary => true}, :except => { :no_release => true } do
659
+ on_rollback do
660
+ rollback
661
+ end
662
+
663
+ commands = []
664
+
665
+ dp_domains.each do |domain|
666
+ drush_history = "#{shared_path}/#{dp_migration}/#{domain}/drush.history"
667
+ drush_available = "#{shared_path}/#{dp_migration}/#{domain}/drush.available"
668
+ sql_history = "#{shared_path}/#{dp_migration}/#{domain}/sql.history"
669
+ sql_available = "#{shared_path}/#{dp_migration}/#{domain}/sql.available"
670
+
671
+ # Append hook_update migration
672
+ commands << "#{drush} updb --root=#{current_path} --uri=#{domain} -y"
673
+
674
+ # Append drush migration
675
+ commands << "#{try_sudo} touch #{drush_history}"
676
+ commands << "find #{current_path}/#{dp_migration}/#{domain} -type f -name *.drush | xargs ls -1v 2>/dev/null > #{drush_available}"
677
+ commands << "diff #{drush_available} #{drush_history} | awk \"/^</ {print \\$2}\" | while read f; do echo \"Migrating: $(basename $f)\"; egrep -v \"^$|^#|^[[:space:]]+$\" $f | while read line; do echo \"Running: drush $line\"; #{drush} $line --root=#{current_path} --uri=#{domain} -y; done; echo $f >> #{drush_history}; done"
678
+ commands << "#{try_sudo} rm -f #{drush_available}"
679
+
680
+ # Append sql migration
681
+ commands << "#{try_sudo} touch #{sql_history}"
682
+ commands << "find #{current_path}/#{dp_migration}/#{domain} -type f -name *.sql | xargs ls -1v 2>/dev/null > #{sql_available}"
683
+ commands << "diff #{sql_available} #{sql_history} | awk \"/^</ {print \\$2}\" | while read f; do echo \"Migrating $(basename $f)\"; #{drush} -r #{current_path} --uri=#{domain} sqlq --file=$f -y && echo $f >> #{sql_history}; done"
684
+ commands << "#{try_sudo} rm -f #{sql_available}"
685
+ end
686
+
687
+ run commands.join('; ') if commands.any?
688
+ end
689
+
690
+ desc "Cache clear"
691
+ task :clear_cache, :roles => [:web], :only => { :primary => true }, :except => { :no_release => true } do
692
+ commands = []
693
+
694
+ dp_domains.each do |domain|
695
+ commands << "#{drush} cc all --root=#{current_path} --uri=#{domain} -y"
696
+ end
697
+
698
+ run commands.join('; ') if commands.any?
699
+ end
700
+
701
+ desc "Backup files"
702
+ task :backup_files, :roles => [:web], :only => { :primary => true }, :except => { :no_release => true } do
703
+ on_rollback do
704
+ files = []
705
+
706
+ dp_domains.each do |domain|
707
+ files << "#{shared_path}/#{dp_released_files}/#{domain}/#{domain}_files_#{release_name}.tar.bz2"
708
+ end
709
+
710
+ run "#{try_sudo} rm -rf #{files.join(' ')}" if files.any?
711
+ end
712
+
713
+ if previous_release
714
+ commands = []
715
+
716
+ dp_domains.each do |domain|
717
+ commands << "cd #{shared_path}/#{dp_sites}/#{domain}"
718
+ commands << "#{try_sudo} tar cjf #{shared_path}/#{dp_released_files}/#{domain}/#{domain}_files_#{release_name}.tar.bz2 files"
719
+ commands << "cd -"
720
+ end
721
+
722
+ run commands.join('; ') if commands.any?
723
+ end
724
+ end
725
+
726
+ desc "Backup database"
727
+ task :backup_database, :roles => [:web], :only => { :primary => true }, :except => { :no_release => true } do
728
+ on_rollback do
729
+ files = []
730
+
731
+ dp_domains.each do |domain|
732
+ files << "#{shared_path}/#{dp_released_db}/#{domain}/#{domain}_db_#{release_name}.sql.gz"
733
+ end
734
+
735
+ run "#{try_sudo} rm -rf #{files.join(' ')}" if files.any?
736
+ end
737
+
738
+ if previous_release
739
+ commands = []
740
+
741
+ dp_domains.each do |domain|
742
+ commands << "#{try_sudo} #{drush} sql-dump --gzip --result-file=#{shared_path}/#{dp_released_db}/#{domain}/#{domain}_db_#{release_name}.sql --root=#{current_path} --uri=#{domain} -y"
743
+ end
744
+
745
+ run commands.join('; ') if commands.any?
746
+ end
747
+ end
748
+
749
+ desc "Rollback files and database from release backup"
750
+ task :rollback, :roles => [:web], :only => { :primary => true }, :except => { :no_release => true } do
751
+ if previous_release
752
+ commands = []
753
+
754
+ dp_domains.each do |domain|
755
+ latest_release_name = latest_release.split('/').last
756
+
757
+ files = "#{shared_path}/#{dp_released_files}/#{domain}/#{domain}_files_#{latest_release_name}.tar.bz2"
758
+ if remote_file_exists?(files)
759
+ domain_shared_path = "#{shared_path}/#{dp_sites}/#{domain}"
760
+
761
+ commands << "#{try_sudo} rm -rf #{domain_shared_path}/files"
762
+ commands << "#{try_sudo} tar xjf #{files} -C #{domain_shared_path}"
763
+ commands << "#{try_sudo} chmod -R g+w #{domain_shared_path}/files"
764
+ commands << "#{try_sudo} rm -rf #{files}"
765
+ end
766
+
767
+ db = "#{shared_path}/#{dp_released_db}/#{domain}/#{domain}_db_#{latest_release_name}.sql"
768
+ if remote_file_exists?("#{db}.gz")
769
+ commands << "#{try_sudo} gzip -d #{db}.gz"
770
+ commands << "#{drush} sql-drop --root=#{current_path} --uri=#{domain} -y"
771
+ commands << "#{drush} sqlq --file=#{db} --root=#{current_path} --uri=#{domain} -y"
772
+ commands << "#{try_sudo} rm -rf #{db}"
773
+ end
774
+ end
775
+
776
+ run commands.join('; ') if commands.any?
777
+
778
+ clear_cache
779
+ end
780
+ end
781
+
782
+ desc "Clean up files and database backup"
783
+ task :cleanup, :roles => [:web], :only => { :primary => true }, :except => { :no_release => true } do
784
+ if previous_release
785
+ count = fetch(:keep_releases, 5).to_i
786
+ commands = []
787
+
788
+ dp_domains.each do |domain|
789
+ commands << "ls -1At #{releases_path} | tail -n +#{count} | sed 's!.*!#{shared_path}/#{dp_released_files}/#{domain}/#{domain}_files_&.tar.bz2 #{shared_path}/#{dp_released_db}/#{domain}/#{domain}_db_&.sql.gz!' | #{try_sudo} xargs rm -rf"
790
+ #commands << "ls -1At #{releases_path} | tail -n +#{count + 1} | sed 's!.*!#{shared_path}/#{dp_released_db}/#{domain}/#{domain}_db_&.sql.gz!' | #{try_sudo} xargs rm -rf"
791
+ end
792
+ run commands.join('; ') if commands.any?
793
+ end
794
+ end
795
+
796
+ namespace :download do
797
+ desc "Download latest files and database"
798
+ task :default, :roles => [:web], :only => { :primary => true }, :except => { :no_release => true } do
799
+ files
800
+ database
801
+ end
802
+
803
+ desc "Download files"
804
+ task :files, :roles => [:web], :only => { :primary => true }, :except => { :no_release => true } do
805
+ run_locally "mkdir -p #{dp_local_backup}/files"
806
+
807
+ dp_domains.each do |domain|
808
+ dump_file = "#{stage}_#{domain}_#{release_name}.tar.bz2"
809
+ temp = "/tmp/#{dump_file}"
810
+
811
+ run "cd #{shared_path}/#{dp_sites}/#{domain}; #{try_sudo} tar cjf #{temp} files; cd -"
812
+ get temp, "#{dp_local_backup}/files/#{dump_file}"
813
+ run "rm -rf #{temp}"
814
+ end
815
+ end
816
+
817
+ desc "Download database"
818
+ task :database, :roles => [:web], :only => { :primary => true }, :except => { :no_release => true } do
819
+ run_locally "mkdir -p #{dp_local_backup}/db"
820
+
821
+ dp_domains.each do |domain|
822
+ dump_file = "#{stage}_#{domain}_#{release_name}.sql"
823
+ temp = "/tmp/#{dump_file}"
824
+
825
+ run "#{drush} sql-dump --gzip --result-file=#{temp} --root=#{current_path} --uri=#{domain}"
826
+ get "#{temp}.gz", "#{dp_local_backup}/db/#{dump_file}.gz"
827
+ run "rm -rf #{temp}.gz"
828
+ end
829
+ end
830
+ end
831
+ end
832
+ end
833
+ end
metadata ADDED
@@ -0,0 +1,129 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: erCapistranoDrupal
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - everright.chen
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2013-06-17 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: capistrano
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 3
29
+ segments:
30
+ - 0
31
+ version: "0"
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: capistrano-ext
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ hash: 3
43
+ segments:
44
+ - 0
45
+ version: "0"
46
+ type: :runtime
47
+ version_requirements: *id002
48
+ - !ruby/object:Gem::Dependency
49
+ name: bundler
50
+ prerelease: false
51
+ requirement: &id003 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ~>
55
+ - !ruby/object:Gem::Version
56
+ hash: 9
57
+ segments:
58
+ - 1
59
+ - 3
60
+ version: "1.3"
61
+ type: :development
62
+ version_requirements: *id003
63
+ - !ruby/object:Gem::Dependency
64
+ name: rake
65
+ prerelease: false
66
+ requirement: &id004 !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ hash: 3
72
+ segments:
73
+ - 0
74
+ version: "0"
75
+ type: :development
76
+ version_requirements: *id004
77
+ description: A Drupal Deploy File for Capistrano. Includes site install, database migration; support multiple subsites.
78
+ email:
79
+ - everright.chen@gmail.com
80
+ executables: []
81
+
82
+ extensions: []
83
+
84
+ extra_rdoc_files: []
85
+
86
+ files:
87
+ - .gitignore
88
+ - Gemfile
89
+ - LICENSE.txt
90
+ - README.md
91
+ - Rakefile
92
+ - erCapistranoDrupal.gemspec
93
+ - lib/erCapistranoDrupal.rb
94
+ - lib/erCapistranoDrupal/version.rb
95
+ homepage: http://github.com/everright/erCapistranoDrupal
96
+ licenses:
97
+ - MIT
98
+ post_install_message:
99
+ rdoc_options: []
100
+
101
+ require_paths:
102
+ - lib
103
+ required_ruby_version: !ruby/object:Gem::Requirement
104
+ none: false
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ hash: 3
109
+ segments:
110
+ - 0
111
+ version: "0"
112
+ required_rubygems_version: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ hash: 3
118
+ segments:
119
+ - 0
120
+ version: "0"
121
+ requirements: []
122
+
123
+ rubyforge_project:
124
+ rubygems_version: 1.8.15
125
+ signing_key:
126
+ specification_version: 3
127
+ summary: A Drupal Deploy File for Capistrano.
128
+ test_files: []
129
+