Class: Homebrew::Service

Inherits:
Object
  • Object
show all
Extended by:
Forwardable, T::Sig
Defined in:
service.rb

Overview

The Service class implements the DSL methods used in a formula’s service block and stores related instance variables. Most of these methods also return the related instance variable when no argument is provided.

Constant Summary collapse

RUN_TYPE_IMMEDIATE =
"immediate"
RUN_TYPE_INTERVAL =
"interval"
RUN_TYPE_CRON =
"cron"
PROCESS_TYPE_BACKGROUND =
"background"
PROCESS_TYPE_STANDARD =
"standard"
PROCESS_TYPE_INTERACTIVE =
"interactive"
PROCESS_TYPE_ADAPTIVE =
"adaptive"

Instance Method Summary collapse

Constructor Details

#initialize(formula, &block) ⇒ Service

sig { params(formula: Formula).void }



22
23
24
25
26
27
# File 'service.rb', line 22

def initialize(formula, &block)
  @formula = formula
  @run_type = RUN_TYPE_IMMEDIATE
  @environment_variables = {}
  @service_block = block
end

Instance Method Details

#commandArray<String>

Returns:



189
190
191
192
# File 'service.rb', line 189

def command
  instance_eval(&@service_block)
  @run.map(&:to_s)
end

#environment_variables(variables = {}) ⇒ Hash{String => String}?

Parameters:

Returns:



160
161
162
163
164
165
166
167
# File 'service.rb', line 160

def environment_variables(variables = {})
  case T.unsafe(variables)
  when Hash
    @environment_variables = variables.transform_values(&:to_s)
  else
    raise TypeError, "Service#environment_variables expects a hash"
  end
end

#error_log_path(path = nil) ⇒ String?

Parameters:

Returns:



92
93
94
95
96
97
98
99
100
101
# File 'service.rb', line 92

def error_log_path(path = nil)
  case T.unsafe(path)
  when nil
    @error_log_path
  when String, Pathname
    @error_log_path = path.to_s
  else
    raise TypeError, "Service#error_log_path expects a String"
  end
end

#input_path(path = nil) ⇒ String?

Parameters:

Returns:



68
69
70
71
72
73
74
75
76
77
# File 'service.rb', line 68

def input_path(path = nil)
  case T.unsafe(path)
  when nil
    @input_path
  when String, Pathname
    @input_path = path.to_s
  else
    raise TypeError, "Service#input_path expects a String or Pathname"
  end
end

#keep_alive(value = nil) ⇒ Boolean?

Parameters:

  • value (Boolean, nil) (defaults to: nil)

Returns:

  • (Boolean, nil)


104
105
106
107
108
109
110
111
112
113
# File 'service.rb', line 104

def keep_alive(value = nil)
  case T.unsafe(value)
  when nil
    @keep_alive
  when true, false
    @keep_alive = value
  else
    raise TypeError, "Service#keep_alive expects a Boolean"
  end
end

#log_path(path = nil) ⇒ String?

Parameters:

Returns:



80
81
82
83
84
85
86
87
88
89
# File 'service.rb', line 80

def log_path(path = nil)
  case T.unsafe(path)
  when nil
    @log_path
  when String, Pathname
    @log_path = path.to_s
  else
    raise TypeError, "Service#log_path expects a String"
  end
end

#macos_legacy_timers(value = nil) ⇒ Boolean?

Parameters:

  • value (Boolean, nil) (defaults to: nil)

Returns:

  • (Boolean, nil)


170
171
172
173
174
175
176
177
178
179
# File 'service.rb', line 170

def macos_legacy_timers(value = nil)
  case T.unsafe(value)
  when nil
    @macos_legacy_timers
  when true, false
    @macos_legacy_timers = value
  else
    raise TypeError, "Service#macos_legacy_timers expects a Boolean"
  end
end

#manual_commandString

Returns:



195
196
197
198
199
200
201
202
# File 'service.rb', line 195

def manual_command
  instance_eval(&@service_block)
  vars = @environment_variables.except(:PATH)
                               .map { |k, v| "#{k}=\"#{v}\"" }

  out = vars + command
  out.join(" ")
end

#process_type(type = nil) ⇒ String?

Parameters:

  • type (String, nil) (defaults to: nil)

Returns:



128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'service.rb', line 128

def process_type(type = nil)
  case T.unsafe(type)
  when nil
    @process_type
  when PROCESS_TYPE_BACKGROUND, PROCESS_TYPE_STANDARD, PROCESS_TYPE_INTERACTIVE, PROCESS_TYPE_ADAPTIVE
    @process_type = type.to_s
  when String
    raise TypeError, "Service#process_type allows: "\
                     "'#{PROCESS_TYPE_BACKGROUND}'/'#{PROCESS_TYPE_STANDARD}'/"\
                     "'#{PROCESS_TYPE_INTERACTIVE}'/'#{PROCESS_TYPE_ADAPTIVE}'"
  else
    raise TypeError, "Service#process_type expects a String"
  end
