From 2677aedea8eaad819c4a00beaed2278b687ab7d7 Mon Sep 17 00:00:00 2001 From: Douglas Eichelberger Date: Sun, 26 Apr 2026 20:06:19 -0700 Subject: [PATCH] system_command: avoid loading plist and URI libraries at startup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- AGENTS.md | 2 ++ Library/Homebrew/system_command.rb | 16 ++++++++-------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 527f6cd3b4..f6b230a56c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -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 -- ` 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 diff --git a/Library/Homebrew/system_command.rb b/Library/Homebrew/system_command.rb index 5d3dcad4ba..2db76f094c 100644 --- a/Library/Homebrew/system_command.rb +++ b/Library/Homebrew/system_command.rb @@ -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