mirror of
https://github.com/Homebrew/brew.git
synced 2026-08-12 22:29:27 +04:00
config: gather system configuration concurrently
This commit is contained in:
@@ -62,14 +62,22 @@ class DevelopmentTools
|
||||
Version::NULL
|
||||
end
|
||||
|
||||
sig { returns(T.nilable(String)) }
|
||||
def clang_version_output
|
||||
@clang_version_output ||= T.let(
|
||||
if (path = locate("clang"))
|
||||
`#{path} --version`
|
||||
end, T.nilable(String)
|
||||
)
|
||||
end
|
||||
|
||||
# Get the Clang version.
|
||||
#
|
||||
# @api public
|
||||
sig { returns(Version) }
|
||||
def clang_version
|
||||
@clang_version ||= T.let(
|
||||
if (path = locate("clang")) &&
|
||||
(build_version = `#{path} --version`[/(?:clang|LLVM) version (\d+\.\d(?:\.\d)?)/, 1])
|
||||
if (build_version = clang_version_output&.[](/(?:clang|LLVM) version (\d+\.\d(?:\.\d)?)/, 1))
|
||||
Version.new(build_version)
|
||||
else
|
||||
Version::NULL
|
||||
@@ -83,8 +91,7 @@ class DevelopmentTools
|
||||
sig { returns(Version) }
|
||||
def clang_build_version
|
||||
@clang_build_version ||= T.let(
|
||||
if (path = locate("clang")) &&
|
||||
(build_version = `#{path} --version`[%r{clang(-| version [^ ]+ \(tags/RELEASE_)(\d{2,})}, 2])
|
||||
if (build_version = clang_version_output&.[](%r{clang(-| version [^ ]+ \(tags/RELEASE_)(\d{2,})}, 2))
|
||||
Version.new(build_version)
|
||||
else
|
||||
Version::NULL
|
||||
@@ -134,6 +141,7 @@ class DevelopmentTools
|
||||
|
||||
sig { void }
|
||||
def clear_version_cache
|
||||
@clang_version_output = T.let(nil, T.nilable(String))
|
||||
@clang_version = @clang_build_version = T.let(nil, T.nilable(Version))
|
||||
@gcc_version = T.let({}, T.nilable(T::Hash[String, Version]))
|
||||
end
|
||||
|
||||
@@ -104,10 +104,8 @@ module OS
|
||||
end
|
||||
|
||||
sig { params(out: T.any(File, StringIO, IO)).void }
|
||||
def dump_verbose_config(out = $stdout)
|
||||
kernel = Utils.safe_popen_read("uname", "-mors").chomp
|
||||
super
|
||||
out.puts "Kernel: #{kernel}"
|
||||
def linux_config(out = $stdout)
|
||||
out.puts "Kernel: #{Utils.safe_popen_read("uname", "-mors").chomp}"
|
||||
out.puts "OS: #{OS::Linux.os_version}"
|
||||
if OS.wsl?
|
||||
out.puts "WSL: #{OS::Linux.wsl_version}"
|
||||
@@ -122,6 +120,11 @@ module OS
|
||||
out.puts "#{f}: #{formula_linked_version(f)}"
|
||||
end
|
||||
end
|
||||
|
||||
sig { returns(T::Array[Symbol]) }
|
||||
def config_sections
|
||||
super + [:linux_config]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -62,8 +62,7 @@ module OS
|
||||
end
|
||||
|
||||
sig { params(out: T.any(File, StringIO, IO)).void }
|
||||
def dump_verbose_config(out = $stdout)
|
||||
super
|
||||
def macos_config(out = $stdout)
|
||||
out.puts "macOS: #{MacOS.full_version}-#{kernel}"
|
||||
out.puts "CLT: #{clt || "N/A"}"
|
||||
out.puts "Xcode: #{xcode || "N/A"}"
|
||||
@@ -73,6 +72,11 @@ module OS
|
||||
end
|
||||
out.puts "Rosetta 2: #{::Hardware::CPU.in_rosetta2?}" if ::Hardware::CPU.physical_cpu_arm64?
|
||||
end
|
||||
|
||||
sig { returns(T::Array[Symbol]) }
|
||||
def config_sections
|
||||
super + [:macos_config]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -45,6 +45,19 @@ class GitRepository
|
||||
popen_git("show", "-s", "--format=%cr", "HEAD")
|
||||
end
|
||||
|
||||
# Gets the full commit hash of the HEAD commit, the relative date of the
|
||||
# last commit and the currently checked-out branch (or HEAD if the
|
||||
# repository is in a detached HEAD state) in a single Git invocation.
|
||||
sig { returns([T.nilable(String), T.nilable(String), T.nilable(String)]) }
|
||||
def head_info
|
||||
output = popen_git("show", "-s", "--format=%H%n%cr%n%D", "HEAD")
|
||||
return [nil, nil, nil] if output.nil?
|
||||
|
||||
head, last_committed, refs = output.lines(chomp: true)
|
||||
branch = refs&.[](/\AHEAD -> ([^,\n]+)/, 1) || "HEAD"
|
||||
[head, last_committed, branch]
|
||||
end
|
||||
|
||||
# Gets the name of the currently checked-out branch, or HEAD if the repository is in a detached HEAD state.
|
||||
sig { params(safe: T::Boolean).returns(T.nilable(String)) }
|
||||
def branch_name(safe: false)
|
||||
|
||||
@@ -42,19 +42,27 @@ module SystemConfig
|
||||
GitRepository.new(HOMEBREW_REPOSITORY)
|
||||
end
|
||||
|
||||
sig { returns([T.nilable(String), T.nilable(String), T.nilable(String)]) }
|
||||
def homebrew_head_info
|
||||
@homebrew_head_info ||= T.let(
|
||||
homebrew_repo.head_info,
|
||||
T.nilable([T.nilable(String), T.nilable(String), T.nilable(String)]),
|
||||
)
|
||||
end
|
||||
|
||||
sig { returns(String) }
|
||||
def branch
|
||||
homebrew_repo.branch_name || "(none)"
|
||||
homebrew_head_info[2] || "(none)"
|
||||
end
|
||||
|
||||
sig { returns(String) }
|
||||
def head
|
||||
homebrew_repo.head_ref || "(none)"
|
||||
homebrew_head_info[0] || "(none)"
|
||||
end
|
||||
|
||||
sig { returns(String) }
|
||||
def last_commit
|
||||
homebrew_repo.last_committed || "never"
|
||||
homebrew_head_info[1] || "never"
|
||||
end
|
||||
|
||||
sig { returns(String) }
|
||||
@@ -127,10 +135,11 @@ module SystemConfig
|
||||
|
||||
if tap.installed?
|
||||
out.puts "#{tap_name} origin: #{tap.remote}" if tap.remote != tap.default_remote
|
||||
out.puts "#{tap_name} HEAD: #{tap.git_head || "(none)"}"
|
||||
out.puts "#{tap_name} last commit: #{tap.git_last_commit || "never"}"
|
||||
head, last_commit, branch = tap.git_repository.head_info
|
||||
out.puts "#{tap_name} HEAD: #{head || "(none)"}"
|
||||
out.puts "#{tap_name} last commit: #{last_commit || "never"}"
|
||||
default_branches = %w[main master].freeze
|
||||
out.puts "#{tap_name} branch: #{tap.git_branch || "(none)"}" if default_branches.exclude?(tap.git_branch)
|
||||
out.puts "#{tap_name} branch: #{branch || "(none)"}" if default_branches.exclude?(branch)
|
||||
end
|
||||
|
||||
json_file = Homebrew::API::HOMEBREW_CACHE_API/json_file_name
|
||||
@@ -194,12 +203,29 @@ module SystemConfig
|
||||
end
|
||||
|
||||
sig { params(out: T.any(File, StringIO, IO)).void }
|
||||
def dump_verbose_config(out = $stdout)
|
||||
homebrew_config(out)
|
||||
core_tap_config(out)
|
||||
homebrew_env_config(out)
|
||||
def hardware_config(out = $stdout)
|
||||
hardware = self.hardware
|
||||
out.puts hardware if hardware
|
||||
host_software_config(out)
|
||||
end
|
||||
|
||||
sig { returns(T::Array[Symbol]) }
|
||||
def config_sections
|
||||
[:homebrew_config, :core_tap_config, :homebrew_env_config, :hardware_config, :host_software_config]
|
||||
end
|
||||
|
||||
sig { params(out: T.any(File, StringIO, IO)).void }
|
||||
def dump_verbose_config(out = $stdout)
|
||||
# Most sections shell out for their values (Git, compilers, curl,
|
||||
# etc.), so render them concurrently and print them in order.
|
||||
threads = config_sections.map do |section|
|
||||
Thread.new do
|
||||
Thread.current.report_on_exception = false
|
||||
io = StringIO.new
|
||||
public_send(section, io)
|
||||
io.string
|
||||
end
|
||||
end
|
||||
threads.each { |thread| out.print thread.value }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -69,6 +69,21 @@ RSpec.describe Homebrew::Cmd::Config do
|
||||
expect(output.string).to include("Windows: Windows 11 Pro (25H2) [26200.8457]\n")
|
||||
end
|
||||
|
||||
it "prints config sections in order" do
|
||||
output = StringIO.new
|
||||
|
||||
allow(SystemConfig).to receive(:config_sections).and_return([:homebrew_config, :host_software_config])
|
||||
allow(SystemConfig).to receive(:homebrew_config) do |io|
|
||||
sleep(0.01)
|
||||
io.puts "first"
|
||||
end
|
||||
allow(SystemConfig).to receive(:host_software_config) { |io| io.puts "second" }
|
||||
|
||||
SystemConfig.dump_verbose_config(output)
|
||||
|
||||
expect(output.string).to eq("first\nsecond\n")
|
||||
end
|
||||
|
||||
it "does not print HOMEBREW_EVAL_ALL unless it is directly set" do
|
||||
output = StringIO.new
|
||||
|
||||
|
||||
@@ -47,6 +47,19 @@ RSpec.describe GitRepository do
|
||||
end
|
||||
end
|
||||
|
||||
describe "#head_info" do
|
||||
it "returns the HEAD commit hash, relative commit time and branch name in one Git invocation" do
|
||||
expect(git_repo.head_info).to eq([git_repo.head_ref, git_repo.last_committed, branch_name])
|
||||
|
||||
clone_path.cd do
|
||||
safe_system Utils::Git.git, "checkout", "--quiet", "--detach"
|
||||
end
|
||||
expect(git_repo.head_info[2]).to eq("HEAD")
|
||||
|
||||
expect(described_class.new(repo_root/"nonexistent").head_info).to eq([nil, nil, nil])
|
||||
end
|
||||
end
|
||||
|
||||
describe "when the origin has a branch and tag with the same name" do
|
||||
it "disambiguates branch_name, origin_branch_name, and default_origin_branch?" do
|
||||
expect(git_repo.branch_name).to eq(branch_name)
|
||||
|
||||
Reference in New Issue
Block a user