apphunkd 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (204) hide show
  1. data/.document +5 -0
  2. data/.gitignore +22 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +18 -0
  5. data/Rakefile +78 -0
  6. data/TODO +1 -0
  7. data/VERSION +1 -0
  8. data/apphunkd.gemspec +258 -0
  9. data/bin/apphunkd +4 -0
  10. data/config/arguments.rb +12 -0
  11. data/config/boot.rb +68 -0
  12. data/config/environment.rb +23 -0
  13. data/config/environments/development.rb +2 -0
  14. data/config/environments/production.rb +2 -0
  15. data/config/environments/test.rb +2 -0
  16. data/config/post-daemonize/readme +5 -0
  17. data/config/pre-daemonize/readme +12 -0
  18. data/config/pre-daemonize/requires.rb +2 -0
  19. data/lib/apphunkd.rb +25 -0
  20. data/lib/apphunkd/api.rb +5 -0
  21. data/lib/apphunkd/api/service.rb +27 -0
  22. data/lib/apphunkd/queue.rb +96 -0
  23. data/lib/apphunkd/remote.rb +29 -0
  24. data/lib/apphunkd/remote/result.rb +15 -0
  25. data/libexec/apphunkd-daemon.rb +13 -0
  26. data/script/console +3 -0
  27. data/script/destroy +14 -0
  28. data/script/generate +14 -0
  29. data/spec/lib/apphunkd/api/service_spec.rb +47 -0
  30. data/spec/lib/apphunkd/queue_spec.rb +129 -0
  31. data/spec/lib/apphunkd/remote_spec.rb +61 -0
  32. data/spec/lib/apphunkd_spec.rb +50 -0
  33. data/spec/spec.opts +1 -0
  34. data/spec/spec_helper.rb +13 -0
  35. data/support/apphunkd.initd +47 -0
  36. data/support/apphunkd.monitrc +3 -0
  37. data/tasks/rspec.rake +21 -0
  38. data/vendor/daemon-kit/Configuration.txt +102 -0
  39. data/vendor/daemon-kit/Deployment.txt +113 -0
  40. data/vendor/daemon-kit/History.txt +97 -0
  41. data/vendor/daemon-kit/Logging.txt +92 -0
  42. data/vendor/daemon-kit/Manifest.txt +166 -0
  43. data/vendor/daemon-kit/PostInstall.txt +6 -0
  44. data/vendor/daemon-kit/README.rdoc +130 -0
  45. data/vendor/daemon-kit/Rakefile +37 -0
  46. data/vendor/daemon-kit/RuoteParticipants.txt +113 -0
  47. data/vendor/daemon-kit/TODO.txt +37 -0
  48. data/vendor/daemon-kit/app_generators/daemon_kit/USAGE +7 -0
  49. data/vendor/daemon-kit/app_generators/daemon_kit/daemon_kit_generator.rb +161 -0
  50. data/vendor/daemon-kit/app_generators/daemon_kit/templates/README +48 -0
  51. data/vendor/daemon-kit/app_generators/daemon_kit/templates/Rakefile +6 -0
  52. data/vendor/daemon-kit/app_generators/daemon_kit/templates/bin/daemon.erb +7 -0
  53. data/vendor/daemon-kit/app_generators/daemon_kit/templates/config/arguments.rb +12 -0
  54. data/vendor/daemon-kit/app_generators/daemon_kit/templates/config/boot.rb +68 -0
  55. data/vendor/daemon-kit/app_generators/daemon_kit/templates/config/environment.rb +23 -0
  56. data/vendor/daemon-kit/app_generators/daemon_kit/templates/config/environments/development.rb +2 -0
  57. data/vendor/daemon-kit/app_generators/daemon_kit/templates/config/environments/production.rb +2 -0
  58. data/vendor/daemon-kit/app_generators/daemon_kit/templates/config/environments/test.rb +2 -0
  59. data/vendor/daemon-kit/app_generators/daemon_kit/templates/config/post-daemonize/readme +5 -0
  60. data/vendor/daemon-kit/app_generators/daemon_kit/templates/config/pre-daemonize/readme +12 -0
  61. data/vendor/daemon-kit/app_generators/daemon_kit/templates/lib/daemon.rb +2 -0
  62. data/vendor/daemon-kit/app_generators/daemon_kit/templates/libexec/daemon.erb +18 -0
  63. data/vendor/daemon-kit/app_generators/daemon_kit/templates/script/console +3 -0
  64. data/vendor/daemon-kit/app_generators/daemon_kit/templates/script/destroy +14 -0
  65. data/vendor/daemon-kit/app_generators/daemon_kit/templates/script/generate +14 -0
  66. data/vendor/daemon-kit/bin/daemon_kit +18 -0
  67. data/vendor/daemon-kit/daemon_generators/amqp/USAGE +5 -0
  68. data/vendor/daemon-kit/daemon_generators/amqp/amqp_generator.rb +65 -0
  69. data/vendor/daemon-kit/daemon_generators/amqp/templates/config/amqp.yml +28 -0
  70. data/vendor/daemon-kit/daemon_generators/amqp/templates/config/initializers/amqp.rb +7 -0
  71. data/vendor/daemon-kit/daemon_generators/amqp/templates/libexec/daemon.rb +37 -0
  72. data/vendor/daemon-kit/daemon_generators/cron/USAGE +5 -0
  73. data/vendor/daemon-kit/daemon_generators/cron/cron_generator.rb +64 -0
  74. data/vendor/daemon-kit/daemon_generators/cron/templates/config/initializers/cron.rb +11 -0
  75. data/vendor/daemon-kit/daemon_generators/cron/templates/libexec/daemon.rb +43 -0
  76. data/vendor/daemon-kit/daemon_generators/cucumber/USAGE +11 -0
  77. data/vendor/daemon-kit/daemon_generators/cucumber/cucumber_generator.rb +38 -0
  78. data/vendor/daemon-kit/daemon_generators/cucumber/templates/cucumber +8 -0
  79. data/vendor/daemon-kit/daemon_generators/cucumber/templates/cucumber.rake +13 -0
  80. data/vendor/daemon-kit/daemon_generators/cucumber/templates/cucumber_environment.rb +2 -0
  81. data/vendor/daemon-kit/daemon_generators/cucumber/templates/env.rb +7 -0
  82. data/vendor/daemon-kit/daemon_generators/deploy_capistrano/deploy_capistrano_generator.rb +35 -0
  83. data/vendor/daemon-kit/daemon_generators/deploy_capistrano/templates/Capfile +10 -0
  84. data/vendor/daemon-kit/daemon_generators/deploy_capistrano/templates/USAGE +10 -0
  85. data/vendor/daemon-kit/daemon_generators/deploy_capistrano/templates/config/deploy.rb +53 -0
  86. data/vendor/daemon-kit/daemon_generators/deploy_capistrano/templates/config/deploy/production.rb +6 -0
  87. data/vendor/daemon-kit/daemon_generators/deploy_capistrano/templates/config/deploy/staging.rb +6 -0
  88. data/vendor/daemon-kit/daemon_generators/deploy_capistrano/templates/config/environments/staging.rb +0 -0
  89. data/vendor/daemon-kit/daemon_generators/jabber/USAGE +5 -0
  90. data/vendor/daemon-kit/daemon_generators/jabber/jabber_generator.rb +65 -0
  91. data/vendor/daemon-kit/daemon_generators/jabber/templates/config/initializers/jabber.rb +7 -0
  92. data/vendor/daemon-kit/daemon_generators/jabber/templates/config/jabber.yml +26 -0
  93. data/vendor/daemon-kit/daemon_generators/jabber/templates/libexec/daemon.rb +27 -0
  94. data/vendor/daemon-kit/daemon_generators/nanite_agent/USAGE +5 -0
  95. data/vendor/daemon-kit/daemon_generators/nanite_agent/nanite_agent_generator.rb +68 -0
  96. data/vendor/daemon-kit/daemon_generators/nanite_agent/templates/config/initializers/nanite_agent.rb +6 -0
  97. data/vendor/daemon-kit/daemon_generators/nanite_agent/templates/config/nanite.yml +35 -0
  98. data/vendor/daemon-kit/daemon_generators/nanite_agent/templates/lib/actors/sample.rb +11 -0
  99. data/vendor/daemon-kit/daemon_generators/nanite_agent/templates/libexec/daemon.rb +31 -0
  100. data/vendor/daemon-kit/daemon_generators/rspec/USAGE +5 -0
  101. data/vendor/daemon-kit/daemon_generators/rspec/rspec_generator.rb +55 -0
  102. data/vendor/daemon-kit/daemon_generators/rspec/templates/spec.rb +11 -0
  103. data/vendor/daemon-kit/daemon_generators/rspec/templates/spec/spec.opts +1 -0
  104. data/vendor/daemon-kit/daemon_generators/rspec/templates/spec/spec_helper.rb +21 -0
  105. data/vendor/daemon-kit/daemon_generators/rspec/templates/tasks/rspec.rake +21 -0
  106. data/vendor/daemon-kit/daemon_generators/ruote/USAGE +5 -0
  107. data/vendor/daemon-kit/daemon_generators/ruote/ruote_generator.rb +67 -0
  108. data/vendor/daemon-kit/daemon_generators/ruote/templates/config/amqp.yml +30 -0
  109. data/vendor/daemon-kit/daemon_generators/ruote/templates/config/initializers/ruote.rb +13 -0
  110. data/vendor/daemon-kit/daemon_generators/ruote/templates/config/ruote.yml +23 -0
  111. data/vendor/daemon-kit/daemon_generators/ruote/templates/lib/daemon.rb +4 -0
  112. data/vendor/daemon-kit/daemon_generators/ruote/templates/lib/sample.rb +26 -0
  113. data/vendor/daemon-kit/daemon_generators/ruote/templates/libexec/daemon.rb +33 -0
  114. data/vendor/daemon-kit/lib/daemon_kit.rb +54 -0
  115. data/vendor/daemon-kit/lib/daemon_kit/abstract_logger.rb +235 -0
  116. data/vendor/daemon-kit/lib/daemon_kit/amqp.rb +38 -0
  117. data/vendor/daemon-kit/lib/daemon_kit/application.rb +187 -0
  118. data/vendor/daemon-kit/lib/daemon_kit/arguments.rb +165 -0
  119. data/vendor/daemon-kit/lib/daemon_kit/commands/console.rb +38 -0
  120. data/vendor/daemon-kit/lib/daemon_kit/config.rb +108 -0
  121. data/vendor/daemon-kit/lib/daemon_kit/console_daemon.rb +2 -0
  122. data/vendor/daemon-kit/lib/daemon_kit/core_ext.rb +1 -0
  123. data/vendor/daemon-kit/lib/daemon_kit/core_ext/configurable.rb +96 -0
  124. data/vendor/daemon-kit/lib/daemon_kit/core_ext/string.rb +22 -0
  125. data/vendor/daemon-kit/lib/daemon_kit/cron.rb +48 -0
  126. data/vendor/daemon-kit/lib/daemon_kit/cucumber/world.rb +38 -0
  127. data/vendor/daemon-kit/lib/daemon_kit/deployment/capistrano.rb +482 -0
  128. data/vendor/daemon-kit/lib/daemon_kit/em.rb +43 -0
  129. data/vendor/daemon-kit/lib/daemon_kit/error_handlers/base.rb +32 -0
  130. data/vendor/daemon-kit/lib/daemon_kit/error_handlers/hoptoad.rb +61 -0
  131. data/vendor/daemon-kit/lib/daemon_kit/error_handlers/mail.rb +85 -0
  132. data/vendor/daemon-kit/lib/daemon_kit/exceptions.rb +8 -0
  133. data/vendor/daemon-kit/lib/daemon_kit/initializer.rb +438 -0
  134. data/vendor/daemon-kit/lib/daemon_kit/jabber.rb +170 -0
  135. data/vendor/daemon-kit/lib/daemon_kit/nanite.rb +7 -0
  136. data/vendor/daemon-kit/lib/daemon_kit/nanite/agent.rb +56 -0
  137. data/vendor/daemon-kit/lib/daemon_kit/pid_file.rb +61 -0
  138. data/vendor/daemon-kit/lib/daemon_kit/ruote_participants.rb +119 -0
  139. data/vendor/daemon-kit/lib/daemon_kit/ruote_pseudo_participant.rb +68 -0
  140. data/vendor/daemon-kit/lib/daemon_kit/ruote_workitem.rb +169 -0
  141. data/vendor/daemon-kit/lib/daemon_kit/safety.rb +85 -0
  142. data/vendor/daemon-kit/lib/daemon_kit/tasks.rb +2 -0
  143. data/vendor/daemon-kit/lib/daemon_kit/tasks/environment.rake +10 -0
  144. data/vendor/daemon-kit/lib/daemon_kit/tasks/framework.rake +120 -0
  145. data/vendor/daemon-kit/lib/daemon_kit/tasks/god.rake +62 -0
  146. data/vendor/daemon-kit/lib/daemon_kit/tasks/log.rake +8 -0
  147. data/vendor/daemon-kit/lib/daemon_kit/tasks/monit.rake +29 -0
  148. data/vendor/daemon-kit/script/console +10 -0
  149. data/vendor/daemon-kit/script/destroy +14 -0
  150. data/vendor/daemon-kit/script/generate +14 -0
  151. data/vendor/daemon-kit/script/txt2html +71 -0
  152. data/vendor/daemon-kit/spec/abstract_logger_spec.rb +126 -0
  153. data/vendor/daemon-kit/spec/argument_spec.rb +70 -0
  154. data/vendor/daemon-kit/spec/config_spec.rb +79 -0
  155. data/vendor/daemon-kit/spec/configurable_spec.rb +56 -0
  156. data/vendor/daemon-kit/spec/daemon_kit_spec.rb +7 -0
  157. data/vendor/daemon-kit/spec/error_handlers_spec.rb +23 -0
  158. data/vendor/daemon-kit/spec/fixtures/env.yml +15 -0
  159. data/vendor/daemon-kit/spec/fixtures/noenv.yml +4 -0
  160. data/vendor/daemon-kit/spec/initializer_spec.rb +26 -0
  161. data/vendor/daemon-kit/spec/spec.opts +1 -0
  162. data/vendor/daemon-kit/spec/spec_helper.rb +27 -0
  163. data/vendor/daemon-kit/tasks/rspec.rake +21 -0
  164. data/vendor/daemon-kit/templates/god/god.erb +69 -0
  165. data/vendor/daemon-kit/templates/monit/monit.erb +14 -0
  166. data/vendor/daemon-kit/test/test_amqp_generator.rb +48 -0
  167. data/vendor/daemon-kit/test/test_cron_generator.rb +45 -0
  168. data/vendor/daemon-kit/test/test_daemon-kit_generator.rb +84 -0
  169. data/vendor/daemon-kit/test/test_daemon_kit_config.rb +28 -0
  170. data/vendor/daemon-kit/test/test_deploy_capistrano_generator.rb +48 -0
  171. data/vendor/daemon-kit/test/test_generator_helper.rb +29 -0
  172. data/vendor/daemon-kit/test/test_helper.rb +7 -0
  173. data/vendor/daemon-kit/test/test_jabber_generator.rb +49 -0
  174. data/vendor/daemon-kit/test/test_nanite_agent_generator.rb +49 -0
  175. data/vendor/daemon-kit/test/test_ruote_generator.rb +45 -0
  176. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail.rb +5 -0
  177. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/address.rb +426 -0
  178. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/attachments.rb +46 -0
  179. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/base64.rb +46 -0
  180. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/compat.rb +41 -0
  181. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/config.rb +67 -0
  182. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/core_extensions.rb +63 -0
  183. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/encode.rb +581 -0
  184. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/header.rb +960 -0
  185. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/index.rb +9 -0
  186. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/interface.rb +1130 -0
  187. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/loader.rb +3 -0
  188. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/mail.rb +578 -0
  189. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/mailbox.rb +495 -0
  190. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/main.rb +6 -0
  191. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/mbox.rb +3 -0
  192. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/net.rb +248 -0
  193. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/obsolete.rb +132 -0
  194. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/parser.rb +1476 -0
  195. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/port.rb +379 -0
  196. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/quoting.rb +118 -0
  197. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/require_arch.rb +58 -0
  198. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/scanner.rb +49 -0
  199. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/scanner_r.rb +261 -0
  200. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/stringio.rb +280 -0
  201. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/utils.rb +337 -0
  202. data/vendor/daemon-kit/vendor/tmail-1.2.3/tmail/version.rb +39 -0
  203. data/vendor/daemon-kit/vendor/tmail.rb +13 -0
  204. metadata +281 -0
