From ae5e9387b95c81a7247068053a013339a6fc7762 Mon Sep 17 00:00:00 2001 From: apainintheneck Date: Sat, 23 Sep 2023 14:40:24 -0700 Subject: [PATCH] service: support multiple sockets in DSL This adds support for multiple named sockets to the service DSL. It also retains backwards compatibility with the previous DSL where you can declare one socket and it is always just named Listener by default. --- Library/Homebrew/service.rb | 43 ++++++++++++++++++--------- Library/Homebrew/test/service_spec.rb | 2 +- 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/Library/Homebrew/service.rb b/Library/Homebrew/service.rb index 130e2f1e7e..8eaeac13fc 100644 --- a/Library/Homebrew/service.rb +++ b/Library/Homebrew/service.rb @@ -187,17 +187,26 @@ module Homebrew end end - sig { params(value: T.nilable(String)).returns(T.nilable(T::Hash[Symbol, String])) } + SOCKET_STRING_REGEX = %r{([a-z]+)://([a-z0-9.]+):([0-9]+)}i.freeze + + sig { + params(value: T.nilable(T.any(String, T::Hash[String, String]))) + .returns(T.nilable(T::Hash[String, T::Hash[Symbol, String]])) + } def sockets(value = nil) - case value - when nil - @sockets + return @sockets if value.nil? + + @sockets = case value when String - match = T.must(value).match(%r{([a-z]+)://([a-z0-9.]+):([0-9]+)}i) + { "Listeners" => value } + when Hash + value + end.transform_values do |socket_string| + match = socket_string.match(SOCKET_STRING_REGEX) raise TypeError, "Service#sockets a formatted socket definition as ://:" if match.blank? type, host, port = match.captures - @sockets = { host: host, port: port, type: type } + { host: host, port: port, type: type } end end @@ -410,12 +419,14 @@ module Homebrew if @sockets.present? base[:Sockets] = {} - base[:Sockets][:Listeners] = { - SockNodeName: @sockets[:host], - SockServiceName: @sockets[:port], - SockProtocol: @sockets[:type].upcase, - SockFamily: "IPv4v6", - } + @sockets.each do |name, info| + base[:Sockets][name] = { + SockNodeName: info[:host], + SockServiceName: info[:port], + SockProtocol: info[:type].upcase, + SockFamily: "IPv4v6", + } + end end if @cron.present? && @run_type == RUN_TYPE_CRON @@ -511,7 +522,11 @@ module Homebrew .join(" ") end - sockets_string = "#{@sockets[:type]}://#{@sockets[:host]}:#{@sockets[:port]}" if @sockets.present? + sockets_hash = if @sockets.present? + @sockets.transform_values do |info| + "#{info[:type]}://#{info[:host]}:#{info[:port]}" + end + end { name: name_params.presence, @@ -531,7 +546,7 @@ module Homebrew restart_delay: @restart_delay, process_type: @process_type, macos_legacy_timers: @macos_legacy_timers, - sockets: sockets_string, + sockets: sockets_hash, }.compact end diff --git a/Library/Homebrew/test/service_spec.rb b/Library/Homebrew/test/service_spec.rb index 324a373086..bece2ae9d9 100644 --- a/Library/Homebrew/test/service_spec.rb +++ b/Library/Homebrew/test/service_spec.rb @@ -990,7 +990,7 @@ describe Homebrew::Service do run_type: :immediate, working_dir: "/$HOME", cron: "0 0 * * 0", - sockets: "tcp://0.0.0.0:80", + sockets: { "Listeners" => "tcp://0.0.0.0:80" }, } end