derpy 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (6) hide show
  1. checksums.yaml +7 -0
  2. data/README.markdown +18 -0
  3. data/VERSION +1 -0
  4. data/derpy.gemspec +29 -0
  5. data/lib/derpy.rb +388 -0
  6. metadata +77 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ data.tar.gz: 58f7a8c72bc4157d3d23022069ad0c3898e7ec63
4
+ metadata.gz: a2b754b92c8b0696f040d13373eb65df68d97ed0
5
+ SHA512:
6
+ data.tar.gz: 267d501f86e3e75f348d690e8fe17637cfacf03b896788f2416da4100cdb2ac7478410ee7d265eaefdb824827f3909d981cb3df0b6dfe7e9af480a2ad62a2a2e
7
+ metadata.gz: fe5994238bed6c115e306d90561f20b2646aaf1fa17daad159d7c87555fe22c706e4978e4cbb3316f8a7e247d8e235a1b8ff041450401b29af757a6d9724dc68
data/README.markdown ADDED
@@ -0,0 +1,18 @@
1
+ # Derpy
2
+
3
+ This gem provides a number of tasks which are useful for deploying Drupal projects with [Capistrano](https://github.com/capistrano/capistrano).
4
+
5
+
6
+ ## Installation
7
+ [gems](http://rubygems.org) must be installed on your system first.
8
+
9
+ ### From RubyGems.org
10
+
11
+ $ gem install derpy
12
+
13
+ ### From Github
14
+
15
+ $ git clone git://github.com/3sign/derpy.git
16
+ $ cd derpy
17
+ $ gem build derpy.gemspec
18
+ $ gem install derpy-{version}.gem
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
data/derpy.gemspec ADDED
@@ -0,0 +1,29 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = 'derpy'
5
+ s.version = '1.0.0'
6
+ s.platform = Gem::Platform::RUBY
7
+ s.description = <<-DESC
8
+ A set of tasks for deploying Drupal projects with Capistrano and the help of Drush.
9
+ DESC
10
+ s.summary = 'A set of tasks for deploying Drupal projects with Capistrano'
11
+
12
+ s.extra_rdoc_files = [
13
+ "README.markdown"
14
+ ]
15
+ s.files = [
16
+ "README.markdown",
17
+ "VERSION",
18
+ "derpy.gemspec",
19
+ "lib/derpy.rb"
20
+ ]
21
+ s.require_path = 'lib'
22
+
23
+ s.add_dependency 'capistrano', ">= 2.13.5","<= 2.15.4"
24
+ s.add_dependency 'railsless-deploy', "~> 1.1.2"
25
+
26
+ s.authors = [ "Robin De Langhe" ]
27
+ s.email = 'robin@3sign.com'
28
+ s.homepage = %q{http://github.com/3sign/derpy/}
29
+ end
data/lib/derpy.rb ADDED
@@ -0,0 +1,388 @@
1
+ Capistrano::Configuration.instance(:must_exist).load do
2
+
3
+ require 'capistrano/recipes/deploy/scm'
4
+ require 'capistrano/recipes/deploy/strategy'
5
+ require 'railsless-deploy'
6
+
7
+ # =========================================================================
8
+ # These variables MUST be set in the client capfiles. If they are not set,
9
+ # the deploy will fail with an error.
10
+ # =========================================================================
11
+
12
+ _cset(:db_type) { abort "Please specify the Drupal database type (:db_type)." }
13
+ _cset(:db_name) { abort "Please specify the Drupal database name (:db_name)." }
14
+ _cset(:db_username) { abort "Please specify the Drupal database username (:db_username)." }
15
+ _cset(:db_password) { abort "Please specify the Drupal database password (:db_password)." }
16
+ _cset(:db_host) { abort "Please specify the Drupal database host (:db_host)." }
17
+
18
+ # =========================================================================
19
+ # These variables may be set in the client capfile if their default values
20
+ # are not sufficient.
21
+ # =========================================================================
22
+
23
+ set :use_sudo, false
24
+ set :scm, :git
25
+ set :deploy_via, :remote_cache
26
+ set :branch, "master"
27
+ set :git_enable_submodules, true
28
+ set :keep_releases, 5
29
+
30
+ set :runner_group, "www-data"
31
+ set :group_writable, false
32
+
33
+ set (:deploy_to) {"/var/www/#{application}"}
34
+ set :app_path, "drupal"
35
+ set :shared_children, ['sites/default/files']
36
+ set :shared_files, ['sites/default/settings.php']
37
+
38
+ set :backup_database, true
39
+ set :dbbackups, "db_backups"
40
+ _cset(:dbbackups_path) { File.join(deploy_to, dbbackups) }
41
+
42
+ set :local_database, nil
43
+ set :push_dump_enabled, false
44
+
45
+ set :download_drush, false
46
+ _cset(:drush_cmd) { download_drush ? "#{shared_path}/drush/drush" : "drush" }
47
+
48
+ default_run_options[:pty] = true
49
+ ssh_options[:forward_agent] = true
50
+
51
+ if download_drush
52
+ depend :remote, :command, "curl"
53
+ end
54
+
55
+ # This is an optional step that can be defined.
56
+ #after "deploy", "git:push_deploy_tag"
57
+
58
+ # =========================
59
+ # Deploy methods
60
+ # =========================
61
+
62
+ namespace :deploy do
63
+ desc <<-DESC
64
+ Prepares one or more servers for deployment. Before you can use any \
65
+ of the Capistrano deployment tasks with your project, you will need to \
66
+ make sure all of your servers have been prepared with `cap deploy:setup'. When \
67
+ you add a new server to your cluster, you can easily run the setup task \
68
+ on just that server by specifying the HOSTS environment variable:
69
+
70
+ $ cap HOSTS=new.server.com deploy:setup
71
+
72
+ It is safe to run this task on servers that have already been set up; it \
73
+ will not destroy any deployed revisions or data.
74
+ DESC
75
+ task :setup, :except => { :no_release => true } do
76
+ if download_drush
77
+ drush.get
78
+ end
79
+
80
+ dirs = [deploy_to, releases_path, shared_path, dbbackups].join(' ')
81
+ run "#{try_sudo} mkdir -p #{releases_path} #{shared_path} #{dbbackups_path}"
82
+ run "#{try_sudo} chown -R #{user}:#{runner_group} #{deploy_to}"
83
+ if shared_children.size > 0
84
+ sub_dirs = shared_children.map { |d| File.join(shared_path, d) }
85
+ run "#{try_sudo} mkdir -p #{sub_dirs.join(' ')}"
86
+ run "#{try_sudo} chmod 2775 #{sub_dirs.join(' ')}"
87
+ end
88
+
89
+ #create drupal config file
90
+ configuration = drupal_settings()
91
+ put configuration, "#{shared_path}/#{shared_files[0]}"
92
+
93
+ end
94
+
95
+ desc <<-DESC
96
+ Deploys your Drupal site, runs drush:update. It supposes that the Setup task was already executed.
97
+ This overrides the default Capistrano Deploy task to handle database operations and backups,
98
+ all of them via Drush.
99
+ DESC
100
+ task :default do
101
+ update
102
+ manage.dbdump_previous
103
+ end
104
+ after "deploy:default", "deploy:cc"
105
+
106
+ desc "Setup a drupal site from scratch"
107
+ task :cold do
108
+ setup
109
+ update
110
+ manage.push_dump
111
+ end
112
+ after "deploy:cold", "deploy:cc"
113
+
114
+ desc "[internal] Rebuild files and settings symlinks"
115
+ task :finalize_update, :except => { :no_release => true } do
116
+ if shared_children
117
+ # Creating symlinks for shared directories
118
+ shared_children.each do |link|
119
+ run "#{try_sudo} sh -c 'if [ -d #{release_path}/#{link} ] ; then rm -rf #{release_path}/#{link}; fi'"
120
+ run "#{try_sudo} ln -nfs #{shared_path}/#{link} #{release_path}/#{link}"
121
+ end
122
+ end
123
+
124
+ if shared_files
125
+ # Creating symlinks for shared files
126
+ shared_files.each do |link|
127
+ link_dir = File.dirname("#{shared_path}/#{link}")
128
+ run "#{try_sudo} ln -nfs #{shared_path}/#{link} #{release_path}/#{link}"
129
+ end
130
+ end
131
+ end
132
+
133
+ desc <<-DESC
134
+ Removes old releases and corresponding DB backups.
135
+ DESC
136
+ task :cleanup, :except => { :no_release => true } do
137
+ count = fetch(:keep_releases, 5).to_i
138
+ if count >= releases.length
139
+ logger.important "No old releases to clean up"
140
+ else
141
+ logger.info "keeping #{count} of #{releases.length} deployed releases"
142
+ old_releases = (releases - releases.last(count))
143
+ directories = old_releases.map { |release| File.join(releases_path, release) }.join(" ")
144
+ databases = old_releases.map { |release| File.join(dbbackups_path, "#{release}.sql")}.join(" ") if backup_database
145
+ run "rm -rf #{directories} #{databases}"
146
+ end
147
+ end
148
+
149
+ task :cc do
150
+ drush.site_offline
151
+ drush.updatedb
152
+ drush.cache_clear
153
+ drush.site_online
154
+ drush.cache_clear
155
+ end
156
+
157
+ namespace :rollback do
158
+
159
+ desc <<-DESC
160
+ Go back to the previous release (code and database)
161
+ DESC
162
+ task :default do
163
+ revision
164
+ db_rollback if domain.to_a.size == 1
165
+ cleanup
166
+ end
167
+
168
+ desc <<-DESC
169
+ [internal] Removes the most recently deployed release.
170
+ This is called by the rollback sequence, and should rarely
171
+ (if ever) need to be called directly.
172
+ DESC
173
+ task :cleanup, :except => { :no_release => true } do
174
+ run "if [ `readlink #{current_path}` != #{current_release} ]; then rm -rf #{current_release}; fi"
175
+ end
176
+
177
+ desc <<-DESC
178
+ [internal] Points the current, files, and settings symlinks at the previous revision.
179
+ DESC
180
+ task :revision, :except => { :no_release => true } do
181
+ if previous_release
182
+ run "rm #{current_path}"
183
+ run "ln -s #{previous_release} #{current_path}"
184
+ else
185
+ abort "could not rollback the code because there is no prior release"
186
+ end
187
+ end
188
+
189
+
190
+ desc <<-DESC
191
+ [internal] If a database backup from the previous release is found, dump the current
192
+ database and import the backup. This task should NEVER be called standalone.
193
+ DESC
194
+ task :db_rollback, :except => { :no_release => true } do
195
+ if previous_release
196
+ logger.info "Dumping current database and importing previous one (If one is found)."
197
+ previous_db = File.join(dbbackups_path, "#{releases[-2]}.sql")
198
+ import_cmd = "cd #{current_path}/#{app_path} && #{drush_cmd} sql-drop -y && #{drush_cmd} sql-cli < #{previous_db} && rm #{previous_db}"
199
+ run "if [ -e #{previous_db} ]; then #{import_cmd}; fi"
200
+ else
201
+ abort "could not rollback the database because there is no prior release db backups"
202
+ end
203
+ end
204
+ end
205
+ end
206
+
207
+ # =========================
208
+ # Files methods
209
+ # =========================
210
+
211
+ namespace :files do
212
+ desc "Pull drupal sites files (from remote to local)"
213
+ task :pull, :roles => :app, :except => { :no_release => true } do
214
+ remote_files_dir = "#{current_path}/sites/default/files/"
215
+ local_files_dir = "sites/default/files/"
216
+
217
+ run_locally("rsync --recursive --times --rsh=ssh --compress --human-readable --progress #{user}@#{roles[:app].servers[0].host}:#{remote_files_dir} #{local_files_dir}")
218
+ end
219
+
220
+ desc "Push drupal sites files (from local to remote)"
221
+ task :push, :roles => :app, :except => { :no_release => true } do
222
+ remote_files_dir = "#{current_path}/sites/default/files/"
223
+ local_files_dir = "sites/default/files/"
224
+
225
+ run_locally("rsync --recursive --times --rsh=ssh --compress --human-readable --progress #{local_files_dir} #{user}@#{roles[:app].servers[0].host}:#{remote_files_dir}")
226
+
227
+ end
228
+ end
229
+
230
+ # =========================
231
+ # Git methods
232
+ # =========================
233
+
234
+ namespace :git do
235
+
236
+ desc "Place release tag into Git and push it to origin server."
237
+ task :push_deploy_tag do
238
+ user = `git config --get user.name`
239
+ email = `git config --get user.email`
240
+ tag = "release_#{release_name}"
241
+ if exists?(:stage)
242
+ tag = "#{stage}_#{tag}"
243
+ end
244
+ puts `git tag #{tag} #{revision} -m "Deployed by #{user} <#{email}>"`
245
+ puts `git push origin tag #{tag}`
246
+ end
247
+
248
+ end
249
+
250
+ # =========================
251
+ # Drush methods
252
+ # =========================
253
+
254
+ namespace :drush do
255
+
256
+ desc "Gets drush and installs it"
257
+ task :get, :roles => :app, :except => { :no_release => true } do
258
+ run "#{try_sudo} cd #{shared_path} && curl -O -s http://ftp.drupal.org/files/projects/drush-7.x-5.8.tar.gz && tar -xf drush-7.x-5.8.tar.gz && rm drush-7.x-5.8.tar.gz"
259
+ run "#{try_sudo} cd #{shared_path} && chmod u+x drush/drush"
260
+ end
261
+
262
+ desc "Set the site offline"
263
+ task :site_offline, :on_error => :continue do
264
+ run "#{drush_cmd} -r #{latest_release}/#{app_path} vset site_offline 1 -y"
265
+ run "#{drush_cmd} -r #{latest_release}/#{app_path} vset maintenance_mode 1 -y"
266
+ end
267
+
268
+ desc "Backup the database"
269
+ task :backupdb, :on_error => :continue do
270
+ run "#{drush_cmd} -r #{latest_release}/#{app_path} bam-backup"
271
+ end
272
+
273
+ desc "Run Drupal database migrations if required"
274
+ task :updatedb, :on_error => :continue do
275
+ run "#{drush_cmd} -r #{latest_release}/#{app_path} updatedb -y"
276
+ end
277
+
278
+ desc "Clear the drupal cache"
279
+ task :cache_clear, :on_error => :continue do
280
+ run "#{drush_cmd} -r #{latest_release}/#{app_path} cache-clear all"
281
+ end
282
+
283
+ desc "Revert feature"
284
+ task :feature_revert, :on_error => :continue do
285
+ run "#{drush_cmd} -r #{latest_release}/#{app_path} features-revert-all -y"
286
+ end
287
+
288
+ desc "Set the site online"
289
+ task :site_online, :on_error => :continue do
290
+ run "#{drush_cmd} -r #{latest_release}/#{app_path} vset site_offline 0 -y"
291
+ run "#{drush_cmd} -r #{latest_release}/#{app_path} vset maintenance_mode 0 -y"
292
+ end
293
+
294
+ end
295
+
296
+ # =========================
297
+ # Manage methods
298
+ # =========================
299
+
300
+ namespace :manage do
301
+
302
+ desc "Block bots via robots.txt"
303
+ task :block_robots do
304
+ put "User-agent: *\nDisallow: /", "#{current_path}/#{app_path}/robots.txt"
305
+ end
306
+
307
+ task :dbdump_previous do
308
+ #Backup the previous release's database
309
+ if previous_release && backup_database
310
+ run "cd #{current_path}/#{app_path} && #{drush_cmd} sql-dump > #{ File.join(dbbackups_path, "#{releases[-2]}.sql") }"
311
+ end
312
+ end
313
+
314
+ desc 'Dump remote database and restore locally'
315
+ task :pull_dump do
316
+ abort("NO LOCAL DATABASE FOUND, set :local_database in the config file..") unless local_database
317
+
318
+ set(:runit, Capistrano::CLI.ui.ask("WARNING!! will overwrite this local database: '#{local_database}', type 'yes' to continue: "))
319
+ if runit == 'yes'
320
+ sql_file = File.join(dbbackups_path, "#{releases.last}-pull.sql")
321
+ # dump & gzip remote file
322
+ run "cd #{current_path}/#{app_path} && #{drush_cmd} sql-dump > #{sql_file} && gzip -f #{sql_file}"
323
+ # copy to local
324
+ system "if [ ! -d build ]; then mkdir build; fi" # create build folder locally if needed
325
+ download "#{sql_file}.gz", "build/", :once => true, :via => :scp
326
+ run "rm #{sql_file}.gz"
327
+ # extract and restore
328
+ system "gunzip -f build/#{File.basename(sql_file)}.gz && drush sql-drop -y && drush sql-cli < build/#{File.basename(sql_file)}" if local_database
329
+ system "rm build/#{File.basename(sql_file)}"
330
+ end
331
+ end
332
+
333
+ desc 'Dump local database and restore remote'
334
+ task :push_dump do
335
+ abort("NO LOCAL DATABASE FOUND, set :local_database in the config file..") unless local_database
336
+ abort("THIS STAGE: #{stage} DOES NOT SUPPORT manage:push_dump") unless push_dump_enabled
337
+
338
+ set(:runit, Capistrano::CLI.ui.ask("WARNING!! will overwrite this REMOTE database: '#{db_name}', type 'yes' to continue: "))
339
+ if runit == 'yes'
340
+ sql_file = "#{Time.now.to_i}.sql"
341
+ system "if [ ! -d build ]; then mkdir build; fi" # create build folder locally if needed
342
+ # dump & gzip local file
343
+ system "drush sql-dump > ./build/#{sql_file} && gzip ./build/#{sql_file}"
344
+ # copy to remote
345
+ upload "build/#{sql_file}.gz", File.join(dbbackups_path, "#{sql_file}.gz"), :once => true, :via => :scp
346
+ system "rm build/#{sql_file}.gz"
347
+ # extract and restore
348
+ run "gunzip -f #{File.join(dbbackups_path, "#{sql_file}.gz")} && cd #{current_path}/#{app_path} && #{drush_cmd} sql-drop -y && #{drush_cmd} sql-cli < #{File.join(dbbackups_path, "#{sql_file}")}"
349
+ run "rm #{File.join(dbbackups_path, "#{sql_file}")}"
350
+ end
351
+ end
352
+ end
353
+
354
+ # =========================
355
+ # Helper methods
356
+ # =========================
357
+
358
+ # Builds initial contents of the Drupal website's settings file
359
+ def drupal_settings()
360
+ settings = <<-STRING
361
+ <?php
362
+ $databases = array ('default' => array ('default' => array (
363
+ 'database' => '#{db_name}',
364
+ 'username' => '#{db_username}',
365
+ 'password' => '#{db_password}',
366
+ 'host' => '#{db_host}',
367
+ 'port' => '',
368
+ 'driver' => '#{db_type}',
369
+ 'prefix' => '',
370
+ )));
371
+ ini_set('session.gc_probability', 1);
372
+ ini_set('session.gc_divisor', 100);
373
+ ini_set('session.gc_maxlifetime', 200000);
374
+ ini_set('session.cookie_lifetime', 2000000);
375
+
376
+ $conf['404_fast_paths_exclude'] = '/\/(?:styles)\//';
377
+ $conf['404_fast_paths'] = '/\.(?:txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i';
378
+ $conf['404_fast_html'] = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL "@path" was not found on this server.</p></body></html>';
379
+
380
+ // Allow local env to override settings by creating a local.settings.php.
381
+ $path = str_replace('settings.php', 'local.settings.php', __FILE__);
382
+
383
+ if (file_exists($path)) {
384
+ include_once($path);
385
+ }
386
+ STRING
387
+ end
388
+ end
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: derpy
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Robin De Langhe
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2014-03-17 00:00:00 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: capistrano
16
+ prerelease: false
17
+ requirement: &id001 !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - ">="
20
+ - !ruby/object:Gem::Version
21
+ version: 2.13.5
22
+ - - <=
23
+ - !ruby/object:Gem::Version
24
+ version: 2.15.4
25
+ type: :runtime
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
28
+ name: railsless-deploy
29
+ prerelease: false
30
+ requirement: &id002 !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ~>
33
+ - !ruby/object:Gem::Version
34
+ version: 1.1.2
35
+ type: :runtime
36
+ version_requirements: *id002
37
+ description: " A set of tasks for deploying Drupal projects with Capistrano and the help of Drush.\n"
38
+ email: robin@3sign.com
39
+ executables: []
40
+
41
+ extensions: []
42
+
43
+ extra_rdoc_files:
44
+ - README.markdown
45
+ files:
46
+ - README.markdown
47
+ - VERSION
48
+ - derpy.gemspec
49
+ - lib/derpy.rb
50
+ homepage: http://github.com/3sign/derpy/
51
+ licenses: []
52
+
53
+ metadata: {}
54
+
55
+ post_install_message:
56
+ rdoc_options: []
57
+
58
+ require_paths:
59
+ - lib
60
+ required_ruby_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - &id003
63
+ - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: "0"
66
+ required_rubygems_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - *id003
69
+ requirements: []
70
+
71
+ rubyforge_project:
72
+ rubygems_version: 2.0.4
73
+ signing_key:
74
+ specification_version: 4
75
+ summary: A set of tasks for deploying Drupal projects with Capistrano
76
+ test_files: []
77
+