@@ -0,0 +1,2 @@
1
+ # Load and configure our daemon process, without daemonizing
2
+ DaemonKit::Application.running!
@@ -0,0 +1 @@
1
+ require File.dirname(__FILE__) + '/core_ext/string'
@@ -0,0 +1,96 @@
1
+ module DaemonKit
2
+
3
+ # Provide some advanced helpers for managing access to instance variables.
4
+ module Configurable
5
+
6
+ def self.included(base) #:nodoc:
7
+ base.class_eval <<-EOF
8
+ @configurables = {}
9
+ @configurable_defaults = {}
10
+
11
+ class << self
12
+ attr_reader :configurables, :configurable_defaults
13
+ end
14
+ EOF
15
+
16
+ base.extend( ClassMethods )
17
+ base.send( :include, InstanceMethods )
18
+ end
19
+
20
+ module ClassMethods
21
+
22
+ # Create a configurable value on any instance, which can contain
23
+ # a default value, and/or be locked.
24
+ #
25
+ # Create a standard getter/setter without a default value
26
+ #
27
+ # configurable :foo
28
+ #
29
+ # Create a getter/setter with a default value
30
+ #
31
+ # configurable :foo, true
32
+ #
33
+ # The final argument can be an options hash, which currently
34
+ # respects only one key: +locked+ (false by default). Locking a
35
+ # configurable means the value can only be set once by the
36
+ # setter method.
37
+ #
38
+ # configurable :foo, :locked => true
39
+ #
40
+ # As long as the getter method (+foo+) returns nil, the standard
41
+ # setter method will work. As soon as the getter returns a
42
+ # non-nil value the setter won't set a new value. To set a new
43
+ # value you'll have to explicitly use the #set instance method.
44
+ def configurable( name, *args )
45
+ opts = args.last.is_a?( Hash ) ? args.pop : {}
46
+ opts = { :locked => false }.merge( opts )
47
+
48
+ default = args.size <= 1 ? args.pop : args
49
+
50
+ name = name.to_sym
51
+
52
+ self.configurables[ name ] = opts
53
+ self.configurable_defaults[ name ] = default
54
+
55
+ class_eval( <<-EOF, __FILE__, __LINE__ )
56
+ def #{name} # def foo
57
+ if _configurables[:#{name}].nil? # if _configurables[:foo].nil?
58
+ self.class.configurable_defaults[:#{name}] # self.class.configurable_defaults[:foo]
59
+ else # else
60
+ _configurables[:#{name}] # _configurables[:foo]
61
+ end # end
62
+ end #
63
+
64
+ def #{name}=( value ) # def foo=( value )
65
+ if #{name}.nil? || # if foo.nil? ||
66
+ !self.class.configurables[:#{name}][:locked] # !self.class.configurables[:foo][:locked]
67
+ #
68
+ _configurables[:#{name}] = value # _configurables[:foo] = value
69
+ end # end
70
+ end # end
71
+ EOF
72
+ end
73
+
74
+ end
75
+
76
+ module InstanceMethods
77
+
78
+ # Force the value of a configurable to be set without any
79
+ # respect for it's locked status.
80
+ def set( name, value )
81
+ name = name.to_sym
82
+
83
+ if self.class.configurables.has_key?( name )
84
+ _configurables[ name ] = value
85
+ end
86
+ end
87
+
88
+ private
89
+
90
+ def _configurables
91
+ @_configurables ||= {}
92
+ end
93
+
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,22 @@
1
+ require 'pathname'
2
+
3
+ class String
4
+
5
+ # Assuming the string is a file or path name, convert it into an
6
+ # absolute path.
7
+ def to_absolute_path
8
+ # Pathname is incompatible with Windows, but Windows doesn't have
9
+ # real symlinks so File.expand_path is safe.
10
+ if RUBY_PLATFORM =~ /(:?mswin|mingw)/
11
+ File.expand_path( self )
12
+
13
+ # Otherwise use Pathname#realpath which respects symlinks.
14
+ else
15
+ begin
16
+ File.expand_path( Pathname.new( self ).realpath.to_s )
17
+ rescue Errno::ENOENT
18
+ File.expand_path( Pathname.new( self ).cleanpath.to_s )
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,48 @@
1
+ module DaemonKit
2
+
3
+ # Thin wrapper around rufus-scheduler gem, specifically designed to ease
4
+ # configuration of a scheduler and provide some added simplicity.
5
+ #
6
+ # For more information on rufus-scheduler, please visit the RDoc's
7
+ # at http://rufus.rubyforge.org/rufus-scheduler/
8
+ #
9
+ # To use the evented scheduler, call #DaemonKit::EM.run prior to
10
+ # setting up your first schedule.
11
+ class Cron
12
+
13
+ @instance = nil
14
+
15
+ attr_reader :scheduler
16
+
17
+ class << self
18
+
19
+ # Access to the scheduler instance
20
+ def instance
21
+ @instance ||= new
22
+ end
23
+
24
+ def scheduler
25
+ instance.scheduler
26
+ end
27
+
28
+ private :new
29
+
30
+ # Once the scheduler has been configured, call #run to block the
31
+ # current thread and keep the process alive for the scheduled
32
+ # tasks to run
33
+ def run
34
+ DaemonKit.logger.info "Starting rufus-scheduler"
35
+
36
+ if instance.is_a?( Rufus::Scheduler::PlainScheduler )
37
+ instance.scheduler.join
38
+ else
39
+ Thread.stop
40
+ end
41
+ end
42
+ end
43
+
44
+ def initialize
45
+ @scheduler = Rufus::Scheduler.start_new
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,38 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Based on code from Brian Takita, Yurii Rashkovskii, Ben Mabey and Aslak Hellesøy
3
+ # Adapted by Kenneth Kalmer for daemon-kit
4
+
5
+ begin
6
+ require 'test/unit/testresult'
7
+ rescue LoadError => e
8
+ e.message << "\nYou must gem install test-unit. For more info see https://rspec.lighthouseapp.com/projects/16211/tickets/292"
9
+ raise e
10
+ end
11
+
12
+ # So that Test::Unit doesn't launch at the end - makes it think it has already been run.
13
+ Test::Unit.run = true if Test::Unit.respond_to?(:run=)
14
+
15
+ $__cucumber_toplevel = self
16
+
17
+ module DaemonKit
18
+ module Cucumber
19
+ # All scenarios will execute in the context of a new instance of World.
20
+ class World
21
+ def initialize #:nodoc:
22
+ @_result = Test::Unit::TestResult.new
23
+ end
24
+ end
25
+
26
+ $__cucumber_toplevel.Before do
27
+ # Placeholder
28
+ end
29
+
30
+ $__cucumber_toplevel.After do
31
+ # Placeholder
32
+ end
33
+ end
34
+ end
35
+
36
+ World do
37
+ DaemonKit::Cucumber::World.new
38
+ end
@@ -0,0 +1,482 @@
1
+ require 'yaml'
2
+ require 'capistrano/recipes/deploy/scm'
3
+ require 'capistrano/recipes/deploy/strategy'
4
+
5
+ def _cset(name, *args, &block)
6
+ unless exists?(name)
7
+ set(name, *args, &block)
8
+ end
9
+ end
10
+
11
+ # =========================================================================
12
+ # These variables MUST be set in the client capfiles. If they are not set,
13
+ # the deploy will fail with an error.
14
+ # =========================================================================
15
+
16
+ _cset(:application) { abort "Please specify the name of your application, set :application, 'foo'" }
17
+ _cset(:repository) { abort "Please specify the repository that houses your application's code, set :repository, 'foo'" }
18
+
19
+ # =========================================================================
20
+ # These variables may be set in the client capfile if their default values
21
+ # are not sufficient.
22
+ # =========================================================================
23
+
24
+ _cset :scm, :subversion
25
+ _cset :deploy_via, :checkout
26
+
27
+ _cset(:deploy_to) { "/u/apps/#{application}" }
28
+ _cset(:revision) { source.head }
29
+
30
+ # =========================================================================
31
+ # These variables should NOT be changed unless you are very confident in
32
+ # what you are doing. Make sure you understand all the implications of your
33
+ # changes if you do decide to muck with these!
34
+ # =========================================================================
35
+
36
+ _cset(:source) { Capistrano::Deploy::SCM.new(scm, self) }
37
+ _cset(:real_revision) { source.local.query_revision(revision) { |cmd| with_env("LC_ALL", "C") { run_locally(cmd) } } }
38
+
39
+ _cset(:strategy) { Capistrano::Deploy::Strategy.new(deploy_via, self) }
40
+
41
+ _cset(:release_name) { set :deploy_timestamped, true; Time.now.utc.strftime("%Y%m%d%H%M%S") }
42
+
43
+ _cset :version_dir, "releases"
44
+ _cset :shared_dir, "shared"
45
+ _cset :shared_children, %w(log tmp)
46
+ _cset :current_dir, "current"
47
+
48
+ _cset(:releases_path) { File.join(deploy_to, version_dir) }
49
+ _cset(:shared_path) { File.join(deploy_to, shared_dir) }
50
+ _cset(:current_path) { File.join(deploy_to, current_dir) }
51
+ _cset(:release_path) { File.join(releases_path, release_name) }
52
+
53
+ _cset(:releases) { capture("ls -xt #{releases_path}").split.reverse }
54
+ _cset(:current_release) { File.join(releases_path, releases.last) }
55
+ _cset(:previous_release) { releases.length > 1 ? File.join(releases_path, releases[-2]) : nil }
56
+
57
+ _cset(:current_revision) { capture("cat #{current_path}/REVISION").chomp }
58
+ _cset(:latest_revision) { capture("cat #{current_release}/REVISION").chomp }
59
+ _cset(:previous_revision) { capture("cat #{previous_release}/REVISION").chomp }
60
+
61
+ _cset(:run_method) { fetch(:use_sudo, true) ? :sudo : :run }
62
+
63
+ # some tasks, like symlink, need to always point at the latest release, but
64
+ # they can also (occassionally) be called standalone. In the standalone case,
65
+ # the timestamped release_path will be inaccurate, since the directory won't
66
+ # actually exist. This variable lets tasks like symlink work either in the
67
+ # standalone case, or during deployment.
68
+ _cset(:latest_release) { exists?(:deploy_timestamped) ? release_path : current_release }
69
+
70
+ # =========================================================================
71
+ # These are helper methods that will be available to your recipes.
72
+ # =========================================================================
73
+
74
+ # Auxiliary helper method for the `deploy:check' task. Lets you set up your
75
+ # own dependencies.
76
+ def depend(location, type, *args)
77
+ deps = fetch(:dependencies, {})
78
+ deps[location] ||= {}
79
+ deps[location][type] ||= []
80
+ deps[location][type] << args
81
+ set :dependencies, deps
82
+ end
83
+
84
+ # Temporarily sets an environment variable, yields to a block, and restores
85
+ # the value when it is done.
86
+ def with_env(name, value)
87
+ saved, ENV[name] = ENV[name], value
88
+ yield
89
+ ensure
90
+ ENV[name] = saved
91
+ end
92
+
93
+ # logs the command then executes it locally.
94
+ # returns the command output as a string
95
+ def run_locally(cmd)
96
+ logger.trace "executing locally: #{cmd.inspect}" if logger
97
+ `#{cmd}`
98
+ end
99
+
100
+ # If a command is given, this will try to execute the given command, as
101
+ # described below. Otherwise, it will return a string for use in embedding in
102
+ # another command, for executing that command as described below.
103
+ #
104
+ # If :run_method is :sudo (or :use_sudo is true), this executes the given command
105
+ # via +sudo+. Otherwise is uses +run+. If :as is given as a key, it will be
106
+ # passed as the user to sudo as, if using sudo. If the :as key is not given,
107
+ # it will default to whatever the value of the :admin_runner variable is,
108
+ # which (by default) is unset.
109
+ #
110
+ # THUS, if you want to try to run something via sudo, and what to use the
111
+ # root user, you'd just to try_sudo('something'). If you wanted to try_sudo as
112
+ # someone else, you'd just do try_sudo('something', :as => "bob"). If you
113
+ # always wanted sudo to run as a particular user, you could do
114
+ # set(:admin_runner, "bob").
115
+ def try_sudo(*args)
116
+ options = args.last.is_a?(Hash) ? args.pop : {}
117
+ command = args.shift
118
+ raise ArgumentError, "too many arguments" if args.any?
119
+
120
+ as = options.fetch(:as, fetch(:admin_runner, nil))
121
+ via = fetch(:run_method, :sudo)
122
+ if command
123
+ invoke_command(command, :via => via, :as => as)
124
+ elsif via == :sudo
125
+ sudo(:as => as)
126
+ else
127
+ ""
128
+ end
129
+ end
130
+
131
+ # Same as sudo, but tries sudo with :as set to the value of the :runner
132
+ # variable (which defaults to "app").
133
+ def try_runner(*args)
134
+ options = args.last.is_a?(Hash) ? args.pop : {}
135
+ args << options.merge(:as => fetch(:runner, "app"))
136
+ try_sudo(*args)
137
+ end
138
+
139
+ # =========================================================================
140
+ # These are the tasks that are available to help with deploying web apps,
141
+ # and specifically, Rails applications. You can have cap give you a summary
142
+ # of them with `cap -T'.
143
+ # =========================================================================
144
+
145
+ namespace :deploy do
146
+ desc <<-DESC
147
+ Deploys your project. This calls both `update' and `restart'. Note that \
148
+ this will generally only work for applications that have already been deployed \
149
+ once. For a "cold" deploy, you'll want to take a look at the `deploy:cold' \
150
+ task, which handles the cold start specifically.
151
+ DESC
152
+ task :default do
153
+ update
154
+ restart
155
+ end
156
+
157
+ desc <<-DESC
158
+ Prepares one or more servers for deployment. Before you can use any \
159
+ of the Capistrano deployment tasks with your project, you will need to \
160
+ make sure all of your servers have been prepared with `cap deploy:setup'. When \
161
+ you add a new server to your cluster, you can easily run the setup task \
162
+ on just that server by specifying the HOSTS environment variable:
163
+
164
+ $ cap HOSTS=new.server.com deploy:setup
165
+
166
+ It is safe to run this task on servers that have already been set up; it \
167
+ will not destroy any deployed revisions or data.
168
+ DESC
169
+ task :setup, :except => { :no_release => true } do
170
+ dirs = [deploy_to, releases_path, shared_path]
171
+ dirs += shared_children.map { |d| File.join(shared_path, d) }
172
+ run "#{try_sudo} mkdir -p #{dirs.join(' ')} && #{try_sudo} chmod g+w #{dirs.join(' ')}"
173
+ end
174
+
175
+ desc <<-DESC
176
+ Copies your project and updates the symlink. It does this in a \
177
+ transaction, so that if either `update_code' or `symlink' fail, all \
178
+ changes made to the remote servers will be rolled back, leaving your \
179
+ system in the same state it was in before `update' was invoked. Usually, \
180
+ you will want to call `deploy' instead of `update', but `update' can be \
181
+ handy if you want to deploy, but not immediately restart your application.
182
+ DESC
183
+ task :update do
184
+ transaction do
185
+ update_code
186
+ symlink
187
+ end
188
+ end
189
+
190
+ desc <<-DESC
191
+ Copies your project to the remote servers. This is the first stage \
192
+ of any deployment; moving your updated code and assets to the deployment \
193
+ servers. You will rarely call this task directly, however; instead, you \
194
+ should call the `deploy' task (to do a complete deploy) or the `update' \
195
+ task (if you want to perform the `restart' task separately).
196
+
197
+ You will need to make sure you set the :scm variable to the source \
198
+ control software you are using (it defaults to :subversion), and the \
199
+ :deploy_via variable to the strategy you want to use to deploy (it \
200
+ defaults to :checkout).
201
+ DESC
202
+ task :update_code, :except => { :no_release => true } do
203
+ on_rollback { run "rm -rf #{release_path}; true" }
204
+ strategy.deploy!
205
+ finalize_update
206
+ end
207
+
208
+ desc <<-DESC
209
+ [internal] Touches up the released code. This is called by update_code \
210
+ after the basic deploy finishes. It assumes a Rails project was deployed, \
211
+ so if you are deploying something else, you may want to override this \
212
+ task with your own environment's requirements.
213
+
214
+ This task will make the release group-writable (if the :group_writable \
215
+ variable is set to true, which is the default). It will then set up \
216
+ symlinks to the shared directory for the :shared_children \
217
+ directories, and will lastly touch all assets in public/images, \
218
+ public/stylesheets, and public/javascripts so that the times are \
219
+ consistent (so that asset timestamping works). This touch process \
220
+ is only carried out if the :normalize_asset_timestamps variable is \
221
+ set to true, which is the default.
222
+ DESC
223
+ task :finalize_update, :except => { :no_release => true } do
224
+ run "chmod -R g+w #{latest_release}" if fetch(:group_writable, true)
225
+
226
+ # mkdir -p is making sure that the directories are there for some SCM's that don't
227
+ # save empty folders
228
+ dirs = fetch(:shared_children, [])
229
+ cmd = dirs.inject([]) do |c,d|
230
+ c.push "rm -rf #{latest_release}/#{d}"
231
+ c.push "ln -s #{shared_path}/#{d} #{latest_release}/#{d}"
232
+ c
233
+ end
234
+
235
+ run cmd.join( ' && ' )
236
+
237
+ if fetch(:normalize_asset_timestamps, false)
238
+ stamp = Time.now.utc.strftime("%Y%m%d%H%M.%S")
239
+ asset_paths = %w(images stylesheets javascripts).map { |p| "#{latest_release}/public/#{p}" }.join(" ")
240
+ run "find #{asset_paths} -exec touch -t #{stamp} {} ';'; true", :env => { "TZ" => "UTC" }
241
+ end
242
+
243
+ copy_configs
244
+ end
245
+
246
+ desc <<-DESC
247
+ Copies any shared configuration files from :deploy_to/config into \
248
+ the current release's config directory. Original files, if present, \
249
+ are renamed to the same name with .orig appended.
250
+
251
+ Specify a list of files by setting :config_files to an array in your \
252
+ deployment configuration.
253
+ DESC
254
+ task :copy_configs do
255
+ fetch(:config_files, []).each do |f|
256
+ run "[ -f #{release_path}/config/#{f} ]; mv #{release_path}/config/#{f} #{release_path}/config/#{f}.orig"
257
+ run "[ -f #{deploy_to}/config/#{f} ]; cp #{deploy_to}/config/#{f} #{release_path}/config/#{f}"
258
+ end
259
+ end
260
+
261
+ desc <<-DESC
262
+ Updates the symlink to the most recently deployed version. Capistrano works \
263
+ by putting each new release of your application in its own directory. When \
264
+ you deploy a new version, this task's job is to update the `current' symlink \
265
+ to point at the new version. You will rarely need to call this task \
266
+ directly; instead, use the `deploy' task (which performs a complete \
267
+ deploy, including `restart') or the 'update' task (which does everything \
268
+ except `restart').
269
+ DESC
270
+ task :symlink, :except => { :no_release => true } do
271
+ on_rollback do
272
+ if previous_release
273
+ run "rm -f #{current_path}; ln -s #{previous_release} #{current_path}; true"
274
+ else
275
+ logger.important "no previous release to rollback to, rollback of symlink skipped"
276
+ end
277
+ end
278
+
279
+ run "rm -f #{current_path} && ln -s #{latest_release} #{current_path}"
280
+ end
281
+
282
+ desc <<-DESC
283
+ Copy files to the currently deployed version. This is useful for updating \
284
+ files piecemeal, such as when you need to quickly deploy only a single \
285
+ file. Some files, such as updated templates, images, or stylesheets, \
286
+ might not require a full deploy, and especially in emergency situations \
287
+ it can be handy to just push the updates to production, quickly.
288
+
289
+ To use this task, specify the files and directories you want to copy as a \
290
+ comma-delimited list in the FILES environment variable. All directories \
291
+ will be processed recursively, with all files being pushed to the \
292
+ deployment servers.
293
+
294
+ $ cap deploy:upload FILES=templates,controller.rb
295
+
296
+ Dir globs are also supported:
297
+
298
+ $ cap deploy:upload FILES='config/apache/*.conf'
299
+ DESC
300
+ task :upload, :except => { :no_release => true } do
301
+ files = (ENV["FILES"] || "").split(",").map { |f| Dir[f.strip] }.flatten
302
+ abort "Please specify at least one file or directory to update (via the FILES environment variable)" if files.empty?
303
+
304
+ files.each { |file| top.upload(file, File.join(current_path, file)) }
305
+ end
306
+
307
+ desc <<-DESC
308
+ Restarts your application. This works by calling 'stop' task, \
309
+ followed by the 'start' task.
310
+
311
+ See the descriptions for the 'start' and 'stop' tasks for any \
312
+ additional info.
313
+ DESC
314
+ task :restart, :except => { :no_release => true } do
315
+ stop
316
+ start
317
+ end
318
+
319
+ namespace :rollback do
320
+ desc <<-DESC
321
+ [internal] Points the current symlink at the previous revision.
322
+ This is called by the rollback sequence, and should rarely (if
323
+ ever) need to be called directly.
324
+ DESC
325
+ task :revision, :except => { :no_release => true } do
326
+ if previous_release
327
+ run "rm #{current_path}; ln -s #{previous_release} #{current_path}"
328
+ else
329
+ abort "could not rollback the code because there is no prior release"
330
+ end
331
+ end
332
+
333
+ desc <<-DESC
334
+ [internal] Removes the most recently deployed release.
335
+ This is called by the rollback sequence, and should rarely
336
+ (if ever) need to be called directly.
337
+ DESC
338
+ task :cleanup, :except => { :no_release => true } do
339
+ run "if [ `readlink #{current_path}` != #{current_release} ]; then rm -rf #{current_release}; fi"
340
+ end
341
+
342
+ desc <<-DESC
343
+ Rolls back to the previously deployed version. The `current' symlink will \
344
+ be updated to point at the previously deployed version, and then the \
345
+ current release will be removed from the servers. You'll generally want \
346
+ to call `rollback' instead, as it performs a `restart' as well.
347
+ DESC
348
+ task :code, :except => { :no_release => true } do
349
+ revision
350
+ cleanup
351
+ end
352
+
353
+ desc <<-DESC
354
+ Rolls back to a previous version and restarts. This is handy if you ever \
355
+ discover that you've deployed a lemon; `cap rollback' and you're right \
356
+ back where you were, on the previously deployed version.
357
+ DESC
358
+ task :default do
359
+ revision
360
+ restart
361
+ cleanup
362
+ end
363
+ end
364
+
365
+ desc <<-DESC
366
+ Clean up old releases. By default, the last 5 releases are kept on each \
367
+ server (though you can change this with the keep_releases variable). All \
368
+ other deployed revisions are removed from the servers. By default, this \
369
+ will use sudo to clean up the old releases, but if sudo is not available \
370
+ for your environment, set the :use_sudo variable to false instead.
371
+ DESC
372
+ task :cleanup, :except => { :no_release => true } do
373
+ count = fetch(:keep_releases, 5).to_i
374
+ if count >= releases.length
375
+ logger.important "no old releases to clean up"
376
+ else
377
+ logger.info "keeping #{count} of #{releases.length} deployed releases"
378
+
379
+ directories = (releases - releases.last(count)).map { |release|
380
+ File.join(releases_path, release) }.join(" ")
381
+
382
+ try_sudo "rm -rf #{directories}"
383
+ end
384
+ end
385
+
386
+ desc <<-DESC
387
+ Test deployment dependencies. Checks things like directory permissions, \
388
+ necessary utilities, and so forth, reporting on the things that appear to \
389
+ be incorrect or missing. This is good for making sure a deploy has a \
390
+ chance of working before you actually run `cap deploy'.
391
+
392
+ You can define your own dependencies, as well, using the `depend' method:
393
+
394
+ depend :remote, :gem, "tzinfo", ">=0.3.3"
395
+ depend :local, :command, "svn"
396
+ depend :remote, :directory, "/u/depot/files"
397
+ DESC
398
+ task :check, :except => { :no_release => true } do
399
+ dependencies = strategy.check!
400
+
401
+ other = fetch(:dependencies, {})
402
+ other.each do |location, types|
403
+ types.each do |type, calls|
404
+ if type == :gem
405
+ dependencies.send(location).command(fetch(:gem_command, "gem")).or("`gem' command could not be found. Try setting :gem_command")
406
+ end
407
+
408
+ calls.each do |args|
409
+ dependencies.send(location).send(type, *args)
410
+ end
411
+ end
412
+ end
413
+
414
+ if dependencies.pass?
415
+ puts "You appear to have all necessary dependencies installed"
416
+ else
417
+ puts "The following dependencies failed. Please check them and try again:"
418
+ dependencies.reject { |d| d.pass? }.each do |d|
419
+ puts "--> #{d.message}"
420
+ end
421
+ abort
422
+ end
423
+ end
424
+
425
+ desc <<-DESC
426
+ Deploys and starts a `cold' application. This is useful if you have not \
427
+ deployed your application before, or if your application is (for some \
428
+ other reason) not currently running. It will deploy the code, and then \
429
+ instead of invoking `deploy:restart', it will invoke `deploy:start' to \
430
+ fire up the application servers.
431
+ DESC
432
+ task :cold do
433
+ update
434
+ start
435
+ end
436
+
437
+ desc <<-DESC
438
+ Start the daemon processes. This will attempt to invoke a script \
439
+ in your application called `bin/:application', with the 'start' parameter.
440
+
441
+ By default, the script will be executed via sudo as the `app' user. If \
442
+ you wish to run it as a different user, set the :runner variable to \
443
+ that user. If you are in an environment where you can't use sudo, set \
444
+ the :use_sudo variable to false.
445
+ DESC
446
+ task :start do
447
+ try_runner "/usr/bin/env DAEMON_ENV=#{fetch(:daemon_env)} #{current_path}/bin/#{application} start"
448
+ end
449
+
450
+ desc <<-DESC
451
+ Stop the daemon processes. This will call 'bin/:application stop'.
452
+
453
+ By default, the script will be executed via sudo as the `app' user. If \
454
+ you wish to run it as a different user, set the :runner variable to \
455
+ that user. If you are in an environment where you can't use sudo, set \
456
+ the :use_sudo variable to false.
457
+ DESC
458
+ task :stop do
459
+ try_runner "/usr/bin/env DAEMON_ENV=#{fetch(:daemon_env)} #{current_path}/bin/#{application} stop"
460
+ end
461
+
462
+ namespace :pending do
463
+ desc <<-DESC
464
+ Displays the `diff' since your last deploy. This is useful if you want \
465
+ to examine what changes are about to be deployed. Note that this might \
466
+ not be supported on all SCM's.
467
+ DESC
468
+ task :diff, :except => { :no_release => true } do
469
+ system(source.local.diff(current_revision))
470
+ end
471
+
472
+ desc <<-DESC
473
+ Displays the commits since your last deploy. This is good for a summary \
474
+ of the changes that have occurred since the last deploy. Note that this \
475
+ might not be supported on all SCM's.
476
+ DESC
477
+ task :default, :except => { :no_release => true } do
478
+ from = source.next_revision(current_revision)
479
+ system(source.local.log(from))
480
+ end
481
+ end
482
+ end