kapify 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. data/.gitignore +18 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE.txt +22 -0
  4. data/README.md +51 -0
  5. data/Rakefile +1 -0
  6. data/kapify.gemspec +22 -0
  7. data/lib/generators/kapify/base.rb +9 -0
  8. data/lib/generators/kapify/logrotate/USAGE +9 -0
  9. data/lib/generators/kapify/logrotate/logrotate_generator.rb +14 -0
  10. data/lib/generators/kapify/logrotate/templates/logrotate.erb +8 -0
  11. data/lib/generators/kapify/nginx/USAGE +9 -0
  12. data/lib/generators/kapify/nginx/nginx_generator.rb +14 -0
  13. data/lib/generators/kapify/nginx/templates/nginx_conf.erb +85 -0
  14. data/lib/generators/kapify/pg/USAGE +9 -0
  15. data/lib/generators/kapify/pg/pg_generator.rb +14 -0
  16. data/lib/generators/kapify/pg/templates/database.yml.erb +8 -0
  17. data/lib/generators/kapify/resque/USAGE +9 -0
  18. data/lib/generators/kapify/resque/resque_generator.rb +14 -0
  19. data/lib/generators/kapify/resque/templates/resque_init.erb +89 -0
  20. data/lib/generators/kapify/unicorn/USAGE +9 -0
  21. data/lib/generators/kapify/unicorn/templates/unicorn.rb.erb +48 -0
  22. data/lib/generators/kapify/unicorn/templates/unicorn_init.erb +84 -0
  23. data/lib/generators/kapify/unicorn/unicorn_generator.rb +15 -0
  24. data/lib/kapify/base.rb +17 -0
  25. data/lib/kapify/logrotate/README.md +83 -0
  26. data/lib/kapify/logrotate/configuration.rb +15 -0
  27. data/lib/kapify/logrotate.rb +1 -0
  28. data/lib/kapify/nginx/README.md +105 -0
  29. data/lib/kapify/nginx/configuration.rb +41 -0
  30. data/lib/kapify/nginx.rb +1 -0
  31. data/lib/kapify/pg/README.md +118 -0
  32. data/lib/kapify/pg/configuration.rb +52 -0
  33. data/lib/kapify/pg.rb +1 -0
  34. data/lib/kapify/resque/README.md +104 -0
  35. data/lib/kapify/resque/configuration.rb +34 -0
  36. data/lib/kapify/resque.rb +1 -0
  37. data/lib/kapify/unicorn/README.md +109 -0
  38. data/lib/kapify/unicorn/configuration.rb +35 -0
  39. data/lib/kapify/unicorn.rb +2 -0
  40. data/lib/kapify/version.rb +3 -0
  41. data/lib/kapify.rb +5 -0
  42. metadata +125 -0
