
The main thing is that this DSL allows us to provide an interface that can be serialized to the JSON API. Changes: - Homebrew::Service - Adds `#service_name` and `#plist_name` methods - Each is now included in the `#serialize` method as well - Eval block on instantiation - Before we lazy evaluated this but the cost is not significant and it complicated the code a bunch. This only gets called during install, when evaluating caveats and in the `brew service` command. It skips this evaluation if the service block isn't there. - Add `#command?` helper to avoid `#command.blank?` and `#command.present?` - Formula - `#service` now returns a service whenever it's called. This call is hidden behind a call to `#service?` most of the time anyway so this should be fine. - `#plist_name` and `#service_name` now call the methods of the same name on the service class. This should have already been in the service object to begin with and keeping these methods here helps preserve backwards compatibility with people who were overwriting these methods before. - Caveats - Prefer `service#command?` - Add helpers for checking on service commands - This duplicates some of the work in `brew services`. Maybe we should merge that repo in at some point. - Check for installed service at `#plist_name` or `#service_name`. I think this should be used instead of `Keg#plist_installed?` which checked for any plist file. We should think about deprecating `#plist_installed?` in the future. - Stop using `ps aux | grep #{formula.plist_name}` to check for service files because it was inaccurate (it always returns true on my machine) because the grep process is started before the ps process. - Note: The behavior is the same as it was before. This means that caveats only show up for custom service files on install or if they're already installed. Otherwise it won't show up in `brew info`. This is because it has to check first if the service file has been installed. - Utils::Service - Add utils for evaluating if a service is installed and running. This duplicates some of the work already found in `brew services`. We should seriously consider merging `brew services` with the main brew repo in the future since it's already tightly coupled to the code in the main repo. - Formulary.load_formula_from_api - Be more explicit about which types can be deserialized into run params since it is now possible for run params to be nil. - Update and add tests
333 lines
10 KiB
Ruby
333 lines
10 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require "formula"
|
|
require "caveats"
|
|
|
|
describe Caveats do
|
|
subject(:caveats) { described_class.new(f) }
|
|
|
|
let(:f) { formula { url "foo-1.0" } }
|
|
|
|
specify "#f" do
|
|
expect(caveats.formula).to eq(f)
|
|
end
|
|
|
|
describe "#empty?" do
|
|
it "returns true if the Formula has no caveats" do
|
|
expect(caveats).to be_empty
|
|
end
|
|
|
|
it "returns false if the Formula has caveats" do
|
|
f = formula do
|
|
url "foo-1.0"
|
|
|
|
def caveats
|
|
"something"
|
|
end
|
|
end
|
|
|
|
expect(described_class.new(f)).not_to be_empty
|
|
end
|
|
end
|
|
|
|
describe "#caveats" do
|
|
context "when f.plist is not nil", :needs_macos do
|
|
before do
|
|
allow(Utils::Service).to receive(:launchctl?).and_return(true)
|
|
end
|
|
|
|
it "prints error when no launchd is present" do
|
|
f = formula do
|
|
url "foo-1.0"
|
|
def plist
|
|
"plist_test.plist"
|
|
end
|
|
end
|
|
expect(Utils::Service).to receive(:launchctl?).once.and_return(false)
|
|
expect(described_class.new(f).caveats).to include("provides a launchd plist which can only be used on macOS!")
|
|
end
|
|
|
|
it "prints plist login information when f.plist_startup is nil" do
|
|
f = formula do
|
|
url "foo-1.0"
|
|
def plist
|
|
"plist_test.plist"
|
|
end
|
|
end
|
|
expect(described_class.new(f).caveats).to include("restart at login")
|
|
end
|
|
|
|
it "gives information about service" do
|
|
f = formula do
|
|
url "foo-1.0"
|
|
service do
|
|
run [bin/"php", "test"]
|
|
end
|
|
end
|
|
caveats = described_class.new(f).caveats
|
|
|
|
expect(f.service?).to be(true)
|
|
expect(caveats).to include("#{f.bin}/php test")
|
|
expect(caveats).to include("background service")
|
|
end
|
|
|
|
it "warns about brew failing under tmux" do
|
|
f = formula do
|
|
url "foo-1.0"
|
|
def plist
|
|
"plist_test.plist"
|
|
end
|
|
end
|
|
ENV["HOMEBREW_TMUX"] = "1"
|
|
allow(Homebrew).to receive(:_system).and_return(true)
|
|
allow(Homebrew).to receive(:_system).with("/usr/bin/pbpaste").and_return(false)
|
|
caveats = described_class.new(f).caveats
|
|
|
|
expect(caveats).to include("WARNING:")
|
|
expect(caveats).to include("tmux")
|
|
end
|
|
|
|
# @todo This should get deprecated and the service block `plist_name` method should get used instead.
|
|
it "prints info when there are custom service files" do
|
|
f = formula do
|
|
url "foo-1.0"
|
|
def plist_name
|
|
"custom.mxcl.foo"
|
|
end
|
|
end
|
|
expect(Utils::Service).to receive(:installed?).with(f).once.and_return(true)
|
|
expect(Utils::Service).to receive(:running?).with(f).once.and_return(false)
|
|
expect(described_class.new(f).caveats).to include("restart at login")
|
|
end
|
|
end
|
|
|
|
context "when service block is defined" do
|
|
before do
|
|
allow(Utils::Service).to receive(:launchctl?).and_return(true)
|
|
allow(Utils::Service).to receive(:systemctl?).and_return(true)
|
|
end
|
|
|
|
it "prints warning when no service deamon is found" do
|
|
f = formula do
|
|
url "foo-1.0"
|
|
service do
|
|
run [bin/"cmd"]
|
|
end
|
|
end
|
|
expect(Utils::Service).to receive(:launchctl?).twice.and_return(false)
|
|
expect(Utils::Service).to receive(:systemctl?).once.and_return(false)
|
|
expect(described_class.new(f).caveats).to include("service which can only be used on macOS or systemd!")
|
|
end
|
|
|
|
it "prints service startup information when service.require_root is true" do
|
|
f = formula do
|
|
url "foo-1.0"
|
|
service do
|
|
run [bin/"cmd"]
|
|
require_root true
|
|
end
|
|
end
|
|
expect(Utils::Service).to receive(:running?).with(f).once.and_return(false)
|
|
expect(described_class.new(f).caveats).to include("startup")
|
|
end
|
|
|
|
it "prints service login information when f.plist_startup is nil" do
|
|
f = formula do
|
|
url "foo-1.0"
|
|
service do
|
|
run [bin/"cmd"]
|
|
end
|
|
end
|
|
expect(Utils::Service).to receive(:running?).with(f).once.and_return(false)
|
|
expect(described_class.new(f).caveats).to include("restart at login")
|
|
end
|
|
|
|
it "gives information about require_root restarting services after upgrade" do
|
|
f = formula do
|
|
url "foo-1.0"
|
|
service do
|
|
run [bin/"cmd"]
|
|
require_root true
|
|
end
|
|
end
|
|
f_obj = described_class.new(f)
|
|
expect(Utils::Service).to receive(:running?).with(f).once.and_return(true)
|
|
expect(f_obj.caveats).to include(" sudo brew services restart #{f.full_name}")
|
|
end
|
|
|
|
it "gives information about user restarting services after upgrade" do
|
|
f = formula do
|
|
url "foo-1.0"
|
|
service do
|
|
run [bin/"cmd"]
|
|
end
|
|
end
|
|
f_obj = described_class.new(f)
|
|
expect(Utils::Service).to receive(:running?).with(f).once.and_return(true)
|
|
expect(f_obj.caveats).to include(" brew services restart #{f.full_name}")
|
|
end
|
|
|
|
it "gives information about require_root starting services after upgrade" do
|
|
f = formula do
|
|
url "foo-1.0"
|
|
service do
|
|
run [bin/"cmd"]
|
|
require_root true
|
|
end
|
|
end
|
|
f_obj = described_class.new(f)
|
|
expect(Utils::Service).to receive(:running?).with(f).once.and_return(false)
|
|
expect(f_obj.caveats).to include(" sudo brew services start #{f.full_name}")
|
|
end
|
|
|
|
it "gives information about user starting services after upgrade" do
|
|
f = formula do
|
|
url "foo-1.0"
|
|
service do
|
|
run [bin/"cmd"]
|
|
end
|
|
end
|
|
f_obj = described_class.new(f)
|
|
expect(Utils::Service).to receive(:running?).with(f).once.and_return(false)
|
|
expect(f_obj.caveats).to include(" brew services start #{f.full_name}")
|
|
end
|
|
|
|
it "gives information about service manual command" do
|
|
f = formula do
|
|
url "foo-1.0"
|
|
service do
|
|
run [bin/"cmd", "start"]
|
|
environment_variables VAR: "foo"
|
|
end
|
|
end
|
|
cmd = "#{HOMEBREW_CELLAR}/formula_name/1.0/bin/cmd"
|
|
caveats = described_class.new(f).caveats
|
|
|
|
expect(caveats).to include("if you don't want/need a background service")
|
|
expect(caveats).to include("VAR=\"foo\" #{cmd} start")
|
|
end
|
|
|
|
it "prints info when there are custom service files" do
|
|
f = formula do
|
|
url "foo-1.0"
|
|
service do
|
|
plist_name "custom.mxcl.foo"
|
|
service_name "custom.foo"
|
|
end
|
|
end
|
|
expect(Utils::Service).to receive(:installed?).with(f).once.and_return(true)
|
|
expect(Utils::Service).to receive(:running?).with(f).once.and_return(false)
|
|
expect(described_class.new(f).caveats).to include("restart at login")
|
|
end
|
|
end
|
|
|
|
context "when f.keg_only is not nil" do
|
|
let(:f) do
|
|
formula do
|
|
url "foo-1.0"
|
|
keg_only "some reason"
|
|
end
|
|
end
|
|
let(:caveats) { described_class.new(f).caveats }
|
|
|
|
it "tells formula is keg_only" do
|
|
expect(caveats).to include("keg-only")
|
|
end
|
|
|
|
it "gives command to be run when f.bin is a directory" do
|
|
Pathname.new(f.bin).mkpath
|
|
expect(caveats).to include(f.opt_bin.to_s)
|
|
end
|
|
|
|
it "gives command to be run when f.sbin is a directory" do
|
|
Pathname.new(f.sbin).mkpath
|
|
expect(caveats).to include(f.opt_sbin.to_s)
|
|
end
|
|
|
|
context "when f.lib or f.include is a directory" do
|
|
it "gives command to be run when f.lib is a directory" do
|
|
Pathname.new(f.lib).mkpath
|
|
expect(caveats).to include("-L#{f.opt_lib}")
|
|
end
|
|
|
|
it "gives command to be run when f.include is a directory" do
|
|
Pathname.new(f.include).mkpath
|
|
expect(caveats).to include("-I#{f.opt_include}")
|
|
end
|
|
|
|
it "gives PKG_CONFIG_PATH when f.lib/'pkgconfig' and f.share/'pkgconfig' are directories" do
|
|
allow_any_instance_of(Object).to receive(:which).with(any_args).and_return(Pathname.new("blah"))
|
|
|
|
Pathname.new(f.share/"pkgconfig").mkpath
|
|
Pathname.new(f.lib/"pkgconfig").mkpath
|
|
|
|
expect(caveats).to include("#{f.opt_lib}/pkgconfig")
|
|
expect(caveats).to include("#{f.opt_share}/pkgconfig")
|
|
end
|
|
end
|
|
|
|
context "when joining different caveat types together" do
|
|
let(:f) do
|
|
formula do
|
|
url "foo-1.0"
|
|
keg_only "some reason"
|
|
|
|
def caveats
|
|
"something else"
|
|
end
|
|
|
|
service do
|
|
run [bin/"cmd"]
|
|
end
|
|
end
|
|
end
|
|
|
|
let(:caveats) { described_class.new(f).caveats }
|
|
|
|
it "adds the correct amount of new lines to the output" do
|
|
expect(caveats).to include("something else")
|
|
expect(caveats).to include("keg-only")
|
|
expect(caveats).to include("if you don't want/need a background service")
|
|
expect(caveats.count("\n")).to eq(9)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "shell completions" do
|
|
let(:f) do
|
|
formula do
|
|
url "foo-1.0"
|
|
end
|
|
end
|
|
let(:caveats) { described_class.new(f).caveats }
|
|
let(:path) { f.prefix.resolved_path }
|
|
|
|
before do
|
|
# don't try to load/fetch gcc/glibc
|
|
allow(DevelopmentTools).to receive(:needs_libc_formula?).and_return(false)
|
|
allow(DevelopmentTools).to receive(:needs_compiler_formula?).and_return(false)
|
|
|
|
allow_any_instance_of(Pathname).to receive(:children).and_return([Pathname.new("child")])
|
|
allow_any_instance_of(Object).to receive(:which).with(any_args).and_return(Pathname.new("shell"))
|
|
allow(Utils::Shell).to receive(:preferred).and_return(nil)
|
|
allow(Utils::Shell).to receive(:parent).and_return(nil)
|
|
end
|
|
|
|
it "gives dir where Bash completions have been installed" do
|
|
(path/"etc/bash_completion.d").mkpath
|
|
expect(caveats).to include(HOMEBREW_PREFIX/"etc/bash_completion.d")
|
|
end
|
|
|
|
it "gives dir where zsh completions have been installed" do
|
|
(path/"share/zsh/site-functions").mkpath
|
|
expect(caveats).to include(HOMEBREW_PREFIX/"share/zsh/site-functions")
|
|
end
|
|
|
|
it "gives dir where fish completions have been installed" do
|
|
(path/"share/fish/vendor_completions.d").mkpath
|
|
expect(caveats).to include(HOMEBREW_PREFIX/"share/fish/vendor_completions.d")
|
|
end
|
|
end
|
|
end
|
|
end
|