alcapon 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +24 -2
- data/bin/capezit +34 -8
- data/lib/capez.rb +260 -37
- data/lib/ext/spinner.rb +26 -0
- metadata +17 -3
data/README.md
CHANGED
@@ -1,8 +1,30 @@
|
|
1
1
|
# AlCapON : Enable Capistrano for your eZ Publish installations
|
2
2
|
|
3
|
-
AlCapON is a simple recipe for Capistrano, the well-known deployment toolbox.
|
3
|
+
AlCapON is a simple recipe for Capistrano, the well-known deployment toolbox.
|
4
|
+
It helps you dealing with simple task such as pushing your code to your
|
5
|
+
webserver(s), clearing cache, etc.
|
4
6
|
|
5
|
-
IMPORTANT: this package is currently under development, please consider testing
|
7
|
+
IMPORTANT: this package is currently under development, please consider testing
|
8
|
+
it on a preproduction environment before going further. Please also do read the
|
9
|
+
"Known bugs" section carefully.
|
10
|
+
|
11
|
+
## Changelog
|
12
|
+
|
13
|
+
### 0.3.x
|
14
|
+
|
15
|
+
- added the possibility to trigger rename and in-file replace operations
|
16
|
+
during the deployment (see the generated file
|
17
|
+
config/deploy/production.rb after running the capezit command)
|
18
|
+
|
19
|
+
- major changes in permissions management for the var/ folders. Previous
|
20
|
+
versions tried to manage different cases by using sudo commands but I'm
|
21
|
+
convinced that it is not the right place to do that. Permissions have to be
|
22
|
+
handled by sysadmin, not Capistrano.
|
23
|
+
This will be improved, maybe simplified again, in next versions.
|
24
|
+
In consequence, you might experienced some issues, but please, let me know.
|
25
|
+
|
26
|
+
- usage of siteaccess_list in ezpublish.rb is deprecated as of 0.3.0. Please
|
27
|
+
use storage_directories instead (see issue #2)
|
6
28
|
|
7
29
|
## Requirements, installation & co
|
8
30
|
|
data/bin/capezit
CHANGED
@@ -69,6 +69,14 @@ files = {
|
|
69
69
|
# Need if you want to deploy somewhere where sudo is needed
|
70
70
|
default_run_options[:pty] = true
|
71
71
|
|
72
|
+
# Set debug level to IMPORTANT only
|
73
|
+
# Comment if you want to get more debug outputs
|
74
|
+
logger.level = Logger::IMPORTANT
|
75
|
+
|
76
|
+
# Override default feature (not needed for eZ Publish)
|
77
|
+
# If turned on, you will get a warning during deployment but it should not be aborted
|
78
|
+
set :normalize_asset_timestamps, false
|
79
|
+
|
72
80
|
# Use this to use your ssh keys
|
73
81
|
# (you might need to run ssh-add /path/to/your/deploy_key before)
|
74
82
|
ssh_options[:forward_agent] = true
|
@@ -99,8 +107,9 @@ files = {
|
|
99
107
|
# This file contains eZ Publish adjustable variables depending on your custom setup
|
100
108
|
|
101
109
|
# Your webserver user and group, used to chmod directories just after deploy:setup
|
102
|
-
|
103
|
-
set :
|
110
|
+
# By default, this is the user as the one used to connect via SSH
|
111
|
+
set :webserver_user, :user
|
112
|
+
set :webserver_group, :user
|
104
113
|
|
105
114
|
# If true, will always turn your webserver offline
|
106
115
|
# Requires a specific rewrite rule (see documentation)
|
@@ -117,15 +126,22 @@ files = {
|
|
117
126
|
# your var directory (2012.5 for instance)
|
118
127
|
set :cache_purge, false
|
119
128
|
|
120
|
-
#
|
121
|
-
#
|
129
|
+
# A list of var directories which will handle siteaccess's specific assets, such as
|
130
|
+
# the storage
|
131
|
+
#set :storage_directories, [ "ezflow_site" ]
|
122
132
|
|
123
133
|
# Set this to tell Capistrano with which host you want to sync your local storage dir
|
124
134
|
#set :shared_host, "domain.com"
|
125
135
|
|
136
|
+
# Changes the group of shared_children items (by default, webserver_group is used)
|
137
|
+
# If not set, permissions remain unchanged
|
138
|
+
#set :shared_children_group, "#{webserver_group}"
|
139
|
+
|
126
140
|
# Which autoloads to generate. By default, regenerates extensions and
|
127
141
|
# kernel-override autoloads
|
128
142
|
# Possible values : see bin/php/ezpgenerateautoloads.php --help
|
143
|
+
# Feature can be disabled by using :
|
144
|
+
#set :autoload_list, []
|
129
145
|
set :autoload_list, [ "extension", "kernel-override" ]
|
130
146
|
|
131
147
|
# TODO : use yml files to manage database credentials securely
|
@@ -161,8 +177,8 @@ files = {
|
|
161
177
|
#set :admin_runner, "sudouser"
|
162
178
|
|
163
179
|
# This is used for permissions related tasks
|
164
|
-
#set :webserver_user,
|
165
|
-
#set :webserver_group,
|
180
|
+
#set :webserver_user, :user
|
181
|
+
#set :webserver_group, :user
|
166
182
|
FILE
|
167
183
|
|
168
184
|
"#{alcapon_path}/config/deploy/production.rb" => unindent(<<-FILE)
|
@@ -175,8 +191,18 @@ files = {
|
|
175
191
|
#set :admin_runner, "sudouser"
|
176
192
|
|
177
193
|
# This is used for permissions related tasks
|
178
|
-
#set :webserver_user,
|
179
|
-
#set :webserver_group,
|
194
|
+
#set :webserver_user, :user
|
195
|
+
#set :webserver_group, :user
|
196
|
+
|
197
|
+
#set :file_changes, {
|
198
|
+
# 'settings/override/site.ini.append.dist' => {
|
199
|
+
# 'rename' => 'settings/override/site.ini.append.php',
|
200
|
+
# 'replace' => {
|
201
|
+
# '@tokens_database_host@' => 'prod-dbs',
|
202
|
+
# },
|
203
|
+
# }
|
204
|
+
#}
|
205
|
+
|
180
206
|
FILE
|
181
207
|
}
|
182
208
|
|
data/lib/capez.rb
CHANGED
@@ -1,16 +1,60 @@
|
|
1
1
|
load_paths.push File.expand_path('../', __FILE__)
|
2
2
|
load 'db.rb'
|
3
|
+
require 'colored'
|
3
4
|
|
4
5
|
# This will simply do chmod g+w on all dir
|
5
6
|
# See task :setup
|
6
7
|
set :group_writable, true
|
7
8
|
|
9
|
+
# triggered after all recipes have loaded
|
10
|
+
on :load do
|
11
|
+
if( fetch( :siteaccess_list, nil ) != nil )
|
12
|
+
abort "The usage of siteaccess_list in ezpublish.rb is deprecated as of 0.3.0.\nPlease use storage_directories instead".red
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
before "deploy:setup" do
|
17
|
+
print_dotted( "--> Creating default directories" )
|
18
|
+
end
|
19
|
+
|
8
20
|
after "deploy:setup", :roles => :web do
|
21
|
+
puts( " OK".green )
|
22
|
+
print_dotted( "--> Fixing permissions on deployment directory" )
|
23
|
+
try_sudo( "chown -R #{user} #{deploy_to}" ) # if not code checkout cannot be done :/
|
24
|
+
puts( " OK".green )
|
9
25
|
capez.var.init_shared
|
10
26
|
end
|
11
27
|
|
12
|
-
|
13
|
-
|
28
|
+
before "deploy:update_code" do
|
29
|
+
puts( "\n*** Building release ***" )
|
30
|
+
puts( "Started at " + Time.now.utc.strftime("%H:%M:%S") )
|
31
|
+
print_dotted( "--> Updating code", :sol => true )
|
32
|
+
end
|
33
|
+
|
34
|
+
after "deploy:update_code" do
|
35
|
+
puts( "\n*** Release ready ***".green )
|
36
|
+
puts( "Finished at " + Time.now.utc.strftime("%H:%M:%S") )
|
37
|
+
end
|
38
|
+
|
39
|
+
before "deploy:finalize_update" do
|
40
|
+
puts( " OK".green )
|
41
|
+
# Needed if you want to create extra shared directories under var/ with
|
42
|
+
# set :shared_children, [ "var/something",
|
43
|
+
# "var/something_else" ]
|
44
|
+
# Note that :shared_children creates a folder within shared which name is
|
45
|
+
# the last path element (ie: something or something_else) => that's why
|
46
|
+
# we cannot use it to create siteaccess storages (var/siteaccess/storage)
|
47
|
+
run( "mkdir #{latest_release}/var" )
|
48
|
+
end
|
49
|
+
|
50
|
+
after "deploy:finalize_update" do
|
51
|
+
if fetch( :shared_children_group, false )
|
52
|
+
shared_children.map { |d| run( "chgrp -R #{shared_children_group} #{shared_path}/#{d.split('/').last}") }
|
53
|
+
end
|
54
|
+
capez.var.init_release
|
55
|
+
capez.var.link
|
56
|
+
capez.settings.deploy
|
57
|
+
capez.autoloads.generate
|
14
58
|
#capez.cache.clear
|
15
59
|
end
|
16
60
|
|
@@ -23,15 +67,16 @@ after "deploy", :roles => :web do
|
|
23
67
|
deploy.web.enable
|
24
68
|
end
|
25
69
|
|
26
|
-
|
70
|
+
before "deploy:create_symlink" do
|
71
|
+
print_dotted( "--> Going live (symlink)", :sol => true )
|
72
|
+
end
|
27
73
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
end
|
74
|
+
after "deploy:create_symlink" do
|
75
|
+
puts( " OK".green )
|
76
|
+
end
|
77
|
+
|
78
|
+
# Default behavior overrides
|
79
|
+
namespace :deploy do
|
35
80
|
|
36
81
|
namespace :web do
|
37
82
|
desc <<-DESC
|
@@ -61,6 +106,116 @@ end
|
|
61
106
|
|
62
107
|
|
63
108
|
namespace :capez do
|
109
|
+
namespace :settings do
|
110
|
+
|
111
|
+
def make_file_changes( options={} )
|
112
|
+
|
113
|
+
default_options = { :locally => false }
|
114
|
+
options = default_options.merge( options )
|
115
|
+
|
116
|
+
puts( "\n--> File operations" )
|
117
|
+
|
118
|
+
unless !(file_changes = get_file_changes) then
|
119
|
+
|
120
|
+
path = options[:locally] ? "" : "#{latest_release}/"
|
121
|
+
|
122
|
+
changes = 0
|
123
|
+
renames = 0
|
124
|
+
errors = []
|
125
|
+
messages = []
|
126
|
+
|
127
|
+
print_dotted( "execution", :eol_msg => (options[:locally] ? "local" : "distant" ), :eol => true, :max_length => 25 )
|
128
|
+
print_dotted( "files count", :eol_msg => "#{file_changes.count}", :eol => true, :max_length => 25 )
|
129
|
+
|
130
|
+
# process each files
|
131
|
+
print( "progress " )
|
132
|
+
file_changes.each { |filename,operations|
|
133
|
+
|
134
|
+
print( "." )
|
135
|
+
|
136
|
+
target_filename = filename
|
137
|
+
renamed = false
|
138
|
+
|
139
|
+
# rename operation is caught and executed at first
|
140
|
+
if operations.has_key?("rename")
|
141
|
+
if( target_filename != operations['rename'] )
|
142
|
+
target_filename = operations['rename']
|
143
|
+
cmd = "if [ -f #{path}#{filename} ]; then cp #{path}#{filename} #{path}#{target_filename}; fi;"
|
144
|
+
options[:locally] ? run_locally( "#{cmd}" ) : run( "#{cmd}" )
|
145
|
+
renames += 1
|
146
|
+
else
|
147
|
+
target_filename = operations['rename']
|
148
|
+
errors += ["target and original name are the same (#{target_filename})"]
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
operations.each { |operation,value|
|
153
|
+
case operation
|
154
|
+
when 'rename'
|
155
|
+
when 'replace'
|
156
|
+
|
157
|
+
if( value.count > 0 )
|
158
|
+
|
159
|
+
# download file if necessary
|
160
|
+
if options[:locally]
|
161
|
+
tmp_filename = target_filename
|
162
|
+
else
|
163
|
+
tmp_filename = target_filename+".tmp"
|
164
|
+
get "#{path}#{target_filename}", tmp_filename
|
165
|
+
end
|
166
|
+
|
167
|
+
text = File.read(tmp_filename)
|
168
|
+
value.each { |search,replace|
|
169
|
+
changes += 1
|
170
|
+
text = text.gsub( "#{search}", "#{replace}" )
|
171
|
+
}
|
172
|
+
File.open(tmp_filename, "w") {|file| file.write(text) }
|
173
|
+
|
174
|
+
# upload and remove temporary file
|
175
|
+
if !options[:locally]
|
176
|
+
run( "if [ -f #{target_filename} ]; then rm #{target_filename}; fi;" )
|
177
|
+
upload( tmp_filename, "#{path}#{target_filename}" )
|
178
|
+
run_locally( "rm #{tmp_filename}" )
|
179
|
+
end
|
180
|
+
end
|
181
|
+
else
|
182
|
+
errors += ( "operation '#{operation}' supported" )
|
183
|
+
end
|
184
|
+
}
|
185
|
+
}
|
186
|
+
puts " done".green
|
187
|
+
|
188
|
+
# stats
|
189
|
+
print_dotted( "files renamed", :eol_msg => "#{renames}", :eol => true, :max_length => 25 )
|
190
|
+
print_dotted( "changes count", :eol_msg => "#{changes}", :eol => true, :max_length => 25 )
|
191
|
+
print_dotted( "changes avg / file", :max_length => 25, :eol_msg => ( file_changes.count > 0 ? "#{changes/file_changes.count}" : "" ), :eol => true )
|
192
|
+
messages.each { |msg| puts( "#{msg}") }
|
193
|
+
puts( "errors : ".red ) unless errors.count == 0
|
194
|
+
errors.each { |msg| puts( "- #{msg}".red ) }
|
195
|
+
else
|
196
|
+
puts( "No file changes needs to be applied. Please set :file_changes".blue )
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
desc <<-DESC
|
201
|
+
Makes some file level operations if needed (rename, replace)
|
202
|
+
DESC
|
203
|
+
task :deploy, :roles => :web do
|
204
|
+
make_file_changes
|
205
|
+
end
|
206
|
+
|
207
|
+
desc <<-DESC
|
208
|
+
[local] Makes some file level operations if needed (rename, replace)
|
209
|
+
DESC
|
210
|
+
task :deploy_locally, :roles => :web do
|
211
|
+
make_file_changes( :locally => true )
|
212
|
+
end
|
213
|
+
|
214
|
+
def get_file_changes
|
215
|
+
return fetch( :file_changes, false )
|
216
|
+
end
|
217
|
+
|
218
|
+
end
|
64
219
|
|
65
220
|
namespace :cache do
|
66
221
|
desc <<-DESC
|
@@ -70,10 +225,12 @@ namespace :capez do
|
|
70
225
|
# Multiple server platform are supposed to use a cluster configuration (eZDFS/eZDBFS)
|
71
226
|
# and cache management is done via expiry.php which is managed by the cluster API
|
72
227
|
task :clear, :roles => :web, :only => { :primary => true } do
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
228
|
+
puts( "\n--> Clearing caches #{'with --purge'.red if cache_purge}" )
|
229
|
+
cache_list.each { |cache_tag|
|
230
|
+
print_dotted( "#{cache_tag}" )
|
231
|
+
capture "cd #{current_path} && sudo -u #{webserver_user} php bin/php/ezcache.php --clear-tag=#{cache_tag}#{' --purge' if cache_purge}"
|
232
|
+
puts( " OK".green )
|
233
|
+
}
|
77
234
|
end
|
78
235
|
end
|
79
236
|
|
@@ -82,29 +239,65 @@ namespace :capez do
|
|
82
239
|
Creates the needed folder within your remote(s) var directories
|
83
240
|
DESC
|
84
241
|
task :init_shared, :roles => :web do
|
242
|
+
puts( "--> Creating eZ Publish var directories" )
|
243
|
+
print_dotted( "var " )
|
244
|
+
run( "mkdir -p #{shared_path}/var" )
|
245
|
+
puts( " OK".green )
|
246
|
+
|
247
|
+
print_dotted( "var/storage" )
|
85
248
|
run( "mkdir -p #{shared_path}/var/storage" )
|
86
|
-
|
87
|
-
|
249
|
+
puts( " OK".green )
|
250
|
+
|
251
|
+
storage_directories.each{ |sd|
|
252
|
+
print_dotted( "var/#{sd}/storage" )
|
253
|
+
run( "mkdir -p #{shared_path}/var/#{sd}/storage" )
|
254
|
+
puts( " OK".green )
|
255
|
+
}
|
256
|
+
run( "chmod -R g+w #{shared_path}/var")
|
257
|
+
run( "chown -R #{fetch(:webserver_group,:user)} #{shared_path}/var")
|
258
|
+
end
|
259
|
+
|
260
|
+
|
261
|
+
|
262
|
+
desc <<-DESC
|
263
|
+
[internal] Creates release directories
|
264
|
+
DESC
|
265
|
+
task :init_release, :roles => :web do
|
266
|
+
puts( "\n--> Release directories" )
|
267
|
+
|
268
|
+
# creates a storage dir for elements specified by :storage_directories
|
269
|
+
storage_directories.each{ |sd|
|
270
|
+
print_dotted( "var/#{sd}/storage" )
|
271
|
+
run( "mkdir #{latest_release}/var/#{sd}" )
|
272
|
+
puts( " OK".green )
|
88
273
|
}
|
89
274
|
|
90
|
-
|
275
|
+
# makes sure the webserver can write into var/
|
276
|
+
run( "chmod -R g+w #{latest_release}/var")
|
277
|
+
run( "chown -R #{fetch(:webserver_user,:user)}:#{fetch(:webserver_group,:user)} #{latest_release}/var")
|
278
|
+
# needed even if we just want to run 'bin/php/ezpgenerateautoloads.php' with --extension
|
279
|
+
run( "chown -R #{fetch(:webserver_user,:user)}:#{fetch(:webserver_group,:user)} #{latest_release}/autoload")
|
91
280
|
end
|
92
281
|
|
93
282
|
desc <<-DESC
|
94
283
|
Link .../shared/var into ../releases/[latest_release]/var
|
95
284
|
DESC
|
96
285
|
task :link, :roles => :web do
|
97
|
-
|
98
|
-
siteaccess_list.each{ |siteaccess_identifier|
|
99
|
-
run( "mkdir #{latest_release}/var/#{siteaccess_identifier}" )
|
100
|
-
}
|
286
|
+
puts( "\n--> Symlinks" )
|
101
287
|
|
102
|
-
|
288
|
+
print_dotted( "var/storage" )
|
289
|
+
run( "ln -s #{shared_path}/var/storage #{latest_release}/var/storage" )
|
290
|
+
puts( " OK".green )
|
103
291
|
|
104
|
-
|
105
|
-
|
106
|
-
|
292
|
+
storage_directories.each{ |sd|
|
293
|
+
print_dotted( "var/#{sd}/storage" )
|
294
|
+
run( "ln -s #{shared_path}/var/#{sd}/storage #{latest_release}/var/#{sd}/storage", :as => webserver_user )
|
295
|
+
#run( "chmod -h g+w #{latest_release}/var/#{sd}/storage")
|
296
|
+
puts( " OK".green )
|
107
297
|
}
|
298
|
+
|
299
|
+
run( "chmod -R g+w #{latest_release}/var")
|
300
|
+
run( "chown -R #{fetch(:webserver_user,:user)}:#{fetch(:webserver_group,:user)} #{shared_path}/var")
|
108
301
|
end
|
109
302
|
|
110
303
|
desc <<-DESC
|
@@ -159,12 +352,17 @@ namespace :capez do
|
|
159
352
|
Generates autoloads (extensions and kernel overrides)
|
160
353
|
DESC
|
161
354
|
task :generate do
|
162
|
-
|
163
|
-
|
355
|
+
if autoload_list.count == 0
|
356
|
+
print_dotted( "--> eZ Publish autoloads (disabled)", :sol => true )
|
357
|
+
puts( " OK".green )
|
358
|
+
else
|
359
|
+
puts( "\n--> eZ Publish autoloads " )
|
360
|
+
autoload_list.each { |autoload|
|
361
|
+
print_dotted( "#{autoload}" )
|
362
|
+
capture( "cd #{latest_release} && sudo -u #{webserver_user} php bin/php/ezpgenerateautoloads.php --#{autoload}" )
|
363
|
+
puts( " OK".green )
|
364
|
+
}
|
164
365
|
end
|
165
|
-
autoload_list.each { |autoload|
|
166
|
-
capture( "cd #{latest_release} && sudo -u #{webserver_user} php bin/php/ezpgenerateautoloads.php --#{autoload}" )
|
167
|
-
}
|
168
366
|
end
|
169
367
|
end
|
170
368
|
# End of namespace :capez:autoloads
|
@@ -172,7 +370,7 @@ namespace :capez do
|
|
172
370
|
# Should be transformed in a simple function (not aimed to be called as a Cap task...)
|
173
371
|
namespace :dev do
|
174
372
|
desc <<-DESC
|
175
|
-
Checks
|
373
|
+
Checks changes on your local installation
|
176
374
|
Considers that your main git repo is at the top of your eZ Publish install
|
177
375
|
If changes are detected, then ask the user to continue or not
|
178
376
|
DESC
|
@@ -184,26 +382,26 @@ namespace :capez do
|
|
184
382
|
ezroot_path = fetch( :ezpublish_path, false )
|
185
383
|
abort "Please set a correct path to your eZ Publish root (:ezpublish_path) or add 'set :ezpublish_path, File.expand_path( File.dirname( __FILE__ ) )' in your Capfile" unless ezroot_path != false and File.exists?(ezroot_path)
|
186
384
|
|
385
|
+
puts( "\n--> Local installation check with git status" )
|
187
386
|
git_status = git_status_result( ezroot_path )
|
188
387
|
|
189
388
|
ask_to_abort = false
|
190
|
-
puts "Checking your local git..."
|
191
389
|
if git_status['has_local_changes']
|
192
390
|
ask_to_abort = true
|
193
|
-
puts "You have local changes"
|
391
|
+
puts( " - You have local changes" )
|
194
392
|
end
|
195
393
|
if git_status['has_new_files']
|
196
394
|
ask_to_abort = true
|
197
|
-
puts "You have
|
395
|
+
puts( " - You have untracked files (not under git control)" )
|
198
396
|
end
|
199
397
|
|
200
398
|
if ask_to_abort
|
201
|
-
user_abort = Capistrano::CLI.ui.ask "Abort ? y/n (n)"
|
202
|
-
abort "Deployment aborted to commit/add local changes" unless user_abort == "n" or user_abort == ""
|
399
|
+
user_abort = Capistrano::CLI.ui.ask " Abort ? y/n (n)"
|
400
|
+
abort "Deployment aborted to commit/add local changes".red unless user_abort == "n" or user_abort == ""
|
203
401
|
end
|
204
402
|
|
205
403
|
if git_status['tracked_branch_status'] == 'ahead'
|
206
|
-
|
404
|
+
print " - You have #{git_status['tracked_branch_commits']} commits that need to be pushed"
|
207
405
|
push_before = Capistrano::CLI.ui.ask "Push them before deployment ? y/n (y)"
|
208
406
|
if push_before == "" or push_before == "y"
|
209
407
|
system "git push"
|
@@ -248,4 +446,29 @@ namespace :capez do
|
|
248
446
|
end
|
249
447
|
end
|
250
448
|
|
449
|
+
|
450
|
+
end
|
451
|
+
|
452
|
+
def print_dotted( message, options={} )
|
453
|
+
defaults_options = { :eol => false,
|
454
|
+
:sol => false,
|
455
|
+
:max_length => 40,
|
456
|
+
:eol_msg => false }
|
457
|
+
|
458
|
+
options = defaults_options.merge( options )
|
459
|
+
message = "#{message} " + "." * [0,options[:max_length]-message.length-1].max
|
460
|
+
|
461
|
+
if options[:sol]
|
462
|
+
message = "\n#{message}"
|
463
|
+
end
|
464
|
+
|
465
|
+
if options[:eol_msg]
|
466
|
+
message += " #{options[:eol_msg]}"
|
467
|
+
end
|
468
|
+
|
469
|
+
if options[:eol]
|
470
|
+
puts message
|
471
|
+
else
|
472
|
+
print message
|
473
|
+
end
|
251
474
|
end
|
data/lib/ext/spinner.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# spinner stuff
|
2
|
+
# inspired from http://jondavidjohn.com/blog/2012/04/cleaning-up-capistrano-deployment-output
|
3
|
+
@spinner_running = false
|
4
|
+
@chars = ['|', '/', '-', '\\']
|
5
|
+
@spinner = Thread.new do
|
6
|
+
loop do
|
7
|
+
unless @spinner_running
|
8
|
+
Thread.stop
|
9
|
+
end
|
10
|
+
print @chars[0]
|
11
|
+
sleep(0.1)
|
12
|
+
print "\b"
|
13
|
+
@chars.push @chars.shift
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def start_spinner
|
18
|
+
@spinner_running = true
|
19
|
+
@spinner.wakeup
|
20
|
+
end
|
21
|
+
|
22
|
+
# stops the spinner and backspaces over last displayed character
|
23
|
+
def stop_spinner
|
24
|
+
@spinner_running = false
|
25
|
+
print "\b"
|
26
|
+
end
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
7
|
+
- 3
|
8
8
|
- 0
|
9
|
-
version: 0.
|
9
|
+
version: 0.3.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Arnaud Lafon
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2012-
|
17
|
+
date: 2012-11-29 00:00:00 +01:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -31,6 +31,19 @@ dependencies:
|
|
31
31
|
version: 2.12.0
|
32
32
|
type: :runtime
|
33
33
|
version_requirements: *id001
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: colored
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
segments:
|
42
|
+
- 1
|
43
|
+
- 2
|
44
|
+
version: "1.2"
|
45
|
+
type: :runtime
|
46
|
+
version_requirements: *id002
|
34
47
|
description: Capistrano is a utility and framework for executing commands in parallel on multiple remote machines, via SSH. This package gives you some tools to deploy your eZ Publish projects.
|
35
48
|
email: alcapon@arnaudlafon.com
|
36
49
|
executables:
|
@@ -43,6 +56,7 @@ files:
|
|
43
56
|
- bin/capezit
|
44
57
|
- lib/capez.rb
|
45
58
|
- lib/db.rb
|
59
|
+
- lib/ext/spinner.rb
|
46
60
|
- README.md
|
47
61
|
- LICENSE.md
|
48
62
|
has_rdoc: true
|