data/.gitignore ADDED
@@ -0,0 +1,18 @@
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
18
+ /vendor
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in kapify.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Ivan Tkalin
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,51 @@
1
+ # Kapify
2
+
3
+ Provides several useful capistrano recipes, that can be used for deployment of Ruby on Rails applications with rbenv.
4
+
5
+ * [Logrotate](https://github.com/ivalkeen/kapify/tree/master/lib/kapify/logrotate)
6
+ + set up logs rotation
7
+ * [Nginx](https://github.com/ivalkeen/kapify/tree/master/lib/kapify/nginx)
8
+ + config site
9
+ + reload
10
+ * [PostgreSQL](https://github.com/ivalkeen/kapify/tree/master/lib/kapify/pg)
11
+ + link database.yml from template
12
+ + create pg user for application
13
+ * [Resque](https://github.com/ivalkeen/kapify/tree/master/lib/kapify/resque)
14
+ + create and register init script
15
+ + start/stop/restart using init script
16
+ * [Unicorn](https://github.com/ivalkeen/kapify/tree/master/lib/kapify/unicorn)
17
+ (with zero downtime deployments with nginx)
18
+ + create and register init script
19
+ + start/stop/restart using init script
20
+
21
+ ## Installation
22
+
23
+ Add this line to your application's Gemfile:
24
+
25
+ ```ruby
26
+ gem 'kapify', group: :development, require: false
27
+ ```
28
+
29
+ And then execute:
30
+
31
+ $ bundle
32
+
33
+ Or install it yourself as:
34
+
35
+ $ gem install kapify
36
+
37
+ ## Usage
38
+
39
+ Require each recipe in `deploy.rb` file.
40
+ All recipes could be customized using variables.
41
+ Also there are template generators for deep customization.
42
+ See README for recipes for details.
43
+
44
+
45
+ ## Contributing
46
+
47
+ 1. Fork it
48
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
49
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
50
+ 4. Push to the branch (`git push origin my-new-feature`)
51
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/kapify.gemspec ADDED
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'kapify/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "kapify"
8
+ gem.version = Kapify::VERSION
9
+ gem.authors = ["Ivan Tkalin"]
10
+ gem.email = ["itkalin@gmail.com"]
11
+ gem.description = %q{Capistrano recipes useful for rails app deployment. Includes repices for nginx, unicorn, postgres, logrotate, resque}
12
+ gem.summary = %q{Capistrano recipes useful for rails app deployment}
13
+ gem.homepage = "https://github.com/ivalkeen/kapify"
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_dependency 'capistrano', '>= 2.0'
21
+ gem.add_development_dependency "rake"
22
+ end
@@ -0,0 +1,9 @@
1
+ module Kapify
2
+ module Generators
3
+ class Base < Rails::Generators::Base
4
+ argument :templates_path, :type => :string,
5
+ :default => "config/deploy/templates",
6
+ :banner => "path to templates"
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ To create local logrotate configuration file call
2
+
3
+ rails generate kapify:logrotate [path]
4
+
5
+ The default path is "config/deploy/templates". You can override it like so:
6
+
7
+ rails generate kapify:logrotate "config/templates"
8
+
9
+ If you override templates path, don't forget to set "templates_path" variable in your deploy.rb
@@ -0,0 +1,14 @@
1
+ require 'generators/kapify/base'
2
+
3
+ module Kapify
4
+ module Generators
5
+ class LogrotateGenerator < Kapify::Generators::Base
6
+ desc "Create logrotate configuration files for customization"
7
+ source_root File.expand_path('../templates', __FILE__)
8
+
9
+ def copy_template
10
+ copy_file "logrotate.erb", "#{templates_path}/logrotate.erb"
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,8 @@
1
+ <%= shared_path %>/log/*.log {
2
+ daily
3
+ missingok
4
+ rotate 180
5
+ compress
6
+ dateext
7
+ delaycompress
8
+ }
@@ -0,0 +1,9 @@
1
+ To create local nginx configuration file call
2
+
3
+ rails generate kapify:nginx [path]
4
+
5
+ The default path is "config/deploy/templates". You can override it like so:
6
+
7
+ rails generate kapify:nginx "config/templates"
8
+
9
+ If you override templates path, don't forget to set "templates_path" variable in your deploy.rb
@@ -0,0 +1,14 @@
1
+ require 'generators/kapify/base'
2
+
3
+ module Kapify
4
+ module Generators
5
+ class NginxGenerator < Kapify::Generators::Base
6
+ desc "Create local nginx configuration files for customization"
7
+ source_root File.expand_path('../templates', __FILE__)
8
+
9
+ def copy_template
10
+ copy_file "nginx_conf.erb", "#{templates_path}/nginx_conf.erb"
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,85 @@
1
+ upstream <%= application %> {
2
+ server unix:/tmp/<%= application %>.sock fail_timeout=0;
3
+ }
4
+
5
+ <% if nginx_use_ssl %>
6
+ server {
7
+ listen 80;
8
+ rewrite ^(.*) https://$host$1 permanent;
9
+ }
10
+ <% end %>
11
+
12
+ server {
13
+ <% if nginx_use_ssl %>
14
+ listen 443;
15
+ ssl on;
16
+ ssl_certificate /etc/ssl/certs/<%= nginx_ssl_certificate %>;
17
+ ssl_certificate_key /etc/ssl/private/<%= nginx_ssl_certificate_key %>;
18
+ <% else %>
19
+ listen 80;
20
+ <% end %>
21
+
22
+ server_name <%= nginx_server_name %>;
23
+ root <%= current_path %>/public;
24
+ try_files $uri/index.html $uri @<%= application %>;
25
+
26
+ location @<%= application %> {
27
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
28
+ proxy_set_header Host $http_host;
29
+ proxy_redirect off;
30
+ <% if nginx_use_ssl %>
31
+ proxy_set_header X-Forwarded-Proto https;
32
+ <% end %>
33
+ proxy_pass http://<%= application %>;
34
+ # limit_req zone=one;
35
+ access_log <%= shared_path %>/log/nginx.access.log;
36
+ error_log <%= shared_path %>/log/nginx.error.log;
37
+ }
38
+
39
+ location ~ ^/(assets|images|javascripts|stylesheets|swfs|system)/ {
40
+ gzip_static on;
41
+ expires max;
42
+ add_header Cache-Control public;
43
+ add_header Last-Modified "";
44
+ add_header ETag "";
45
+
46
+ open_file_cache max=1000 inactive=500s;
47
+ open_file_cache_valid 600s;
48
+ open_file_cache_errors on;
49
+ break;
50
+ }
51
+
52
+ client_max_body_size 4G;
53
+ keepalive_timeout 10;
54
+
55
+ error_page 500 502 504 /500.html;
56
+ error_page 503 @503;
57
+
58
+ location = /50x.html {
59
+ root html;
60
+ }
61
+
62
+ location = /404.html {
63
+ root html;
64
+ }
65
+
66
+ location @503 {
67
+ error_page 405 = /system/maintenance.html;
68
+ if (-f $document_root/system/maintenance.html) {
69
+ rewrite ^(.*)$ /system/maintenance.html break;
70
+ }
71
+ rewrite ^(.*)$ /503.html break;
72
+ }
73
+
74
+ if ($request_method !~ ^(GET|HEAD|PUT|POST|DELETE|OPTIONS)$ ){
75
+ return 405;
76
+ }
77
+
78
+ if (-f $document_root/system/maintenance.html) {
79
+ return 503;
80
+ }
81
+
82
+ location ~ \.(php|html)$ {
83
+ return 405;
84
+ }
85
+ }
@@ -0,0 +1,9 @@
1
+ To create local database.yml.erb configuration file call
2
+
3
+ rails generate kapify:pg [path]
4
+
5
+ The default path is "config/deploy/templates". You can override it like so:
6
+
7
+ rails generate kapify:pg "config/templates"
8
+
9
+ If you override templates path, don't forget to set "templates_path" variable in your deploy.rb
@@ -0,0 +1,14 @@
1
+ require 'generators/kapify/base'
2
+
3
+ module Kapify
4
+ module Generators
5
+ class PgGenerator < Kapify::Generators::Base
6
+ desc "Create local database.yml.erb configuration files for customization"
7
+ source_root File.expand_path('../templates', __FILE__)
8
+
9
+ def copy_template
10
+ copy_file "database.yml.erb", "#{templates_path}/database.yml.erb"
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,8 @@
1
+ production:
2
+ adapter: postgresql
3
+ encoding: unicode
4
+ database: <%= pg_database %>
5
+ pool: <%= pg_pool %>
6
+ username: <%= pg_user %>
7
+ password: <%= pg_password %>
8
+ host: <%= pg_host %>
@@ -0,0 +1,9 @@
1
+ To create local resque configuration files call
2
+
3
+ rails generate kapify:resque [path]
4
+
5
+ The default path is "config/deploy/templates". You can override it like so:
6
+
7
+ rails generate kapify:resque "config/templates"
8
+
9
+ If you override templates path, don't forget to set "templates_path" variable in your deploy.rb
@@ -0,0 +1,14 @@
1
+ require 'generators/kapify/base'
2
+
3
+ module Kapify
4
+ module Generators
5
+ class ResqueGenerator < Kapify::Generators::Base
6
+ desc "Create local resque configuration files for customization"
7
+ source_root File.expand_path('../templates', __FILE__)
8
+
9
+ def copy_template
10
+ copy_file "resque_init.erb", "#{templates_path}/resque_init.erb"
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,89 @@
1
+ #!/bin/sh -e
2
+ ### BEGIN INIT INFO
3
+ # Provides: resque
4
+ # Required-Start: $local_fs $remote_fs
5
+ # Required-Stop: $local_fs $remote_fs
6
+ # Should-Start: $local_fs
7
+ # Should-Stop: $local_fs
8
+ # Default-Start: 2 3 4 5
9
+ # Default-Stop: 0 1 6
10
+ # Short-Description: resque - a Redis-backed Ruby library for creating background jobs
11
+ # Description: resque - a Redis-backed Ruby library for creating background jobs, placing those jobs on multiple queues, and processing them later.
12
+ ### END INIT INFO
13
+
14
+ set -e
15
+
16
+ . /lib/lsb/init-functions
17
+
18
+ NAME="<%= application %>"
19
+ ROOT=<%= current_path %>
20
+ USER="<%= resque_user %>"
21
+ GROUP="<%= resque_user %>"
22
+ ENVIRONMENT="production"
23
+ QUEUES="<%= resque_queue %>"
24
+ COUNT=<%= resque_workers %>
25
+ TASK="<%= resque_task %>"
26
+ PIDFILE="$ROOT/tmp/pids/resque_worker.%d.pid"
27
+
28
+ BUNDLE="<%= resque_bundle %>"
29
+
30
+ start() {
31
+ local program
32
+ local options
33
+
34
+ program=$BUNDLE
35
+ options="exec rake $TASK"
36
+ options="$options RACK_ENV=$ENVIRONMENT QUEUES=$QUEUES"
37
+
38
+ for i in $(seq 1 $COUNT); do
39
+ pidfile=$(printf "$PIDFILE" $i)
40
+
41
+ if start-stop-daemon --start --background --quiet --pidfile $pidfile --chdir $ROOT --chuid $USER:$GROUP --exec $program -- $options PIDFILE=$pidfile
42
+ then
43
+ log_daemon_msg "Starting worker #$i for $NAME ..."
44
+ else
45
+ log_failure_msg "Failed to start worker #$i for $NAME!"
46
+ fi
47
+ done
48
+ }
49
+
50
+ stop() {
51
+ local pidfile
52
+
53
+ for i in $(seq 1 $COUNT); do
54
+ pidfile=$(printf "$PIDFILE" $i)
55
+
56
+ if start-stop-daemon --stop --quiet --oknodo --pidfile $pidfile
57
+ then
58
+ log_daemon_msg "Stopped Resque worker #$i for $NAME"
59
+ rm -f $pidfile
60
+ else
61
+ log_failure_msg "Failed to stop Resque worker #$i for $NAME!" >&2
62
+ fi
63
+ done
64
+ }
65
+
66
+ status() {
67
+ local pidfile
68
+
69
+ for i in $(seq 1 $COUNT); do
70
+ pidfile=$(printf "$PIDFILE" $i)
71
+
72
+ status_of_proc -p $pidfile "rake $TASK" "$NAME worker #$i"
73
+ done
74
+ }
75
+
76
+ case "$1" in
77
+ start) start ;;
78
+ stop) stop ;;
79
+ restart|force-reload)
80
+ stop
81
+ sleep 1
82
+ start
83
+ ;;
84
+ status) status ;;
85
+ *)
86
+ echo "Usage: $0 {start|stop|restart|force-reload|status}" >&2
87
+ exit 1
88
+ ;;
89
+ esac
@@ -0,0 +1,9 @@
1
+ To create local unicorn configuration files call
2
+
3
+ rails generate kapify:unicorn [path]
4
+
5
+ The default path is "config/deploy/templates". You can override it like so:
6
+
7
+ rails generate kapify:unicorn "config/templates"
8
+
9
+ If you override templates path, don't forget to set "templates_path" variable in your deploy.rb
@@ -0,0 +1,48 @@
1
+ working_directory "<%= current_path %>"
2
+ pid "<%= unicorn_pid %>"
3
+ stderr_path "<%= unicorn_log %>"
4
+ stdout_path "<%= unicorn_log %>"
5
+
6
+ listen "/tmp/<%= application %>.sock"
7
+ worker_processes <%= unicorn_workers %>
8
+ timeout 30
9
+
10
+ preload_app true
11
+
12
+ before_exec do |server|
13
+ ENV["BUNDLE_GEMFILE"] = "<%= current_path %>/Gemfile"
14
+ end
15
+
16
+ before_fork do |server, worker|
17
+ # Disconnect since the database connection will not carry over
18
+ if defined? ActiveRecord::Base
19
+ ActiveRecord::Base.connection.disconnect!
20
+ end
21
+
22
+ # Quit the old unicorn process
23
+ old_pid = "#{server.config[:pid]}.oldbin"
24
+ if File.exists?(old_pid) && server.pid != old_pid
25
+ begin
26
+ Process.kill("QUIT", File.read(old_pid).to_i)
27
+ rescue Errno::ENOENT, Errno::ESRCH
28
+ # someone else did our job for us
29
+ end
30
+ end
31
+
32
+ if defined?(Resque)
33
+ Resque.redis.quit
34
+ end
35
+
36
+ sleep 1
37
+ end
38
+
39
+ after_fork do |server, worker|
40
+ # Start up the database connection again in the worker
41
+ if defined?(ActiveRecord::Base)
42
+ ActiveRecord::Base.establish_connection
43
+ end
44
+
45
+ if defined?(Resque)
46
+ Resque.redis = 'localhost:6379'
47
+ end
48
+ end
@@ -0,0 +1,84 @@
1
+ #!/bin/sh
2
+ ### BEGIN INIT INFO
3
+ # Provides: unicorn
4
+ # Required-Start: $remote_fs $syslog
5
+ # Required-Stop: $remote_fs $syslog
6
+ # Default-Start: 2 3 4 5
7
+ # Default-Stop: 0 1 6
8
+ # Short-Description: Manage unicorn server
9
+ # Description: Start, stop, restart unicorn server for a specific application.
10
+ ### END INIT INFO
11
+ set -e
12
+
13
+ # Feel free to change any of the following variables for your app:
14
+ TIMEOUT=${TIMEOUT-60}
15
+ APP_ROOT=<%= current_path %>
16
+ PID=<%= unicorn_pid %>
17
+ CMD="cd <%= current_path %>; bundle exec unicorn -D -c <%= unicorn_config %> -E production"
18
+ AS_USER=<%= unicorn_user %>
19
+ set -u
20
+
21
+ OLD_PIN="$PID.oldbin"
22
+
23
+ sig () {
24
+ test -s "$PID" && kill -$1 `cat $PID`
25
+ }
26
+
27
+ oldsig () {
28
+ test -s $OLD_PIN && kill -$1 `cat $OLD_PIN`
29
+ }
30
+
31
+ run () {
32
+ if [ "$(id -un)" = "$AS_USER" ]; then
33
+ eval $1
34
+ else
35
+ su -c "$1" - $AS_USER
36
+ fi
37
+ }
38
+
39
+ case "$1" in
40
+ start)
41
+ sig 0 && echo >&2 "Already running" && exit 0
42
+ run "$CMD"
43
+ ;;
44
+ stop)
45
+ sig QUIT && exit 0
46
+ echo >&2 "Not running"
47
+ ;;
48
+ force-stop)
49
+ sig TERM && exit 0
50
+ echo >&2 "Not running"
51
+ ;;
52
+ restart|reload)
53
+ sig USR2 && echo reloaded OK && exit 0
54
+ echo >&2 "Couldn't reload, starting '$CMD' instead"
55
+ run "$CMD"
56
+ ;;
57
+ upgrade)
58
+ if sig USR2 && sleep 2 && sig 0 && oldsig QUIT
59
+ then
60
+ n=$TIMEOUT
61
+ while test -s $OLD_PIN && test $n -ge 0
62
+ do
63
+ printf '.' && sleep 1 && n=$(( $n - 1 ))
64
+ done
65
+ echo
66
+
67
+ if test $n -lt 0 && test -s $OLD_PIN
68
+ then
69
+ echo >&2 "$OLD_PIN still exists after $TIMEOUT seconds"
70
+ exit 1
71
+ fi
72
+ exit 0
73
+ fi
74
+ echo >&2 "Couldn't upgrade, starting '$CMD' instead"
75
+ run "$CMD"
76
+ ;;
77
+ reopen-logs)
78
+ sig USR1
79
+ ;;
80
+ *)
81
+ echo >&2 "Usage: $0 <start|stop|restart|upgrade|force-stop|reopen-logs>"
82
+ exit 1
83
+ ;;
84
+ esac
@@ -0,0 +1,15 @@
1
+ require 'generators/kapify/base'
2
+
3
+ module Kapify
4
+ module Generators
5
+ class UnicornGenerator < Kapify::Generators::Base
6
+ desc "Create local unicorn configuration files for customization"
7
+ source_root File.expand_path('../templates', __FILE__)
8
+
9
+ def copy_template
10
+ copy_file "unicorn.rb.erb", "#{templates_path}/unicorn.rb.erb"
11
+ copy_file "unicorn_init.erb", "#{templates_path}/unicorn_init.erb"
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,17 @@
1
+ Capistrano::Configuration.instance.load do
2
+ def set_default(name, *args, &block)
3
+ set(name, *args, &block) unless exists?(name)
4
+ end
5
+
6
+ set_default(:templates_path, "config/deploy/templates")
7
+
8
+ def kapify_template(generator, template_name, target)
9
+ config_file = "#{templates_path}/#{template_name}"
10
+ # if no customized file, proceed with default
11
+ unless File.exists?(config_file)
12
+ config_file = File.join(File.dirname(__FILE__), "../generators/kapify/#{generator}/templates/#{template_name}")
13
+ end
14
+ put ERB.new(File.read(config_file)).result(binding), target
15
+ end
16
+
17
+ end