1
- # typed: true # rubocop:todo Sorbet/StrictSigil
1
+ # typed: strict
2
2
# frozen_string_literal: true
3
3
4
4
require "ipaddr"
@@ -23,13 +23,38 @@ class Service
23
23
PROCESS_TYPE_ADAPTIVE = :adaptive
24
24
25
25
KEEP_ALIVE_KEYS = [ :always , :successful_exit , :crashed , :path ] . freeze
26
+ SOCKET_STRING_REGEX = %r{^([a-z]+)://(.+):([0-9]+)$}i
27
+
28
+ RunParam = T . type_alias { T . nilable ( T . any ( T ::Array [ T . any ( String , Pathname ) ] , String , Pathname ) ) }
29
+ Sockets = T . type_alias { T ::Hash [ Symbol , { host : String , port : String , type : String } ] }
26
30
27
- # sig { params(formula: Formula).void }
31
+ sig { returns ( String ) }
32
+ attr_reader :plist_name , :service_name
33
+
34
+ sig { params ( formula : Formula , block : T . nilable ( T . proc . void ) ) . void }
28
35
def initialize ( formula , &block )
36
+ @cron = T . let ( { } , T ::Hash [ Symbol , T . any ( Integer , String ) ] )
37
+ @environment_variables = T . let ( { } , T ::Hash [ Symbol , String ] )
38
+ @error_log_path = T . let ( nil , T . nilable ( String ) )
29
39
@formula = formula
30
- @run_type = RUN_TYPE_IMMEDIATE
31
- @run_at_load = true
32
- @environment_variables = { }
40
+ @input_path = T . let ( nil , T . nilable ( String ) )
41
+ @interval = T . let ( nil , T . nilable ( Integer ) )
42
+ @keep_alive = T . let ( { } , T ::Hash [ Symbol , T . untyped ] )
43
+ @launch_only_once = T . let ( false , T ::Boolean )
44
+ @log_path = T . let ( nil , T . nilable ( String ) )
45
+ @macos_legacy_timers = T . let ( false , T ::Boolean )
46
+ @plist_name = T . let ( default_plist_name , String )
47
+ @process_type = T . let ( nil , T . nilable ( Symbol ) )
48
+ @require_root = T . let ( false , T ::Boolean )
49
+ @restart_delay = T . let ( nil , T . nilable ( Integer ) )
50
+ @root_dir = T . let ( nil , T . nilable ( String ) )
51
+ @run = T . let ( [ ] , T ::Array [ String ] )
52
+ @run_at_load = T . let ( true , T ::Boolean )
53
+ @run_params = T . let ( nil , T . any ( RunParam , T ::Hash [ Symbol , RunParam ] ) )
54
+ @run_type = T . let ( RUN_TYPE_IMMEDIATE , Symbol )
55
+ @service_name = T . let ( default_service_name , String )
56
+ @sockets = T . let ( { } , Sockets )
57
+ @working_dir = T . let ( nil , T . nilable ( String ) )
33
58
instance_eval ( &block ) if block
34
59
end
35
60
@@ -43,21 +68,11 @@ def default_plist_name
43
68
"homebrew.mxcl.#{ @formula . name } "
44
69
end
45
70
46
- sig { returns ( String ) }
47
- def plist_name
48
- @plist_name ||= default_plist_name
49
- end
50
-
51
71
sig { returns ( String ) }
52
72
def default_service_name
53
73
"homebrew.#{ @formula . name } "
54
74
end
55
75
56
- sig { returns ( String ) }
57
- def service_name
58
- @service_name ||= default_service_name
59
- end
60
-
61
76
sig { params ( macos : T . nilable ( String ) , linux : T . nilable ( String ) ) . void }
62
77
def name ( macos : nil , linux : nil )
63
78
raise TypeError , "Service#name expects at least one String" if [ macos , linux ] . none? ( String )
@@ -68,9 +83,9 @@ def name(macos: nil, linux: nil)
68
83
69
84
sig {
70
85
params (
71
- command : T . nilable ( T . any ( T :: Array [ T . any ( String , Pathname ) ] , String , Pathname ) ) ,
72
- macos : T . nilable ( T . any ( T :: Array [ T . any ( String , Pathname ) ] , String , Pathname ) ) ,
73
- linux : T . nilable ( T . any ( T :: Array [ T . any ( String , Pathname ) ] , String , Pathname ) ) ,
86
+ command : T . nilable ( RunParam ) ,
87
+ macos : T . nilable ( RunParam ) ,
88
+ linux : T . nilable ( RunParam ) ,
74
89
) . returns ( T . nilable ( T ::Array [ T . any ( String , Pathname ) ] ) )
75
90
}
76
91
def run ( command = nil , macos : nil , linux : nil )
@@ -86,9 +101,9 @@ def run(command = nil, macos: nil, linux: nil)
86
101
when nil
87
102
@run
88
103
when String , Pathname
89
- @run = [ command ]
104
+ @run = [ command . to_s ]
90
105
when Array
91
- @run = command
106
+ @run = command . map ( & :to_s )
92
107
end
93
108
end
94
109
@@ -161,18 +176,17 @@ def keep_alive(value = nil)
161
176
end
162
177
end
163
178
164
- sig { params ( value : T . nilable ( T ::Boolean ) ) . returns ( T . nilable ( T ::Boolean ) ) }
179
+ sig { params ( value : T . nilable ( T ::Boolean ) ) . returns ( T ::Boolean ) }
165
180
def require_root ( value = nil )
166
181
case value
167
182
when nil
168
183
@require_root
169
- when true , false
184
+ when TrueClass , FalseClass
170
185
@require_root = value
171
186
end
172
187
end
173
188
174
189
# Returns a `Boolean` describing if a service requires root access.
175
- # @return [Boolean]
176
190
sig { returns ( T ::Boolean ) }
177
191
def requires_root?
178
192
@require_root . present? && @require_root == true
@@ -183,16 +197,14 @@ def run_at_load(value = nil)
183
197
case value
184
198
when nil
185
199
@run_at_load
186
- when true , false
200
+ when TrueClass , FalseClass
187
201
@run_at_load = value
188
202
end
189
203
end
190
204
191
- SOCKET_STRING_REGEX = %r{^([a-z]+)://(.+):([0-9]+)$}i
192
-
193
205
sig {
194
206
params ( value : T . nilable ( T . any ( String , T ::Hash [ Symbol , String ] ) ) )
195
- . returns ( T . nilable ( T ::Hash [ Symbol , T ::Hash [ Symbol , String ] ] ) )
207
+ . returns ( T ::Hash [ Symbol , T ::Hash [ Symbol , String ] ] )
196
208
}
197
209
def sockets ( value = nil )
198
210
return @sockets if value . nil?
@@ -204,9 +216,11 @@ def sockets(value = nil)
204
216
value
205
217
end . transform_values do |socket_string |
206
218
match = socket_string . match ( SOCKET_STRING_REGEX )
207
- raise TypeError , "Service#sockets a formatted socket definition as <type>://<host>:<port>" if match . blank?
219
+ raise TypeError , "Service#sockets a formatted socket definition as <type>://<host>:<port>" unless match
208
220
209
- type , host , port = match . captures
221
+ type = T . must ( match [ 1 ] )
222
+ host = T . must ( match [ 2 ] )
223
+ port = T . must ( match [ 3 ] )
210
224
211
225
begin
212
226
IPAddr . new ( host )
@@ -219,18 +233,17 @@ def sockets(value = nil)
219
233
end
220
234
221
235
# Returns a `Boolean` describing if a service is set to be kept alive.
222
- # @return [Boolean]
223
236
sig { returns ( T ::Boolean ) }
224
237
def keep_alive?
225
- @keep_alive . present ? && @keep_alive [ :always ] != false
238
+ ! @keep_alive . empty ? && @keep_alive [ :always ] != false
226
239
end
227
240
228
- sig { params ( value : T . nilable ( T ::Boolean ) ) . returns ( T . nilable ( T ::Boolean ) ) }
241
+ sig { params ( value : T . nilable ( T ::Boolean ) ) . returns ( T ::Boolean ) }
229
242
def launch_only_once ( value = nil )
230
243
case value
231
244
when nil
232
245
@launch_only_once
233
- when true , false
246
+ when TrueClass , FalseClass
234
247
@launch_only_once = value
235
248
end
236
249
end
@@ -281,13 +294,13 @@ def interval(value = nil)
281
294
end
282
295
end
283
296
284
- sig { params ( value : T . nilable ( String ) ) . returns ( T . nilable ( Hash ) ) }
297
+ sig { params ( value : T . nilable ( String ) ) . returns ( T :: Hash [ Symbol , T . any ( Integer , String ) ] ) }
285
298
def cron ( value = nil )
286
299
case value
287
300
when nil
288
301
@cron
289
302
when String
290
- @cron = parse_cron ( T . must ( value ) )
303
+ @cron = parse_cron ( value )
291
304
end
292
305
end
293
306
@@ -345,12 +358,12 @@ def environment_variables(variables = {})
345
358
end
346
359
end
347
360
348
- sig { params ( value : T . nilable ( T ::Boolean ) ) . returns ( T . nilable ( T ::Boolean ) ) }
361
+ sig { params ( value : T . nilable ( T ::Boolean ) ) . returns ( T ::Boolean ) }
349
362
def macos_legacy_timers ( value = nil )
350
363
case value
351
364
when nil
352
365
@macos_legacy_timers
353
- when true , false
366
+ when TrueClass , FalseClass
354
367
@macos_legacy_timers = value
355
368
end
356
369
end
@@ -362,36 +375,33 @@ def std_service_path_env
362
375
"#{ HOMEBREW_PREFIX } /bin:#{ HOMEBREW_PREFIX } /sbin:/usr/bin:/bin:/usr/sbin:/sbin"
363
376
end
364
377
365
- sig { returns ( T . nilable ( T ::Array [ String ] ) ) }
378
+ sig { returns ( T ::Array [ String ] ) }
366
379
def command
367
- @run & .map ( &:to_s ) & .map { |arg | arg . start_with? ( "~" ) ? File . expand_path ( arg ) : arg }
380
+ @run . map ( &:to_s ) . map { |arg | arg . start_with? ( "~" ) ? File . expand_path ( arg ) : arg }
368
381
end
369
382
370
383
sig { returns ( T ::Boolean ) }
371
384
def command?
372
- @run . present ?
385
+ ! @run . empty ?
373
386
end
374
387
375
388
# Returns the `String` command to run manually instead of the service.
376
- # @return [String]
377
389
sig { returns ( String ) }
378
390
def manual_command
379
391
vars = @environment_variables . except ( :PATH )
380
392
. map { |k , v | "#{ k } =\" #{ v } \" " }
381
393
382
- out = vars + T . must ( command ) . map { |arg | Utils ::Shell . sh_quote ( arg ) } if command?
383
- out . join ( " " )
394
+ vars . concat ( command . map { |arg | Utils ::Shell . sh_quote ( arg ) } )
395
+ vars . join ( " " )
384
396
end
385
397
386
398
# Returns a `Boolean` describing if a service is timed.
387
- # @return [Boolean]
388
399
sig { returns ( T ::Boolean ) }
389
400
def timed?
390
401
@run_type == RUN_TYPE_CRON || @run_type == RUN_TYPE_INTERVAL
391
402
end
392
403
393
404
# Returns a `String` plist.
394
- # @return [String]
395
405
sig { returns ( String ) }
396
406
def to_plist
397
407
# command needs to be first because it initializes all other values
@@ -425,7 +435,7 @@ def to_plist
425
435
end
426
436
end
427
437
428
- if @sockets . present ?
438
+ unless @sockets . empty ?
429
439
base [ :Sockets ] = { }
430
440
@sockets . each do |name , info |
431
441
base [ :Sockets ] [ name ] = {
@@ -436,7 +446,7 @@ def to_plist
436
446
end
437
447
end
438
448
439
- if @cron . present ? && @run_type == RUN_TYPE_CRON
449
+ if ! @cron . empty ? && @run_type == RUN_TYPE_CRON
440
450
base [ :StartCalendarInterval ] = @cron . reject { |_ , value | value == "*" }
441
451
end
442
452
@@ -452,12 +462,11 @@ def to_plist
452
462
end
453
463
454
464
# Returns a `String` systemd unit.
455
- # @return [String]
456
465
sig { returns ( String ) }
457
466
def to_systemd_unit
458
467
# command needs to be first because it initializes all other values
459
- cmd = command & .map { |arg | Utils ::Service . systemd_quote ( arg ) }
460
- & .join ( " " )
468
+ cmd = command . map { |arg | Utils ::Service . systemd_quote ( arg ) }
469
+ . join ( " " )
461
470
462
471
options = [ ]
463
472
options << "Type=#{ ( @launch_only_once == true ) ? "oneshot" : "simple" } "
@@ -485,7 +494,6 @@ def to_systemd_unit
485
494
end
486
495
487
496
# Returns a `String` systemd unit timer.
488
- # @return [String]
489
497
sig { returns ( String ) }
490
498
def to_systemd_timer
491
499
options = [ ]
@@ -512,7 +520,7 @@ def to_systemd_timer
512
520
end
513
521
514
522
# Prepare the service hash for inclusion in the formula API JSON.
515
- sig { returns ( Hash ) }
523
+ sig { returns ( T :: Hash [ Symbol , T . untyped ] ) }
516
524
def to_hash
517
525
name_params = {
518
526
macos : ( plist_name if plist_name != default_plist_name ) ,
@@ -521,13 +529,13 @@ def to_hash
521
529
522
530
return { name : name_params } . compact_blank if @run_params . blank?
523
531
524
- cron_string = if @cron . present ?
532
+ cron_string = unless @cron . empty ?
525
533
[ :Minute , :Hour , :Day , :Month , :Weekday ]
526
534
. map { |key | @cron [ key ] . to_s }
527
535
. join ( " " )
528
536
end
529
537
530
- sockets_var = if @sockets . present ?
538
+ sockets_var = unless @sockets . empty ?
531
539
@sockets . transform_values { |info | "#{ info [ :type ] } ://#{ info [ :host ] } :#{ info [ :port ] } " }
532
540
. then do |sockets_hash |
533
541
# TODO: Remove this code when all users are running on versions of Homebrew
@@ -561,11 +569,11 @@ def to_hash
561
569
process_type : @process_type ,
562
570
macos_legacy_timers : @macos_legacy_timers ,
563
571
sockets : sockets_var ,
564
- } . compact
572
+ } . compact_blank
565
573
end
566
574
567
575
# Turn the service API hash values back into what is expected by the formula DSL.
568
- sig { params ( api_hash : Hash ) . returns ( Hash ) }
576
+ sig { params ( api_hash : T :: Hash [ String , T . untyped ] ) . returns ( T :: Hash [ Symbol , T . untyped ] ) }
569
577
def self . from_hash ( api_hash )
570
578
hash = { }
571
579
hash [ :name ] = api_hash [ "name" ] . transform_keys ( &:to_sym ) if api_hash . key? ( "name" )
0 commit comments