daemons 1.2.4 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 860b58ef469300cda2269a45f189796af8f36bcb
4
- data.tar.gz: 29894094754c8013a9901f918f9e9ca2d700258f
2
+ SHA256:
3
+ metadata.gz: 5114c4c5cb5dba3befcc82f6eaa45d901036bc7357a6d4d81cfd8cad8c49dae6
4
+ data.tar.gz: 0eb7b12972a659d053b87d4d59e24d5a3de21a9ff94c3432e8da62ac08f5c127
5
5
  SHA512:
6
- metadata.gz: cd7e03dbc97d7dcaa21b582b868cea9b5610e52b975737b8c8309ce71f803647d3a87444e04a79b63feb2da895b0ee5ab8624985540c4a5dfba0be916f23d55a
7
- data.tar.gz: c42a97021220ffbbe114349c8fe2ebeff0894b265cd4c2a960cf9efbdce5b0bcf873d92dd393b54fdde336b4d53c8ea4c53d827f567d0313829fd0f4f23c7cdb
6
+ metadata.gz: '00970b9deb9eab30e1ce69b31ceca7617bf406692f5dbbb5a9459c5a5a898bc8a0e751fb751cb463f027be1977b54c0b914fcee996ad0cbea997829ce54d2360'
7
+ data.tar.gz: f98f5696a4f482e29eb22c38fddc9fa6dafcfaaa4c6989a5015191c53711848e703267dc3c0da25080d9509035bf91b7aac7f009b4ccbb6de53fd8a299a4834b
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2005-2016 Thomas Uehlinger, 2014-2016 Aaron Stone
1
+ Copyright (c) 2005-2021 Thomas Uehlinger, 2014-2016 Aaron Stone
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person
4
4
  obtaining a copy of this software and associated documentation
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  Ruby Daemons
2
2
  ============
