ripta-daemon-kit 0.1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. data/History.txt +7 -0
  2. data/Manifest.txt +58 -0
  3. data/PostInstall.txt +6 -0
  4. data/README.textile +77 -0
  5. data/Rakefile +30 -0
  6. data/TODO.txt +24 -0
  7. data/app_generators/daemon_kit/USAGE +7 -0
  8. data/app_generators/daemon_kit/daemon_kit_generator.rb +121 -0
  9. data/app_generators/daemon_kit/templates/README +48 -0
  10. data/app_generators/daemon_kit/templates/Rakefile +4 -0
  11. data/app_generators/daemon_kit/templates/bin/daemon.erb +7 -0
  12. data/app_generators/daemon_kit/templates/config/boot.rb +52 -0
  13. data/app_generators/daemon_kit/templates/config/environment.rb +19 -0
  14. data/app_generators/daemon_kit/templates/config/environments/development.rb +0 -0
  15. data/app_generators/daemon_kit/templates/config/environments/production.rb +0 -0
  16. data/app_generators/daemon_kit/templates/config/environments/test.rb +0 -0
  17. data/app_generators/daemon_kit/templates/config/initializers/readme +11 -0
  18. data/app_generators/daemon_kit/templates/libexec/daemon.erb +18 -0
  19. data/bin/daemon_kit +19 -0
  20. data/daemon_generators/jabber/USAGE +5 -0
  21. data/daemon_generators/jabber/jabber_generator.rb +65 -0
  22. data/daemon_generators/jabber/templates/config/initializers/jabber.rb +8 -0
  23. data/daemon_generators/jabber/templates/config/jabber.yml +26 -0
  24. data/daemon_generators/jabber/templates/libexec/daemon.rb +27 -0
  25. data/lib/daemon_kit/application.rb +32 -0
  26. data/lib/daemon_kit/initializer.rb +249 -0
  27. data/lib/daemon_kit/jabber.rb +172 -0
  28. data/lib/daemon_kit/patches/force_kill_wait.rb +120 -0
  29. data/lib/daemon_kit/tasks/framework.rake +75 -0
  30. data/lib/daemon_kit/tasks.rb +2 -0
  31. data/lib/daemon_kit.rb +11 -0
  32. data/rubygems_generators/install_rspec/USAGE +5 -0
  33. data/rubygems_generators/install_rspec/install_rspec_generator.rb +57 -0
  34. data/rubygems_generators/install_rspec/templates/spec/spec.opts +1 -0
  35. data/rubygems_generators/install_rspec/templates/spec/spec_helper.rb +10 -0
  36. data/rubygems_generators/install_rspec/templates/spec.rb +11 -0
  37. data/rubygems_generators/install_rspec/templates/tasks/rspec.rake +21 -0
  38. data/script/console +10 -0
  39. data/script/destroy +14 -0
  40. data/script/generate +14 -0
  41. data/script/txt2html +71 -0
  42. data/spec/daemon_kit_spec.rb +7 -0
  43. data/spec/initializer_spec.rb +31 -0
  44. data/spec/spec.opts +1 -0
  45. data/spec/spec_helper.rb +30 -0
  46. data/tasks/rspec.rake +21 -0
  47. data/test/test_daemon-kit_generator.rb +67 -0
  48. data/test/test_generator_helper.rb +29 -0
  49. data/test/test_jabber_generator.rb +49 -0
  50. metadata +150 -0
