system_command: avoid loading plist and URI libraries at startup

These two requires were loaded globally on every brew invocation via
extend/pathname → system_command, but neither was needed at startup:

- `plist`: only used in Result#plist method body; deferred with a lazy
  require inside the method. This avoids loading the plist gem and its
  transitive deps (cgi, date, stringio) for commands that don't parse
  plist output (the vast majority).

- `uri`: URI::Generic only appears in Sorbet sigs. Changed the six
  affected sigs to T::Sig::WithoutRuntime.sig so the sig blocks are
  not evaluated at runtime, allowing the require to be dropped
  entirely. Added an explicit require "stringio" since that was a
  transitive dep of plist relied on by utils/tty.rb.

Also adds an AGENTS.md note to always use `./bin/brew ruby` instead
of the system Ruby when running Ruby directly.
This commit is contained in:
Douglas Eichelberger
2026-05-03 15:20:54 -07:00
parent b9763ee528
commit 2677aedea8
2 changed files with 10 additions and 8 deletions
+2
View File
@@ -8,6 +8,8 @@ Please follow these guidelines when contributing:
When running commands in this repository, use `./bin/brew` (not a system `brew` on `PATH`).
When running Ruby directly (e.g. `ruby -e ...`, `gem`, profiling tools), never use the system Ruby. Use `./bin/brew ruby -- <args>` to run Ruby scripts with Homebrew's vendored Ruby and libraries loaded. The system macOS Ruby is an incompatible older version.
## Code Standards
### Required Before Each Commit
+8 -8
View File
@@ -1,9 +1,8 @@
# typed: strict
# frozen_string_literal: true
require "plist"
require "shellwords"
require "uri"
require "stringio"
require "context"
require "readline_nonblock"
@@ -24,7 +23,7 @@ class SystemCommand
sig {
params(
executable: T.any(String, Pathname),
args: T::Array[T.any(String, Integer, Float, Pathname, URI::Generic)],
args: T::Array[T.any(String, Integer, Float, Pathname)],
sudo: T::Boolean,
sudo_as_root: T::Boolean,
env: T::Hash[String, T.nilable(T.any(String, T::Boolean, PATH))],
@@ -54,7 +53,7 @@ class SystemCommand
sig {
params(
executable: T.any(String, Pathname),
args: T::Array[T.any(String, Integer, Float, Pathname, URI::Generic)],
args: T::Array[T.any(String, Integer, Float, Pathname)],
sudo: T::Boolean,
sudo_as_root: T::Boolean,
env: T::Hash[String, T.nilable(T.any(String, T::Boolean, PATH))],
@@ -83,7 +82,7 @@ class SystemCommand
sig {
params(
executable: T.any(String, Pathname),
args: T::Array[T.any(String, Integer, Float, Pathname, URI::Generic)],
args: T::Array[T.any(String, Integer, Float, Pathname)],
sudo: T::Boolean,
sudo_as_root: T::Boolean,
env: T::Hash[String, T.nilable(T.any(String, T::Boolean, PATH))],
@@ -110,7 +109,7 @@ class SystemCommand
sig {
params(
executable: T.any(String, Pathname),
args: T::Array[T.any(String, Integer, Float, Pathname, URI::Generic)],
args: T::Array[T.any(String, Integer, Float, Pathname)],
sudo: T::Boolean,
sudo_as_root: T::Boolean,
env: T::Hash[String, T.nilable(T.any(String, T::Boolean, PATH))],
@@ -170,7 +169,7 @@ class SystemCommand
sig {
params(
executable: T.any(String, Pathname),
args: T::Array[T.any(String, Integer, Float, Pathname, URI::Generic)],
args: T::Array[T.any(String, Integer, Float, Pathname)],
sudo: T::Boolean,
sudo_as_root: T::Boolean,
env: T::Hash[String, T.nilable(T.any(String, T::Boolean, PATH))],
@@ -235,7 +234,7 @@ class SystemCommand
sig { returns(T.any(Pathname, String)) }
attr_reader :executable
sig { returns(T::Array[T.any(String, Integer, Float, Pathname, URI::Generic)]) }
sig { returns(T::Array[T.any(String, Integer, Float, Pathname)]) }
attr_reader :args
sig { returns(T::Array[String]) }
@@ -548,6 +547,7 @@ class SystemCommand
sig { returns(T.untyped) }
def plist
require "plist"
@plist ||= T.let(begin
output = stdout