capifony 0.4.3 → 2.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. data/CHANGELOG +6 -0
  2. data/bin/capifony +47 -12
  3. data/lib/capifony.rb +3 -565
  4. data/lib/symfony1.rb +569 -0
  5. data/lib/symfony2.rb +215 -0
  6. metadata +11 -9
@@ -0,0 +1,569 @@
1
+ require 'yaml'
2
+ load Gem.required_location('capifony', 'capifony.rb')
3
+
4
+ # Dirs that need to remain the same between deploys (shared dirs)
5
+ set :shared_children, %w(log web/uploads)
6
+
7
+ # Files that need to remain the same between deploys
8
+ set :shared_files, %w(config/databases.yml)
9
+
10
+ # Asset folders (that need to be timestamped)
11
+ set :asset_children, %w(web/css web/images web/js)
12
+
13
+ # Use ORM
14
+ set :use_orm, true
15
+
16
+ # Symfony default ORM
17
+ set(:symfony_orm) { guess_symfony_orm }
18
+
19
+ # Symfony lib path
20
+ set(:symfony_lib) { guess_symfony_lib }
21
+
22
+ def guess_symfony_orm
23
+ databases = YAML::load(IO.read('config/databases.yml'))
24
+
25
+ if databases[symfony_env_local]
26
+ databases[symfony_env_local].keys[0].to_s
27
+ else
28
+ databases['all'].keys[0].to_s
29
+ end
30
+ end
31
+
32
+ def guess_symfony_lib
33
+ symfony_version = capture("#{php_bin} #{latest_release}/symfony -V")
34
+
35
+ /\((.*)\)/.match(symfony_version)[1]
36
+ end
37
+
38
+ def load_database_config(data, env)
39
+ databases = YAML::load(data)
40
+
41
+ if databases[env]
42
+ db_param = databases[env][symfony_orm]['param']
43
+ else
44
+ db_param = databases['all'][symfony_orm]['param']
45
+ end
46
+
47
+ {
48
+ 'type' => /(\w+)\:/.match(db_param['dsn'])[1],
49
+ 'user' => db_param['username'],
50
+ 'pass' => db_param['password'],
51
+ 'db' => /dbname=([^;$]+)/.match(db_param['dsn'])[1]
52
+ }
53
+ end
54
+
55
+ namespace :deploy do
56
+ desc "Customize migrate task because symfony doesn't need it."
57
+ task :migrate do
58
+ symfony.orm.migrate
59
+ end
60
+
61
+ desc "Symlink static directories and static files that need to remain between deployments."
62
+ task :share_childs do
63
+ if shared_children
64
+ shared_children.each do |link|
65
+ run "mkdir -p #{shared_path}/#{link}"
66
+ run "if [ -d #{release_path}/#{link} ] ; then rm -rf #{release_path}/#{link}; fi"
67
+ run "ln -nfs #{shared_path}/#{link} #{release_path}/#{link}"
68
+ end
69
+ end
70
+ if shared_files
71
+ shared_files.each do |link|
72
+ link_dir = File.dirname("#{shared_path}/#{link}")
73
+ run "mkdir -p #{link_dir}"
74
+ run "touch #{shared_path}/#{link}"
75
+ run "ln -nfs #{shared_path}/#{link} #{release_path}/#{link}"
76
+ end
77
+ end
78
+ end
79
+
80
+ desc "Customize the finalize_update task to work with symfony."
81
+ task :finalize_update, :except => { :no_release => true } do
82
+ run "chmod -R g+w #{latest_release}" if fetch(:group_writable, true)
83
+ run "mkdir -p #{latest_release}/cache"
84
+
85
+ # Share common files & folders
86
+ share_childs
87
+
88
+ if fetch(:normalize_asset_timestamps, true)
89
+ stamp = Time.now.utc.strftime("%Y%m%d%H%M.%S")
90
+ asset_paths = asset_children.map { |p| "#{latest_release}/#{p}" }.join(" ")
91
+ run "find #{asset_paths} -exec touch -t #{stamp} {} ';'; true", :env => { "TZ" => "UTC" }
92
+ end
93
+ end
94
+
95
+ desc "Need to overwrite the deploy:cold task so it doesn't try to run the migrations."
96
+ task :cold do
97
+ update
98
+ symfony.orm.build_db_and_load
99
+ start
100
+ end
101
+
102
+ desc "Deploy the application and run the test suite."
103
+ task :testall do
104
+ update_code
105
+ symlink
106
+ symfony.orm.build_db_and_load
107
+ symfony.tests.all
108
+ end
109
+ end
110
+
111
+ namespace :symfony do
112
+ desc "Runs custom symfony task"
113
+ task :default do
114
+ prompt_with_default(:task_arguments, "cache:clear")
115
+
116
+ stream "#{php_bin} #{latest_release}/symfony #{task_arguments}"
117
+ end
118
+
119
+ desc "Downloads & runs check_configuration.php on remote"
120
+ task :check_configuration do
121
+ prompt_with_default(:version, "1.4")
122
+
123
+ run "wget http://sf-to.org/#{version}/check.php -O /tmp/check_configuration.php"
124
+ stream "#{php_bin} /tmp/check_configuration.php"
125
+ run "rm /tmp/check_configuration.php"
126
+ end
127
+
128
+ desc "Clears the cache"
129
+ task :cc do
130
+ run "#{php_bin} #{latest_release}/symfony cache:clear"
131
+ end
132
+
133
+ namespace :configure do
134
+ desc "Configure database DSN"
135
+ task :database do
136
+ prompt_with_default(:dsn, "mysql:host=localhost;dbname=#{application}")
137
+ prompt_with_default(:db_username, "root")
138
+ db_password = Capistrano::CLI.password_prompt("db_password : ")
139
+
140
+ # surpress debug log output to hide the password
141
+ current_logger_level = self.logger.level
142
+ if current_logger_level >= Capistrano::Logger::DEBUG
143
+ logger.debug %(executing "#{php_bin} #{latest_release}/symfony configure:database '#{dsn}' '#{db_username}' ***")
144
+ self.logger.level = Capistrano::Logger::INFO
145
+ end
146
+
147
+ run "#{php_bin} #{latest_release}/symfony configure:database '#{dsn}' '#{db_username}' '#{db_password}'"
148
+
149
+ # restore logger level
150
+ self.logger.level = current_logger_level
151
+ end
152
+ end
153
+
154
+ namespace :project do
155
+ desc "Disables an application in a given environment"
156
+ task :disable do
157
+ run "#{php_bin} #{latest_release}/symfony project:disable #{symfony_env_prod}"
158
+ end
159
+
160
+ desc "Enables an application in a given environment"
161
+ task :enable do
162
+ run "#{php_bin} #{latest_release}/symfony project:enable #{symfony_env_prod}"
163
+ end
164
+
165
+ desc "Fixes symfony directory permissions"
166
+ task :permissions do
167
+ run "#{php_bin} #{latest_release}/symfony project:permissions"
168
+ end
169
+
170
+ desc "Optimizes a project for better performance"
171
+ task :optimize do
172
+ prompt_with_default(:application, "frontend")
173
+
174
+ run "#{php_bin} #{latest_release}/symfony project:optimize #{application}"
175
+ end
176
+
177
+ desc "Clears all non production environment controllers"
178
+ task :clear_controllers do
179
+ run "#{php_bin} #{latest_release}/symfony project:clear-controllers"
180
+ end
181
+
182
+ desc "Sends emails stored in a queue"
183
+ task :send_emails do
184
+ prompt_with_default(:message_limit, 10)
185
+ prompt_with_default(:time_limit, 10)
186
+
187
+ stream "#{php_bin} #{latest_release}/symfony project:send-emails --message-limit=#{message_limit} --time-limit=#{time_limit} --env=#{symfony_env_prod}"
188
+ end
189
+
190
+ desc 'Task to set all front controllers to a specific environment'
191
+ task :set_environment do
192
+ if (env = fetch(:symfony_env_prod, nil)) && env != 'prod'
193
+ cmd = []
194
+ apps = fetch(:symfony_apps, ['frontend'])
195
+
196
+ # First application listed becomes index.php
197
+ if app = apps.shift
198
+ cmd << "cp #{release_path}/web/#{app}_#{env}.php #{release_path}/web/index.php"
199
+ end
200
+
201
+ # All other apps are copied to their default controllers
202
+ for app in apps
203
+ cmd << "cp #{release_path}/web/#{app}_#{env}.php #{release_path}/web/#{app}.php"
204
+ end
205
+
206
+ run cmd.join(';') if cmd.join(';')
207
+ end
208
+ end
209
+ end
210
+
211
+ namespace :plugin do
212
+ desc "Publishes web assets for all plugins"
213
+ task :publish_assets do
214
+ run "#{php_bin} #{latest_release}/symfony plugin:publish-assets"
215
+ end
216
+ end
217
+
218
+ namespace :log do
219
+ desc "Clears log files"
220
+ task :clear do
221
+ run "#{php_bin} #{latest_release}/symfony log:clear"
222
+ end
223
+
224
+ desc "Rotates an application's log files"
225
+ task :rotate do
226
+ prompt_with_default(:application, "frontend")
227
+
228
+ run "#{php_bin} #{latest_release}/symfony log:rotate #{application} #{symfony_env_prod}"
229
+ end
230
+ end
231
+
232
+ namespace :tests do
233
+ desc "Launches all tests"
234
+ task :all do
235
+ run "#{php_bin} #{latest_release}/symfony test:all"
236
+ end
237
+
238
+ desc "Launches functional tests"
239
+ task :functional do
240
+ prompt_with_default(:application, "frontend")
241
+
242
+ run "#{php_bin} #{latest_release}/symfony test:functional #{application}"
243
+ end
244
+
245
+ desc "Launches unit tests"
246
+ task :unit do
247
+ run "#{php_bin} #{latest_release}/symfony test:unit"
248
+ end
249
+ end
250
+
251
+ namespace :orm do
252
+ desc "Ensure symfony ORM is properly configured"
253
+ task :setup do
254
+ find_and_execute_task("symfony:#{symfony_orm}:setup")
255
+ end
256
+
257
+ desc "Migrates database to current version"
258
+ task :migrate do
259
+ find_and_execute_task("symfony:#{symfony_orm}:migrate")
260
+ end
261
+
262
+ desc "Generate model lib form and filters classes based on your schema"
263
+ task :build_classes do
264
+ find_and_execute_task("symfony:#{symfony_orm}:build_classes")
265
+ end
266
+
267
+ desc "Generate code & database based on your schema"
268
+ task :build_all do
269
+ find_and_execute_task("symfony:#{symfony_orm}:build_all")
270
+ end
271
+
272
+ desc "Generate code & database based on your schema & load fixtures"
273
+ task :build_all_and_load do
274
+ find_and_execute_task("symfony:#{symfony_orm}:build_all_and_load")
275
+ end
276
+
277
+ desc "Generate sql & database based on your schema"
278
+ task :build_db do
279
+ find_and_execute_task("symfony:#{symfony_orm}:build_db")
280
+ end
281
+
282
+ desc "Generate sql & database based on your schema & load fixtures"
283
+ task :build_db_and_load do
284
+ find_and_execute_task("symfony:#{symfony_orm}:build_db_and_load")
285
+ end
286
+ end
287
+
288
+ namespace :doctrine do
289
+ desc "Compile doctrine"
290
+ task :compile do
291
+ run "#{php_bin} #{latest_release}/symfony doctrine:compile"
292
+ end
293
+
294
+ desc "Ensure Doctrine is correctly configured"
295
+ task :setup do
296
+ conf_files_exists = capture("if test -s #{shared_path}/config/databases.yml ; then echo 'exists' ; fi").strip
297
+ if (!conf_files_exists.eql?("exists"))
298
+ symfony.configure.database
299
+ end
300
+ end
301
+
302
+ desc "Execute a DQL query and view the results"
303
+ task :dql do
304
+ prompt_with_default(:query, "")
305
+
306
+ stream "#{php_bin} #{latest_release}/symfony doctrine:dql #{query} --env=#{symfony_env_prod}"
307
+ end
308
+
309
+ desc "Dumps data to the fixtures directory"
310
+ task :data_dump do
311
+ run "#{php_bin} #{latest_release}/symfony doctrine:data-dump --env=#{symfony_env_prod}"
312
+ end
313
+
314
+ desc "Loads YAML fixture data"
315
+ task :data_load do
316
+ run "#{php_bin} #{latest_release}/symfony doctrine:data-load --env=#{symfony_env_prod}"
317
+ end
318
+
319
+ desc "Loads YAML fixture data without remove"
320
+ task :data_load_append do
321
+ run "#{php_bin} #{latest_release}/symfony doctrine:data-load --append --env=#{symfony_env_prod}"
322
+ end
323
+
324
+ desc "Migrates database to current version"
325
+ task :migrate do
326
+ run "#{php_bin} #{latest_release}/symfony doctrine:migrate --env=#{symfony_env_prod}"
327
+ end
328
+
329
+ desc "Generate model lib form and filters classes based on your schema"
330
+ task :build_classes do
331
+ run "#{php_bin} #{latest_release}/symfony doctrine:build --all-classes --env=#{symfony_env_prod}"
332
+ end
333
+
334
+ desc "Generate code & database based on your schema"
335
+ task :build_all do
336
+ if Capistrano::CLI.ui.agree("Do you really want to rebuild #{symfony_env_prod}'s database? (y/N)")
337
+ run "#{php_bin} #{latest_release}/symfony doctrine:build --all --no-confirmation --env=#{symfony_env_prod}"
338
+ end
339
+ end
340
+
341
+ desc "Generate code & database based on your schema & load fixtures"
342
+ task :build_all_and_load do
343
+ if Capistrano::CLI.ui.agree("Do you really want to rebuild #{symfony_env_prod}'s database and load #{symfony_env_prod}'s fixtures? (y/N)")
344
+ run "#{php_bin} #{latest_release}/symfony doctrine:build --all --and-load --no-confirmation --env=#{symfony_env_prod}"
345
+ end
346
+ end
347
+
348
+ desc "Generate sql & database based on your schema"
349
+ task :build_db do
350
+ if Capistrano::CLI.ui.agree("Do you really want to rebuild #{symfony_env_prod}'s database? (y/N)")
351
+ run "#{php_bin} #{latest_release}/symfony doctrine:build --sql --db --no-confirmation --env=#{symfony_env_prod}"
352
+ end
353
+ end
354
+
355
+ desc "Generate sql & database based on your schema & load fixtures"
356
+ task :build_db_and_load do
357
+ if Capistrano::CLI.ui.agree("Do you really want to rebuild #{symfony_env_prod}'s database and load #{symfony_env_prod}'s fixtures? (y/N)")
358
+ run "#{php_bin} #{latest_release}/symfony doctrine:build --sql --db --and-load --no-confirmation --env=#{symfony_env_prod}"
359
+ end
360
+ end
361
+ end
362
+
363
+ namespace :propel do
364
+ desc "Ensure Propel is correctly configured"
365
+ task :setup do
366
+ conf_files_exists = capture("if test -s #{shared_path}/config/propel.ini -a -s #{shared_path}/config/databases.yml ; then echo 'exists' ; fi").strip
367
+
368
+ # share childs again (for propel.ini file)
369
+ shared_files << "config/propel.ini"
370
+ deploy.share_childs
371
+
372
+ if (!conf_files_exists.eql?("exists"))
373
+ run "cp #{symfony_lib}/plugins/sfPropelPlugin/config/skeleton/config/propel.ini #{shared_path}/config/propel.ini"
374
+ symfony.configure.database
375
+ end
376
+ end
377
+
378
+ desc "Migrates database to current version"
379
+ task :migrate do
380
+ puts "propel doesn't have built-in migration for now"
381
+ end
382
+
383
+ desc "Generate model lib form and filters classes based on your schema"
384
+ task :build_classes do
385
+ run "php #{latest_release}/symfony propel:build --all-classes --env=#{symfony_env_prod}"
386
+ end
387
+
388
+ desc "Generate code & database based on your schema"
389
+ task :build_all do
390
+ if Capistrano::CLI.ui.agree("Do you really want to rebuild #{symfony_env_prod}'s database? (y/N)")
391
+ run "#{php_bin} #{latest_release}/symfony propel:build --sql --db --no-confirmation --env=#{symfony_env_prod}"
392
+ end
393
+ end
394
+
395
+ desc "Generate code & database based on your schema & load fixtures"
396
+ task :build_all_and_load do
397
+ if Capistrano::CLI.ui.agree("Do you really want to rebuild #{symfony_env_prod}'s database and load #{symfony_env_prod}'s fixtures? (y/N)")
398
+ run "#{php_bin} #{latest_release}/symfony propel:build --sql --db --and-load --no-confirmation --env=#{symfony_env_prod}"
399
+ end
400
+ end
401
+
402
+ desc "Generate sql & database based on your schema"
403
+ task :build_db do
404
+ if Capistrano::CLI.ui.agree("Do you really want to rebuild #{symfony_env_prod}'s database? (y/N)")
405
+ run "#{php_bin} #{latest_release}/symfony propel:build --sql --db --no-confirmation --env=#{symfony_env_prod}"
406
+ end
407
+ end
408
+
409
+ desc "Generate sql & database based on your schema & load fixtures"
410
+ task :build_db_and_load do
411
+ if Capistrano::CLI.ui.agree("Do you really want to rebuild #{symfony_env_prod}'s database and load #{symfony_env_prod}'s fixtures? (y/N)")
412
+ run "#{php_bin} #{latest_release}/symfony propel:build --sql --db --and-load --no-confirmation --env=#{symfony_env_prod}"
413
+ end
414
+ end
415
+ end
416
+ end
417
+
418
+ namespace :database do
419
+ namespace :dump do
420
+ desc "Dump remote database"
421
+ task :remote do
422
+ filename = "#{application}.remote_dump.#{Time.now.to_i}.sql.bz2"
423
+ file = "/tmp/#{filename}"
424
+ sqlfile = "#{application}_dump.sql"
425
+ config = ""
426
+
427
+ run "cat #{shared_path}/config/databases.yml" do |ch, st, data|
428
+ config = load_database_config data, symfony_env_prod
429
+ end
430
+
431
+ case config['type']
432
+ when 'mysql'
433
+ run "mysqldump -u#{config['user']} --password='#{config['pass']}' #{config['db']} | bzip2 -c > #{file}" do |ch, stream, data|
434
+ puts data
435
+ end
436
+ when 'pgsql'
437
+ run "pg_dump -U #{config['user']} --password='#{config['pass']}' #{config['db']} | bzip2 -c > #{file}" do |ch, stream, data|
438
+ puts data
439
+ end
440
+ end
441
+
442
+ `mkdir -p backups`
443
+ get file, "backups/#{filename}"
444
+ `cd backups && ln -nfs #{filename} #{application}.remote_dump.latest.sql.bz2`
445
+ run "rm #{file}"
446
+ end
447
+
448
+ desc "Dump local database"
449
+ task :local do
450
+ filename = "#{application}.local_dump.#{Time.now.to_i}.sql.bz2"
451
+ file = "backups/#{filename}"
452
+ config = load_database_config IO.read('config/databases.yml'), symfony_env_local
453
+ sqlfile = "#{application}_dump.sql"
454
+
455
+ `mkdir -p backups`
456
+ case config['type']
457
+ when 'mysql'
458
+ `mysqldump -u#{config['user']} --password='#{config['pass']}' #{config['db']} | bzip2 -c > #{file}`
459
+ when 'pgsql'
460
+ `pg_dump -U #{config['user']} --password='#{config['pass']}' #{config['db']} | bzip2 -c > #{file}`
461
+ end
462
+
463
+ `cd backups && ln -nfs #{filename} #{application}.local_dump.latest.sql.bz2`
464
+ end
465
+ end
466
+
467
+ namespace :move do
468
+ desc "Dump remote database, download it to local & populate here"
469
+ task :to_local do
470
+ filename = "#{application}.remote_dump.latest.sql.bz2"
471
+ config = load_database_config IO.read('config/databases.yml'), symfony_env_local
472
+ sqlfile = "#{application}_dump.sql"
473
+
474
+ database.dump.remote
475
+
476
+ `bunzip2 -kc backups/#{filename} > backups/#{sqlfile}`
477
+ case config['type']
478
+ when 'mysql'
479
+ `mysql -u#{config['user']} --password='#{config['pass']}' #{config['db']} < backups/#{sqlfile}`
480
+ when 'pgsql'
481
+ `psql -U #{config['user']} --password='#{config['pass']}' #{config['db']} < backups/#{sqlfile}`
482
+ end
483
+ `rm backups/#{sqlfile}`
484
+ end
485
+
486
+ desc "Dump local database, load it to remote & populate there"
487
+ task :to_remote do
488
+ filename = "#{application}.local_dump.latest.sql.bz2"
489
+ file = "backups/#{filename}"
490
+ sqlfile = "#{application}_dump.sql"
491
+ config = ""
492
+
493
+ database.dump.local
494
+
495
+ upload(file, "/tmp/#{filename}", :via => :scp)
496
+ run "bunzip2 -kc /tmp/#{filename} > /tmp/#{sqlfile}"
497
+
498
+ run "cat #{shared_path}/config/databases.yml" do |ch, st, data|
499
+ config = load_database_config data, symfony_env_prod
500
+ end
501
+
502
+ case config['type']
503
+ when 'mysql'
504
+ run "mysql -u#{config['user']} --password='#{config['pass']}' #{config['db']} < /tmp/#{sqlfile}" do |ch, stream, data|
505
+ puts data
506
+ end
507
+ when 'pgsql'
508
+ run "psql -U #{config['user']} --password='#{config['pass']}' #{config['db']} < /tmp/#{sqlfile}" do |ch, stream, data|
509
+ puts data
510
+ end
511
+ end
512
+
513
+ run "rm /tmp/#{filename}"
514
+ run "rm /tmp/#{sqlfile}"
515
+ end
516
+ end
517
+ end
518
+
519
+ namespace :shared do
520
+ namespace :databases do
521
+ desc "Download config/databases.yml from remote server"
522
+ task :to_local do
523
+ download("#{shared_path}/config/databases.yml", "config/databases.yml", :via => :scp)
524
+ end
525
+
526
+ desc "Upload config/databases.yml to remote server"
527
+ task :to_remote do
528
+ upload("config/databases.yml", "#{shared_path}/config/databases.yml", :via => :scp)
529
+ end
530
+ end
531
+
532
+ namespace :log do
533
+ desc "Download all logs from remote folder to local one"
534
+ task :to_local do
535
+ download("#{shared_path}/log", "./", :via => :scp, :recursive => true)
536
+ end
537
+
538
+ desc "Upload all logs from local folder to remote one"
539
+ task :to_remote do
540
+ upload("log", "#{shared_path}/", :via => :scp, :recursive => true)
541
+ end
542
+ end
543
+
544
+ namespace :uploads do
545
+ desc "Download all files from remote web/uploads folder to local one"
546
+ task :to_local do
547
+ download("#{shared_path}/web/uploads", "web", :via => :scp, :recursive => true)
548
+ end
549
+
550
+ desc "Upload all files from local web/uploads folder to remote one"
551
+ task :to_remote do
552
+ upload("web/uploads", "#{shared_path}/web", :via => :scp, :recursive => true)
553
+ end
554
+ end
555
+ end
556
+
557
+ # After finalizing update:
558
+ after "deploy:finalize_update" do
559
+ if use_orm
560
+ symfony.orm.setup # 1. Ensure that ORM is configured
561
+ symfony.orm.build_classes # 2. (Re)build the model
562
+ end
563
+ symfony.cc # 3. Clear cache
564
+ symfony.plugin.publish_assets # 4. Publish plugin assets
565
+ symfony.project.permissions # 5. Fix project permissions
566
+ if symfony_env_prod.eql?("prod")
567
+ symfony.project.clear_controllers # 6. Clear controllers in production environment
568
+ end
569
+ end