Skip to content

bundle/brew_services: typed strict#21829

Open
branchv wants to merge 1 commit intoHomebrew:mainfrom
branchv:brew-services-typed
Open

bundle/brew_services: typed strict#21829
branchv wants to merge 1 commit intoHomebrew:mainfrom
branchv:brew-services-typed

Conversation

@branchv
Copy link
Copy Markdown
Member

@branchv branchv commented Mar 25, 2026


  • Have you followed the guidelines in our Contributing document?
  • Have you checked to ensure there aren't other open Pull Requests for the same change?
  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you written new tests (excluding integration tests) for your changes? Here's an example.
  • Have you successfully run brew lgtm (style, typechecking and tests) with your changes locally?

  • AI was used to generate or assist with generating this PR. Please specify below how you used AI to help you, and what steps you have taken to manually verify the changes.

Just tightening this file up after #21828

Copilot AI review requested due to automatic review settings March 25, 2026 04:49
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR tightens Sorbet typing around Homebrew Bundle’s service integration by moving bundle/brew_services.rb to typed: strict and adjusting call sites accordingly.

Changes:

  • Switch Library/Homebrew/bundle/brew_services.rb to # typed: strict and add Sorbet sigs / typed ivars.
  • Add typed memoization for cached service state and old-name lookup.
  • Adjust bundle exec service conflict handling to use a typed local variable for the service name.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
Library/Homebrew/bundle/commands/exec.rb Adds a Sorbet cast to satisfy typing when stopping conflicting services.
Library/Homebrew/bundle/brew_services.rb Moves to typed: strict and introduces method signatures and typed instance variables.
Comments suppressed due to low confidence (1)

Library/Homebrew/bundle/brew_services.rb:114

  • In a typed: strict file, installed_and_up_to_date? is overriding Homebrew::Bundle::PackageType#installed_and_up_to_date?, but the new sig uses T.untyped and doesn’t declare override. Consider tightening this to match the parent signature (e.g., override.params(package: Object, no_upgrade: T::Boolean).returns(T::Boolean)) to keep strict-mode type safety consistent with other Bundle package types.
        sig { params(formula: T.untyped, no_upgrade: T::Boolean).returns(T::Boolean) }
        def installed_and_up_to_date?(formula, no_upgrade: false)
          _ = no_upgrade

          return true unless formula_needs_to_start?(entry_to_formula(formula))
          return true if self.class.started?(formula.name)

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@branchv branchv force-pushed the brew-services-typed branch from 5666dbc to 17b257f Compare March 25, 2026 05:25
Copy link
Copy Markdown
Member

@MikeMcQuaid MikeMcQuaid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good so far, some notes. May be worth tightening up Homebrew::Bundle::Brew if that's where all the Objects have crept in.

conflicting_services.each do |conflict|
if Bundle::Brew::Services.stop(conflict["name"], keep: true)
services_to_restart << conflict["name"] if conflict["registered"]
name = T.cast(conflict["name"], String)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
name = T.cast(conflict["name"], String)
name = conflict["name"].to_s

Comment on lines +109 to +112
sig { override.params(formula: Object, no_upgrade: T::Boolean).returns(T::Boolean) }
def installed_and_up_to_date?(formula, no_upgrade: false)
_ = no_upgrade
formula = T.cast(formula, Homebrew::Bundle::Dsl::Entry)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This cast is weird.

Suggested change
sig { override.params(formula: Object, no_upgrade: T::Boolean).returns(T::Boolean) }
def installed_and_up_to_date?(formula, no_upgrade: false)
_ = no_upgrade
formula = T.cast(formula, Homebrew::Bundle::Dsl::Entry)
sig { override.params(formula: Homebrew::Bundle::Dsl::Entry, no_upgrade: T::Boolean).returns(T::Boolean) }
def installed_and_up_to_date?(formula, no_upgrade: false)
_ = no_upgrade

old_name
end

sig { override.params(entries: T::Array[Object]).returns(T::Array[Object]) }
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can something more specific than Object be used here?

@started_services = T.let(nil, T.nilable(T::Array[String]))
end

sig { params(name: String, keep: T::Boolean, verbose: T::Boolean).returns(T.nilable(T::Boolean)) }
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoiding T.nilable(T::Boolean) would be good, nicer to return false or true and make a T::Boolean. Same with all others below.

end
end

sig { override.params(name: Object, no_upgrade: T::Boolean).returns(String) }
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid Object for name

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants