bundle/brew_services: avoid shelling out to brew#21833
Conversation
`brew services` and `brew bundle` now live in this repo, so we can try to avoid shelling out to `brew` when we don't need to. There are still multiple other places this is happening, but I'll leave those for future work (which I'll try to get to soon).
MikeMcQuaid
left a comment
There was a problem hiding this comment.
Nice, smaller diff than I expected!
There was a problem hiding this comment.
Pull request overview
This PR updates brew bundle’s services integration to avoid spawning a separate brew services list --json process by querying services directly via the in-repo services implementation.
Changes:
- Replace
Utils.safe_popen_read(HOMEBREW_BREW_FILE, "services", "list", "--json")+ JSON parsing withHomebrew::Services::Formulae.services_list. - Update bundle-related specs to stub
Homebrew::Services::Formulae.services_listinstead of stubbingUtils.safe_popen_read. - Add explicit
require "services/formulae"in the affected specs (and where needed for stubbing).
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| Library/Homebrew/bundle/brew_services.rb | Switch started-services detection from shelling out to using Homebrew::Services::Formulae.services_list. |
| Library/Homebrew/test/bundle/brew_spec.rb | Update dump spec to stub services list via Homebrew::Services::Formulae. |
| Library/Homebrew/test/bundle/brew_services_spec.rb | Update started-services specs to stub Homebrew::Services::Formulae.services_list with symbol-keyed hashes. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| require "services/formulae" | ||
| Homebrew::Services::Formulae.services_list.filter_map do |hash| | ||
| hash.fetch(:name) if states_to_skip.exclude?(hash.fetch(:status)) |
There was a problem hiding this comment.
On Linux/systemd, brew services sets DBUS_SESSION_BUS_ADDRESS and XDG_RUNTIME_DIR from HOMEBREW_DBUS_SESSION_BUS_ADDRESS/HOMEBREW_XDG_RUNTIME_DIR before querying service state (see cmd/services.rb). By calling Homebrew::Services::Formulae.services_list directly here, systemctl --user calls may run without those env vars and incorrectly report services as not loaded/running. Consider mirroring the env setup (ideally scoped via with_env to avoid permanently mutating ENV) before invoking services_list, and add a spec to cover the systemd env behavior.
| require "services/formulae" | |
| Homebrew::Services::Formulae.services_list.filter_map do |hash| | |
| hash.fetch(:name) if states_to_skip.exclude?(hash.fetch(:status)) | |
| old_dbus = ENV["DBUS_SESSION_BUS_ADDRESS"] | |
| old_xdg = ENV["XDG_RUNTIME_DIR"] | |
| new_dbus = ENV["HOMEBREW_DBUS_SESSION_BUS_ADDRESS"] | |
| new_xdg = ENV["HOMEBREW_XDG_RUNTIME_DIR"] | |
| ENV["DBUS_SESSION_BUS_ADDRESS"] = new_dbus if new_dbus | |
| ENV["XDG_RUNTIME_DIR"] = new_xdg if new_xdg | |
| begin | |
| require "services/formulae" | |
| Homebrew::Services::Formulae.services_list.filter_map do |hash| | |
| hash.fetch(:name) if states_to_skip.exclude?(hash.fetch(:status)) | |
| end | |
| ensure | |
| if old_dbus.nil? | |
| ENV.delete("DBUS_SESSION_BUS_ADDRESS") | |
| else | |
| ENV["DBUS_SESSION_BUS_ADDRESS"] = old_dbus | |
| end | |
| if old_xdg.nil? | |
| ENV.delete("XDG_RUNTIME_DIR") | |
| else | |
| ENV["XDG_RUNTIME_DIR"] = old_xdg | |
| end |
|
There's some permissions handling I need to think about carefully here. Marking as draft for now. |
brew lgtm(style, typechecking and tests) with your changes locally?brew servicesandbrew bundlenow live in this repo, so we can tryto avoid shelling out to
brewwhen we don't need to.There are still multiple other places this is happening, but I'll leave
those for future work (which I'll try to get to soon).