Skip to content

Add JSON output method for doctor#22448

Open
SMillerDev wants to merge 3 commits into
mainfrom
feat/doctor/output_json
Open

Add JSON output method for doctor#22448
SMillerDev wants to merge 3 commits into
mainfrom
feat/doctor/output_json

Conversation

@SMillerDev

Copy link
Copy Markdown
Member

Add an option to output the brew doctor results in easily parseable JSON output.


  • 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? Performance claims (e.g. "this is faster") must include Hyperfine benchmarks.
  • 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.

Copilot AI review requested due to automatic review settings May 29, 2026 13:06

@MikeMcQuaid MikeMcQuaid left a comment

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.

Great idea but I think this needs a lot of work before we can merge. We need to actually provide structured output from all diagnostics rather than relying on regexes.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 adds JSON output support to brew doctor, making diagnostic results easier for scripts and tools to consume.

Changes:

  • Adds a --json switch to brew doctor.
  • Builds and prints a JSON object containing a support tier and findings.
  • Adds the generated Sorbet RBI predicate and a basic command spec.

Reviewed changes

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

File Description
Library/Homebrew/cmd/doctor.rb Adds JSON output generation for doctor diagnostics.
Library/Homebrew/sorbet/rbi/dsl/homebrew/cmd/doctor.rbi Adds the json? argument predicate.
Library/Homebrew/test/cmd/doctor_spec.rb Adds a basic spec for brew doctor --json.
Files not reviewed (1)
  • Library/Homebrew/sorbet/rbi/dsl/homebrew/cmd/doctor.rbi: Language not supported

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

Comment thread Library/Homebrew/cmd/doctor.rb Outdated
Comment thread Library/Homebrew/cmd/doctor.rb Outdated
Comment thread Library/Homebrew/cmd/doctor.rb Outdated
Comment thread Library/Homebrew/test/cmd/doctor_spec.rb
@SMillerDev

SMillerDev commented May 29, 2026

Copy link
Copy Markdown
Member Author

Fair enough, I'd suggest a structure like this:

  • Title
  • Issue description
  • Tier indicator
  • Affects (list of full package names)
  • links: (list of URLs)
  • Remediation
    • commands (list)
    • text (or empty)

That we can then turn into a string or json object in the output.

@MikeMcQuaid

Copy link
Copy Markdown
Member

@SMillerDev yeh something like that sounds good. Also may want to have things like: affected formulae/casks, relevant URL(s).

@SMillerDev

Copy link
Copy Markdown
Member Author

Adjusted to include that

@MikeMcQuaid

Copy link
Copy Markdown
Member

@SMillerDev looks good except we need to return the structured data from diagnostics rather than using regex on their string output.

@SMillerDev

Copy link
Copy Markdown
Member Author

Yeah, fully planning to do that. Just wanted to work out a structure here before I get on reshaping all audit check output 😅

@SMillerDev SMillerDev force-pushed the feat/doctor/output_json branch from 81d5b7e to 3bbaf15 Compare June 2, 2026 09:27
@SMillerDev

Copy link
Copy Markdown
Member Author

JSON output:

{
  "tier": 1,
  "findings": [
    {
      "title": "Deprecated or disabled formulae",
      "issue": "Some installed formulae are deprecated or disabled.",
      "tier": 1,
      "affects": [
        "php@7.2",
        "mysql@8.0"
      ],
      "links": [],
      "remediation": {
        "commands": [],
        "text": "You should find replacements for the following formulae:\nmysql@8.0\n  php@7.2\n"
      }
    }
  ]
}

@SMillerDev SMillerDev force-pushed the feat/doctor/output_json branch from 3bbaf15 to bb17f35 Compare June 2, 2026 09:30

@MikeMcQuaid MikeMcQuaid left a comment

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.

Thanks, this is looking good! Will take another look when 🟢 and comments addressed. Happy to discuss more before addressing.

Comment thread Library/Homebrew/diagnostic.rb Outdated
Comment thread Library/Homebrew/diagnostic.rb Outdated
Comment thread Library/Homebrew/diagnostic.rb Outdated
@SMillerDev SMillerDev force-pushed the feat/doctor/output_json branch 4 times, most recently from e94087a to 2324ef7 Compare June 10, 2026 12:36
@SMillerDev SMillerDev force-pushed the feat/doctor/output_json branch 7 times, most recently from a816ce5 to 800b5e2 Compare June 23, 2026 09:16
@SMillerDev SMillerDev requested a review from MikeMcQuaid June 23, 2026 09:44