end

#restart_delay(value = nil) ⇒ Integer?

Parameters:

  • value (Integer, nil) (defaults to: nil)

Returns:

  • (Integer, nil)


116
117
118
119
120
121
122
123
124
125
# File 'service.rb', line 116

def restart_delay(value = nil)
  case T.unsafe(value)
  when nil
    @restart_delay
  when Integer
    @restart_delay = value
  else
    raise TypeError, "Service#restart_delay expects an Integer"
  end
end

#root_dir(path = nil) ⇒ String?

Parameters:

Returns:



56
57
58
59
60
61
62
63
64
65
# File 'service.rb', line 56

def root_dir(path = nil)
  case T.unsafe(path)
  when nil
    @root_dir
  when String, Pathname
    @root_dir = path.to_s
  else
    raise TypeError, "Service#root_dir expects a String or Pathname"
  end
end

#run(command = nil) ⇒ Array?

Parameters:

Returns:

  • (Array, nil)


30
31
32
33
34
35
36
37
38
39
40
41
# File 'service.rb', line 30

def run(command = nil)
  case T.unsafe(command)
  when nil
    @run
  when String, Pathname
    @run = [command]
  when Array
    @run = command
  else
    raise TypeError, "Service#run expects an Array"
  end
end

#run_type(type = nil) ⇒ String?

Parameters:

Returns:



144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'service.rb', line 144

def run_type(type = nil)
  case T.unsafe(type)
  when nil
    @run_type
  when "immediate", :immediate
    @run_type = type.to_s
  when RUN_TYPE_INTERVAL, RUN_TYPE_CRON
    raise TypeError, "Service#run_type does not support timers"
  when String
    raise TypeError, "Service#run_type allows: '#{RUN_TYPE_IMMEDIATE}'/'#{RUN_TYPE_INTERVAL}'/'#{RUN_TYPE_CRON}'"
  else
    raise TypeError, "Service#run_type expects a string"
  end
end

#std_service_path_envString

Returns:



184
185
186
# File 'service.rb', line 184

def std_service_path_env
  "#{HOMEBREW_PREFIX}/bin:#{HOMEBREW_PREFIX}/sbin:/usr/bin:/bin:/usr/sbin:/sbin"
end

#to_plistString

Returns a String plist.

Returns:



207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
# File 'service.rb', line 207

def to_plist
  base = {
    Label:            @formula.plist_name,
    RunAtLoad:        @run_type == RUN_TYPE_IMMEDIATE,
    ProgramArguments: command,
  }

  base[:KeepAlive] = @keep_alive if @keep_alive == true
  base[:LegacyTimers] = @macos_legacy_timers if @macos_legacy_timers == true
  base[:TimeOut] = @restart_delay if @restart_delay.present?
  base[:ProcessType] = @process_type.capitalize if @process_type.present?
  base[:WorkingDirectory] = @working_dir if @working_dir.present?
  base[:RootDirectory] = @root_dir if @root_dir.present?
  base[:StandardInPath] = @input_path if @input_path.present?
  base[:StandardOutPath] = @log_path if @log_path.present?
  base[:StandardErrorPath] = @error_log_path if @error_log_path.present?
  base[:EnvironmentVariables] = @environment_variables unless @environment_variables.empty?

  base.to_plist
end

#to_systemd_unitString

Returns a String systemd unit.

Returns:



231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
# File 'service.rb', line 231

def to_systemd_unit
  unit = <<~EOS
    [Unit]
    Description=Homebrew generated unit for #{@formula.name}

    [Install]
    WantedBy=multi-user.target

    [Service]
    Type=simple
    ExecStart=#{command.join(" ")}
  EOS

  options = []
  options << "Restart=always" if @keep_alive == true
  options << "RestartSec=#{restart_delay}" if @restart_delay.present?
  options << "WorkingDirectory=#{@working_dir}" if @working_dir.present?
  options << "RootDirectory=#{@root_dir}" if @root_dir.present?
  options << "StandardInput=file:#{@input_path}" if @input_path.present?
  options << "StandardOutput=append:#{@log_path}" if @log_path.present?
  options << "StandardError=append:#{@error_log_path}" if @error_log_path.present?
  options += @environment_variables.map { |k, v| "Environment=\"#{k}=#{v}\"" } if @environment_variables.present?

  unit + options.join("\n")
end

#working_dir(path = nil) ⇒ String?

Parameters:

Returns:



44
45
46
47
48
49
50
51
52
53
# File 'service.rb', line 44

def working_dir(path = nil)
  case T.unsafe(path)
  when nil
    @working_dir
  when String, Pathname
    @working_dir = path.to_s
  else
    raise TypeError, "Service#working_dir expects a String"
  end
end