capistrano-cul 0.0.17 → 0.0.18

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8a0e53d0b3eedd681257e528aebf115a1970ac10
4
- data.tar.gz: 7768d92de643aa8f389f88e9083967d7862cea3c
3
+ metadata.gz: b8f18b075e8eb0daa92a48fbba497a780a6a8cb2
4
+ data.tar.gz: 28bffd4b2afec0899e3918e3d09c6ac9aacf4903
5
5
  SHA512:
6
- metadata.gz: 5e6c6c71b3b07cbc76c8b0c24c27bb3f2fe72a73c39571ccb4243e3f9dbcf4d4db6ab692d8cd716f73e68a62abd399bd6a1b6d5b34476ff1092cdcfee5e62971
7
- data.tar.gz: 6db4f2a1ccc30f3f92d55ee7d51d4f940d4ccd15d02bd7aa446b623c953d8ccc308da45a981410e4e2043a594806321fd5b2620c8ce3ba2b1e5320323d86cf2f
6
+ metadata.gz: 3171e4f2cf8c7e2ff01c1bca1ef4de7c563619f376a203278b51c8f405303620cd7bd86d218583208d53e6c110366973c5885fddee20b3eeaa740ba1752357fc
7
+ data.tar.gz: 3ee2c4c9ef618595da89a4c67f7d2eb8d158e6c48681dc1195d7c5e6a10e3d3787156e51e601b11346c8b30c7078f5355ded52c8ef2056d0adf2e6fed25ae22e
data/README.md CHANGED
@@ -93,7 +93,6 @@ Here's a sample configuration:
93
93
 
