potluck 0.0.5 → 0.0.6

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 67a2b224bd6ed00dcfe15688c0ebaa8764649cc7a201174c20c6238bab45bc27
4
- data.tar.gz: e1fececdb06d683f1879ac8baab15a26ba8bb6db2a15a3ea8e0dd247876435e9
3
+ metadata.gz: 6881b14c35b5ae6be793e8390d8ab87d1b8220ea78a2803dac55f5ea8c2bc4cf
4
+ data.tar.gz: e0c7b0e3a472f03dded30e35e38fbad4f8f484a1d3cb44cd4ced99248cdd298c
5
5
  SHA512:
6
- metadata.gz: 43b41b2bade1a6b87ee0d266a38f0d59b7417e5a652804521952356d7aec8fb9f98c3e2727e903e5b79b91587ff621c557b7be90325e86db303ab66cf5c193d1
7
- data.tar.gz: 6ffedd39746332d83f7c09b3cf3a7a4e40c60503eb88f3083e904347712a60a508199fcb44b8d8949250992e61de160e476654f5acb2f4a1b7ca867e26a13ba8
6
+ metadata.gz: 0ce2edbef44e0f8e27ffb0bb63e717d5f9781f29a27661b72de6bd77b0421f73757a230f5d3193f8e04bbaba8abd9e282d8021af9c4aded66e5e10efd78bb2c7
7
+ data.tar.gz: 5246bb757a883318ed514c8a5a5a94d5631732170c9622d1b20f92541a419fb36b9b559a3a6967ca700d2ba765ec58a323fed3b39fb464f222a9ca9dfc84e77b
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2021 Nate Pickens
1
+ Copyright 2021-2022 Nate Pickens
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
4
4
  documentation files (the "Software"), to deal in the Software without restriction, including without
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.5
1
+ 0.0.6
@@ -24,9 +24,10 @@ module Potluck
24
24
  # * +manage+ - True if the service runs locally and should be managed by this process (default: true if
25
25
  # launchctl is available and false otherwise).
26
26
  #
27
- def initialize(logger: nil, manage: launchctl?)
27
+ def initialize(logger: nil, manage: self.class.launchctl?)
28
28
  @logger = logger
29
29
  @manage = !!manage
30
+ @manage_with_launchctl = false
30
31
 
31
32
  if manage.kind_of?(Hash)
32
33
  @status_command = manage[:status]
@@ -34,7 +35,8 @@ module Potluck
34
35
  @start_command = manage[:start]
35
36
  @stop_command = manage[:stop]
36
37
  elsif manage
37
- ensure_launchctl!
38
+ @manage_with_launchctl = true
39
+ self.class.ensure_launchctl!
38
40
  end
39
41
  end
40
42
 
@@ -46,54 +48,10 @@ module Potluck
46
48
  end
47
49
 
48
50
  ##
49
- # Returns true if launchctl is available.
50
- #
51
- def launchctl?
52
- defined?(@@launchctl) ? @@launchctl : (@@launchctl = `which launchctl 2>&1` && $? == 0)
53
- end
54
-
55
- ##
56
- # Checks if launchctl is available and raises an error if not.
57
- #
58
- def ensure_launchctl!
59
- launchctl? || raise(ServiceError.new("Cannot manage #{self.pretty_name}: launchctl not found"))
60
- end
61
-
62
- ##
63
- # Command to get the status of the service.
64
- #
65
- def status_command
66
- @status_command || "launchctl list 2>&1 | grep #{SERVICE_PREFIX}#{self.class.service_name}"
67
- end
68
-
69
- ##
70
- # Regular expression to check the output of +#status_command+ against to determine if the service is in
71
- # an error state.
72
- #
73
- def status_error_regex
74
- @status_error_regex || LAUNCHCTL_ERROR_REGEX
75
- end
76
-
77
- ##
78
- # Command to start the service.
79
- #
80
- def start_command
81
- @start_command || "launchctl bootstrap gui/#{Process.uid} #{self.class.plist_path}"
82
- end
83
-
84
- ##
85
- # Command to stop the service.
86
- #
87
- def stop_command
88
- @stop_command || "launchctl bootout gui/#{Process.uid}/#{self.class.launchctl_name}"
89
- end
90
-
91
- ##
92
- # Writes the service's launchctl plist file to disk.
51
+ # Returns true if the service is managed via launchctl.
93
52
  #
94
- def ensure_plist
95
- FileUtils.mkdir_p(File.dirname(self.class.plist_path))
96
- File.write(self.class.plist_path, self.class.plist)
53
+ def manage_with_launchctl?
54
+ @manage_with_launchctl
97
55
  end
98
56
 
99
57
  ##
@@ -123,17 +81,16 @@ module Potluck
123
81
  def start
124
82
  return unless manage?
125
83
 
126
- ensure_plist unless @start_command
127
-
128
84
  case status
129
85
  when :error then stop
130
86
  when :active then return
131
87
  end
132
88
 
89
+ self.class.write_plist if manage_with_launchctl?
133
90
  run(start_command)
134
91
  wait { status == :inactive }
135
92
 
136
- raise(ServiceError.new("Could not start #{self.class.pretty_name}")) if status != :active
93
+ raise(ServiceError, "Could not start #{self.class.pretty_name}") if status != :active
137
94
 
138
95
  log("#{self.class.pretty_name} started")
139
96
  end
@@ -144,10 +101,11 @@ module Potluck
144
101
  def stop
145
102
  return unless manage? && status != :inactive
146
103
 
104
+ self.class.write_plist if manage_with_launchctl?
147
105
  run(stop_command)
148
106
  wait { status != :inactive }
149
107
 