3
- [![Code Climate](https://codeclimate.com/github/acuppy/daemons/badges/gpa.svg)](https://codeclimate.com/github/acuppy/daemons)[![Test Coverage](https://circleci.com/gh/acuppy/daemons.svg?style=shield&circle-token=a4f96fd41f7682661d6543e30207427ac8870c0d)](https://circleci.com/gh/acuppy/daemons)
3
+ [![Build Status](https://travis-ci.org/thuehlinger/daemons.svg?branch=master)](https://travis-ci.org/thuehlinger/daemons)[![Code Climate](https://codeclimate.com/github/acuppy/daemons/badges/gpa.svg)](https://codeclimate.com/github/acuppy/daemons)[![Test Coverage](https://circleci.com/gh/acuppy/daemons.svg?style=shield&circle-token=a4f96fd41f7682661d6543e30207427ac8870c0d)](https://circleci.com/gh/acuppy/daemons)
4
4
 
5
5
  Daemons provides an easy way to wrap existing ruby scripts (for example a self-written server)
6
6
  to be _run as a daemon_ and to be _controlled by simple start/stop/restart commands_.
@@ -201,7 +201,12 @@ end
201
201
  Daemons.run('myserver.rb', { show_status_callback: :custom_show_status })
202
202
  ```
203
203
 
204
+ Documentation
205
+ -------------------
206
+
207
+ Documentation can be found at http://www.rubydoc.info/gems/daemons.
208
+
204
209
  Author
205
210
  ------
206
211
 
207
- Written 2005-2016 by Thomas Uehlinger, 2014-2016 by Aaron Stone.
212
+ Written 2005-2021 by Thomas Uehlinger, 2014-2016 by Aaron Stone.
data/Releases CHANGED
@@ -1,5 +1,30 @@
1
1
  = Daemons Release History
2
2
 
3
+ == Release 1.4.0: May 1, 2021
4
+
5
+ * Allow for customization which signals are sent to stop process (thanks to philister)
6
+ * Resolves mismatched indentations (thanks to Luis M Rodriguez)
7
+ * Allow to use pry-byebug 3.8.0 (thanks to kamipo)
8
+
9
+ == Release 1.3.1: December 14, 2018
10
+
11
+ * Fix undefined local variable or method `pid_delimiter'
12
+
13
+ == Release 1.3.0: December 10, 2018
14
+
15
+ * Make logging more configurable.
16
+ * Add configuration options for pid file delimters, force_kill_waittime
17
+ * All status callback to be anything callable.
18
+
19
+ == Release 1.2.6: December 24, 2017
20
+
21
+ * Add links to rubydoc.info documentation.
22
+
23
+ == Release 1.2.5: October 22, 2017
24
+
25
+ * In Application#stop, call zap, not cleanup on the pidfile (thanks to wevanscfi)
26
+ * Use File.expand_path on and output and log files (thanks to Dave Harris)
27
+
3
28
  == Release 1.2.4: August 1, 2016
4
29
 
5
30
  * add :shush option
data/lib/daemons.rb CHANGED
@@ -99,6 +99,7 @@ module Daemons
99
99
  # <tt>:dir</tt>:: Used in combination with <tt>:dir_mode</tt> (description above)
100
100
  # <tt>:multiple</tt>:: Specifies whether multiple instances of the same script are allowed to run at the
101
101
  # same time
102
+ # <tt>:pid_delimiter</tt>:: Specifies the separator used when enumerating multiple process names/pid-files. Default is '_num'.
102
103
  # <tt>:ontop</tt>:: When given (i.e. set to true), stay on top, i.e. do not daemonize the application
103
104
  # (but the pid-file and other things are written as usual)
104
105
  # <tt>:shush</tt>:: When given (i.e. set to true), turn on silent mode (no output to the terminal)
@@ -129,6 +130,7 @@ module Daemons
129
130
  # :dir_mode => :script,
130
131
  # :dir => 'pids',
131
132
  # :multiple => true,
133
+ # :pid_delimiter => '.n',
132
134
  # :ontop => true,
133
135
  # :shush => false,
134
136
  # :mode => :exec,
@@ -238,23 +240,26 @@ module Daemons
238
240
  # end
239
241
  #
240
242
  def call(options = {}, &block)
241
- unless block_given?
242
- fail 'Daemons.call: no block given'
243
- end
243
+ new_app = Daemons.new(options, &block)
244
+ new_app.start
245
+ new_app
246
+ end
247
+ module_function :call
244
248
 
245
- options[:proc] = block
246
- options[:mode] = :proc
249
+ # Create a new Daemon application, like <tt>Daemons.call</tt>, but will not start it automatically
250
+ def new(options = {}, &block)
251
+ fail 'Daemons.call: no block given' unless block_given?
247
252
 
248
253
  options[:app_name] ||= 'proc'
254
+ options[:proc] = Proc.new
255
+ options[:mode] = :proc
256
+ options[:dir_mode] = :normal
249
257
 
250
258
  @group ||= ApplicationGroup.new(options[:app_name], options)
251
259
 
252
- new_app = @group.new_application(options)
253
- new_app.start
254
-
255
- new_app
260
+ @group.new_application(options)
256
261
  end
257
- module_function :call
262
+ module_function :new
258
263
 
259
264
  # Daemonize the currently runnig process, i.e. the calling process will become a daemon.
260
265
  #
@@ -28,10 +28,16 @@ module Daemons
28
28
  @options = group.options.dup
29
29
  @options.update(add_options)
30
30
 
31
+ ['dir', 'log_dir', 'logfilename', 'output_logfilename'].each do |k|
32
+ @options[k] = File.expand_path(@options[k]) if @options.key?(k)
33
+ end
34
+
31
35
  @dir_mode = @dir = @script = nil
32
36
 
33
37
  @force_kill_waittime = @options[:force_kill_waittime] || 20
34
38
 
39
+ @signals_and_waits = parse_signals_and_waits(@options[:signals_and_waits])
40
+
35
41
  @show_status_callback = method(:default_show_status)
36
42
 
37
43
  @report = Reporter.new(@options)
@@ -40,7 +46,7 @@ module Daemons
40
46
  if @options[:no_pidfiles]
41
47
  @pid = PidMem.new
42
48
  elsif dir = pidfile_dir
43
- @pid = PidFile.new(dir, @group.app_name, @group.multiple)
49
+ @pid = PidFile.new(dir, @group.app_name, @group.multiple, @options[:pid_delimiter])
44
50
  else
45
51
  @pid = PidMem.new
46
52
  end
@@ -48,7 +54,12 @@ module Daemons
48
54
  end
49
55
 
50
56
  def show_status_callback=(function)
51
- @show_status_callback = method(function)
57
+ @show_status_callback =
58
+ if function.respond_to?(:call)
59
+ function
60
+ else
61
+ method(function)
62
+ end
52
63
  end
53
64
 
54
65
  def change_privilege
@@ -194,7 +205,7 @@ module Daemons
194
205
  if $daemons_stop_proc
195
206
  $daemons_stop_proc.call
196
207
  end
197
- rescue ::Exception
208
+ rescue ::Exception
198
209
  end
199
210
 
200
211
  begin; @pid.cleanup; rescue ::Exception; end
@@ -251,7 +262,7 @@ module Daemons
251
262
  if $daemons_stop_proc
252
263
  $daemons_stop_proc.call
253
264
  end
254
- rescue ::Exception
265
+ rescue ::Exception
255
266
  end
256
267
 
257
268
  begin; @pid.cleanup; rescue ::Exception; end
@@ -364,6 +375,7 @@ module Daemons
364
375
  return
365
376
  end
366
377
 
378
+ # confusing: pid is also a attribute_reader
367
379
  pid = @pid.pid
368
380
 
369
381
  # Catch errors when trying to kill a process that doesn't
@@ -371,55 +383,43 @@ module Daemons
371
383
  # restarted by the monitor yet. By catching the error, we allow the
372
384
  # pid file clean-up to occur.
373
385
  begin
374
- Process.kill(SIGNAL, pid)
386
+ wait_and_retry_kill_harder(pid, @signals_and_waits, no_wait)
375
387
  rescue Errno::ESRCH => e
376
388
  @report.output_message("#{e} #{pid}")
377
389
  @report.output_message('deleting pid-file.')
378
390
  end
379
391
 
380
- unless no_wait
381
- if @force_kill_waittime > 0
382
- @report.stopping_process(group.app_name, pid)
383
- $stdout.flush
384
-
385
- begin
386
- Timeout.timeout(@force_kill_waittime, TimeoutError) do
387
- while Pid.running?(pid)
388
- sleep(0.2)
389
- end
390
- end
391
- rescue TimeoutError
392
- @report.forcefully_stopping_process(group.app_name, pid)
393
- $stdout.flush
394
-
395
- begin
396
- Process.kill('KILL', pid)
397
- rescue Errno::ESRCH
398
- end
399
-
400
- begin
401
- Timeout.timeout(20, TimeoutError) do
402
- while Pid.running?(pid)
403
- sleep(1)
404
- end
405
- end
406
- rescue TimeoutError
407
- @report.cannot_stop_process(group.app_name, pid)
408
- $stdout.flush
409
- end
410
- end
411
- end
412
-
413
- end
414
-
415
392
  sleep(0.1)
416
393
  unless Pid.running?(pid)
417
394
  # We try to remove the pid-files by ourselves, in case the application
418
395
  # didn't clean it up.
419
- begin; @pid.cleanup; rescue ::Exception; end
396
+ zap!
420
397
 
421
398
  @report.stopped_process(group.app_name, pid)
422
- $stdout.flush
399
+ end
400
+ end
401
+
402
+ # @param Hash remaing_signals
403
+ # @param Boolean no_wait Send first Signal and return
404
+ def wait_and_retry_kill_harder(pid, remaining_signals, no_wait = false)
405
+ sig_wait = remaining_signals.shift
406
+ sig = sig_wait[:sig]
407
+ wait = sig_wait[:wait]
408
+ Process.kill(sig, pid)
409
+ return if no_wait || !wait.positive?
410
+
411
+ @report.stopping_process(group.app_name, pid, sig, wait)
412
+
413
+ begin
414
+ Timeout.timeout(wait, TimeoutError) do
415
+ sleep(0.2) while Pid.running?(pid)
416
+ end
417
+ rescue TimeoutError
418
+ if remaining_signals.any?
419
+ wait_and_retry_kill_harder(pid, remaining_signals)
420
+ else
421
+ @report.cannot_stop_process(group.app_name, pid)
422
+ end
423
423
  end
424
424
  end
425
425
 
@@ -469,5 +469,15 @@ module Daemons
469
469
  def dir
470
470
  @dir or group.dir
471
471
  end
472
+
473
+ def parse_signals_and_waits(argv)
474
+ unless argv
475
+ return [
476
+ { sig: 'TERM', wait: @force_kill_waittime },
477
+ { sig: 'KILL', wait: 20 }
478
+ ]
479
+ end
480
+ argv.split('|').collect{ |part| splitted = part.split(':'); {sig: splitted[0], wait: splitted[1].to_i}}
481
+ end
472
482
  end
473
483
  end
@@ -23,19 +23,25 @@ module Daemons
23
23
  @app_name = app_name
24
24
  @options = options
25
25
 
26
- if options[:script]
27
- @script = File.expand_path(options[:script])
26
+ if @options[:script]
27
+ @script = File.expand_path(@options[:script])
28
28
  end
29
29
 
30
30
  @monitor = nil
31
31
 
32
- @multiple = options[:multiple] || false
32
+ @multiple = @options[:multiple] || false
33
33
 
34
- @dir_mode = options[:dir_mode] || :script
35
- @dir = options[:dir] || ''
34
+ @dir_mode = @options[:dir_mode] || :script
35
+ ['dir'].each do |k|
36
+ @options[k] = File.expand_path(@options[k]) if @options.key?(k)
37
+ end
38
+ @dir = @options[:dir] || ''
39
+
40
+ @keep_pid_files = @options[:keep_pid_files] || false
41
+
42
+ @no_pidfiles = @options[:no_pidfiles] || false
36
43
 
37
- @keep_pid_files = options[:keep_pid_files] || false
38
- @no_pidfiles = options[:no_pidfiles] || false
44
+ @pid_delimiter = @options[:pid_delimiter]
39
45
 
40
46
  @applications = []
41
47
  end
@@ -77,7 +83,7 @@ module Daemons
77
83
  end
78
84
  pids = processes.map { |p| p.split(/\s/)[0].to_i }
79
85
  end
80
- rescue ::Exception
86
+ rescue ::Exception
81
87
  end
82
88
 
83
89
  pids.map do |f|
@@ -91,7 +97,7 @@ module Daemons
91
97
  @monitor = Monitor.find(dir, app_name + '_monitor')
92
98
 
93
99
  reporter = Reporter.new(options)
94
- pid_files = PidFile.find_files(dir, app_name, ! @keep_pid_files) do |pid, file|
100
+ pid_files = PidFile.find_files(dir, app_name, ! @keep_pid_files, @pid_delimiter) do |pid, file|
95
101
  reporter.deleted_found_pidfile(pid, file)
96
102
  end
97
103
 
@@ -12,7 +12,7 @@ module Daemons
12
12
  opts.on('-t', '--ontop', 'Stay on top (does not daemonize)') do |t|
13
13
  @options[:ontop] = t
14
14
  end
15
-
15
+
16
16
  opts.on('-s', '--shush', 'Silent mode (no output to the terminal)') do |t|
17
17
  @options[:shush] = t
18
18
  end
@@ -25,9 +25,40 @@ module Daemons
25
25
  @options[:no_wait] = t
26
26
  end
27
27
 
28
+ opts.on('-w', '--force_kill_waittime SECONDS', Integer, 'Maximum time to wait for processes to stop before force-killing') do |t|
29
+ @options[:force_kill_waittime] = t
30
+ end
31
+ opts.on('--signals_and_waits STRING', String, 'which signal to use to stop and how long to wait e.g. TERM:20|KILL:20') do |t|
32
+ @options[:signals_and_waits] = t
33
+ end
34
+
35
+ opts.on('--pid_delimiter STRING', 'Text used to separate process number in full process name and pid-file name') do |value|
36
+ @options[:pid_delimiter] = value
37
+ end
38
+
28
39
  opts.separator ''
29
40
  opts.separator 'Common options:'
30
41
 
42
+ opts.on('-l', '--log_output', 'Enable input/output stream redirection') do |value|
43
+ @options[:log_output] = value
44
+ end
45
+
46
+ opts.on('--logfilename FILE', String, 'Custom log file name for exceptions') do |value|
47
+ @options[:logfilename] = value
48
+ end
49
+
50
+ opts.on('--output_logfilename FILE', String, 'Custom file name for input/output stream redirection log') do |value|
51
+ @options[:output_logfilename] = value
52
+ end
53
+
54
+ opts.on('--log_dir DIR', String, 'Directory for log files') do |value|
55
+ @options[:log_dir] = value
56
+ end
57
+
58
+ opts.on('--syslog', 'Enable output redirction into SYSLOG instead of a file') do |value|
59
+ @options[:log_output_syslog] = value
60
+ end
61
+
31
62
  # No argument, shows at tail. This will print an options summary
32
63
  opts.on_tail('-h', '--help', 'Show this message') do
33
64
  controller.print_usage
@@ -62,7 +93,7 @@ END
62
93
  def parse(args)
63
94
  # The options specified on the command line will be collected in *options*.
64
95
  # We set default values here.
65
-
96
+
66
97
  @opts.parse(args)
67
98
 
68
99
  @options
@@ -71,20 +102,21 @@ END
71
102
 
72
103
  class Controller
73
104
  def print_usage
74
- puts "Usage: #{@app_name} <command> <options> -- <application options>"
75
- puts
76
- puts '* where <command> is one of:'
77
- puts ' start start an instance of the application'
78
- puts ' stop stop all instances of the application'
79
- puts ' restart stop all instances and restart them afterwards'
80
- puts ' reload send a SIGHUP to all instances of the application'
81
- puts ' run start the application and stay on top'
82
- puts ' zap set the application to a stopped state'
83
- puts ' status show status (PID) of application instances'
84
- puts
85
- puts '* and where <options> may contain several of the following:'
86
-
87
- puts @optparse.usage
105
+ puts <<-USAGE.gsub(/^ {6}/, '')
106
+ Usage: #{@app_name} <command> <options> -- <application options>
107
+
108
+ * where <command> is one of:
109
+ start start an instance of the application
110
+ stop stop all instances of the application
111
+ restart stop all instances and restart them afterwards
112
+ reload send a SIGHUP to all instances of the application
113
+ run run the application in the foreground (same as start -t)
114
+ zap set the application to a stopped state
115
+ status show status (PID) of application instances
116
+
117
+ * and where <options> may contain several of the following:
118
+ #{@optparse.usage}
119
+ USAGE
88
120
  end
89
121
 
90
122
  def catch_exceptions(&block)
@@ -61,7 +61,7 @@ module Daemons
61
61
  @group.stop_all(@options[:no_wait])
62
62
  when 'restart'
63
63
  unless @group.applications.empty?
64
- @group.stop_all
64
+ @group.stop_all(@options[:no_wait])
65
65
  sleep(1)
66
66
  @group.start_all
67
67
  else
@@ -107,7 +107,7 @@ module Daemons
107
107
  end
108
108
  rescue ::Exception => e
109
109
  $stderr.puts "exception while trying to stop monitor process #{pid}: #{e}"
110
- $stderr.puts 'deleting pid-file.'
110
+ $stderr.puts "deleting pid-file."
111
111
  end
112
112
 
113
113
  # We try to remove the pid-files by ourselves, in case the monitor
@@ -13,8 +13,8 @@ module Daemons
13
13
  # === How does a Pid-File look like?
14
14
  #
15
15
  # Pid-Files generated by Daemons have to following format:
16
- # <scriptname>.rb<number>.pid
17
- # (Note that <tt><number></tt> is omitted if only one instance of the script can
16
+ # <scriptname>_num<number>.pid
17
+ # (Note that <tt>_num<number></tt> is omitted if only one instance of the script can
18
18
  # run at any time)
19
19
  #
20
20
  # Each file just contains one line with the pid as string (for example <tt>6432</tt>).
@@ -28,10 +28,11 @@ module Daemons
28
28
  # 3. in the preconfigured directory <tt>/var/run</tt> (<tt>:system</tt> option for <tt>:dir_mode</tt>)
29
29
  #
30
30
  class PidFile < Pid
31
- attr_reader :dir, :progname, :multiple, :number
31
+ DEFAULT_PID_DELIMITER = '_num'
32
+ attr_reader :dir, :progname, :multiple, :number, :pid_delimiter
32
33
 
33
- def self.find_files(dir, progname, delete = false)
34
- files = Dir[File.join(dir, "#{progname}_num*.pid")]
34
+ def self.find_files(dir, progname, delete = false, pid_delimiter = nil)
35
+ files = Dir[File.join(dir, "#{progname}#{pid_delimiter || DEFAULT_PID_DELIMITER}*.pid")]
35
36
  files = Dir[File.join(dir, "#{progname}.pid")] if files.size == 0
36
37
 
37
38
  files.delete_if { |f| not (File.file?(f) and File.readable?(f)) }
@@ -62,10 +63,11 @@ module Daemons
62
63
  new_instance
63
64
  end
64
65
 
65
- def initialize(dir, progname, multiple = false)
66
+ def initialize(dir, progname, multiple = false, pid_delimiter = nil)
66
67
  @dir = File.expand_path(dir)
67
68
  @progname = progname
68
69
  @multiple = multiple
70
+ @pid_delimiter = pid_delimiter || DEFAULT_PID_DELIMITER
69
71
  @number = nil
70
72
  @number = 0 if multiple
71
73
 
@@ -81,7 +83,8 @@ module Daemons
81
83
  end
82
84
 
83
85
  def filename
84
- File.join(@dir, "#{@progname}#{@number ? '_num' + @number.to_s : '' }.pid")
86
+ suffix = "#{pid_delimiter}#{@number}" if @number
87
+ File.join(@dir, "#{@progname}#{suffix}.pid")
85
88
  end
86
89
 
87
90
  def exist?
@@ -100,9 +103,9 @@ module Daemons
100
103
  end
101
104
 
102
105
  def zap
103
- File.delete(filename)
106
+ File.delete(filename) if exist?
104
107
  end
105
-
108
+
106
109
  def pid
107
110
  begin
108
111
  File.open(filename) do |f|
@@ -32,20 +32,19 @@ module Daemons
32
32
  output_message 'option :backtrace is not supported with :mode => :exec, ignoring'
33
33
  end
34
34
 
35
- def stopping_process(app_name, pid)
36
- output_message "#{app_name}: trying to stop process with pid #{pid}..."
37
- end
38
-
39
- def forcefully_stopping_process(app_name, pid)
40
- output_message "#{app_name}: process with pid #{pid} won't stop, we forcefully kill it..."
35
+ def stopping_process(app_name, pid, sig, wait)
36
+ output_message "#{app_name}: trying to stop process with pid #{pid}#{' forcefully :(' if sig == 'KILL'} sending #{sig} and waiting #{wait}s ..."
37
+ $stdout.flush
41
38
  end
42
39
 
43
40
  def cannot_stop_process(app_name, pid)
44
41
  output_message "#{app_name}: unable to forcefully kill process with pid #{pid}."
42
+ $stdout.flush
45
43
  end
46
44
 
47
45
  def stopped_process(app_name, pid)
48
46
  output_message "#{app_name}: process with pid #{pid} successfully stopped."
47
+ $stdout.flush
49
48
  end
50
49
 
51
50
  def status(app_name, running, pid_exists, pid)
@@ -1,3 +1,3 @@
1
1
  module Daemons
2
- VERSION = '1.2.4'
2
+ VERSION = '1.4.0'
3
3
  end
metadata CHANGED
@@ -1,71 +1,77 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: daemons
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.4
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas Uehlinger
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-01 00:00:00.000000000 Z
11
+ date: 2021-05-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: '12.3'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 12.3.3
20
23
  type: :development
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
- - - ~>
27
+ - - "~>"
25
28
  - !ruby/object:Gem::Version
26
- version: '0'
29
+ version: '12.3'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 12.3.3
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: rspec
29
35
  requirement: !ruby/object:Gem::Requirement
30
36
  requirements:
31
- - - ~>
37
+ - - "~>"
32
38
  - !ruby/object:Gem::Version
33
39
  version: '3.1'
34
40
  type: :development
35
41
  prerelease: false
36
42
  version_requirements: !ruby/object:Gem::Requirement
37
43
  requirements:
38
- - - ~>
44
+ - - "~>"
39
45
  - !ruby/object:Gem::Version
40
46
  version: '3.1'
41
47
  - !ruby/object:Gem::Dependency
42
48
  name: simplecov
43
49
  requirement: !ruby/object:Gem::Requirement
44
50
  requirements:
45
- - - ~>
51
+ - - "~>"
46
52
  - !ruby/object:Gem::Version
47
53
  version: '0'
48
54
  type: :development
49
55
  prerelease: false
50
56
  version_requirements: !ruby/object:Gem::Requirement
51
57
  requirements:
52
- - - ~>
58
+ - - "~>"
53
59
  - !ruby/object:Gem::Version
54
60
  version: '0'
55
61
  - !ruby/object:Gem::Dependency
56
62
  name: pry-byebug
57
63
  requirement: !ruby/object:Gem::Requirement
58
64
  requirements:
59
- - - ~>
65
+ - - "~>"
60
66
  - !ruby/object:Gem::Version
61
- version: '0'
67
+ version: '3.0'
62
68
  type: :development
63
69
  prerelease: false
64
70
  version_requirements: !ruby/object:Gem::Requirement
65
71
  requirements:
66
- - - ~>
72
+ - - "~>"
67
73
  - !ruby/object:Gem::Version
68
- version: '0'
74
+ version: '3.0'
69
75
  description: |2
70
76
  Daemons provides an easy way to wrap existing ruby scripts (for example a
71
77
  self-written server) to be run as a daemon and to be controlled by simple
@@ -130,24 +136,24 @@ files:
130
136
  homepage: https://github.com/thuehlinger/daemons
131
137
  licenses:
132
138
  - MIT
133
- metadata: {}
139
+ metadata:
140
+ documentation_uri: http://www.rubydoc.info/gems/daemons
134
141
  post_install_message:
135
142
  rdoc_options: []
136
143
  require_paths:
137
144
  - lib
138
145
  required_ruby_version: !ruby/object:Gem::Requirement
139
146
  requirements:
140
- - - '>='
147
+ - - ">="
141
148
  - !ruby/object:Gem::Version
142
149
  version: '0'
143
150
  required_rubygems_version: !ruby/object:Gem::Requirement
144
151
  requirements:
145
- - - '>='
152
+ - - ">="
146
153
  - !ruby/object:Gem::Version
147
154
  version: '0'
148
155
  requirements: []
149
- rubyforge_project:
150
- rubygems_version: 2.4.6
156
+ rubygems_version: 3.0.3
151
157
  signing_key:
152
158
  specification_version: 4
153
159
  summary: A toolkit to create and control daemons in different ways