@MikeMcQuaid MikeMcQuaid left a comment

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.

Looking good so far!

Comment thread Library/Homebrew/cmd/doctor.rb Outdated
Comment thread Library/Homebrew/cmd/doctor.rb Outdated
Comment thread Library/Homebrew/cmd/doctor.rb Outdated
Comment thread Library/Homebrew/cmd/doctor.rb Outdated
Comment thread Library/Homebrew/cmd/doctor.rb Outdated
Comment thread Library/Homebrew/diagnostic.rb Outdated
Comment thread Library/Homebrew/diagnostic.rb Outdated
Comment thread Library/Homebrew/diagnostic.rb Outdated
Comment thread Library/Homebrew/diagnostic.rb Outdated
Comment thread Library/Homebrew/diagnostic.rb Outdated
@SMillerDev SMillerDev force-pushed the feat/doctor/output_json branch 4 times, most recently from aa5857b to ed7767d Compare July 2, 2026 15:44
@SMillerDev SMillerDev force-pushed the feat/doctor/output_json branch 13 times, most recently from 309e62a to 4c60d4e Compare July 7, 2026 16:06
@SMillerDev

Copy link
Copy Markdown
Member Author

I think this is ready for review again, now with a split out Findings class.

@MikeMcQuaid MikeMcQuaid left a comment

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.

Thanks! Looking better. I think I'd have more confidence to give a ✅ and have us merge this if we can split into two PRs:

  1. mostly this PR: make --json option hidden:, make it mostly a no-op, add Finding class, port maybe one method in each file to use a Finding (or just a single one or even zero), add all the to_s test changes that should be a no-op etc.

  2. make all the */diagnostic.rb changes so we can review those more closely line-by-line, unhide --json, will actually change behaviour for users.

Comment thread Library/Homebrew/cmd/doctor.rb Outdated
Comment thread Library/Homebrew/cmd/doctor.rb Outdated
Comment thread Library/Homebrew/os.rb Outdated
@SMillerDev SMillerDev force-pushed the feat/doctor/output_json branch 3 times, most recently from c7ec868 to a11c1e0 Compare July 10, 2026 10:12
@SMillerDev SMillerDev force-pushed the feat/doctor/output_json branch from a11c1e0 to 823007f Compare July 10, 2026 10:28
@SMillerDev SMillerDev force-pushed the feat/doctor/output_json branch from 377b846 to 39b875e Compare July 10, 2026 10:38
@SMillerDev

Copy link
Copy Markdown
Member Author

Okay, split it into two pull requests and made 2 methods a finding in this PR.

@MikeMcQuaid MikeMcQuaid left a comment

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.

Thanks, couple of last tiny things.

Comment thread Library/Homebrew/os.rb

sig { returns(T.nilable(String)) }
def self.issues_url
OS::ISSUES_URL if defined?(OS::ISSUES_URL)

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.

Again: why is this better than just a defined?(OS::ISSUES_URL) check? We're literally doing that in method just above.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I misunderstood the question then. I don't think it's better, I just need the url. Not just the check.

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.

Cool, just inline OS::ISSUES_URL if defined?(OS::ISSUES_URL) instead of adding this IMO

next if out.blank?
finding = checks.public_send(method)
method_findings = T.let(Array(finding).compact, T::Array[T.any(Diagnostic::Finding, 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

Comment thread Library/Homebrew/cmd/doctor.rb Outdated

sig { params(formula: ::Formula).returns(T.nilable(String)) }
def check_flat_namespace(formula)
# See https://developer.apple.com/forums/thread/689991?answerId=687895022#687895022

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.

What's this about?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

So that's where that went. That's meant to be a separate pull request, ignore it

def mismatch_warning_message(mismatch)
<<~EOS
You have pkgconf installed that was built on macOS #{mismatch[0]},
You have pkgconf installed that was built on macOS #{mismatch[0]},

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.

Same here

Co-authored-by: Mike McQuaid <mike@mikemcquaid.com>
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