150
- raise(ServiceError.new("Could not stop #{self.class.pretty_name}")) if status != :inactive
108
+ raise(ServiceError, "Could not stop #{self.class.pretty_name}") if status != :inactive
151
109
 
152
110
  log("#{self.class.pretty_name} stopped")
153
111
  end
@@ -166,16 +124,16 @@ module Potluck
166
124
  # Runs a command with the default shell. Raises an error if the command exits with a non-zero status.
167
125
  #
168
126
  # * +command+ - Command to run.
169
- # * +redirect_stderr+ - True if stderr should be redirected to stdout; otherwise stderr output will not
127
+ # * +capture_stderr+ - True if stderr should be redirected to stdout; otherwise stderr output will not
170
128
  # be logged (default: true).
171
129
  #
172
- def run(command, redirect_stderr: true)
173
- output = `#{command}#{' 2>&1' if redirect_stderr}`
130
+ def run(command, capture_stderr: true)
131
+ output = `#{command}#{' 2>&1' if capture_stderr}`
174
132
  status = $?
175
133
 
176
134
  if status != 0
177
135
  output.split("\n").each { |line| log(line, :error) }
178
- raise(ServiceError.new("Command exited with status #{status.to_i}: #{command}"))
136
+ raise(ServiceError, "Command exited with status #{status.exitstatus}: #{command}")
179
137
  else
180
138
  output
181
139
  end
@@ -195,24 +153,6 @@ module Potluck
195
153
  end
196
154
  end
197
155
 
198
- private
199
-
200
- ##
201
- # Calls the supplied block repeatedly until it returns false. Checks frequently at first and gradually
202
- # reduces down to one-second intervals.
203
- #
204
- # * +timeout+ - Maximum number of seconds to wait before timing out (default: 30).
205
- # * +block+ - Block to call until it returns false.
206
- #
207
- def wait(timeout = 30, &block)
208
- while block.call && timeout > 0
209
- reduce = [[(30 - timeout.to_i) / 5.0, 0.1].max, 1].min
210
- timeout -= reduce
211
-
212
- sleep(reduce)
213
- end
214
- end
215
-
216
156
  ##
217
157
  # Human-friendly name of the service.
218
158
  #
@@ -244,7 +184,7 @@ module Potluck
244
184
  ##
245
185
  # Content of the launchctl plist file.
246
186
  #
247
- def self.plist(content)
187
+ def self.plist(content = '')
248
188
  <<~EOS
249
189
  <?xml version="1.0" encoding="UTF-8"?>
250
190
  #{'<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.'\
@@ -262,5 +202,74 @@ module Potluck
262
202
  </plist>
263
203
  EOS
264
204
  end
205
+
206
+ ##
207
+ # Writes the service's launchctl plist file to disk.
208
+ #
209
+ def self.write_plist
210
+ FileUtils.mkdir_p(File.dirname(plist_path))
211
+ File.write(plist_path, plist)
212
+ end
213
+
214
+ ##
215
+ # Returns true if launchctl is available.
216
+ #
217
+ def self.launchctl?
218
+ defined?(@@launchctl) ? @@launchctl : (@@launchctl = `which launchctl 2>&1` && $? == 0)
219
+ end
220
+
221
+ ##
222
+ # Checks if launchctl is available and raises an error if not.
223
+ #
224
+ def self.ensure_launchctl!
225
+ launchctl? || raise(ServiceError, "Cannot manage #{pretty_name}: launchctl not found")
226
+ end
227
+
228
+ private
229
+
230
+ ##
231
+ # Command to get the status of the service.
232
+ #
233
+ def status_command
234
+ @status_command || "launchctl list 2>&1 | grep #{SERVICE_PREFIX}#{self.class.service_name}"
235
+ end
236
+
237
+ ##
238
+ # Regular expression to check the output of +#status_command+ against to determine if the service is in
239
+ # an error state.
240
+ #
241
+ def status_error_regex
242
+ @status_error_regex || LAUNCHCTL_ERROR_REGEX
243
+ end
244
+
245
+ ##
246
+ # Command to start the service.
247
+ #
248
+ def start_command
249
+ @start_command || "launchctl bootstrap gui/#{Process.uid} #{self.class.plist_path}"
250
+ end
251
+
252
+ ##
253
+ # Command to stop the service.
254
+ #
255
+ def stop_command
256
+ @stop_command || "launchctl bootout gui/#{Process.uid}/#{self.class.launchctl_name}"
257
+ end
258
+
259
+ ##
260
+ # Calls the supplied block repeatedly until it returns false. Checks frequently at first and gradually
261
+ # reduces down to one-second intervals.
262
+ #
263
+ # * +timeout+ - Maximum number of seconds to wait before timing out (default: 30).
264
+ # * +block+ - Block to call until it returns false.
265
+ #
266
+ def wait(timeout = 30, &block)
267
+ while block.call && timeout > 0
268
+ reduce = [[(30 - timeout.to_i) / 5.0, 0.1].max, 1].min
269
+ timeout -= reduce
270
+
271
+ sleep(reduce)
272
+ end
273
+ end
265
274
  end
266
275
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Potluck
4
- VERSION = '0.0.5'
4
+ VERSION = '0.0.6'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: potluck
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nate Pickens
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-12-31 00:00:00.000000000 Z
11
+ date: 2022-01-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -44,7 +44,10 @@ dependencies:
44
44
  - - "<"
45
45
  - !ruby/object:Gem::Version
46
46
  version: 6.0.0
47
- description: An extensible Ruby framework for managing external processes.
47
+ description: Potluck provides a simple interface for managing external processes in
48
+ a way that plays nice with others as well as smoothly handling both development
49
+ and production environments. Current official gem extensions provide Nginx and Postgres
50
+ management.
48
51
  email:
49
52
  executables: []
50
53
  extensions: []