94
94
  ```ruby
95
95
  set :wp_docroot, "#{fetch(:deploy_to)}/wp-docroot"
96
- set :wp_content_path, "#{fetch(:deploy_to)}/wp-content"
97
96
  set :multisite, false
98
97
  set :title, 'Amazing WordPress Site'
99
98
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.17
1
+ 0.0.18
@@ -20,6 +20,7 @@ Gem::Specification.new do |spec|
20
20
  spec.require_paths = ["lib"]
21
21
 
22
22
  spec.add_dependency 'capistrano', '~> 3.1'
23
+ spec.add_dependency 'capistrano-git-with-submodules', '~> 2.0'
23
24
 
24
25
  spec.add_development_dependency "bundler", "~> 1.15"
25
26
  end
@@ -1,3 +1,6 @@
1
1
  load File.expand_path('../../tasks/wp.cap', __FILE__)
2
+ load File.expand_path('../../tasks/wp/deploy.cap', __FILE__)
3
+ load File.expand_path('../../tasks/wp/setup.cap', __FILE__)
4
+ load File.expand_path('../../tasks/wp/install.cap', __FILE__)
2
5
  load File.expand_path('../../tasks/wp/update.cap', __FILE__)
3
6
  load File.expand_path('../../tasks/wp/migrate.cap', __FILE__)
@@ -25,4 +25,28 @@ namespace :cul do
25
25
  execute :mv, tmp_current_path, current_path.parent
26
26
  end
27
27
  end
28
+
29
+ # Throws an error if any of the given variables are nil or blank, potentially prompting
30
+ # the user for a value if a variable was configured to be set by the ask() method.
31
+ def self.require_cap_variables!(variables)
32
+ variables.each do |variable|
33
+ value = fetch(variable) # fetch the variable, potentially prompting the use to enter a value on the command line
34
+ next if value.is_a?(TrueClass) || value.is_a?(FalseClass)
35
+ raise Capistrano::ValidationError, "Missing required variable #{variable}" if value.nil? || value.empty?
36
+ end
37
+ end
38
+
39
+ def self.enter_y_to_continue(prompt)
40
+ puts prompt
41
+ set :confirmation_value, ask('"y" or "yes" to continue (or any other value to cancel)')
42
+ entered_y = ['y', 'yes'].include?(fetch(:confirmation_value))
43
+ delete :confirmation_value
44
+ entered_y
45
+ end
46
+
47
+ def self.color_text(message, color_number=35)
48
+ text_color = "\e[#{color_number}m"
49
+ default_color = "\e[0m"
50
+ text_color + message + default_color
51
+ end
28
52
  end
@@ -0,0 +1,88 @@
1
+ namespace :cul do
2
+ namespace :wp do
3
+ namespace :deploy do
4
+
5
+ before 'deploy:starting', 'cul:wp:deploy:display_maintenance_mode_warning'
6
+ before 'deploy:starting', 'cul:wp:deploy:require_deploy_cap_variables'
7
+ after 'deploy:starting', 'cul:wp:enable_maintenance_mode'
8
+
9
+ after :deploy, 'cul:wp:deploy:download_cul_allowed_upload_types_plugin'
10
+ after :deploy, 'cul:wp:deploy:symlink_custom_plugins_and_themes'
11
+ after :deploy, 'cul:wp:disable_maintenance_mode'
12
+
13
+ desc "Verifies that all deployed-related cap variables have been set in the application's deploy config."
14
+ task :require_deploy_cap_variables do
15
+ require_cap_variables!([:branch, :wp_docroot, :multisite])
16
+ end
17
+
18
+ desc "Displays a message to the deploying user about how to disable maintenance mode"
19
+ task :display_maintenance_mode_warning do
20
+ puts color_text("WARNING: Starting a deployment will set WordPress to maintenance mode. If you cancel deployment mid-way through, you'll need to manually disable maintenance mode by running: cap [env] cul:wp:disable_maintenance_mode")
21
+ end
22
+
23
+ desc "Downloads the cul-allowed-upload-types plugin from its remote web location"
24
+ task :download_cul_allowed_upload_types_plugin do
25
+ on roles(:web) do
26
+ within(current_path) do
27
+ zip_file_name = "#{fetch(:cul_allowed_upload_types_version)}.zip"
28
+ execute :curl, '-L', '--silent', '-o', zip_file_name, "https://github.com/cul/#{fetch(:cul_allowed_upload_types_plugin_name)}/archive/#{zip_file_name}"
29
+ execute :unzip, zip_file_name
30
+ execute :rm, zip_file_name # clean up zip file
31
+
32
+ # rename plugin directory so that it's just called
33
+ # "#{fetch(:cul_allowed_upload_types_plugin_name)}",
34
+ # so we can easily reference it later in our symlinking step,
35
+ # regardless of version number
36
+ versioned_plugin_directory_name = capture :find, '.', '-mindepth', '1', '-maxdepth', '1', '-name', "#{fetch(:cul_allowed_upload_types_plugin_name)}*"
37
+ execute :mv, versioned_plugin_directory_name, fetch(:cul_allowed_upload_types_downloaded_plugin_path)
38
+ end
39
+ end
40
+ end
41
+
42
+ desc "Downloads the cul-allowed-upload-types plugin from its remote web location"
43
+ task :symlink_custom_plugins_and_themes do
44
+ on roles(:web) do
45
+ wp_content_path = File.join(fetch(:wp_docroot), 'wp-content')
46
+ wp_content_plugin_path = File.join(wp_content_path, 'plugins')
47
+ wp_content_mu_plugin_path = File.join(wp_content_path, 'mu-plugins')
48
+ wp_content_themes_path = File.join(wp_content_path, 'themes')
49
+
50
+ ### Create necessary directories
51
+ execute :mkdir, '-p', wp_content_plugin_path, wp_content_mu_plugin_path, wp_content_themes_path
52
+
53
+ ### Remove old symlinks in each directory
54
+ [wp_content_plugin_path, wp_content_mu_plugin_path, wp_content_themes_path].each do |dir|
55
+ execute :find, dir, '-maxdepth 1', '-type l', '-exec rm {} \;'
56
+ end
57
+
58
+ ### Add symlinks for custom plugins
59
+ fetch(:wp_custom_plugins, {}).each do |plugin, repo_relative_path|
60
+ execute :ln, '-sf', File.join(current_path, repo_relative_path), File.join(wp_content_plugin_path, plugin)
61
+ end
62
+
63
+ ### Add symlinks for custom mu-plugins
64
+ fetch(:wp_custom_mu_plugins, {}).each do |mu_plugin, repo_relative_path|
65
+ execute :ln, '-sf', File.join(current_path, repo_relative_path), File.join(wp_content_mu_plugin_path, mu_plugin)
66
+ end
67
+
68
+ ### Add symlinks for custom themes
69
+ fetch(:wp_custom_themes, {}).each do |theme, repo_relative_path|
70
+ execute :ln, '-sf', File.join(current_path, repo_relative_path), File.join(wp_content_themes_path, theme)
71
+ end
72
+
73
+ ### Add symlinks for all files and directories directly under the cul-allowed-upload-types plugin directory.
74
+ # The symlinks will be created directly under the wordpress instance mu-plugins directory.
75
+ within deploy_path do
76
+ cul_allowed_upload_types_plugin_top_level_files_and_dirs = capture(:find, fetch(:cul_allowed_upload_types_downloaded_plugin_path), '-mindepth', '1', '-maxdepth', '1').split("\n")
77
+ cul_allowed_upload_types_plugin_top_level_files_and_dirs.each do |plugin_file_or_directory_path|
78
+ plugin_file_or_directory_name = File.basename(plugin_file_or_directory_path)
79
+ next if plugin_file_or_directory_name == '.gitignore' # we don't want to symlink the .gitignore file from the plugin's repo
80
+ execute :ln, '-sf', plugin_file_or_directory_path, File.join(wp_content_mu_plugin_path, plugin_file_or_directory_name)
81
+ end
82
+ end
83
+ end
84
+ end
85
+
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,35 @@
1
+ namespace :cul do
2
+ namespace :wp do
3
+
4
+ desc "Runs a WordPress installation for a newly set up instance and creates a new admin user"
5
+ task :install do
6
+ unless enter_y_to_continue(color_text("This will drop any existing database for #{fetch(:stage)}."))
7
+ puts 'Operation cancelled because "y" was not entered.'
8
+ next
9
+ end
10
+
11
+ puts "Please provide administrative user credentials for this new WP instance:"
12
+ ask(:admin_user, "Admin username:")
13
+ ask(:admin_password, "Admin password:", echo: false)
14
+ ask(:admin_email, "Admin email:")
15
+
16
+ require_cap_variables!([:url, :title, :admin_user, :admin_password, :admin_email])
17
+
18
+ on roles(:web) do
19
+ within fetch(:wp_docroot) do
20
+
21
+ # Drop existing database
22
+ execute :wp, 'db', 'reset', '--yes'
23
+
24
+ execute :wp, 'core', fetch(:multisite) ? 'multisite-install' : 'install',
25
+ "--url='#{fetch(:url)}'",
26
+ "--title='#{fetch(:title)}'",
27
+ "--admin_user='#{fetch(:admin_user)}'",
28
+ "--admin_password='#{fetch(:admin_password)}'",
29
+ "--admin_email='#{fetch(:admin_email)}'"
30
+ end
31
+ end
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,268 @@
1
+ require 'tempfile'
2
+ require 'json'
3
+
4
+ namespace :cul do
5
+ namespace :wp do
6
+ namespace :migrate do
7
+
8
+ desc "Copies the WordPress installation from one environment to another (e.g. prod to dev)"
9
+ task :copy_from do
10
+ # Need to store path as local variable so it can be referenced in `on roles(:web) do` portion of script
11
+ path_to_allowed_upload_types_plugin = cul_allowed_upload_types_plugin_path
12
+
13
+ require_cap_variables!([:wp_docroot, :wp_content_path])
14
+
15
+ if fetch(:multisite, false)
16
+ puts "Since this is a multisite, you'll need to specify the source multisite instance domain to continue:"
17
+ set :source_site_multisite_url, ask('source multisite instance domain (e.g. blogs.cul.columbia.edu)')
18
+ fetch(:source_site_multisite_url)
19
+
20
+ puts "And you'll also need to specify the destination multisite instance domain to continue:"
21
+ set :destination_site_multisite_url, ask('destination multisite instance domain (e.g. blogs-dev.cul.columbia.edu)')
22
+ fetch(:destination_site_multisite_url)
23
+ end
24
+
25
+ # TODO: Would be nice to verify that destination wordpress has already had the setup and deploy tasks run for it
26
+ set :src_wp_docroot, ask("server path to source WordPress installation (to copy from)")
27
+
28
+ # Confirm operation because it is destructive
29
+ puts "\nWARNING: This operation will obliterate all content in environment [#{fetch(:stage)}] and replace it with content from [#{fetch(:src_wp_docroot)}]."
30
+ puts "Are you sure you want to continue?"
31
+ set :confirm, ask('"y" or "yes" to continue')
32
+ unless ['y', 'yes'].include?(fetch(:confirm))
33
+ puts 'Copy operation has been cancelled because neither "y" nor "yes" were entered.'
34
+ next
35
+ end
36
+
37
+ # Don't really care about maintenance mode because we're completely destroying the target environment
38
+ # Enter maintenance mode
39
+ #invoke 'cul:wp:enable_maintenance_mode'
40
+
41
+ # Check WP version on source WordPress instance
42
+ failure = false
43
+ on roles(:web) do
44
+ within fetch(:src_wp_docroot) do
45
+ # Ensure that source WordPress is running the latest version
46
+ result = capture :wp, (fetch(:multisite, false) ? "--url=#{fetch(:source_site_multisite_url)}" : ''), 'core', 'check-update'
47
+ unless result.index('Success')
48
+ puts 'Could not copy from source WordPress because it is not running the latest version of WordPress. Please update source before running a copy operation.'
49
+ failure = true
50
+ end
51
+ end
52
+ end
53
+ next if failure # End if the previous checks failed
54
+
55
+ on roles(:web) do
56
+ # Destroy current wp_docroot
57
+ execute :rm, '-rf', fetch(:wp_docroot)
58
+ execute :mkdir, fetch(:wp_docroot)
59
+ end
60
+
61
+ # Download new copy of wordpress
62
+ invoke 'cul:wp:setup'
63
+
64
+ path_to_list_of_files_to_copy = ''
65
+
66
+ on roles(:web) do
67
+ # In source site's wp-content directory, generate file list to copy
68
+ within File.join(fetch(:src_wp_docroot), 'wp-content') do
69
+ # We're going to be copying wp-content in two parts
70
+ # 1. Everything else under wp-content EXCEPT uploads, blogs.dir,
71
+ # plugins, themes, mu-plugins
72
+ # 2. Everything under uploads AND wpblogs.dir with
73
+ # cul-allowed-upload-types file extension filter applied
74
+
75
+ # Make sure find command handles non-ASCII chars
76
+ #execute 'LC_ALL=en_US.iso885915'
77
+
78
+ # Generate two find commands for the above searches
79
+ find_non_upload_dirs = '. -type f ' +
80
+ # EXCLUDE plugins, themes, mu-plugins, uploads, and blogs.dir
81
+ "-not \\( -path './plugins/*' -o -path './mu-plugins/*' -o -path './themes/*' -o -path './uploads/*' -o -path './blogs.dir/*' \\) " +
82
+ # EXCLUDE certain unwanted files and paths
83
+ "-a -not \\( -name '.nfs*' -o -name '*.tmp.*' \\) " +
84
+ "-a -not \\( -path '*/.git*' -o -path '*/.svn*' -o -path '*/.hg*' \\)"
85
+
86
+ find_upload_dirs = '. -type f ' +
87
+ # INCLUDE ONLY uploads and blogs.dir
88
+ "\\( -path './uploads/*' -o -path './blogs.dir/*' \\) " +
89
+ # EXCLUDE certain unwanted files and paths
90
+ "-a -not \\( -name '.nfs*' -o -name '*.tmp.*' \\) " +
91
+ "-a -not \\( -path '*/.git*' -o -path '*/.svn*' -o -path '*/.hg*' \\) " +
92
+ # INCLUDE ONLY certain file extensions
93
+ "-a \\( " + JSON.parse(capture(:wp, (fetch(:multisite, false) ? "--url=#{fetch(:source_site_multisite_url)}" : ''), 'eval', '"echo cul_allowed_upload_file_extensions_as_json();"')).map{ |allowed_file_extension|
94
+ "-iname '*.#{allowed_file_extension}'"
95
+ }.join(' -o ') + " \\) "
96
+
97
+ path_to_list_of_files_to_copy = '/tmp/WP' + fetch(:wp_docroot).gsub('/', '-') + '-' + Time.now.to_i.to_s + '-files.txt'
98
+ execute :find, find_non_upload_dirs, ' > ', path_to_list_of_files_to_copy
99
+ execute :find, find_upload_dirs, ' >> ', path_to_list_of_files_to_copy
100
+
101
+ # Print out which files won't be copied
102
+ files_not_copied = capture(:comm, '-23', "<(find . -type f \\( -path './uploads/*' -o -path './blogs.dir/*' \\) | sort)", "<(find #{find_upload_dirs} | sort)")
103
+
104
+ puts (
105
+ "The following files will not be copied:\n" +
106
+ "-------------------------\n" +
107
+ "./plugins\n" +
108
+ "./mu-plugins\n" +
109
+ "./themes\n" +
110
+ files_not_copied + "\n" +
111
+ "-------------------------"
112
+ )
113
+ end
114
+
115
+ # For destination wordpress, delete and recreate the wp-content directory
116
+ execute :rm, '-rf', fetch(:wp_content_path)
117
+ execute :mkdir, fetch(:wp_content_path)
118
+
119
+ # Copy wp-content files (from path_to_list_of_files_to_copy) from source WP to destination WP
120
+ # Note that because we have the '--copy-links' flag below, we're transforming all symlinks into real file copies
121
+ rsync_params = [
122
+ '--recursive',
123
+ '--perms',
124
+ '--times',
125
+ '--devices',
126
+ '--specials',
127
+ '--copy-links',
128
+ '--prune-empty-dirs'
129
+ ]
130
+
131
+ # we're only copying files from the given file list
132
+ rsync_params << "--files-from=#{path_to_list_of_files_to_copy}"
133
+
134
+ src_wp_content_dir = File.join(fetch(:src_wp_docroot), 'wp-content/')
135
+ # Run a find operation on the wp-content dir to pre-cache all non-UTF compliant files prior to our rsync operation (to handle files with smart quotes, em dashes, foreign characters, etc.)
136
+ #execute :find, src_wp_content_dir, '-print0', '|', 'perl', '-n0e', '\'chomp; print $_, "\n" if /[[:^ascii:][:cntrl:]]/\''
137
+
138
+ # src directory (--files-from values are relative to this src directory)
139
+ rsync_params << src_wp_content_dir
140
+ # dest directory
141
+ rsync_params << fetch(:wp_content_path) + '/'
142
+
143
+ puts 'Copying wp-content. This may take a while for sites with a lot of uploads...'
144
+
145
+ puts 'rsync args:'
146
+ puts rsync_params.join(' ')
147
+
148
+ # begin
149
+ execute :rsync, *rsync_params
150
+ # rescue
151
+ # puts '--- Rsync failed, but will continue with deployment anyway!'
152
+ # end
153
+
154
+ # clean up path_to_list_of_files_to_copy file
155
+ execute :rm, path_to_list_of_files_to_copy
156
+
157
+ # Next, create symlinks to repo-managed plugins and themes, which will also recreate plugins, mu-plugins, and themes directories
158
+
159
+ within fetch(:wp_docroot) do
160
+ # Regenerate symlinks
161
+ invoke! 'cul:wp:symlink_custom_plugins_and_themes'
162
+ end
163
+
164
+ # Now it's time to copy the database
165
+
166
+ db_export_tempfile_path = ''
167
+
168
+ within fetch(:src_wp_docroot) do
169
+ # On source WordPress...
170
+
171
+ puts 'Exporting database from source site. This may take a while for large sites...'
172
+ # Export source WP DB to a temporary file
173
+ db_export_tempfile_path = Dir::Tmpname.make_tmpname '/tmp/', 'db_export_tempfile.sql'
174
+ execute :wp, (fetch(:multisite, false) ? "--url=#{fetch(:source_site_multisite_url)}" : ''), 'db', 'export', db_export_tempfile_path
175
+ end
176
+
177
+ within fetch(:wp_docroot) do
178
+ # On destination WordPress...
179
+
180
+ puts 'Importing database. This may take a while for large sites...'
181
+
182
+ # Drop all tables
183
+ execute :wp, 'db', 'reset', '--yes'
184
+
185
+ # Read in db file
186
+ execute :wp, 'db', 'import', db_export_tempfile_path
187
+
188
+ # Delete db file now that we're done with it
189
+ execute :rm, db_export_tempfile_path
190
+
191
+ # Invoke searchreplace task to update URL
192
+ puts "\nYou'll probably want to run the cul:wp:searchreplace command now, since it's likely that your WP URL differs between environments."
193
+ puts "Do you want to run a search and replace operation?"
194
+ set :confirm_searchreplace, ask('"y" or "yes" to continue')
195
+ if ['y', 'yes'].include?(fetch(:confirm_searchreplace))
196
+ invoke 'cul:wp:searchreplace'
197
+ else
198
+ puts '- Skipping search and replace because neither "y" nor "yes" were entered.'
199
+ end
200
+ end
201
+
202
+ # Next, install all plugins and themes from src wordpress, matching all versions and active vs. inactive plugin and theme states
203
+
204
+ data_for_plugins = []
205
+ data_for_themes = []
206
+
207
+ # Within src wp instance, get list of all plugins and themes with version
208
+ within File.join(fetch(:src_wp_docroot)) do
209
+ data_for_plugins = JSON.parse(capture(:wp, (fetch(:multisite, false) ? "--url=#{fetch(:source_site_multisite_url)}" : ''), 'plugin', 'list', '--fields=name,version,status', '--format=json'))
210
+ data_for_themes = JSON.parse(capture(:wp, (fetch(:multisite, false) ? "--url=#{fetch(:source_site_multisite_url)}" : ''), 'theme', 'list', '--fields=name,version,status', '--format=json'))
211
+ end
212
+
213
+ # Within dest wp instance, install specifically versioned plugins and themes
214
+ within File.join(fetch(:wp_docroot)) do
215
+ # Get list of repo-managed plugins and themes so that we don't attempt to overwrite these directories
216
+ repo_managed_plugin_names = fetch(:wp_custom_plugins, {}).keys
217
+ repo_managed_theme_names = fetch(:wp_custom_themes, {}).keys
218
+
219
+ puts "Downloading new copies of non-repo-managed plugins and themes..."
220
+
221
+ data_for_plugins.delete_if{|plugin_info| repo_managed_plugin_names.include?(plugin_info['name']) }.each do |plugin_info|
222
+ name = plugin_info['name']
223
+ version = plugin_info['version']
224
+ status = plugin_info['status']
225
+
226
+ case status
227
+ when 'active'
228
+ execute :wp, (fetch(:multisite, false) ? "--url=#{fetch(:destination_site_multisite_url)}" : ''), 'plugin', 'install', name, "--version=#{version}", '--activate'
229
+ when 'active-network'
230
+ execute :wp, (fetch(:multisite, false) ? "--url=#{fetch(:destination_site_multisite_url)}" : ''), 'plugin', 'install', name, "--version=#{version}", '--activate-network'
231
+ when 'inactive'
232
+ execute :wp, (fetch(:multisite, false) ? "--url=#{fetch(:destination_site_multisite_url)}" : ''), 'plugin', 'install', name, "--version=#{version}"
233
+ when 'must-use'
234
+ puts "--- WARNING: must-use plugin #{name} was not migrated over. It should be put in your blog's repository and deployed through a regular deployment."
235
+ end
236
+ end
237
+
238
+ data_for_themes.delete_if{|theme_info| repo_managed_theme_names.include?(theme_info['name']) }.each do |theme_info|
239
+ name = theme_info['name']
240
+ version = theme_info['version']
241
+ status = theme_info['status']
242
+
243
+ case status
244
+ when 'active'
245
+ execute :wp, (fetch(:multisite, false) ? "--url=#{fetch(:destination_site_multisite_url)}" : ''), 'theme', 'install', name, "--version=#{version}", '--activate'
246
+ when 'inactive', 'parent'
247
+ execute :wp, (fetch(:multisite, false) ? "--url=#{fetch(:destination_site_multisite_url)}" : ''), 'theme', 'install', name, "--version=#{version}"
248
+ end
249
+ end
250
+ end
251
+
252
+ within fetch(:wp_docroot) do
253
+ # Make docroot readable and executable for "other" user so nginx, which runs as "nobody", can read
254
+ # Use -L flag because we want to follow symlinks. The whole deployment relies on symlinks.
255
+ execute :find, '-L', File.join(fetch(:wp_docroot), 'wp-content'), '-type d -exec chmod o+rx "{}" \;'
256
+ execute :find, '-L', File.join(fetch(:wp_docroot), 'wp-content'), '-type f -exec chmod o+r "{}" \;'
257
+ # Make sure that wp-config file is not world readable
258
+ execute :chmod, 'o-r', shared_path.join('wp-config.php')
259
+ end
260
+
261
+ end
262
+ end
263
+
264
+ #after 'cul:wp:migrate:copy_from', 'cul:wp:disable_maintenance_mode'
265
+
266
+ end
267
+ end
268
+ end