service: add info to API json and load from api
As a part of serializing the hash, certain path placeholders are used for the HOMEBREW_PREFIX and $HOME directories. Beyond that certain elements need to be turned back into strings like cron and sockets and symbols need to be preserved as well. The run command accepts either an arg or kwargs so it has to be treated specially here.
This commit is contained in:
parent
5550aa215e
commit
db8d488db4
@ -1043,7 +1043,7 @@ class Formula
|
||||
def service
|
||||
return unless service?
|
||||
|
||||
Homebrew::Service.new(self, &self.class.service)
|
||||
@service ||= Homebrew::Service.new(self, &self.class.service)
|
||||
end
|
||||
|
||||
# @private
|
||||
@ -2132,6 +2132,7 @@ class Formula
|
||||
"disabled" => disabled?,
|
||||
"disable_date" => disable_date,
|
||||
"disable_reason" => disable_reason,
|
||||
"service" => service&.serialize,
|
||||
"tap_git_head" => tap_git_head,
|
||||
"ruby_source_checksum" => {},
|
||||
}
|
||||
|
||||
@ -263,6 +263,21 @@ module Formulary
|
||||
raise "Cannot build from source from abstract formula."
|
||||
end
|
||||
|
||||
if (service_hash = json_formula["service"])
|
||||
service_hash = Homebrew::Service.deserialize(service_hash)
|
||||
run_params = service_hash.delete("run")
|
||||
service do
|
||||
if run_params.is_a?(Hash)
|
||||
run(**run_params)
|
||||
else
|
||||
run run_params
|
||||
end
|
||||
service_hash.each do |key, arg|
|
||||
public_send(key, arg)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@caveats_string = json_formula["caveats"]
|
||||
def caveats
|
||||
self.class.instance_variable_get(:@caveats_string)
|
||||
|
||||
@ -45,6 +45,9 @@ module Homebrew
|
||||
).returns(T.nilable(Array))
|
||||
}
|
||||
def run(command = nil, macos: nil, linux: nil)
|
||||
# Save parameters for serialization
|
||||
@run_params ||= command || { macos: macos, linux: linux }.compact
|
||||
|
||||
command ||= on_system_conditional(macos: macos, linux: linux)
|
||||
case T.unsafe(command)
|
||||
when nil
|
||||
@ -156,7 +159,7 @@ module Homebrew
|
||||
# @return [Boolean]
|
||||
sig { returns(T::Boolean) }
|
||||
def requires_root?
|
||||
instance_eval(&@service_block)
|
||||
eval_service_block
|
||||
@require_root.present? && @require_root == true
|
||||
end
|
||||
|
||||
@ -192,7 +195,7 @@ module Homebrew
|
||||
# @return [Boolean]
|
||||
sig { returns(T::Boolean) }
|
||||
def keep_alive?
|
||||
instance_eval(&@service_block)
|
||||
eval_service_block
|
||||
@keep_alive.present? && @keep_alive[:always] != false
|
||||
end
|
||||
|
||||
@ -320,7 +323,7 @@ module Homebrew
|
||||
parsed
|
||||
end
|
||||
|
||||
sig { params(variables: T::Hash[String, String]).returns(T.nilable(T::Hash[String, String])) }
|
||||
sig { params(variables: T::Hash[Symbol, String]).returns(T.nilable(T::Hash[Symbol, String])) }
|
||||
def environment_variables(variables = {})
|
||||
case T.unsafe(variables)
|
||||
when Hash
|
||||
@ -351,7 +354,7 @@ module Homebrew
|
||||
|
||||
sig { returns(T.nilable(T::Array[String])) }
|
||||
def command
|
||||
instance_eval(&@service_block)
|
||||
eval_service_block
|
||||
@run&.map(&:to_s)
|
||||
end
|
||||
|
||||
@ -359,7 +362,7 @@ module Homebrew
|
||||
# @return [String]
|
||||
sig { returns(String) }
|
||||
def manual_command
|
||||
instance_eval(&@service_block)
|
||||
eval_service_block
|
||||
vars = @environment_variables.except(:PATH)
|
||||
.map { |k, v| "#{k}=\"#{v}\"" }
|
||||
|
||||
@ -372,7 +375,7 @@ module Homebrew
|
||||
# @return [Boolean]
|
||||
sig { returns(T::Boolean) }
|
||||
def timed?
|
||||
instance_eval(&@service_block)
|
||||
eval_service_block
|
||||
@run_type == RUN_TYPE_CRON || @run_type == RUN_TYPE_INTERVAL
|
||||
end
|
||||
|
||||
@ -484,7 +487,7 @@ module Homebrew
|
||||
Unit=#{@formula.service_name}
|
||||
EOS
|
||||
|
||||
instance_eval(&@service_block)
|
||||
eval_service_block
|
||||
options = []
|
||||
options << "Persistent=true" if @run_type == RUN_TYPE_CRON
|
||||
options << "OnUnitActiveSec=#{@interval}" if @run_type == RUN_TYPE_INTERVAL
|
||||
@ -497,5 +500,93 @@ module Homebrew
|
||||
|
||||
timer + options.join("\n")
|
||||
end
|
||||
|
||||
# Only evaluate the service block once.
|
||||
sig { void }
|
||||
def eval_service_block
|
||||
return if @eval_service_block
|
||||
|
||||
instance_eval(&@service_block)
|
||||
@eval_service_block = true
|
||||
end
|
||||
|
||||
# Recursively prepare the service hash for inclusion in the formula API JSON.
|
||||
# - Replace each Symbol with a String prefixed by ":"
|
||||
# - Replace the local HOMEBREW_PREFIX with "$HOMEBREW_PREFIX"
|
||||
# - Replace the local home directory with "$HOME"
|
||||
def serialize(elem = to_h)
|
||||
case elem
|
||||
when String, Pathname
|
||||
elem.to_s.gsub(HOMEBREW_PREFIX, HOMEBREW_PREFIX_PLACEHOLDER)
|
||||
.gsub(Dir.home, "$HOME")
|
||||
when Symbol
|
||||
elem.inspect
|
||||
when Array
|
||||
elem.map { |value| serialize(value) }
|
||||
when Hash
|
||||
elem.to_h do |key, value|
|
||||
key = key.inspect if key.is_a?(Symbol)
|
||||
[key, serialize(value)]
|
||||
end
|
||||
else
|
||||
elem
|
||||
end
|
||||
end
|
||||
|
||||
# Recursively turn the service API hash values back into what is expected by the formula DSL.
|
||||
# - Replace each String prefixed with ":" with a Symbol
|
||||
# - Replace "$HOMEBREW_PREFIX" with the local HOMEBREW_PREFIX environment variable
|
||||
# - Replace "$HOME" with the local home directory
|
||||
def self.deserialize(elem)
|
||||
case elem
|
||||
when String
|
||||
return T.must(elem[1..]).to_sym if elem.start_with?(":")
|
||||
|
||||
elem.gsub(HOMEBREW_PREFIX_PLACEHOLDER, HOMEBREW_PREFIX)
|
||||
.gsub("$HOME", Dir.home)
|
||||
when Array
|
||||
elem.map { |value| deserialize(value) }
|
||||
when Hash
|
||||
elem.to_h do |key, value|
|
||||
key = key[1..].to_sym if key.start_with?(":")
|
||||
[key, deserialize(value)]
|
||||
end
|
||||
else
|
||||
elem
|
||||
end
|
||||
end
|
||||
|
||||
sig { returns(Hash) }
|
||||
def to_h
|
||||
eval_service_block
|
||||
|
||||
cron_string = if @cron.present?
|
||||
[:Minute, :Hour, :Day, :Month, :Weekday]
|
||||
.map { |key| @cron[key].to_s }
|
||||
.join(" ")
|
||||
end
|
||||
|
||||
sockets_string = "#{@sockets[:type]}://#{@sockets[:host]}:#{@sockets[:port]}" if @sockets.present?
|
||||
|
||||
{
|
||||
"run" => @run_params,
|
||||
"run_type" => @run_type,
|
||||
"interval" => @interval,
|
||||
"cron" => cron_string,
|
||||
"keep_alive" => @keep_alive,
|
||||
"launch_only_once" => @launch_only_once,
|
||||
"require_root" => @require_root,
|
||||
"environment_variables" => @environment_variables.presence,
|
||||
"working_dir" => @working_dir,
|
||||
"root_dir" => @root_dir,
|
||||
"input_path" => @input_path,
|
||||
"log_path" => @log_path,
|
||||
"error_log_path" => @error_log_path,
|
||||
"restart_delay" => @restart_delay,
|
||||
"process_type" => @process_type,
|
||||
"macos_legacy_timers" => @macos_legacy_timers,
|
||||
"sockets" => sockets_string,
|
||||
}.compact
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user