capistrano-choique 0.1.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.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZWNmMjllZTVmZTFhM2EwMjc3Y2UwNzM5YWMzMThmODQ0MjMwMmYzYQ==
5
+ data.tar.gz: !binary |-
6
+ NDNiZGZiOWU4ZDVjNWRhNjk4ODA5NDIxN2I1ZmYyNTYyZDMyYjlmNQ==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ ZTg4NTIwYmMwYzgxOWVkN2ExMzZhZWE5NmYwNGMyZDM0MjI0MmExOTg2YWI1
10
+ NWEyOWM3NTVkMTE0ZDhmYmY3ZTcyMmEyMjg5ZDA0MzIxNDFjZmJjYWVmMDJj
11
+ NzIzMmNjZjA5NjRmOWIwOGQ4MjJiYjg0MjQwMTdiYjY5YTg2ZDc=
12
+ data.tar.gz: !binary |-
13
+ YWZiODZhYzMxMTRkMmMxZmYzMWU2ZWUxMTJhYTY2NjdjMTliNzcwNjhlZTY0
14
+ NWI2MDI2NGIzNGE2YjZkMDlhODFhMGYxZTljNTA0ZWFjZWFkZGZlZjA5NTI0
15
+ M2VkNTFhZjMzNjdmODUxNzkwMmQ3YzY4YzFkNTI1ZDI4ZDIxN2U=
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in capistrano-choique.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Christian Rodriguez
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # Capistrano::Choique
2
+
3
+ Tareas para simplificar el deploy de un choique con capistrano
4
+
5
+ ## Instalacion
6
+
7
+ Agergar la gema a tu Gemfile:
8
+
9
+ gem 'capistrano-choique'
10
+
11
+ y ejecutar:
12
+
13
+ $ bundle
14
+
15
+ O instalarla directamente con:
16
+
17
+ $ gem install capistrano-choique
18
+
19
+ ## Uso
20
+
21
+ Una vez instalada la gema, en el directorio local de trabajo, correr:
22
+
23
+ $ capify-choique .
24
+
25
+
26
+ ## Configurar
27
+
28
+ Analizar la configuracion config/deploy.rb
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,109 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'capistrano'
4
+ require 'capistrano-choique'
5
+ require 'optparse'
6
+ require 'fileutils'
7
+
8
+ capistrano_choique_version = Capistrano::Choique::VERSION
9
+
10
+ OptionParser.new do |opts|
11
+ opts.banner = "Usage: #{File.basename($0)} [path]"
12
+
13
+ opts.on("-h", "--help", "Displays this help info") do
14
+ puts opts
15
+ exit 0
16
+ end
17
+
18
+ opts.on("-v", "--version", "") do
19
+ puts "capistrano-choique v#{Capistrano::Choique::VERSION}"
20
+ exit 0
21
+ end
22
+
23
+ begin
24
+ opts.parse!(ARGV)
25
+ rescue OptionParser::ParseError => e
26
+ warn e.message
27
+ puts opts
28
+ exit 1
29
+ end
30
+ end
31
+
32
+ if ARGV.empty?
33
+ abort "Please specify the directory to capify, e.g. `#{File.basename($0)} .'"
34
+ elsif !File.exists?(ARGV.first)
35
+ abort "`#{ARGV.first}' does not exist."
36
+ elsif !File.directory?(ARGV.first)
37
+ abort "`#{ARGV.first}' is not a directory."
38
+ elsif ARGV.length > 1
39
+ abort "Too many arguments; please specify only the directory to capify."
40
+ end
41
+
42
+ def unindent(string)
43
+ indentation = string[/\A\s*/]
44
+ string.strip.gsub(/^#{indentation}/, "")
45
+ end
46
+
47
+ base = ARGV.shift
48
+
49
+ files = {
50
+ "Capfile" => unindent(<<-FILE),
51
+ load 'deploy'
52
+
53
+ require 'capistrano-choique'
54
+ load 'config/deploy'
55
+ FILE
56
+
57
+ "config/deploy.rb" => unindent(<<-FILE)
58
+ set :application, "set your application name here"
59
+
60
+ # Database settings
61
+ #set :user, "ssh user used for deployment"
62
+ #set :db_type, "mysql"
63
+ #set :db_host, "localhost"
64
+ #set :db_port, "3306"
65
+ #set :db_name, "Set database name. Defaults to \#{application}"
66
+ #set :db_user, "Set database user to connect. Defaults to \#{application}"
67
+ set :db_password, "Change database password"
68
+
69
+ # Deploy settings
70
+ set :domain, "\#{application}.unlp.edu.ar"
71
+ set :deploy_to, "/opt/applications/\#{application}"
72
+
73
+ role :web, domain # Your HTTP server, Apache/etc
74
+ role :app, domain # This may be the same as your `Web` server
75
+ role :db, domain, :primary => true # This is where Symfony2 migrations will run
76
+
77
+ set :keep_releases, 3
78
+
79
+ # Be more verbose by uncommenting the following line
80
+ # logger.level = Logger::MAX_LEVEL
81
+ set :use_sudo, false
82
+
83
+
84
+ # Choique settings
85
+ #set :choique_name, application
86
+ #set :choique_backend_port, 8000
87
+ #set :choique_frontend_url, "http://\#{domain}/"
88
+ #set :choique_backend_url, "https://\#{domain}:\#{choique_backend_port}/"
89
+ #set :choique_testing, false
90
+ FILE
91
+ }
92
+
93
+ files.each do |file, content|
94
+ file = File.join(base, file)
95
+ if File.exists?(file)
96
+ warn "[skip] '#{file}' already exists"
97
+ elsif File.exists?(file.downcase)
98
+ warn "[skip] '#{file.downcase}' exists, which could conflict with `#{file}'"
99
+ else
100
+ unless File.exists?(File.dirname(file))
101
+ puts "[add] making directory '#{File.dirname(file)}'"
102
+ FileUtils.mkdir_p(File.dirname(file))
103
+ end
104
+ puts "[add] writing '#{file}'"
105
+ File.open(file, "w") { |f| f.write(content) }
106
+ end
107
+ end
108
+
109
+ puts "[done] choique project capified!"
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'capistrano-choique/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "capistrano-choique"
8
+ gem.version = Capistrano::Choique::VERSION
9
+ gem.authors = ["Christian Rodriguez"]
10
+ gem.email = ["car@cespi.unlp.edu.ar"]
11
+ gem.description = %q{Capistrano extension to deploy Choique CMS}
12
+ gem.summary = %q{Capify Choique CMS}
13
+ gem.homepage = "https://github.com/Desarrollo-CeSPI/capistrano-choique"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_development_dependency 'rake'
21
+
22
+ gem.add_dependency('capistrano','> 2.0')
23
+ end
@@ -0,0 +1,76 @@
1
+ all:
2
+ choique:
3
+ version: <?php echo file_get_contents(sfConfig::get('sf_root_dir').'/VERSION');?>
4
+
5
+ instance_name: "<%= choique_name %>"
6
+ url:
7
+ frontend: <%= choique_frontend_url %>
8
+ backend: <%= choique_backend_url %>
9
+ default_flavor_dir: %SF_ROOT_DIR%/data/default-flavor
10
+ #La siguiente solapa muestra u oculta un cartel indicando que esta es una version de prueba
11
+ testing: <%= choique_testing %>
12
+ testing_text: Version de PRUEBA
13
+
14
+
15
+
16
+ lucene:
17
+ index: CMSIndex
18
+ advanced: false
19
+ categories: false
20
+ per_page: 20
21
+ pager_radius: 10
22
+ result_size: 200
23
+ result_highlighter: |
24
+ <strong class="highlight">%s</strong>
25
+ extractors:
26
+ doc: /usr/bin/catdoc %s
27
+ pdf: /usr/bin/pdftotext %s -
28
+ ppt: /usr/bin/catppt %s
29
+ xls: /usr/bin/xls2csv %s
30
+ odt: /usr/bin/odt2txt %s
31
+ ods: /usr/bin/ods2txt %s
32
+ odp: /usr/bin/odp2txt %s
33
+
34
+ valid_mime_types:
35
+ text:
36
+ txt: text/plain
37
+ editor:
38
+ css:
39
+ css: [text/plain, text/x-c charset=us-ascii, text/plain charset=us-ascii]
40
+ images:
41
+ jpg: image/jpeg
42
+ jpeg: image/jpeg
43
+ png: image/png
44
+ gif: image/gif
45
+ ico: [image/png, image/gif, image/x-ico]
46
+ link:
47
+ swf: application/x-shockwave-flash
48
+ jpg: image/jpeg
49
+ jpeg: image/jpeg
50
+ png: image/png
51
+ gif: image/gif
52
+ document:
53
+ doc: [application/msword, application/vnd.ms-office]
54
+ docx: application/zip
55
+ xls: application/vnd.ms-excel
56
+ ppt: application/vnd.ms-office
57
+ pps: application/vnd.ms-office
58
+ pdf: application/pdf
59
+ rar: application/x-rar
60
+ zip: application/zip
61
+ rtf: text/rtf
62
+ multimedia:
63
+ images:
64
+ jpg: [image/jpeg ]
65
+ jpeg: [image/jpeg ]
66
+ png: [image/png ]
67
+ gif: [image/gif ]
68
+ videos:
69
+ mpg: [video/mpeg ]
70
+ mpeg: [video/mpeg ]
71
+ flv: [video/x-flv ]
72
+ swf: [application/x-shockwave-flash ]
73
+ audio:
74
+ mp3: [application/octet-stream, audio/mpeg ]
75
+ mp2: [ audio/mpeg ]
76
+ wav: [ audio/x-wav ]
@@ -0,0 +1,41 @@
1
+ cli:
2
+ controller:
3
+ class: sfConsoleController
4
+ request:
5
+ class: sfConsoleRequest
6
+ response:
7
+ class: sfConsoleResponse
8
+
9
+ test:
10
+ storage:
11
+ class: sfSessionTestStorage
12
+
13
+ all:
14
+ storage:
15
+ class: sfSessionStorage
16
+ param:
17
+ session_name: choiqueCMS-b4ck3nd-<%= choique_name.gsub("\s","-") %>
18
+
19
+ #all:
20
+ # controller:
21
+ # class: sfFrontWebController
22
+ #
23
+ # request:
24
+ # class: sfWebRequest
25
+ #
26
+ # response:
27
+ # class: sfWebResponse
28
+ #
29
+ # user:
30
+ # class: myUser
31
+ #
32
+ # storage:
33
+ # class: sfSessionStorage
34
+ # param:
35
+ # session_name: symfony
36
+ #
37
+ # view_cache:
38
+ # class: sfFileCache
39
+ # param:
40
+ # automaticCleaningFactor: 0
41
+ # cacheDir: %SF_TEMPLATE_CACHE_DIR%
@@ -0,0 +1,10 @@
1
+ all:
2
+ propel:
3
+ class: sfPropelDatabase
4
+ param:
5
+ phptype: <%= db_type %>
6
+ port: <%= db_port %>
7
+ hostspec: <%= db_host %>
8
+ database: <%= db_name%>
9
+ username: <%= db_user%>
10
+ password: <%= db_password%>
@@ -0,0 +1,46 @@
1
+ propel.targetPackage = lib.model
2
+ propel.packageObjectModel = true
3
+ propel.project = choique
4
+ propel.database = mysql
5
+ propel.database.createUrl = <%= "#{db_type}://#{db_user}:#{db_password}@#{db_host}:#{db_port}" %>/
6
+ propel.database.url = <%= "#{db_type}://#{db_user}:#{db_password}@#{db_host}:#{db_port}/#{db_name}" %>
7
+
8
+ propel.mysql.tableType = InnoDB
9
+
10
+ propel.addGenericAccessors = true
11
+ propel.addGenericMutators = true
12
+ propel.addTimeStamp = false
13
+
14
+ propel.schema.validate = false
15
+
16
+ ; directories
17
+ propel.home = .
18
+ propel.output.dir = ; Base dir
19
+ propel.schema.dir = ${propel.output.dir}/config
20
+ propel.conf.dir = ${propel.output.dir}/config
21
+ propel.phpconf.dir = ${propel.output.dir}/config
22
+ propel.sql.dir = ${propel.output.dir}/data/sql
23
+ propel.runtime.conf.file = runtime-conf.xml
24
+ propel.php.dir = ${propel.output.dir}
25
+ propel.default.schema.basename = schema
26
+ propel.datadump.mapper.from = *schema.xml
27
+ propel.datadump.mapper.to = *data.xml
28
+
29
+ ; builder settings
30
+ propel.builder.peer.class = addon.propel.builder.SfPeerBuilder
31
+ propel.builder.object.class = addon.propel.builder.SfObjectBuilder
32
+
33
+ propel.builder.objectstub.class = addon.propel.builder.SfExtensionObjectBuilder
34
+ propel.builder.peerstub.class = addon.propel.builder.SfExtensionPeerBuilder
35
+ propel.builder.objectmultiextend.class = addon.propel.builder.SfMultiExtendObjectBuilder
36
+ propel.builder.mapbuilder.class = addon.propel.builder.SfMapBuilderBuilder
37
+ propel.builder.interface.class = propel.engine.builder.om.php5.PHP5InterfaceBuilder
38
+ propel.builder.node.class = propel.engine.builder.om.php5.PHP5NodeBuilder
39
+ propel.builder.nodepeer.class = propel.engine.builder.om.php5.PHP5NodePeerBuilder
40
+ propel.builder.nodestub.class = propel.engine.builder.om.php5.PHP5ExtensionNodeBuilder
41
+ propel.builder.nodepeerstub.class = propel.engine.builder.om.php5.PHP5ExtensionNodePeerBuilder
42
+
43
+ propel.builder.addIncludes = false
44
+ propel.builder.addComments = false
45
+
46
+ propel.builder.addBehaviors = true
@@ -0,0 +1,195 @@
1
+ namespace :choique do
2
+ # Needs to initialize db?
3
+ def need_init?
4
+ config = ""
5
+ run "#{try_sudo} cat #{shared_path}/config/databases.yml" do |ch, st, data|
6
+ config = load_database_config data, :prod
7
+ end
8
+ sql_dump_cmd = generate_sql_command('dump', config)
9
+ logger.debug sql_dump_cmd.gsub(/(--password=)([^ ]+)/, '\1\'********\'') # Log the command with a masked password
10
+ saved_log_level = logger.level
11
+ logger.level = Capistrano::Logger::IMPORTANT # Change log level so that the real command (containing a plaintext password) is not displayed
12
+ ret = 'true' != capture("if `#{sql_dump_cmd} 2> /dev/null | grep -q article`; then echo true; fi").chomp
13
+ logger.level = saved_log_level
14
+ ret
15
+ end
16
+
17
+ # Needs to create a default flavor?
18
+ def flavors_initialize?
19
+ capture("ls #{shared_path}/flavors | wc -l").chomp.to_i == 0
20
+ end
21
+
22
+
23
+ desc "Creates model classes. It will not touch database"
24
+ task :build_model do
25
+ stream "cd #{latest_release} && #{php_bin} ./symfony propel-build-model"
26
+ end
27
+
28
+ desc "Creates model classes and destroy and initialize database with default data"
29
+ task :data_init do
30
+ stream "cd #{latest_release} && #{php_bin} ./symfony propel-build-all-load backend"
31
+ choique.reindex
32
+ end
33
+
34
+ desc "Rebuild search index"
35
+ task :reindex do
36
+ stream "cd #{latest_release} && #{php_bin} ./symfony choique-reindex"
37
+ end
38
+
39
+ desc "Fix file permission"
40
+ task :fix_permissions do
41
+ stream "cd #{latest_release} && #{php_bin} ./symfony choique-fix-perms"
42
+ end
43
+
44
+ desc "Clear symfony cache"
45
+ task :cc do
46
+ stream "cd #{latest_release} && #{php_bin} ./symfony cc"
47
+ end
48
+
49
+ desc "Package current version of choique including dump and download"
50
+ task :package do
51
+ name = "choique-#{Time.now.strftime('%F')}"
52
+ run "cat #{current_release}/VERSION" do |ch, st, data|
53
+ name += "-" + data.gsub(/ build.*/,'').gsub(/^\d{4}-\d{2}-\d{2} (v[\w.-_]+)/,'\1')
54
+ end
55
+ run "test -d #{remote_tmp_dir}/#{name} && rm -fr #{remote_tmp_dir}/#{name}; true"
56
+ run "mkdir #{remote_tmp_dir}/#{name}"
57
+ run "cd #{latest_release}; tar cf - * | (cd #{remote_tmp_dir}/#{name}; tar xfp -)"
58
+ dereference = (shared_children + shared_files).join(' ')
59
+ run "cd #{latest_release}; tar cf - #{dereference} -h | (cd #{remote_tmp_dir}/#{name}; tar xfp -)"
60
+ run "rm #{remote_tmp_dir}/#{name}/config/databases.yml #{remote_tmp_dir}/#{name}/config/propel.ini"
61
+ run "rm -fr #{remote_tmp_dir}/#{name}/cache/*;"
62
+ run "rm -fr #{remote_tmp_dir}/#{name}/log/*;"
63
+
64
+ # Dump database
65
+ file = "#{remote_tmp_dir}/#{name}/dump-#{name}.sql"
66
+ config = ""
67
+ run "#{try_sudo} cat #{shared_path}/config/databases.yml" do |ch, st, data|
68
+ config = load_database_config data, symfony_env_prod
69
+ end
70
+ sql_dump_cmd = generate_sql_command('dump', config)
71
+ logger.debug sql_dump_cmd.gsub(/(--password=)([^ ]+)/, '\1\'********\'') # Log the command with a masked password
72
+ saved_log_level = logger.level
73
+ logger.level = Capistrano::Logger::IMPORTANT # Change log level so that the real command (containing a plaintext password) is not displayed
74
+ try_sudo "#{sql_dump_cmd} | gzip -c > #{file}"
75
+ logger.level = saved_log_level
76
+
77
+ # Package and transfer
78
+ run "cd #{remote_tmp_dir}/; tar cfz #{name}.tgz #{name}"
79
+ require "fileutils"
80
+ FileUtils.mkdir_p("backups")
81
+ get "#{remote_tmp_dir}/#{name}.tgz", "backups/#{name}.tgz"
82
+ begin
83
+ FileUtils.ln_sf("#{name}.tgz", "backups/package-latest.tgz")
84
+ rescue Exception # fallback for file systems that don't support symlinks
85
+ FileUtils.cp_r("#{name}.tgz", "backups/package-latest.tgz")
86
+ end
87
+ run "rm -fr #{remote_tmp_dir}/#{name}.tgz #{remote_tmp_dir}/#{name}"
88
+ end
89
+
90
+ namespace :app do
91
+
92
+ desc "Disable a aplication"
93
+ task :disable do
94
+ app_name = Capistrano::CLI.ui.ask "Enter application name (frontend|backend):"
95
+ env_name = Capistrano::CLI.ui.ask "Enter enviroment name (prod|dev):"
96
+ stream "cd #{latest_release} && #{php_bin} ./symfony disable '#{app_name}' '#{env_name}'"
97
+ end
98
+
99
+ desc "Enable a aplication"
100
+ task :enable do
101
+ app_name = Capistrano::CLI.ui.ask "Enter application name (frontend|backend):"
102
+ env_name = Capistrano::CLI.ui.ask "Enter enviroment name (prod|dev):"
103
+ stream "cd #{latest_release} && #{php_bin} ./symfony enable '#{app_name}' '#{env_name}'"
104
+ end
105
+
106
+ end
107
+
108
+ namespace :user do
109
+
110
+ desc "Create/Update user"
111
+ task :update_or_create_admin do
112
+ username = Capistrano::CLI.ui.ask "Enter username:"
113
+ password = Capistrano::CLI.password_prompt
114
+ stream "cd #{latest_release} && #{php_bin} ./symfony choique-user-update-or-create-admin '#{username}' '#{password}'"
115
+ end
116
+
117
+ desc "Enable user"
118
+ task :enable do
119
+ username = Capistrano::CLI.ui.ask "Enter username:"
120
+ stream "cd #{latest_release} && #{php_bin} ./symfony choique-user-enable '#{username}'"
121
+ end
122
+
123
+ desc "Disable user"
124
+ task :disable do
125
+ username = Capistrano::CLI.ui.ask "Enter username:"
126
+ stream "cd #{latest_release} && #{php_bin} ./symfony choique-user-disable '#{username}'"
127
+ end
128
+ end
129
+
130
+ namespace :flavors do
131
+
132
+ desc "Set default flavor"
133
+ task :init do
134
+ stream "cd #{latest_release} && #{php_bin} ./symfony choique-flavors-initialize"
135
+ end
136
+
137
+ desc "Download current flavor"
138
+ task :download_current do
139
+ choique_config = {}
140
+ run "#{try_sudo} cat #{current_dir}/config/choique.yml" do |ch, st, data|
141
+ choique_config = YAML::load(data)
142
+ end
143
+ current = choique_config['choique']['flavors']['current']
144
+ filename = "#{application}.remote_current_flavor.#{Time.now.strftime("%Y-%m-%d_%H-%M-%S")}.zip"
145
+ file = "#{remote_tmp_dir}/#{filename}"
146
+ try_sudo "cd #{shared_path}/flavors/#{current}; zip -r #{file} *"
147
+ require "fileutils"
148
+ FileUtils.mkdir_p("backups")
149
+ get file, "backups/#{filename}"
150
+ begin
151
+ FileUtils.ln_sf(filename, "backups/#{application}.remote_current_flavor.latest.zip")
152
+ rescue Exception # fallback for file systems that don't support symlinks
153
+ FileUtils.cp_r("backups/#{filename}", "backups/#{application}.remote_current_flavor.latest.zip")
154
+ end
155
+ run "#{try_sudo} rm #{file}"
156
+ end
157
+
158
+ desc "Download flavors folder and install it locally"
159
+ task :to_local do
160
+ choique_config = {}
161
+ run "#{try_sudo} cat #{current_dir}/config/choique.yml" do |ch, st, data|
162
+ choique_config = YAML::load(data)
163
+ end
164
+ run_locally("rm -fr flavors/*")
165
+ current = choique_config['choique']['flavors']['current']
166
+ download("#{shared_path}/flavors", ".", :via => :scp, :recursive => true)
167
+ run_locally("php symfony choique-flavor-select #{current}")
168
+ end
169
+
170
+ desc "Upload flavors folder and install it remotelly"
171
+ task :to_remote do
172
+ choique_config = {}
173
+ run "#{try_sudo} cat #{current_dir}/config/choique.yml" do |ch, st, data|
174
+ choique_config = YAML::load(data)
175
+ end
176
+ current = choique_config['choique']['flavors']['current']
177
+ run "#{try_sudo} rm -fr #{shared_path}/flavors/*"
178
+ upload("flavors", "#{shared_path}", :via => :scp, :recursive => true)
179
+ stream "cd #{latest_release} && #{php_bin} ./symfony choique-flavor-select #{current}"
180
+ end
181
+
182
+
183
+ desc "Fix flavor after deploy"
184
+ task :fix_flavor do
185
+ choique_config = {}
186
+ run "#{try_sudo} cat #{shared_path}/config/choique.yml" do |ch, st, data|
187
+ choique_config = YAML::load(data)
188
+ end
189
+ current = choique_config['choique']['flavors']['current']
190
+ stream "cd #{latest_release} && #{php_bin} ./symfony choique-flavor-select #{current}"
191
+ end
192
+ end
193
+
194
+ end
195
+
@@ -0,0 +1,118 @@
1
+ namespace :database do
2
+ namespace :dump do
3
+ desc "Dump remote database"
4
+ task :remote, :roles => :db, :only => { :primary => true } do
5
+ filename = "#{application}.remote_dump.#{Time.now.strftime("%Y-%m-%d_%H-%M-%S")}.sql.gz"
6
+ file = "#{remote_tmp_dir}/#{filename}"
7
+ sqlfile = "#{application}_dump.sql"
8
+ config = ""
9
+
10
+ run "#{try_sudo} cat #{shared_path}/config/databases.yml" do |ch, st, data|
11
+ config = load_database_config data, symfony_env_prod
12
+ end
13
+
14
+ sql_dump_cmd = generate_sql_command('dump', config)
15
+ logger.debug sql_dump_cmd.gsub(/(--password=)([^ ]+)/, '\1\'********\'') # Log the command with a masked password
16
+ saved_log_level = logger.level
17
+ logger.level = Capistrano::Logger::IMPORTANT # Change log level so that the real command (containing a plaintext password) is not displayed
18
+ try_sudo "#{sql_dump_cmd} | gzip -c > #{file}"
19
+ logger.level = saved_log_level
20
+
21
+ require "fileutils"
22
+ FileUtils.mkdir_p("backups")
23
+ get file, "backups/#{filename}"
24
+ begin
25
+ FileUtils.ln_sf(filename, "backups/#{application}.remote_dump.latest.sql.gz")
26
+ rescue Exception # fallback for file systems that don't support symlinks
27
+ FileUtils.cp_r("backups/#{filename}", "backups/#{application}.remote_dump.latest.sql.gz")
28
+ end
29
+ run "#{try_sudo} rm #{file}"
30
+ end
31
+
32
+ desc "Dump local database"
33
+ task :local do
34
+ filename = "#{application}.local_dump.#{Time.now.strftime("%Y-%m-%d_%H-%M-%S")}.sql.gz"
35
+ tmpfile = "backups/#{application}_dump_tmp.sql"
36
+ file = "backups/#{filename}"
37
+ config = load_database_config IO.read('config/databases.yml'), symfony_env_local
38
+ sqlfile = "#{application}_dump.sql"
39
+
40
+ require "fileutils"
41
+ FileUtils::mkdir_p("backups")
42
+
43
+ sql_dump_cmd = generate_sql_command('dump', config)
44
+ run_locally "#{sql_dump_cmd} > #{tmpfile}"
45
+
46
+ File.open(tmpfile, "r+") do |f|
47
+ gz = Zlib::GzipWriter.open(file)
48
+ while (line = f.gets)
49
+ gz << line
50
+ end
51
+ gz.flush
52
+ gz.close
53
+ end
54
+
55
+ begin
56
+ FileUtils.ln_sf(filename, "backups/#{application}.local_dump.latest.sql.gz")
57
+ rescue Exception # fallback for file systems that don't support symlinks
58
+ FileUtils.cp_r("backups/#{filename}", "backups/#{application}.local_dump.latest.sql.gz")
59
+ end
60
+ FileUtils.rm(tmpfile)
61
+ end
62
+ end
63
+
64
+ namespace :move do
65
+ desc "Dump remote database, download it to local & populate here"
66
+ task :to_local, :roles => :db, :only => { :primary => true } do
67
+
68
+ database.dump.remote
69
+
70
+ begin
71
+ zipped_file_path = `readlink -f backups/#{application}.remote_dump.latest.sql.gz`.chop # gunzip does not work with a symlink
72
+ rescue Exception # fallback for file systems that don't support symlinks
73
+ zipped_file_path = "backups/#{application}.remote_dump.latest.sql.gz"
74
+ end
75
+ unzipped_file_path = "backups/#{application}_dump.sql"
76
+
77
+ run_locally "gunzip -c #{zipped_file_path} > #{unzipped_file_path}"
78
+
79
+ config = load_database_config IO.read('config/databases.yml'), symfony_env_local
80
+
81
+ run_locally generate_sql_command('drop', config)
82
+ run_locally generate_sql_command('create', config)
83
+
84
+ sql_import_cmd = generate_sql_command('import', config)
85
+ run_locally "#{sql_import_cmd} < #{unzipped_file_path}"
86
+
87
+ FileUtils.rm("#{unzipped_file_path}")
88
+ end
89
+
90
+ desc "Dump local database, load it to remote & populate there"
91
+ task :to_remote, :roles => :db, :only => { :primary => true } do
92
+
93
+ filename = "#{application}.local_dump.latest.sql.gz"
94
+ file = "backups/#{filename}"
95
+ sqlfile = "#{application}_dump.sql"
96
+ config = ""
97
+
98
+ database.dump.local
99
+
100
+ upload(file, "#{remote_tmp_dir}/#{filename}", :via => :scp)
101
+ run "#{try_sudo} gunzip -c #{remote_tmp_dir}/#{filename} > #{remote_tmp_dir}/#{sqlfile}"
102
+
103
+ run "#{try_sudo} cat #{shared_path}/config/databases.yml" do |ch, st, data|
104
+ config = load_database_config data, symfony_env_prod
105
+ end
106
+
107
+ try_sudo generate_sql_command('drop', config)
108
+ try_sudo generate_sql_command('create', config)
109
+
110
+ sql_import_cmd = generate_sql_command('import', config)
111
+
112
+ try_sudo "#{sql_import_cmd} < #{remote_tmp_dir}/#{sqlfile}"
113
+
114
+ run "#{try_sudo} rm #{remote_tmp_dir}/#{filename}"
115
+ run "#{try_sudo} rm #{remote_tmp_dir}/#{sqlfile}"
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,58 @@
1
+ # Extend deploy tasks from original
2
+ namespace :deploy do
3
+
4
+ desc <<-DESC
5
+ Prepares one or more servers for deployment. Before you can use any \
6
+ of the Capistrano deployment tasks with your project, you will need to \
7
+ make sure all of your servers have been prepared with `cap deploy:setup'. When \
8
+ you add a new server to your cluster, you can easily run the setup task \
9
+ on just that server by specifying the HOSTS environment variable:
10
+
11
+ $ cap HOSTS=new.server.com deploy:setup
12
+
13
+ It is safe to run this task on servers that have already been set up; it \
14
+ will not destroy any deployed revisions or data.
15
+ DESC
16
+ task :setup, :except => { :no_release => true } do
17
+ dirs = [deploy_to, releases_path, shared_path]
18
+ dirs += shared_children.map { |d| File.join(shared_path, d) }
19
+ run "#{try_sudo} mkdir -p #{dirs.join(' ')}"
20
+ run "#{try_sudo} chmod g+w #{dirs.join(' ')}" if fetch(:group_writable, true)
21
+ end
22
+
23
+ desc "Symlink static directories and static files that need to remain between deployments."
24
+ task :share_childs do
25
+ if shared_children
26
+ shared_children.each do |link|
27
+ run "#{try_sudo} mkdir -p #{shared_path}/#{link}"
28
+ run "#{try_sudo} sh -c 'if [ -d #{release_path}/#{link} ] ; then rm -rf #{release_path}/#{link}; fi'"
29
+ run "#{try_sudo} ln -nfs #{shared_path}/#{link} #{release_path}/#{link}"
30
+ end
31
+ end
32
+ if shared_files
33
+ shared_files.each do |link|
34
+ link_dir = File.dirname("#{shared_path}/#{link}")
35
+ run "#{try_sudo} mkdir -p #{link_dir}"
36
+ run "#{try_sudo} touch #{shared_path}/#{link}"
37
+ run "#{try_sudo} ln -nfs #{shared_path}/#{link} #{release_path}/#{link}"
38
+ end
39
+ end
40
+ end
41
+
42
+ desc "Customize the finalize_update task to work with symfony."
43
+ task :finalize_update, :except => { :no_release => true } do
44
+ run "#{try_sudo} chmod -R g+w #{latest_release}" if fetch(:group_writable, true)
45
+ run "#{try_sudo} mkdir -p #{latest_release}/cache"
46
+ run "#{try_sudo} chmod -R g+w #{latest_release}/cache"
47
+
48
+ # Share common files & folders
49
+ share_childs
50
+
51
+ if fetch(:normalize_asset_timestamps, true)
52
+ stamp = Time.now.utc.strftime("%Y%m%d%H%M.%S")
53
+ asset_paths = asset_children.map { |p| "#{latest_release}/#{p}" }.join(" ")
54
+ run "#{try_sudo} find #{asset_paths} -exec touch -t #{stamp} {} ';'; true", :env => { "TZ" => "UTC" }
55
+ end
56
+ end
57
+ end
58
+
@@ -0,0 +1,13 @@
1
+ namespace :choique do
2
+ namespace :uploads do
3
+ desc "Download all files from remote web-frontend/uploads folder to local one"
4
+ task :to_local do
5
+ download("#{shared_path}/web-frontend/uploads", "web-frontend", :via => :scp, :recursive => true)
6
+ end
7
+
8
+ desc "Upload all files from local web/uploads folder to remote one"
9
+ task :to_remote do
10
+ upload("web-frontend/uploads", "#{shared_path}/web-frontend", :via => :scp, :recursive => true)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,5 @@
1
+ module Capistrano
2
+ module Choique
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,162 @@
1
+ require 'capistrano'
2
+ require 'capistrano-choique/version'
3
+
4
+
5
+ module Capistrano
6
+ module Choique
7
+ def self.load_into(configuration)
8
+ configuration.load do
9
+ load_paths.push File.expand_path('../', __FILE__)
10
+ Dir.glob(File.join(File.dirname(__FILE__), '/capistrano-choique/recipes/*.rb')).sort.each { |f| load f }
11
+
12
+ set :repository, "https://github.com/Desarrollo-CeSPI/choique.git"
13
+ set :deploy_via, :remote_cache
14
+ set :scm, :git
15
+
16
+ set(:choique_tag) { branch }
17
+
18
+ set :branch do
19
+ default_tag = /tags\/([\w.\d]+).*?$/.match(`git ls-remote -t #{repository}`.split("\n").last)
20
+ default_tag = if default_tag
21
+ default_tag[1]
22
+ else
23
+ "master"
24
+ end
25
+ tag = Capistrano::CLI.ui.ask "Tag to deploy (Press enter when done): [#{default_tag}]"
26
+ tag = default_tag if tag.empty?
27
+ tag
28
+ end
29
+
30
+ set(:user) { application }
31
+
32
+ set :php_bin, "php"
33
+
34
+ set :db_type, "mysql"
35
+ set :db_host, "localhost"
36
+ set :db_port, "3306"
37
+ set(:db_name) { application }
38
+ set(:db_user) { application }
39
+
40
+ set :symfony_env_prod, :prod
41
+ set :symfony_env_local, :dev
42
+
43
+ set (:remote_tmp_dir) { "#{deploy_to}/tmp" }
44
+
45
+ set(:choique_name) { application }
46
+ set :choique_backend_port, "8000"
47
+ set(:choique_frontend_url) { "http://#{domain}/" }
48
+ set(:choique_backend_url) { "https://#{domain}:#{choique_backend_port}/" }
49
+ set :choique_testing, false
50
+
51
+ set :shared_children, %w(log web-frontend/uploads flavors data/index)
52
+ set :shared_files, %w(apps/backend/config/factories.yml config/databases.yml config/propel.ini config/app.yml config/choique.yml)
53
+ set :asset_children, %w(web-frontend/css web-frontend/images web-frontend/js web-backend/css web-backend/images web-backend/js)
54
+
55
+ # helper function
56
+ def deep_merge(hash1, hash2)
57
+
58
+ #if both 'all' and env keys are nil break
59
+ if(hash1 == nil && hash2 == nil)
60
+ return nil
61
+ end
62
+
63
+ #the config.yml may not have 'all' key but instead 'dev' 'prod' and so on
64
+ if(hash1 == nil && hash2 != nil)
65
+ return hash2 # no need to merge
66
+ end
67
+
68
+ #if only the 'all' key is specified
69
+ #There might not be a second has to cascade to
70
+ if(hash2 == nil && hash1 != nil)
71
+ return hash1;
72
+ end
73
+ hash1.merge(hash2){|key, subhash1, subhash2|
74
+ if (subhash1.is_a?(Hash) && subhash2.is_a?(Hash))
75
+ next deep_merge(subhash1, subhash2)
76
+ end
77
+ subhash2
78
+ }
79
+ end
80
+
81
+ # load database params from databases.yml to build mysql/pgsql commands
82
+ def load_database_config(data, env)
83
+ db_config = YAML::load(data)
84
+
85
+ connections = deep_merge(db_config['all'], db_config[env.to_s])
86
+
87
+ db_param = connections['propel']['param']
88
+
89
+ {
90
+ 'type' => db_param['phptype'],
91
+ 'user' => db_param['username'],
92
+ 'pass' => db_param['password'],
93
+ 'db' => db_param['database'],
94
+ 'host' => db_param['hostspec'],
95
+ 'port' => db_param['port']
96
+ }
97
+ end
98
+
99
+ # generate mysql / pgsql commands
100
+ def generate_sql_command(cmd_type, config)
101
+ db_type = config['type']
102
+ cmd_conf = {
103
+ 'mysql' => {
104
+ 'create' => "mysqladmin -u #{config['user']} --password='#{config['pass']}' create",
105
+ 'dump' => "mysqldump -u #{config['user']} --password='#{config['pass']}'",
106
+ 'drop' => "mysqladmin -f -u #{config['user']} --password='#{config['pass']}' drop",
107
+ 'import' => "mysql -u #{config['user']} --password='#{config['pass']}'"
108
+ },
109
+ 'pgsql' => {
110
+ 'create' => "createdb -U #{config['user']}",
111
+ 'dump' => "pg_dump -U #{config['user']}",
112
+ 'drop' => "dropdb -U #{config['user']}",
113
+ 'import' => "psql -U #{config['user']} --password='#{config['pass']}'"
114
+ }
115
+ }
116
+
117
+ cmd = cmd_conf[db_type][cmd_type]
118
+ cmd+= " --host=#{config['host']}" if config['host']
119
+ cmd+= " --port=#{config['port']}" if config['port']
120
+ cmd+= " #{config['db']}"
121
+
122
+ cmd
123
+ end
124
+
125
+ after "deploy:finalize_update" do
126
+ choique.flavors.init if choique.flavors_initialize?
127
+ choique.build_model
128
+ choique.fix_permissions
129
+ choique.data_init if choique.need_init?
130
+ choique.flavors.fix_flavor unless choique.flavors_initialize?
131
+ choique.cc
132
+ end
133
+
134
+ after "deploy:setup" do
135
+ prefix = File.join(File.dirname(__FILE__), '/../data/templates/')
136
+ database_conf = ERB.new(File.read("#{prefix}/databases.yml.erb")).result(binding)
137
+ propel_conf = ERB.new(File.read("#{prefix}/propel.ini.erb")).result(binding)
138
+ app_conf = ERB.new(File.read("#{prefix}/app.yml.erb")).result(binding)
139
+ factories_conf = ERB.new(File.read("#{prefix}/backend_factories.yml.erb")).result(binding)
140
+ run "#{try_sudo} mkdir -p #{shared_path}/config #{shared_path}/apps/backend/config"
141
+ put database_conf, "#{shared_path}/config/databases.yml"
142
+ put propel_conf, "#{shared_path}/config/propel.ini"
143
+ put app_conf, "#{shared_path}/config/app.yml"
144
+ put factories_conf, "#{shared_path}/apps/backend/config/factories.yml"
145
+ run "#{try_sudo} mkdir -p #{remote_tmp_dir}"
146
+ end
147
+
148
+ after "deploy:create_symlink" do
149
+ deploy_date = Time.now.strftime('%F')
150
+ build_version = "#{deploy_date} #{choique_tag} build+#{current_revision}"
151
+ put(build_version,"#{current_release}/VERSION")
152
+ end
153
+
154
+ end
155
+ end
156
+ end
157
+ end
158
+
159
+ if Capistrano::Configuration.instance
160
+ Capistrano::Choique.load_into(Capistrano::Configuration.instance)
161
+ end
162
+
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: capistrano-choique
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Christian Rodriguez
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-05-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ! '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ! '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: capistrano
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>'
32
+ - !ruby/object:Gem::Version
33
+ version: '2.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>'
39
+ - !ruby/object:Gem::Version
40
+ version: '2.0'
41
+ description: Capistrano extension to deploy Choique CMS
42
+ email:
43
+ - car@cespi.unlp.edu.ar
44
+ executables:
45
+ - capify-choique
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - .gitignore
50
+ - Gemfile
51
+ - LICENSE.txt
52
+ - README.md
53
+ - Rakefile
54
+ - bin/capify-choique
55
+ - capistrano-choique.gemspec
56
+ - data/templates/app.yml.erb
57
+ - data/templates/backend_factories.yml.erb
58
+ - data/templates/databases.yml.erb
59
+ - data/templates/propel.ini.erb
60
+ - lib/capistrano-choique.rb
61
+ - lib/capistrano-choique/recipes/choique.rb
62
+ - lib/capistrano-choique/recipes/database.rb
63
+ - lib/capistrano-choique/recipes/deploy.rb
64
+ - lib/capistrano-choique/recipes/shared.rb
65
+ - lib/capistrano-choique/version.rb
66
+ homepage: https://github.com/Desarrollo-CeSPI/capistrano-choique
67
+ licenses: []
68
+ metadata: {}
69
+ post_install_message:
70
+ rdoc_options: []
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ! '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ requirements: []
84
+ rubyforge_project:
85
+ rubygems_version: 2.0.3
86
+ signing_key:
87
+ specification_version: 4
88
+ summary: Capify Choique CMS
89
+ test_files: []