brew/Library/Homebrew/caveats.rb

199 lines
6.0 KiB
Ruby
Raw Normal View History

# typed: true
# frozen_string_literal: true
2017-12-30 18:58:30 +00:00
require "language/python"
service: add custom service name DSL 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
2023-04-13 23:33:31 -07:00
require "utils/service"
2017-10-21 20:01:07 +02:00
2020-08-17 02:53:57 +02:00
# A formula's caveats.
#
# @api private
class Caveats
extend Forwardable
attr_reader :formula
def initialize(formula)
@formula = formula
end
def caveats
caveats = []
begin
build = formula.build
formula.build = Tab.for_formula(formula)
string = formula.caveats.to_s
caveats << "#{string.chomp}\n" unless string.empty?
ensure
formula.build = build
end
caveats << keg_only_text
valid_shells = [:bash, :zsh, :fish].freeze
current_shell = Utils::Shell.preferred || Utils::Shell.parent
shells = if current_shell.present? &&
(shell_sym = current_shell.to_sym) &&
valid_shells.include?(shell_sym)
[shell_sym]
else
valid_shells
end
shells.each do |shell|
caveats << function_completion_caveats(shell)
end
caveats << service_caveats
caveats << elisp_caveats
caveats.compact.join("\n")
end
delegate [:empty?, :to_s] => :caveats
def keg_only_text(skip_reason: false)
return unless formula.keg_only?
s = if skip_reason
""
else
<<~EOS
#{formula.name} is keg-only, which means it was not symlinked into #{HOMEBREW_PREFIX},
because #{formula.keg_only_reason.to_s.chomp}.
EOS
2019-04-20 14:07:29 +09:00
end.dup
if formula.bin.directory? || formula.sbin.directory?
s << <<~EOS
If you need to have #{formula.name} first in your PATH, run:
EOS
s << " #{Utils::Shell.prepend_path_in_profile(formula.opt_bin.to_s)}\n" if formula.bin.directory?
s << " #{Utils::Shell.prepend_path_in_profile(formula.opt_sbin.to_s)}\n" if formula.sbin.directory?
end
if formula.lib.directory? || formula.include.directory?
s << <<~EOS
For compilers to find #{formula.name} you may need to set:
EOS
s << " #{Utils::Shell.export_value("LDFLAGS", "-L#{formula.opt_lib}")}\n" if formula.lib.directory?
s << " #{Utils::Shell.export_value("CPPFLAGS", "-I#{formula.opt_include}")}\n" if formula.include.directory?
if which("pkg-config", ORIGINAL_PATHS) &&
((formula.lib/"pkgconfig").directory? || (formula.share/"pkgconfig").directory?)
s << <<~EOS
For pkg-config to find #{formula.name} you may need to set:
EOS
if (formula.lib/"pkgconfig").directory?
s << " #{Utils::Shell.export_value("PKG_CONFIG_PATH", "#{formula.opt_lib}/pkgconfig")}\n"
end
if (formula.share/"pkgconfig").directory?
s << " #{Utils::Shell.export_value("PKG_CONFIG_PATH", "#{formula.opt_share}/pkgconfig")}\n"
end
end
end
s << "\n" unless s.end_with?("\n")
s
end
private
def keg
@keg ||= [formula.prefix, formula.opt_prefix, formula.linked_keg].map do |d|
Keg.new(d.resolved_path)
rescue
nil
end.compact.first
end
def function_completion_caveats(shell)
2016-09-22 20:12:28 +02:00
return unless keg
return unless which(shell.to_s, ORIGINAL_PATHS)
completion_installed = keg.completion_installed?(shell)
functions_installed = keg.functions_installed?(shell)
return if !completion_installed && !functions_installed
installed = []
installed << "completions" if completion_installed
installed << "functions" if functions_installed
root_dir = formula.keg_only? ? formula.opt_prefix : HOMEBREW_PREFIX
case shell
when :bash
2017-10-15 02:28:32 +02:00
<<~EOS
Bash completion has been installed to:
#{root_dir}/etc/bash_completion.d
EOS
when :fish
2019-04-20 14:07:29 +09:00
fish_caveats = +"fish #{installed.join(" and ")} have been installed to:"
fish_caveats << "\n #{root_dir}/share/fish/vendor_completions.d" if completion_installed
fish_caveats << "\n #{root_dir}/share/fish/vendor_functions.d" if functions_installed
2019-04-20 14:07:29 +09:00
fish_caveats.freeze
2024-02-13 18:46:58 +01:00
when :zsh
<<~EOS
zsh #{installed.join(" and ")} have been installed to:
#{root_dir}/share/zsh/site-functions
EOS
end
end
def elisp_caveats
return if formula.keg_only?
2016-09-22 20:12:28 +02:00
return unless keg
return unless keg.elisp_installed?
2017-10-15 02:28:32 +02:00
<<~EOS
2016-09-22 20:12:28 +02:00
Emacs Lisp files have been installed to:
#{HOMEBREW_PREFIX}/share/emacs/site-lisp/#{formula.name}
2016-09-22 20:12:28 +02:00
EOS
end
def service_caveats
service: add custom service name DSL 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
2023-04-13 23:33:31 -07:00
return if !formula.plist && !formula.service? && !Utils::Service.installed?(formula) && !keg&.plist_installed?
return if formula.service? && !formula.service.command? && !Utils::Service.installed?(formula)
s = []
service: add custom service name DSL 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
2023-04-13 23:33:31 -07:00
return <<~EOS if !Utils::Service.launchctl? && formula.plist
#{Formatter.warning("Warning:")} #{formula.name} provides a launchd plist which can only be used on macOS!
EOS
# Brew services only works with these two tools
service: add custom service name DSL 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
2023-04-13 23:33:31 -07:00
return <<~EOS if !Utils::Service.systemctl? && !Utils::Service.launchctl? && formula.service.command?
#{Formatter.warning("Warning:")} #{formula.name} provides a service which can only be used on macOS or systemd!
You can manually execute the service instead with:
#{formula.service.manual_command}
EOS
startup = formula.service.requires_root?
service: add custom service name DSL 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
2023-04-13 23:33:31 -07:00
if Utils::Service.running?(formula)
s << "To restart #{formula.full_name} after an upgrade:"
s << " #{startup ? "sudo " : ""}brew services restart #{formula.full_name}"
elsif startup
s << "To start #{formula.full_name} now and restart at startup:"
s << " sudo brew services start #{formula.full_name}"
else
s << "To start #{formula.full_name} now and restart at login:"
s << " brew services start #{formula.full_name}"
end
if formula.service.command?
s << "Or, if you don't want/need a background service you can just run:"
s << " #{formula.service.manual_command}"
end
# pbpaste is the system clipboard tool on macOS and fails with `tmux` by default
# check if this is being run under `tmux` to avoid failing
if ENV["HOMEBREW_TMUX"] && !quiet_system("/usr/bin/pbpaste")
s << "" << "WARNING: brew services will fail when run under tmux."
end
"#{s.join("\n")}\n" unless s.empty?
end
end