capistrano-cul 0.0.17 → 0.0.18

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.
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