diff --git a/Library/Homebrew/formula.rb b/Library/Homebrew/formula.rb
index 09a237b74..160560519 100644
--- a/Library/Homebrew/formula.rb
+++ b/Library/Homebrew/formula.rb
@@ -392,11 +392,6 @@ class Formula
# @see .livecheckable?
delegate livecheckable?: :"self.class"
- # The service specification for the software.
- # @!method service
- # @see .service=
- delegate service: :"self.class"
-
# Is a service specification defined for the software?
# @!method service?
# @see .service?
@@ -973,6 +968,13 @@ class Formula
prefix/"#{plist_name}.plist"
end
+ # The service specification of the software.
+ def service
+ return Homebrew::Service.new(self, &self.class.service) if service?
+
+ nil
+ end
+
# @private
delegate plist_manual: :"self.class"
@@ -2397,7 +2399,7 @@ class Formula
# It returns true when a service block is present in the {Formula} and
# false otherwise, and is used by service.
def service?
- @service.present?
+ @service_block.present?
end
# The `:startup` attribute set by {.plist_options}.
@@ -2874,10 +2876,9 @@ class Formula
# run [opt_bin/"foo"]
# end
def service(&block)
- @service ||= Homebrew::Service.new(self)
- return @service unless block
+ return @service_block unless block
- @service.instance_eval(&block)
+ @service_block = block
end
# Defines whether the {Formula}'s bottle can be used on the given Homebrew
diff --git a/Library/Homebrew/service.rb b/Library/Homebrew/service.rb
index 32c36aa71..fc826c73c 100644
--- a/Library/Homebrew/service.rb
+++ b/Library/Homebrew/service.rb
@@ -7,16 +7,18 @@ module Homebrew
# also return the related instance variable when no argument is provided.
class Service
extend T::Sig
+ extend Forwardable
RUN_TYPE_IMMEDIATE = "immediate"
RUN_TYPE_INTERVAL = "interval"
RUN_TYPE_CRON = "cron"
# sig { params(formula: Formula).void }
- def initialize(formula)
+ def initialize(formula, &block)
@formula = formula
@run_type = RUN_TYPE_IMMEDIATE
@environment_variables = {}
+ @service_block = block
end
sig { params(command: T.nilable(T.any(T::Array[String], String, Pathname))).returns(T.nilable(Array)) }
@@ -109,47 +111,14 @@ module Homebrew
end
end
- # The directory where the formula's variable files should be installed.
- # This directory is not inside the `HOMEBREW_CELLAR` so it persists
- # across upgrades.
- sig { returns(Pathname) }
- def var
- HOMEBREW_PREFIX/"var"
- end
-
- # The directory where the formula's configuration files should be installed.
- # Anything using `etc.install` will not overwrite other files on e.g. upgrades
- # but will write a new file named `*.default`.
- # This directory is not inside the `HOMEBREW_CELLAR` so it persists
- # across upgrades.
- sig { returns(Pathname) }
- def etc
- HOMEBREW_PREFIX/"etc"
- end
-
- # The directory where the formula's binaries should be installed.
- # This is symlinked into `HOMEBREW_PREFIX` after installation or with
- # `brew link` for formulae that are not keg-only.
- sig { returns(Pathname) }
- def opt_bin
- opt_prefix/"bin"
- end
-
- # The directory where the formula's binaries should be installed.
- # This is symlinked into `HOMEBREW_PREFIX` after installation or with
- # `brew link` for formulae that are not keg-only.
- sig { returns(Pathname) }
- def opt_sbin
- opt_prefix/"sbin"
- end
-
- # A stable path for this formula, when installed. Contains the formula name
- # but no version number. Only the active version will be linked here if
- # multiple versions are installed.
- sig { returns(Pathname) }
- def opt_prefix
- HOMEBREW_PREFIX/"opt/#{@formula.name}"
- end
+ delegate [ # rubocop:disable Layout/HashAlignment
+ :bin,
+ :var,
+ :etc,
+ :opt_bin,
+ :opt_sbin,
+ :opt_prefix,
+ ] => :@formula
sig { returns(String) }
def std_service_path_env
@@ -160,7 +129,9 @@ module Homebrew
# @return [String]
sig { returns(String) }
def to_plist
- clean_command = @run.select {|i| i.is_a?(Pathname)}
+ instance_eval(&@service_block)
+
+ clean_command = @run.select { |i| i.is_a?(Pathname) }
.map(&:to_s)
base = {
diff --git a/Library/Homebrew/test/formula_spec.rb b/Library/Homebrew/test/formula_spec.rb
index c1165deb5..47a890295 100644
--- a/Library/Homebrew/test/formula_spec.rb
+++ b/Library/Homebrew/test/formula_spec.rb
@@ -704,22 +704,17 @@ describe Formula do
specify "#service" do
f = formula do
url "https://brew.sh/test-1.0.tbz"
- service do
- run [opt_bin/"beanstalkd"]
- run_type :immediate
- error_log_path var/"log/beanstalkd.error.log"
- log_path var/"log/beanstalkd.log"
- working_dir var
- keep_alive true
- end
end
- expect(f.service.run).to eq([HOMEBREW_PREFIX/"opt/bin/beanstalkd"])
- expect(f.service.error_log_path).to eq("#{HOMEBREW_PREFIX}/var/log/beanstalkd.error.log")
- expect(f.service.log_path).to eq("#{HOMEBREW_PREFIX}/var/log/beanstalkd.log")
- expect(f.service.working_dir).to eq("#{HOMEBREW_PREFIX}/var")
- expect(f.service.keep_alive).to eq(true)
- expect(f.service.run_type).to eq("immediate")
+ f.class.service do
+ run [opt_bin/"beanstalkd"]
+ run_type :immediate
+ error_log_path var/"log/beanstalkd.error.log"
+ log_path var/"log/beanstalkd.log"
+ working_dir var
+ keep_alive true
+ end
+ expect(f.service).not_to eq(nil)
end
specify "service uses simple run" do
@@ -730,7 +725,7 @@ describe Formula do
end
end
- expect(f.service.run).to eq([HOMEBREW_PREFIX/"opt/bin/beanstalkd"])
+ expect(f.service).not_to eq(nil)
end
specify "dependencies" do
diff --git a/Library/Homebrew/test/service_spec.rb b/Library/Homebrew/test/service_spec.rb
index f6d852814..aad43d0ae 100644
--- a/Library/Homebrew/test/service_spec.rb
+++ b/Library/Homebrew/test/service_spec.rb
@@ -15,12 +15,10 @@ describe Homebrew::Service do
let(:spec) { :stable }
let(:f) { klass.new(name, path, spec) }
- let(:service) { described_class.new(f) }
-
describe "#to_plist" do
it "returns valid plist" do
- service.instance_eval do
- run [opt_bin/"beanstalkd"]
+ f.class.service do
+ run opt_bin/"beanstalkd"
run_type :immediate
environment_variables PATH: std_service_path_env
error_log_path var/"log/beanstalkd.error.log"
@@ -29,7 +27,7 @@ describe Homebrew::Service do
keep_alive true
end
- plist = service.to_plist
+ plist = f.service.to_plist
expect(plist).to include("Label")
expect(plist).to include("homebrew.mxcl.#{name}")
expect(plist).to include("KeepAlive")
@@ -48,12 +46,12 @@ describe Homebrew::Service do
end
it "returns valid partial plist" do
- service.instance_eval do
- run ["#{HOMEBREW_PREFIX}/bin/beanstalkd"]
+ f.class.service do
+ run bin/"beanstalkd"
run_type :immediate
end
- plist = service.to_plist
+ plist = f.service.to_plist
expect(plist).to include("homebrew.mxcl.#{name}")
expect(plist).to include("Label")
expect(plist).not_to include("KeepAlive")