From b927ecfd8512f0fa248bd9766faead33d5d4c841 Mon Sep 17 00:00:00 2001 From: Sean Molenaar Date: Thu, 8 Apr 2021 10:06:45 +0200 Subject: [PATCH] Fix formulae method loading Co-authored-by: nandahkrishna --- Library/Homebrew/formula.rb | 19 ++++----- Library/Homebrew/service.rb | 57 +++++++-------------------- Library/Homebrew/test/formula_spec.rb | 25 +++++------- Library/Homebrew/test/service_spec.rb | 14 +++---- 4 files changed, 40 insertions(+), 75 deletions(-) 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")