potluck 0.0.3 → 0.0.4
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 +4 -4
- data/VERSION +1 -1
- data/lib/potluck/{dish.rb → service.rb} +107 -2
- data/lib/potluck/version.rb +1 -1
- data/lib/potluck.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f1c7870515c28013595dbe15f34ba4c2cf3e76fabbbd55c1859066462df9227f
|
4
|
+
data.tar.gz: a87627ecfe3232593fd0f7223089a15893ad3e7227aed8a47d48ec32326b0572
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6b4cc348d159c69e95de691c0e6f0c159ef94818174f3f45319e76e21b971669e600a1d3fb4040edecc0a05b130c6ab0fcdcd2eb08dfdf3fe5e32936d13d7685
|
7
|
+
data.tar.gz: 9e69dd441a0bf951edbccf7d7c590a9697327033e3e88a61801ceaefb3d05ba13734ecba4580f446e1497964a947d99b725a25832d9c0e8efe841a8fdc3414c0
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.4
|
@@ -1,7 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require('fileutils')
|
4
|
+
|
3
5
|
module Potluck
|
4
|
-
|
6
|
+
##
|
7
|
+
# A Ruby interface for controlling, configuring, and interacting with external processes. Serves as a
|
8
|
+
# parent class for service-specific child classes.
|
9
|
+
#
|
10
|
+
class Service
|
5
11
|
SERVICE_PREFIX = 'potluck.npickens.'
|
6
12
|
|
7
13
|
PLIST_XML = '<?xml version="1.0" encoding="UTF-8"?>'
|
@@ -10,6 +16,15 @@ module Potluck
|
|
10
16
|
|
11
17
|
LAUNCHCTL_ERROR_REGEX = /^-|\t[^0]\t/.freeze
|
12
18
|
|
19
|
+
##
|
20
|
+
# Creates a new instance.
|
21
|
+
#
|
22
|
+
# * +logger+ - +Logger+ instance to use for outputting info and error messages (optional). Output will
|
23
|
+
# be sent to stdout and stderr if none is supplied.
|
24
|
+
# * +manage+ - True if the service runs locally and should be managed by this process (default: true if
|
25
|
+
# launchctl is available and false otherwise).
|
26
|
+
# * +is_local+ - DEPRECATED. True if the service runs locally (use +manage+ instead).
|
27
|
+
#
|
13
28
|
def initialize(logger: nil, manage: launchctl?, is_local: (is_local_omitted = true; nil))
|
14
29
|
@logger = logger
|
15
30
|
@manage = !!manage
|
@@ -23,7 +38,7 @@ module Potluck
|
|
23
38
|
ensure_launchctl!
|
24
39
|
end
|
25
40
|
|
26
|
-
# DEPRECATED. Use
|
41
|
+
# DEPRECATED. Use +manage+ instead.
|
27
42
|
@is_local = is_local.nil? ? (IS_MACOS && ensure_launchctl! rescue false) : is_local
|
28
43
|
|
29
44
|
unless is_local_omitted
|
@@ -32,38 +47,71 @@ module Potluck
|
|
32
47
|
end
|
33
48
|
end
|
34
49
|
|
50
|
+
##
|
51
|
+
# Returns true if the service is managed.
|
52
|
+
#
|
35
53
|
def manage?
|
36
54
|
@manage
|
37
55
|
end
|
38
56
|
|
57
|
+
##
|
58
|
+
# Returns true if launchctl is available.
|
59
|
+
#
|
39
60
|
def launchctl?
|
40
61
|
defined?(@@launchctl) ? @@launchctl : (@@launchctl = `which launchctl 2>&1` && $? == 0)
|
41
62
|
end
|
42
63
|
|
64
|
+
##
|
65
|
+
# Checks if launchctl is available and raises an error if not.
|
66
|
+
#
|
43
67
|
def ensure_launchctl!
|
44
68
|
launchctl? || raise("Cannot manage #{self.class.to_s.split('::').last}: launchctl not found")
|
45
69
|
end
|
46
70
|
|
71
|
+
##
|
72
|
+
# Command to get the status of the service.
|
73
|
+
#
|
47
74
|
def status_command
|
48
75
|
@status_command || "launchctl list 2>&1 | grep #{SERVICE_PREFIX}#{self.class.service_name}"
|
49
76
|
end
|
50
77
|
|
78
|
+
##
|
79
|
+
# Regular expression to check the output of +#status_command+ against to determine if the service is in
|
80
|
+
# an error state.
|
81
|
+
#
|
51
82
|
def status_error_regex
|
52
83
|
@status_error_regex || LAUNCHCTL_ERROR_REGEX
|
53
84
|
end
|
54
85
|
|
86
|
+
##
|
87
|
+
# Command to start the service.
|
88
|
+
#
|
55
89
|
def start_command
|
56
90
|
@start_command || "launchctl bootstrap gui/#{Process.uid} #{self.class.plist_path}"
|
57
91
|
end
|
58
92
|
|
93
|
+
##
|
94
|
+
# Command to stop the service.
|
95
|
+
#
|
59
96
|
def stop_command
|
60
97
|
@stop_command || "launchctl bootout gui/#{Process.uid}/#{self.class.launchctl_name}"
|
61
98
|
end
|
62
99
|
|
100
|
+
##
|
101
|
+
# Writes the service's launchctl plist file to disk.
|
102
|
+
#
|
63
103
|
def ensure_plist
|
104
|
+
FileUtils.mkdir_p(File.dirname(self.class.plist_path))
|
64
105
|
File.write(self.class.plist_path, self.class.plist)
|
65
106
|
end
|
66
107
|
|
108
|
+
##
|
109
|
+
# Returns the status of the service:
|
110
|
+
#
|
111
|
+
# * +:active+ if the service is managed and running.
|
112
|
+
# * +:inactive+ if the service is not managed or is not running.
|
113
|
+
# * +:error+ if the service is managed and is in an error state.
|
114
|
+
#
|
67
115
|
def status
|
68
116
|
return :inactive unless manage?
|
69
117
|
|
@@ -78,6 +126,9 @@ module Potluck
|
|
78
126
|
end
|
79
127
|
end
|
80
128
|
|
129
|
+
##
|
130
|
+
# Starts the service if it's managed and is not active.
|
131
|
+
#
|
81
132
|
def start
|
82
133
|
return unless manage?
|
83
134
|
|
@@ -96,6 +147,9 @@ module Potluck
|
|
96
147
|
log("#{self.class.pretty_name} started")
|
97
148
|
end
|
98
149
|
|
150
|
+
##
|
151
|
+
# Stops the service if it's managed and is active or in an error state.
|
152
|
+
#
|
99
153
|
def stop
|
100
154
|
return unless manage? && status != :inactive
|
101
155
|
|
@@ -107,6 +161,9 @@ module Potluck
|
|
107
161
|
log("#{self.class.pretty_name} stopped")
|
108
162
|
end
|
109
163
|
|
164
|
+
##
|
165
|
+
# Restarts the service if it's managed by calling stop and then start.
|
166
|
+
#
|
110
167
|
def restart
|
111
168
|
return unless manage?
|
112
169
|
|
@@ -114,6 +171,13 @@ module Potluck
|
|
114
171
|
start
|
115
172
|
end
|
116
173
|
|
174
|
+
##
|
175
|
+
# Runs a command with the default shell. Raises an error if the command exits with a non-zero status.
|
176
|
+
#
|
177
|
+
# * +command+ - Command to run.
|
178
|
+
# * +redirect_stderr+ - True if stderr should be redirected to stdout; otherwise stderr output will not
|
179
|
+
# be logged (default: true).
|
180
|
+
#
|
117
181
|
def run(command, redirect_stderr: true)
|
118
182
|
output = `#{command}#{' 2>&1' if redirect_stderr}`
|
119
183
|
status = $?
|
@@ -126,6 +190,12 @@ module Potluck
|
|
126
190
|
end
|
127
191
|
end
|
128
192
|
|
193
|
+
##
|
194
|
+
# Logs a message using the logger or stdout/stderr if no logger is configured.
|
195
|
+
#
|
196
|
+
# * +message+ - Message to log.
|
197
|
+
# * +error+ - True if the message is an error (default: false).
|
198
|
+
#
|
129
199
|
def log(message, error = false)
|
130
200
|
if @logger
|
131
201
|
error ? @logger.error(message) : @logger.info(message)
|
@@ -136,6 +206,13 @@ module Potluck
|
|
136
206
|
|
137
207
|
private
|
138
208
|
|
209
|
+
##
|
210
|
+
# Calls the supplied block repeatedly until it returns false. Checks frequently at first and gradually
|
211
|
+
# reduces down to one-second intervals.
|
212
|
+
#
|
213
|
+
# * +timeout+ - Maximum number of seconds to wait before timing out (default: 30).
|
214
|
+
# * +block+ - Block to call until it returns false.
|
215
|
+
#
|
139
216
|
def wait(timeout = 30, &block)
|
140
217
|
while block.call && timeout > 0
|
141
218
|
reduce = [[(30 - timeout.to_i) / 5.0, 0.1].max, 1].min
|
@@ -145,22 +222,37 @@ module Potluck
|
|
145
222
|
end
|
146
223
|
end
|
147
224
|
|
225
|
+
##
|
226
|
+
# Human-friendly name of the service.
|
227
|
+
#
|
148
228
|
def self.pretty_name
|
149
229
|
@pretty_name ||= self.to_s.split('::').last
|
150
230
|
end
|
151
231
|
|
232
|
+
##
|
233
|
+
# Computer-friendly name of the service.
|
234
|
+
#
|
152
235
|
def self.service_name
|
153
236
|
@service_name ||= pretty_name.downcase
|
154
237
|
end
|
155
238
|
|
239
|
+
##
|
240
|
+
# Name for the launchctl service.
|
241
|
+
#
|
156
242
|
def self.launchctl_name
|
157
243
|
"#{SERVICE_PREFIX}#{service_name}"
|
158
244
|
end
|
159
245
|
|
246
|
+
##
|
247
|
+
# Path to the launchctl plist file of the service.
|
248
|
+
#
|
160
249
|
def self.plist_path
|
161
250
|
File.join(DIR, "#{launchctl_name}.plist")
|
162
251
|
end
|
163
252
|
|
253
|
+
##
|
254
|
+
# Content of the launchctl plist file.
|
255
|
+
#
|
164
256
|
def self.plist(content)
|
165
257
|
<<~EOS
|
166
258
|
#{PLIST_XML}
|
@@ -179,4 +271,17 @@ module Potluck
|
|
179
271
|
EOS
|
180
272
|
end
|
181
273
|
end
|
274
|
+
|
275
|
+
##
|
276
|
+
# DEPRECATED. Old name of Potluck::Service class.
|
277
|
+
#
|
278
|
+
Dish = Service.clone
|
279
|
+
|
280
|
+
# :nodoc: all
|
281
|
+
class Dish
|
282
|
+
def self.inherited(subclass)
|
283
|
+
warn("Potluck::Dish has been renamed to Potluck::Service. Please update #{subclass} to inherit from "\
|
284
|
+
'Potluck::Service instead of Potluck::Dish.')
|
285
|
+
end
|
286
|
+
end
|
182
287
|
end
|
data/lib/potluck/version.rb
CHANGED
data/lib/potluck.rb
CHANGED
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.
|
4
|
+
version: 0.0.4
|
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-
|
11
|
+
date: 2021-12-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -54,7 +54,7 @@ files:
|
|
54
54
|
- README.md
|
55
55
|
- VERSION
|
56
56
|
- lib/potluck.rb
|
57
|
-
- lib/potluck/
|
57
|
+
- lib/potluck/service.rb
|
58
58
|
- lib/potluck/version.rb
|
59
59
|
homepage: https://github.com/npickens/potluck
|
60
60
|
licenses:
|
@@ -78,7 +78,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
78
78
|
- !ruby/object:Gem::Version
|
79
79
|
version: '0'
|
80
80
|
requirements: []
|
81
|
-
rubygems_version: 3.2.
|
81
|
+
rubygems_version: 3.2.32
|
82
82
|
signing_key:
|
83
83
|
specification_version: 4
|
84
84
|
summary: An extensible Ruby framework for managing external processes.
|