pidly 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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