pidly 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ -
2
+ ChangeLog.*
3
+ LICENSE.txt
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --colour --format documentation
@@ -0,0 +1 @@
1
+ --markup rdoc --title "pidly Documentation" --protected
@@ -0,0 +1,4 @@
1
+ === 0.1.0 / 2011-04-04
2
+
3
+ * Initial release:
4
+
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Dustin Willis Webber
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,59 @@
1
+ # pidly
2
+
3
+ * [Homepage][https://github.com/mephux/pidly]
4
+ * [Documentation][http://rubydoc.info/gems/pidly/frames]
5
+
6
+ ## Description
7
+
8
+ Pidly is a very minimalistic daemon library that doesn't make assumptions. Pidly allows you to control the
9
+ daemon without getting in the way with forced verbose output and usage messages.
10
+
11
+ ## Examples
12
+
13
+ require 'pidly'
14
+
15
+ class Test < Pidly::Control
16
+
17
+ before_start do
18
+ "BEFORE START #{@pid}"
19
+ end
20
+
21
+ start :when_daemon_starts
22
+
23
+ stop do
24
+ "Attempting to kill process: #{@pid}"
25
+ end
26
+
27
+ after_stop :test_after_daemon_stops
28
+
29
+ error do
30
+ "SENDING EMAIL | Error Count: #{@error_count}"
31
+ end
32
+
33
+ def when_daemon_starts
34
+ loop do
35
+ print "TEST FROM #{@pid}"
36
+ sleep 2
37
+ end
38
+ end
39
+
40
+ end
41
+
42
+ @daemon = Test.spawn(
43
+ :name => 'Test Daemon',
44
+ :path => '/tmp',
45
+ :verbose => true
46
+ )
47
+
48
+ # @daemon.send ARGV.first
49
+ @daemon.start # stop, status, restart, and kill.
50
+
51
+ ## Install
52
+
53
+ $ gem install pidly
54
+
55
+ ## Copyright
56
+
57
+ Copyright (c) 2011 Dustin Willis Webber
58
+
59
+ See LICENSE.txt for details.
@@ -0,0 +1,38 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ gem 'ore-tasks', '~> 0.4'
6
+ require 'ore/tasks'
7
+
8
+ Ore::Tasks.new
9
+ rescue LoadError => e
10
+ STDERR.puts e.message
11
+ STDERR.puts "Run `gem install ore-tasks` to install 'ore/tasks'."
12
+ end
13
+
14
+ begin
15
+ gem 'rspec', '~> 2.4'
16
+ require 'rspec/core/rake_task'
17
+
18
+ RSpec::Core::RakeTask.new
19
+ rescue LoadError => e
20
+ task :spec do
21
+ abort "Please run `gem install rspec` to install RSpec."
22
+ end
23
+ end
24
+
25
+ task :test => :spec
26
+ task :default => :spec
27
+
28
+ begin
29
+ gem 'yard', '~> 0.6.0'
30
+ require 'yard'
31
+
32
+ YARD::Rake::YardocTask.new
33
+ rescue LoadError => e
34
+ task :yard do
35
+ abort "Please run `gem install yard` to install YARD."
36
+ end
37
+ end
38
+ task :doc => :yard
@@ -0,0 +1,14 @@
1
+ name: pidly
2
+ summary: "A super simple daemon library."
3
+ description:
4
+ "Pidly is a very minimalistic daemon library that doesnt make assumptions. Pidly allows you to control the
5
+ daemon without getting in the way with forced verbose output and usage messages."
6
+ license: MIT
7
+ authors: Dustin Willis Webber
8
+ homepage: https://github.com/mephux/pidly
9
+ has_yard: true
10
+
11
+ development_dependencies:
12
+ ore-tasks: ~> 0.4
13
+ rspec: ~> 2.4
14
+ yard: ~> 0.6.0
@@ -0,0 +1,2 @@
1
+ require 'pidly/control'
2
+ require 'pidly/version'
@@ -0,0 +1,120 @@
1
+ module Pidly
2
+ #
3
+ # Pidly before/after callbacks
4
+ #
5
+ module Callbacks
6
+
7
+ #
8
+ # Before start
9
+ #
10
+ # Right before the daemon is instructed to start the
11
+ # following callback will be invoked and executed.
12
+ #
13
+ # @param [Symbol] callback Method name
14
+ # @yield [] Code to be executed upon callback invocation
15
+ #
16
+ # @example
17
+ # before_start :method_name
18
+ # # OR
19
+ # before_start { puts "#{@pid} is about to start!" }
20
+ #
21
+ def before_start(callback=nil, &block)
22
+ add_callback(:before_start, (callback || block))
23
+ end
24
+
25
+ #
26
+ # Start
27
+ #
28
+ # When the daemon is instructed to start the
29
+ # following callback will be invoked and executed.
30
+ #
31
+ # @param [Symbol] callback Method name
32
+ # @yield [] Code to be executed upon callback invocation
33
+ #
34
+ # @example
35
+ # start :method_name
36
+ # # OR
37
+ # start { puts "Daemon Started!" }
38
+ #
39
+ def start(callback=nil, &block)
40
+ add_callback(:start, (callback || block))
41
+ end
42
+
43
+ #
44
+ # Stop
45
+ #
46
+ # When the daemon is instructed to stop the
47
+ # following callback will be invoked and executed.
48
+ #
49
+ # @param [Symbol] callback Method name
50
+ # @yield [] Code to be executed upon callback invocation
51
+ #
52
+ # @example
53
+ # stop :method_name
54
+ # # OR
55
+ # stop { puts "Attempting to stop #{@name} with pid #{@pid}!" }
56
+ #
57
+ def stop(callback=nil, &block)
58
+ add_callback(:stop, (callback || block))
59
+ end
60
+
61
+ #
62
+ # After stop
63
+ #
64
+ # Right after the daemon is instructed to stop the
65
+ # following callback will be invoked and executed.
66
+ #
67
+ # @param [Symbol] callback Method name
68
+ # @yield [] Code to be executed upon callback invocation
69
+ #
70
+ # @example
71
+ # after_start :method_name
72
+ # # OR
73
+ # after_start { puts "#{@pid} was just killed!" }
74
+ #
75
+ def after_stop(callback=nil, &block)
76
+ add_callback(:after_stop, (callback || block))
77
+ end
78
+
79
+ #
80
+ # Error
81
+ #
82
+ # If the daemon encounters an error or an exception is raised
83
+ # the following callback will be invoked and executed.
84
+ #
85
+ # @param [Symbol] callback Method name
86
+ # @yield [] Code to be executed upon callback invocation
87
+ #
88
+ # @example
89
+ # error :send_error_email
90
+ # # OR
91
+ # error { puts "ZOMG! #{@name} failed!" }
92
+ #
93
+ def error(callback=nil, &block)
94
+ add_callback(:error, (callback || block))
95
+ end
96
+
97
+ #
98
+ # Add callback
99
+ #
100
+ # @param [Symbol] callback Callback method name
101
+ # @param [Symbol, nil] invoke Method to call
102
+ # @yield [] Code to be executed upon callback invocation
103
+ #
104
+ def add_callback(callback, invoke)
105
+ Control.class_variable_set(:"@@#{callback}", invoke)
106
+ end
107
+
108
+ #
109
+ # Extend and include callback methods
110
+ #
111
+ # @param [Class] receiver The calling class
112
+ #
113
+ def self.included(receiver)
114
+ puts receiver.class
115
+ receiver.extend self
116
+ end
117
+
118
+ end # modle Callbacks
119
+
120
+ end # module Pidly
@@ -0,0 +1,331 @@
1
+ require 'fileutils'
2
+ require 'pathname'
3
+
4
+ require 'pidly/callbacks'
5
+ require 'pidly/logger'
6
+
7
+ #
8
+ # Pidly namespace
9
+ #
10
+ module Pidly
11
+
12
+ #
13
+ # Pidly daemon control
14
+ #
15
+ class Control
16
+
17
+ # Include callbacks
18
+ include Pidly::Callbacks
19
+
20
+ # Include logging helpers
21
+ include Pidly::Logger
22
+
23
+ attr_accessor :daemon, :name, :pid_file,
24
+ :log_file, :path, :sync_log, :allow_multiple,
25
+ :verbose, :pid, :timeout, :error_count, :messages
26
+
27
+ #
28
+ # Initialize control object
29
+ #
30
+ # @param [Hash] options The options to create a controller with.
31
+ #
32
+ # @raise [RuntimeError]
33
+ # Raise exception if path does not exist
34
+ #
35
+ # @raise [RuntimeError]
36
+ # Raise exception if path is not readable or writable.
37
+ #
38
+ def initialize(options={})
39
+
40
+ @messages = []
41
+
42
+ @error_count = 0
43
+
44
+ @name = options.fetch(:name)
45
+
46
+ if options.has_key?(:path)
47
+ @path = Pathname.new(options.fetch(:path))
48
+ else
49
+ @path = Pathname.new('/tmp')
50
+ end
51
+
52
+ unless @path.directory?
53
+ raise('Path does not exist or is not a directory.')
54
+ end
55
+
56
+ unless @path.readable? && @path.writable?
57
+ raise('Path must be readable and writable.')
58
+ end
59
+
60
+ if options.has_key?(:pid_file)
61
+ @pid_file = options.fetch(:pid_path)
62
+ else
63
+ @pid_file = File.join(@path.to_s, 'pids', @name + '.pid')
64
+ end
65
+
66
+ if options.has_key?(:log_file)
67
+ @log_file = options.fetch(:log_path)
68
+ else
69
+ @log_file = File.join(@path.to_s, 'logs', @name + '.log')
70
+ end
71
+
72
+ @pid = fetch_pid if File.file?(@pid_file)
73
+
74
+ @sync_log = options.fetch(:sync_log, true)
75
+
76
+ @allow_multiple = options.fetch(:allow_multiple, false)
77
+
78
+ @signal = options.fetch(:signal, "TERM")
79
+
80
+ @timeout = options.fetch(:timeout, 10)
81
+
82
+ @verbosity = options.fetch(:verbose, false)
83
+
84
+ @logger = options.fetch(:logger, true)
85
+ end
86
+
87
+ #
88
+ # Spawn
89
+ #
90
+ # @param [Hash] options The options to create a controller with.
91
+ #
92
+ # @option options [String] :name Daemon name
93
+ #
94
+ # @option options [String] :path Path to create the log/pids directory
95
+ #
96
+ # @option options [String] :pid_file Pid file path
97
+ #
98
+ # @option options [String] :log_file Log file path
99
+ #
100
+ # @option options [true, false] :sync_log Synchronize log files
101
+ #
102
+ # @option options [true, false] :allow_multiple
103
+ # Allow multiple daemons of the same type
104
+ #
105
+ # @option options [true, false] :sync_log Synchronize log files
106
+ #
107
+ # @option options [String] :signal Trap signal
108
+ #
109
+ # @option options [Integer] :timeout Timeout for Process#wait
110
+ #
111
+ # @option options [true, false] :verbose Display daemon messages
112
+ #
113
+ # @option options [true, false] :logger Enable daemon logging
114
+ #
115
+ # @return [Control] Control object
116
+ #
117
+ def self.spawn(options={})
118
+ @daemon = new(options)
119
+ end
120
+
121
+ #
122
+ # Start
123
+ #
124
+ # Validate callbacks and start daemon
125
+ #
126
+ def start
127
+ validate_files_and_paths!
128
+ validate_callbacks!
129
+
130
+ unless @allow_multiple
131
+ if running?
132
+ log(:error, "#{@name} is already running (PID #{@pid})")
133
+ return
134
+ end
135
+ end
136
+
137
+ @pid = fork do
138
+ begin
139
+ Process.setsid
140
+
141
+ open(@pid_file, 'w') do |f|
142
+ f << Process.pid
143
+ @pid = Process.pid
144
+ end
145
+
146
+ execute_callback(:before_start)
147
+
148
+ Dir.chdir @path.to_s
149
+ File.umask 0000
150
+
151
+ if @logger
152
+ log = File.new(@log_file, "a")
153
+ log.sync = @sync_log
154
+
155
+ STDIN.reopen "/dev/null"
156
+ STDOUT.reopen log
157
+ STDERR.reopen STDOUT
158
+ end
159
+
160
+ trap("TERM") do
161
+ stop
162
+ end
163
+
164
+ execute_callback(:start)
165
+
166
+ rescue RuntimeError => message
167
+ STDERR.puts message
168
+ STDERR.puts message.backtrace
169
+
170
+ execute_callback(:error)
171
+ rescue => message
172
+ STDERR.puts message
173
+ STDERR.puts message.backtrace
174
+
175
+ execute_callback(:error)
176
+ end
177
+ end
178
+
179
+ rescue => message
180
+ STDERR.puts message
181
+ STDERR.puts message.backtrace
182
+ execute_callback(:error)
183
+ end
184
+
185
+ #
186
+ # Stop
187
+ #
188
+ # Stop daemon and remove pid file
189
+ #
190
+ def stop
191
+
192
+ if running?
193
+
194
+ Process.kill(@signal, @pid)
195
+ FileUtils.rm(@pid_file)
196
+
197
+ execute_callback(:stop)
198
+
199
+ begin
200
+ Process.wait(@pid)
201
+ rescue Errno::ECHILD
202
+ end
203
+
204
+ @timeout.downto(0) do
205
+ sleep 1
206
+ exit unless running?
207
+ end
208
+
209
+ Process.kill 9, @pid if running?
210
+ execute_callback(:after_stop)
211
+
212
+ else
213
+ FileUtils.rm(@pid_file) if File.exists?(@pid_file)
214
+ log(:info, "PID file not found. Is the daemon started?")
215
+ end
216
+
217
+ rescue Errno::ENOENT
218
+ end
219
+
220
+ #
221
+ # Status
222
+ #
223
+ # Return current daemon status and pid
224
+ #
225
+ # @return [String] Status
226
+ #
227
+ def status
228
+ if running?
229
+ log(:info, "#{@name} is running (PID #{@pid})")
230
+ else
231
+ log(:info, "#{@name} is NOT running")
232
+ end
233
+ end
234
+
235
+ #
236
+ # Restart
237
+ #
238
+ # Restart the daemon
239
+ #
240
+ def restart
241
+ stop; sleep 1 while running?; start
242
+ end
243
+
244
+ #
245
+ # Kill
246
+ #
247
+ # @param [String] remove_pid_file Remove the daemon pid file
248
+ #
249
+ def kill(remove_pid_file=true)
250
+ if running?
251
+ log(:info, "Killing #{@name} (PID #{@pid})")
252
+ Process.kill 9, @pid
253
+ end
254
+
255
+ FileUtils.rm(@pid_file) if remove_pid_file
256
+ rescue Errno::ENOENT
257
+ end
258
+
259
+ #
260
+ # Running?
261
+ #
262
+ # @return [true, false] Return the running status of the daemon.
263
+ #
264
+ def running?
265
+ Process.kill 0, @pid
266
+ true
267
+ rescue Errno::ESRCH
268
+ false
269
+ rescue Errno::EPERM
270
+ true
271
+ rescue
272
+ false
273
+ end
274
+
275
+ def validate_files_and_paths!
276
+ log = Pathname.new(@log_file).dirname
277
+ pid = Pathname.new(@pid_file).dirname
278
+
279
+ unless File.directory?(log)
280
+ FileUtils.mkdir_p(log.to_s)
281
+ end
282
+
283
+ unless File.directory?(pid)
284
+ FileUtils.mkdir_p(pid.to_s)
285
+ end
286
+ end
287
+
288
+ def validate_callbacks!
289
+ unless Control.class_variable_defined?(:"@@start")
290
+ raise('You must define a "start" callback.')
291
+ end
292
+ end
293
+
294
+ def execute_callback(callback_name)
295
+ @error_count += 1 if callback_name == :error
296
+
297
+ if Control.class_variable_defined?(:"@@#{callback_name}")
298
+ callback = Control.class_variable_get(:"@@#{callback_name}")
299
+
300
+ if callback.kind_of?(Symbol)
301
+
302
+ unless self.respond_to?(callback.to_sym)
303
+ raise("Undefined callback method: #{callback}")
304
+ end
305
+
306
+ self.send(callback.to_sym)
307
+
308
+ elsif callback.respond_to?(:call)
309
+
310
+ self.instance_eval(&callback)
311
+
312
+ else
313
+ nil
314
+ end
315
+
316
+ end
317
+
318
+ end
319
+
320
+ def fetch_pid
321
+ IO.read(@pid_file).to_i
322
+ rescue
323
+ nil
324
+ end
325
+
326
+ private :validate_callbacks!, :fetch_pid,
327
+ :validate_files_and_paths!, :execute_callback
328
+
329
+ end # class Control
330
+
331
+ end # module Pidly
@@ -0,0 +1,49 @@
1
+ module Pidly
2
+ #
3
+ # Logger namespace
4
+ #
5
+ module Logger
6
+
7
+ attr_accessor :verbosity
8
+
9
+ #
10
+ # Verbose
11
+ #
12
+ # @return [true, false] Is the logging level verbose?
13
+ #
14
+ def verbose?
15
+ @verbosity
16
+ end
17
+
18
+ #
19
+ # Log
20
+ #
21
+ # @param [String, Symbol] type Log type (info or error)
22
+ # @param [String] message Log message
23
+ #
24
+ # @return [Strign] Log message
25
+ #
26
+ def log(type, message)
27
+ case type.to_sym
28
+ when :info
29
+ msg = message
30
+ when :error
31
+ msg = message
32
+ end
33
+
34
+ @messages << msg
35
+ puts msg if verbose?
36
+ end
37
+
38
+ #
39
+ # Extend and include callback methods
40
+ #
41
+ # @param [Class] receiver The calling class
42
+ #
43
+ def self.included(receiver)
44
+ receiver.extend self
45
+ end
46
+
47
+ end # class Logger
48
+
49
+ end # module Pidly
@@ -0,0 +1,4 @@
1
+ module Pidly
2
+ # pidly version
3
+ VERSION = "0.1.0"
4
+ end
@@ -0,0 +1,15 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ begin
4
+ Ore::Specification.new do |gemspec|
5
+ # custom logic here
6
+ end
7
+ rescue NameError
8
+ begin
9
+ require 'ore/specification'
10
+ retry
11
+ rescue LoadError
12
+ STDERR.puts "The '#{__FILE__}' file requires Ore."
13
+ STDERR.puts "Run `gem install ore-core` to install Ore."
14
+ end
15
+ end
@@ -0,0 +1,65 @@
1
+ require 'spec_helper'
2
+ require 'pidly'
3
+
4
+ describe Control do
5
+
6
+ before(:all) do
7
+ @daemon = Test.spawn(
8
+ :name => 'test',
9
+ :path => '/tmp',
10
+ :verbose => false
11
+ )
12
+ @daemon.kill if @daemon.running?
13
+ @daemon.start
14
+ sleep 1
15
+ end
16
+
17
+ it "should be running" do
18
+ @daemon.running?.should == true
19
+ end
20
+
21
+ it "should have an active status, name and pid" do
22
+ @daemon.status
23
+ reply = "#{@daemon.name} is running (PID #{@daemon.pid})"
24
+ @daemon.messages.last.should == reply
25
+ end
26
+
27
+ it "should have the correct pid path" do
28
+ @daemon.pid_file.should == "/tmp/pids/#{@daemon.name}.pid"
29
+ end
30
+
31
+ it "should have a pid file that exists" do
32
+ File.exists?("/tmp/pids/#{@daemon.name}.pid").should == true
33
+ end
34
+
35
+ it "should have the correct log file" do
36
+ @daemon.log_file.should == "/tmp/logs/#{@daemon.name}.log"
37
+ end
38
+
39
+ it "should have a log file that exists" do
40
+ File.exists?("/tmp/logs/#{@daemon.name}.log").should == true
41
+ end
42
+
43
+ it "should fail when trying to start another daemon" do
44
+ @daemon.start
45
+ reply = "#{@daemon.name} is already running (PID #{@daemon.pid})"
46
+
47
+ @daemon.messages.last.should == reply
48
+ end
49
+
50
+ it "should write to the log file" do
51
+ file = File.open(@daemon.log_file, 'r')
52
+ file.read.should =~ /TEST FROM #{@daemon.pid}/
53
+ end
54
+
55
+ it "should write to the pid file" do
56
+ file = File.open(@daemon.pid_file, 'r')
57
+ file.read.should =~ /#{@daemon.pid}/
58
+ end
59
+
60
+ after(:all) do
61
+ @daemon.kill if @daemon
62
+ FileUtils.rm @daemon.log_file.to_s
63
+ end
64
+
65
+ end
@@ -0,0 +1,8 @@
1
+ require 'spec_helper'
2
+ require 'pidly'
3
+
4
+ describe Pidly do
5
+ it "should have a VERSION constant" do
6
+ subject.const_get('VERSION').should_not be_empty
7
+ end
8
+ end
@@ -0,0 +1,33 @@
1
+ gem 'rspec', '~> 2.4'
2
+ require 'rspec'
3
+
4
+ require 'pp'
5
+ require 'pidly'
6
+ include Pidly
7
+
8
+ class Test < Pidly::Control
9
+
10
+ before_start do
11
+ "BEFORE START #{@pid}"
12
+ end
13
+
14
+ start :when_daemon_starts
15
+
16
+ stop do
17
+ "Attempting to kill process: #{@pid}"
18
+ end
19
+
20
+ after_stop :test_after_daemon_stops
21
+
22
+ error do
23
+ "SENDING EMAIL | Error Count: #{@error_count}"
24
+ end
25
+
26
+ def when_daemon_starts
27
+ loop do
28
+ print "TEST FROM #{@pid}"
29
+ sleep 2
30
+ end
31
+ end
32
+
33
+ end
metadata ADDED
@@ -0,0 +1,108 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pidly
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.1.0
6
+ platform: ruby
7
+ authors:
8
+ - Dustin Willis Webber
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-04-06 00:00:00 -04:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: ore-tasks
18
+ prerelease: false
19
+ requirement: &id001 !ruby/object:Gem::Requirement
20
+ none: false
21
+ requirements:
22
+ - - ~>
23
+ - !ruby/object:Gem::Version
24
+ version: "0.4"
25
+ type: :development
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ prerelease: false
30
+ requirement: &id002 !ruby/object:Gem::Requirement
31
+ none: false
32
+ requirements:
33
+ - - ~>
34
+ - !ruby/object:Gem::Version
35
+ version: "2.4"
36
+ type: :development
37
+ version_requirements: *id002
38
+ - !ruby/object:Gem::Dependency
39
+ name: yard
40
+ prerelease: false
41
+ requirement: &id003 !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ~>
45
+ - !ruby/object:Gem::Version
46
+ version: 0.6.0
47
+ type: :development
48
+ version_requirements: *id003
49
+ description: Pidly is a very minimalistic daemon library that doesnt make assumptions. Pidly allows you to control the daemon without getting in the way with forced verbose output and usage messages.
50
+ email: []
51
+
52
+ executables: []
53
+
54
+ extensions: []
55
+
56
+ extra_rdoc_files:
57
+ - README.md
58
+ - ChangeLog.rdoc
59
+ - LICENSE.txt
60
+ files:
61
+ - .document
62
+ - .rspec
63
+ - .yardopts
64
+ - ChangeLog.rdoc
65
+ - LICENSE.txt
66
+ - README.md
67
+ - Rakefile
68
+ - gemspec.yml
69
+ - lib/pidly.rb
70
+ - lib/pidly/callbacks.rb
71
+ - lib/pidly/control.rb
72
+ - lib/pidly/logger.rb
73
+ - lib/pidly/version.rb
74
+ - pidly.gemspec
75
+ - spec/control_spec.rb
76
+ - spec/pidly_spec.rb
77
+ - spec/spec_helper.rb
78
+ has_rdoc: yard
79
+ homepage: https://github.com/mephux/pidly
80
+ licenses:
81
+ - MIT
82
+ post_install_message:
83
+ rdoc_options: []
84
+
85
+ require_paths:
86
+ - lib
87
+ required_ruby_version: !ruby/object:Gem::Requirement
88
+ none: false
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: "0"
93
+ required_rubygems_version: !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: "0"
99
+ requirements: []
100
+
101
+ rubyforge_project: pidly
102
+ rubygems_version: 1.6.1
103
+ signing_key:
104
+ specification_version: 3
105
+ summary: A super simple daemon library.
106
+ test_files:
107
+ - spec/control_spec.rb
108
+ - spec/pidly_spec.rb