@@ -0,0 +1,32 @@
1
+ require 'daemons'
2
+
3
+ module DaemonKit
4
+
5
+ # Class responsible for making the daemons run and keep them running.
6
+ class Application
7
+
8
+ class << self
9
+
10
+ # Run the file as a daemon
11
+ def run( file )
12
+ raise DaemonNotFound.new( file ) unless File.exist?( file )
13
+
14
+ app_name = DaemonKit.configuration.daemon_name || File.basename( file )
15
+ options = { :backtrace => true, :log_output => true, :app_name => app_name, :dir_mode => :normal, :dir => "log" }
16
+
17
+ options[:multiple] = DaemonKit.configuration.multiple
18
+ options[:force_kill_wait] = DaemonKit.configuration.force_kill_wait if DaemonKit.configuration.force_kill_wait
19
+
20
+ Daemons.run( file, options )
21
+ end
22
+
23
+ # Call this from inside a daemonized process to complete the
24
+ # initialization process
25
+ def running!
26
+ DaemonKit::Initializer.continue!
27
+ end
28
+
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,249 @@
1
+ require 'logger'
2
+ require 'pathname'
3
+
4
+ DAEMON_ENV = (ENV['DAEMON_ENV'] || 'development').dup unless defined?(DAEMON_ENV)
5
+
6
+ $:.unshift File.dirname(__FILE__) + '/..'
7
+ require 'daemon_kit'
8
+
9
+ module DaemonKit
10
+
11
+ class << self
12
+
13
+ def logger
14
+ @logger
15
+ end
16
+
17
+ def logger=( logger )
18
+ @logger = logger
19
+ end
20
+
21
+ def configuration
22
+ @configuration
23
+ end
24
+
25
+ def configuration=( configuration )
26
+ @configuration = configuration
27
+ end
28
+
29
+ def trap( *args, &block )
30
+ self.configuration.trap( *args, &block )
31
+ end
32
+
33
+ end
34
+
35
+
36
+ # This class does all the nightmare work of setting up a working
37
+ # environment for your daemon.
38
+ class Initializer
39
+
40
+ attr_reader :configuration
41
+
42
+ def self.run( configuration = Configuration.new )
43
+ yield configuration if block_given?
44
+ initializer = new configuration
45
+ initializer.before_daemonize
46
+ initializer
47
+ end
48
+
49
+ def self.continue!
50
+ initializer = new DaemonKit.configuration
51
+ initializer.after_daemonize
52
+ end
53
+
54
+ def self.shutdown
55
+ DaemonKit.logger.warn "Shutting down"
56
+ exit
57
+ end
58
+
59
+ def initialize( configuration )
60
+ @configuration = configuration
61
+ end
62
+
63
+ def before_daemonize
64
+ DaemonKit.configuration = @configuration
65
+
66
+ set_load_path
67
+ load_gems
68
+ load_patches
69
+ load_environment
70
+ end
71
+
72
+ def after_daemonize
73
+ initialize_logger
74
+ initialize_signal_traps
75
+ end
76
+
77
+ def set_load_path
78
+ configuration.load_paths.each do |d|
79
+ $:.unshift( "#{DAEMON_ROOT}/#{d}" ) if File.directory?( "#{DAEMON_ROOT}/#{d}" )
80
+ end
81
+ end
82
+
83
+ def load_gems
84
+
85
+ end
86
+
87
+ def load_patches
88
+ if !!configuration.force_kill_wait
89
+ require 'daemon_kit/patches/force_kill_wait'
90
+ end
91
+ end
92
+
93
+ def load_environment
94
+ return if @environment_loaded
95
+ @environment_loaded = true
96
+
97
+ config = configuration
98
+
99
+ eval(IO.read(configuration.environment_path), binding, configuration.environment_path)
100
+
101
+ eval(IO.read(configuration.daemon_initializer), binding, configuration.daemon_initializer) if File.exist?( configuration.daemon_initializer )
102
+ end
103
+
104
+ def initialize_logger
105
+ return if DaemonKit.logger
106
+
107
+ unless logger = configuration.logger
108
+ logger = Logger.new( configuration.log_path )
109
+ logger.level = configuration.log_level
110
+ end
111
+
112
+ DaemonKit.logger = logger
113
+
114
+ configuration.trap("USR1") {
115
+ DaemonKit.logger.level = DaemonKit.logger.debug? ? Logger::INFO : Logger::DEBUG
116
+ DaemonKit.logger.info "Log level changed to #{DaemonKit.logger.debug? ? 'DEBUG' : 'INFO' }"
117
+ }
118
+ configuration.trap("USR2") {
119
+ DaemonKit.logger.level = Logger::DEBUG
120
+ DaemonKit.logger.info "Log level changed to DEBUG"
121
+ }
122
+
123
+ DaemonKit.logger.info "DaemonKit up and running in #{DAEMON_ENV} mode"
124
+ end
125
+
126
+ def initialize_signal_traps
127
+ term_proc = Proc.new { DaemonKit::Initializer.shutdown }
128
+ configuration.trap( 'INT', term_proc )
129
+ configuration.trap( 'TERM', term_proc )
130
+ end
131
+
132
+ end
133
+
134
+ # Holds our various configuration values
135
+ class Configuration
136
+ # Root to the daemon
137
+ attr_reader :root_path
138
+
139
+ # List of load paths
140
+ attr_accessor :load_paths
141
+
142
+ # The log level to use, defaults to DEBUG
143
+ attr_accessor :log_level
144
+
145
+ # Path to the log file, defaults to 'log/<environment>.log'
146
+ attr_accessor :log_path
147
+
148
+ # Provide a custom logger to use
149
+ attr_accessor :logger
150
+
151
+ # The application name
152
+ attr_accessor :daemon_name
153
+
154
+ # Allow multiple copies to run?
155
+ attr_accessor :multiple
156
+
157
+ # Use the force kill patch? Give the number of seconds
158
+ attr_accessor :force_kill_wait
159
+
160
+ # Collection of signal traps
161
+ attr_reader :signal_traps
162
+
163
+ def initialize
164
+ set_root_path!
165
+
166
+ self.load_paths = default_load_paths
167
+ self.log_level = default_log_level
168
+ self.log_path = default_log_path
169
+
170
+ self.multiple = false
171
+ self.force_kill_wait = false
172
+
173
+ @signal_traps = {}
174
+ end
175
+
176
+ def environment
177
+ ::DAEMON_ENV
178
+ end
179
+
180
+ # The path to the current environment's file (<tt>development.rb</tt>, etc.). By
181
+ # default the file is at <tt>config/environments/#{environment}.rb</tt>.
182
+ def environment_path
183
+ "#{root_path}/config/environments/#{environment}.rb"
184
+ end
185
+
186
+ def daemon_initializer
187
+ "#{root_path}/config/initializers/#{self.daemon_name}.rb"
188
+ end
189
+
190
+ # Add a trap for the specified signal, can be code block or a proc
191
+ def trap( signal, proc = nil, &block )
192
+ return if proc.nil? && !block_given?
193
+
194
+ unless @signal_traps.has_key?( signal )
195
+ set_trap( signal )
196
+ end
197
+
198
+ @signal_traps[signal].unshift( proc || block )
199
+ end
200
+
201
+ protected
202
+
203
+ def run_traps( signal )
204
+ DaemonKit.logger.info "Running signal traps for #{signal}"
205
+ self.signal_traps[ signal ].each { |trap| trap.call }
206
+ end
207
+
208
+ private
209
+
210
+ def set_trap( signal )
211
+ DaemonKit.logger.info "Setting up trap for #{signal}"
212
+ @signal_traps[ signal ] = []
213
+ Signal.trap( signal, Proc.new { self.run_traps( signal ) } )
214
+ end
215
+
216
+ def set_root_path!
217
+ raise "DAEMON_ROOT is not set" unless defined?(::DAEMON_ROOT)
218
+ raise "DAEMON_ROOT is not a directory" unless defined?(::DAEMON_ROOT)
219
+
220
+ @root_path =
221
+ # Pathname is incompatible with Windows, but Windows doesn't have
222
+ # real symlinks so File.expand_path is safe.
223
+ if RUBY_PLATFORM =~ /(:?mswin|mingw)/
224
+ File.expand_path(::DAEMON_ROOT)
225
+
226
+ # Otherwise use Pathname#realpath which respects symlinks.
227
+ else
228
+ Pathname.new(::DAEMON_ROOT).realpath.to_s
229
+ end
230
+
231
+ Object.const_set(:RELATIVE_DAEMON_ROOT, ::DAEMON_ROOT.dup) unless defined?(::RELATIVE_DAEMON_ROOT)
232
+ ::DAEMON_ROOT.replace @root_path
233
+ end
234
+
235
+ def default_load_paths
236
+ [ 'lib' ]
237
+ end
238
+
239
+ def default_log_path
240
+ File.join(root_path, 'log', "#{environment}.log")
241
+ end
242
+
243
+ def default_log_level
244
+ environment == 'production' ? Logger::INFO : Logger::DEBUG
245
+ end
246
+ end
247
+
248
+
249
+ end
@@ -0,0 +1,172 @@
1
+ require 'yaml'
2
+
3
+ module DaemonKit
4
+ # Thin wrapper around xmpp4r-simple, specifically designed to ease
5
+ # configuration of a jabber daemon and provide some added simplicity.
6
+ class Jabber
7
+
8
+ # Jabber connection
9
+ attr_reader :connection
10
+
11
+ @@instance = nil
12
+ @@message_handler = nil
13
+ @@presence_handler = nil
14
+ @@subscription_handler = nil
15
+
16
+ class << self
17
+
18
+ # Deliver a message to the specified jid.
19
+ def deliver( jid, message )
20
+ instance.connection.deliver( jid, message )
21
+ end
22
+
23
+ # Use this instead of initializing, keeps it singleton
24
+ def instance
25
+ @instance ||= (
26
+ config = YAML.load_file( "#{DAEMON_ROOT}/config/jabber.yml" )[DAEMON_ENV]
27
+ raise ArgumentError, "Missing Jabber configuration for #{DAEMON_ENV} environment" if config.nil?
28
+ new( config )
29
+ )
30
+ @instance.startup!
31
+ end
32
+ private :new
33
+
34
+ def run
35
+ DaemonKit.logger.info "Starting jabber loop"
36
+
37
+ loop do
38
+ process_messages
39
+ process_updates
40
+ process_subscriptions
41
+
42
+ begin
43
+ sleep 1
44
+ rescue Interrupt
45
+ DaemonKit.logger.warn "Jabber loop interrupted"
46
+ break
47
+ end
48
+ end
49
+ end
50
+
51
+ def process_messages
52
+ @message_handler ||= Proc.new { |m| DaemonKit.logger.info "Received message from #{m.from}: #{m.body}" }
53
+
54
+ instance.valid_messages { |m| @message_handler.call(m) }
55
+ end
56
+
57
+ def process_updates
58
+ @presence_handler ||= Proc.new { |friend, old_presence, new_presence|
59
+ DaemonKit.logger.debug "Received presence update: #{friend} went from #{old_presence} to #{new_presence}"
60
+ }
61
+
62
+ instance.connection.presence_updates { |friend, old_presence, new_presence|
63
+ @presence_handler.call(friend, old_presence, new_presence)
64
+ }
65
+
66
+ end
67
+
68
+ def process_subscriptions
69
+ @subscription_handler ||= Proc.new { |friend,presence| DaemonKit.logger.debug "Received presence update from #{friend}: #{presence}" }
70
+
71
+ instance.connection.subscription_requests { |friend,presence| @subscription_handler.call(friend,presence) }
72
+ end
73
+
74
+ def received_messages(&block)
75
+ @message_handler = block
76
+ end
77
+
78
+ def presence_updates(&block)
79
+ @presence_handler = block
80
+ end
81
+
82
+ def subscription_requests(&block)
83
+ @subscription_handler = block
84
+ end
85
+
86
+ end
87
+
88
+ def initialize( options = {} )
89
+ @jabber_id = options.delete("jabber_id")
90
+ @password = options.delete("password")
91
+ @resource = options.delete("resource") || 'daemon_kit'
92
+ @masters = options.delete("masters") || []
93
+ @supporters = options.delete("supporters") || []
94
+
95
+ raise ArgumentError if [ @jabber_id, @password ].any? { |a| a.nil? }
96
+ end
97
+
98
+ def startup!
99
+ return self if @booted
100
+
101
+ connect!
102
+ setup_roster!
103
+
104
+ DaemonKit.trap( 'INT', Proc.new { self.shutdown! } )
105
+ DaemonKit.trap( 'TERM', Proc.new { self.shutdown! } )
106
+
107
+ @booted = true
108
+
109
+ self
110
+ end
111
+
112
+ def shutdown!
113
+ DaemonKit.logger.warn "Disconnecting jabber connection"
114
+ self.connection.disconnect
115
+ end
116
+
117
+ def contacts
118
+ @masters + @supporters
119
+ end
120
+
121
+ def valid_messages(&block)
122
+ self.connection.received_messages.each do |message|
123
+ next unless valid_master?( message.from )
124
+
125
+ busy do
126
+ block.call message
127
+ end
128
+ end
129
+ end
130
+
131
+ def valid_master?( jid )
132
+ @masters.include?( jid.strip.to_s )
133
+ end
134
+
135
+ def busy(&block)
136
+ self.connection.status(:dnd, "Working...")
137
+ yield
138
+ self.connection.status(:chat, self.status_line )
139
+ end
140
+
141
+ def status_line
142
+ "#{DaemonKit.configuration.daemon_name} ready for instructions"
143
+ end
144
+
145
+ private
146
+
147
+ def connect!
148
+ jid = @jabber_id + '/' + @resource
149
+
150
+ @connection = ::Jabber::Simple.new( jid, @password, nil, self.status_line )
151
+ end
152
+
153
+ def setup_roster!
154
+ # cleanup the roster
155
+ self.connection.roster.items.each_pair do |jid, roster_item|
156
+ jid = jid.strip.to_s
157
+ unless self.contacts.include?( jid )
158
+ self.connection.remove( jid )
159
+ end
160
+ end
161
+
162
+ # add missing contacts
163
+ self.contacts.each do |jid|
164
+ unless self.connection.subscribed_to?( jid )
165
+ self.connection.add( jid )
166
+ #self.connection.accept_subscription( jid )
167
+ end
168
+ end
169
+ end
170
+
171
+ end
172
+ end
@@ -0,0 +1,120 @@
1
+ # Shamelessly taken from http://blog.rapleaf.com/dev/?p=19
2
+
3
+ require 'rubygems'
4
+ require 'daemons'
5
+ require 'timeout'
6
+
7
+ module Daemons
8
+
9
+ class ApplicationGroup
10
+
11
+ # We want to redefine find_applications to not rely on
12
+ # pidfiles (e.g. find application if pidfile is gone)
13
+ # We recreate the pid files if they're not there.
14
+ def find_applications(dir)
15
+ # Find pid_files, like original implementation
16
+ pid_files = PidFile.find_files(dir, app_name)
17
+ @monitor = Monitor.find(dir, app_name + '_monitor')
18
+ pid_files.reject! {|f| f =~ /_monitor.pid$/}
19
+
20
+ # Find the missing pids based on the UNIX pids
21
+ pidfile_pids = pid_files.map {|pf| PidFile.existing(pf).pid}
22
+ missing_pids = unix_pids - pidfile_pids
23
+
24
+ # Create pidfiles that are gone
25
+ if missing_pids.size > 0
26
+ puts "[daemons_ext]: #{missing_pids.size} missing pidfiles: " +
27
+ "#{missing_pids.inspect}... creating pid file(s)."
28
+ missing_pids.each do |pid|
29
+ pidfile = PidFile.new(dir, app_name, multiple)
30
+ pidfile.pid = pid # Doesn't seem to matter if it's a string or Fixnum
31
+ end
32
+ end
33
+
34
+ # Now get all the pid file again
35
+ pid_files = PidFile.find_files(dir, app_name)
36
+
37
+ return pid_files.map {|f|
38
+ app = Application.new(self, {}, PidFile.existing(f))
39
+ setup_app(app)
40
+ app
41
+ }
42
+ end
43
+
44
+ # Specify :force_kill_wait => (seconds to wait) and this method will
45
+ # block until the process is dead. It first sends a TERM signal, then
46
+ # a KILL signal (-9) if the process hasn't died after the wait time.
47
+ def stop_all(force = false)
48
+ @monitor.stop if @monitor
49
+
50
+ wait = options[:force_kill_wait].to_i
51
+ if wait > 0
52
+ puts "[daemons_ext]: Killing #{app_name} with force after #{wait} secs."
53
+
54
+ # Send term first, don't delete PID files.
55
+ @applications.each {|a| a.send_sig('TERM')}
56
+
57
+ begin
58
+ started_at = Time.now
59
+ Timeout::timeout(wait) do
60
+ num_pids = unix_pids.size
61
+ while num_pids > 0
62
+ time_left = wait - (Time.now - started_at)
63
+ puts "[daemons_ext]: Waiting #{time_left.round} secs on " +
64
+ "#{num_pids} #{app_name}(s)..."
65
+ sleep 1
66
+ num_pids = unix_pids.size
67
+ end
68
+ end
69
+ rescue Timeout::Error
70
+ @applications.each {|a| a.send_sig('KILL')}
71
+ ensure
72
+ # Delete Pidfiles
73
+ @applications.each {|a| a.zap!}
74
+ end
75
+
76
+ puts "[daemons_ext]: All #{app_name}(s) dead."
77
+ else
78
+ @applications.each {|a|
79
+ if force
80
+ begin; a.stop; rescue ::Exception; end
81
+ else
82
+ a.stop
83
+ end
84
+ }
85
+ end
86
+ end
87
+
88
+ private
89
+
90
+ # Find UNIX pids based on app_name. CAUTION: This has only been tested on
91
+ # Mac OS X and CentOS.
92
+ def unix_pids
93
+ pids = []
94
+ x = `ps auxw | grep -v grep | awk '{print $2, $11}' | grep #{app_name}`
95
+ if x && x.chomp!
96
+ processes = x.split(/\n/).compact
97
+ processes = processes.delete_if do |p|
98
+ pid, name = p.split(/\s/)
99
+ # We want to make sure that the first part of the process name matches
100
+ # so that app_name matches app_name_22
101
+ app_name != name[0..(app_name.length - 1)]
102
+ end
103
+ pids = processes.map {|p| p.split(/\s/)[0].to_i}
104
+ end
105
+
106
+ pids
107
+ end
108
+
109
+ end
110
+
111
+ class Application
112
+
113
+ # Send signal to the process, rescue if process deson't exist
114
+ def send_sig(sig)
115
+ Process.kill(sig, @pid.pid) rescue Errno::ESRCH
116
+ end
117
+
118
+ end
119
+
120
+ end
@@ -0,0 +1,75 @@
1
+ namespace :daemon_kit do
2
+ namespace :freeze do
3
+ desc "Lock this application to the current gem (by unpacking it into vendor/daemon_kit)"
4
+ task :gems do
5
+ deps = %w()
6
+ require 'rubygems'
7
+ require 'rubygems/gem_runner'
8
+
9
+ kit = (version = ENV['VERSION']) ?
10
+ Gem.cache.find_name('daemon-kit', "= #{version}").first :
11
+ Gem.cache.find_name('daemon-kit').sort_by { |g| g.version }.last
12
+
13
+ version ||= kit.version
14
+
15
+ unless kit
16
+ puts "No daemon_kit gem #{version} is installed. Do 'gem list daemon_kit' to see what you have available."
17
+ exit
18
+ end
19
+
20
+ puts "Freezing the gem for DaemonKit #{kit.version}"
21
+ rm_rf "vendor/daemon_kit"
22
+ mkdir_p "vendor/daemon_kit"
23
+
24
+ begin
25
+ chdir("vendor/daemon_kit") do
26
+ kit.dependencies.select { |g| deps.include? g.name }.each do |g|
27
+ Gem::GemRunner.new.run(["unpack", g.name, "--version", g.version_requirements.to_s])
28
+ mv(Dir.glob("#{g.name}*").first, g.name)
29
+ end
30
+
31
+ Gem::GemRunner.new.run(["unpack", "daemon-kit", "--version", "=#{version}"])
32
+ FileUtils.mv(Dir.glob("daemon-kit*").first, "daemon-kit")
33
+ end
34
+ rescue Exception
35
+ rm_rf "vendor/daemon_kit"
36
+ raise
37
+ end
38
+ end
39
+
40
+ desc 'Lock to latest edge daemon_kit'
41
+ task :edge do
42
+ require 'open-uri'
43
+ #version = ENV["RELEASE"] || "edge"
44
+ commits = "http://github.com/api/v1/yaml/kennethkalmer/daemon-kit/commits/master"
45
+ url = "http://github.com/kennethkalmer/daemon-kit/zipball/master"
46
+
47
+ rm_rf "vendor/daemon_kit"
48
+ mkdir_p "vendor/daemon_kit"
49
+
50
+ chdir 'vendor/daemon_kit' do
51
+ latest_revision = YAML.load(open(commits))["commits"].first["id"]
52
+
53
+ puts "Downloading DaemonKit from #{url}"
54
+ File.open('daemon-kit.zip', 'wb') do |dst|
55
+ open url do |src|
56
+ while chunk = src.read(4096)
57
+ dst << chunk
58
+ end
59
+ end
60
+ end
61
+
62
+ puts 'Unpacking DaemonKit'
63
+ rm_rf 'daemon-kit'
64
+ `unzip daemon-kit.zip`
65
+ FileUtils.mv(Dir.glob("kennethkalmer-daemon-kit*").first, "daemon-kit")
66
+ %w(daemon-kit.zip).each do |goner|
67
+ rm_f goner
68
+ end
69
+
70
+ touch "REVISION_#{latest_revision}"
71
+ end
72
+ end
73
+
74
+ end
75
+ end
@@ -0,0 +1,2 @@
1
+ # Load all the take tasks in the gem
2
+ Dir[File.join(File.dirname(__FILE__), '**/*.rake')].each { |rake| load rake }
data/lib/daemon_kit.rb ADDED
@@ -0,0 +1,11 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ require 'rubygems'
5
+
6
+ require 'daemon_kit/initializer'
7
+ require 'daemon_kit/application'
8
+
9
+ module DaemonKit
10
+ VERSION = '0.1.0.2'
11
+ end
@@ -0,0 +1,5 @@
1
+ Description:
2
+
3
+
4
+ Usage:
5
+