2025-04-02 17:15:32 +01:00
|
|
|
# typed: strict
|
2025-03-18 17:38:37 +00:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2025-03-24 21:55:47 +08:00
|
|
|
require "English"
|
|
|
|
|
|
|
|
module Homebrew
|
|
|
|
module Bundle
|
|
|
|
class << self
|
2025-04-02 17:15:32 +01:00
|
|
|
sig { params(args_upgrade_formula: T.nilable(String)).void }
|
|
|
|
def upgrade_formulae=(args_upgrade_formula)
|
|
|
|
@upgrade_formulae = args_upgrade_formula.to_s.split(",")
|
|
|
|
end
|
|
|
|
|
|
|
|
sig { returns(T::Array[String]) }
|
|
|
|
def upgrade_formulae
|
|
|
|
@upgrade_formulae || []
|
|
|
|
end
|
|
|
|
|
|
|
|
sig { params(cmd: T.any(String, Pathname), args: T.anything, verbose: T::Boolean).returns(T::Boolean) }
|
2025-03-24 21:55:47 +08:00
|
|
|
def system(cmd, *args, verbose: false)
|
|
|
|
return super cmd, *args if verbose
|
|
|
|
|
|
|
|
logs = []
|
2025-04-02 17:15:32 +01:00
|
|
|
success = T.let(false, T::Boolean)
|
2025-03-24 21:55:47 +08:00
|
|
|
IO.popen([cmd, *args], err: [:child, :out]) do |pipe|
|
|
|
|
while (buf = pipe.gets)
|
|
|
|
logs << buf
|
|
|
|
end
|
|
|
|
Process.wait(pipe.pid)
|
|
|
|
success = $CHILD_STATUS.success?
|
|
|
|
pipe.close
|
|
|
|
end
|
|
|
|
puts logs.join unless success
|
|
|
|
success
|
|
|
|
end
|
|
|
|
|
2025-04-02 17:15:32 +01:00
|
|
|
sig { params(args: T.anything, verbose: T::Boolean).returns(T::Boolean) }
|
2025-03-24 21:55:47 +08:00
|
|
|
def brew(*args, verbose: false)
|
|
|
|
system(HOMEBREW_BREW_FILE, *args, verbose:)
|
|
|
|
end
|
|
|
|
|
2025-04-02 17:15:32 +01:00
|
|
|
sig { returns(T::Boolean) }
|
2025-03-24 21:55:47 +08:00
|
|
|
def mas_installed?
|
|
|
|
@mas_installed ||= which_formula("mas")
|
|
|
|
end
|
|
|
|
|
2025-04-02 17:15:32 +01:00
|
|
|
sig { returns(T::Boolean) }
|
2025-03-24 21:55:47 +08:00
|
|
|
def vscode_installed?
|
|
|
|
@vscode_installed ||= which_vscode.present?
|
|
|
|
end
|
|
|
|
|
2025-04-02 17:15:32 +01:00
|
|
|
sig { returns(T.nilable(Pathname)) }
|
2025-03-24 21:55:47 +08:00
|
|
|
def which_vscode
|
|
|
|
@which_vscode ||= which("code", ORIGINAL_PATHS)
|
|
|
|
@which_vscode ||= which("codium", ORIGINAL_PATHS)
|
|
|
|
@which_vscode ||= which("cursor", ORIGINAL_PATHS)
|
|
|
|
@which_vscode ||= which("code-insiders", ORIGINAL_PATHS)
|
|
|
|
end
|
|
|
|
|
2025-04-02 17:15:32 +01:00
|
|
|
sig { returns(T::Boolean) }
|
2025-03-24 21:55:47 +08:00
|
|
|
def whalebrew_installed?
|
|
|
|
@whalebrew_installed ||= which_formula("whalebrew")
|
|
|
|
end
|
|
|
|
|
2025-04-02 17:15:32 +01:00
|
|
|
sig { returns(T::Boolean) }
|
2025-03-24 21:55:47 +08:00
|
|
|
def cask_installed?
|
|
|
|
@cask_installed ||= File.directory?("#{HOMEBREW_PREFIX}/Caskroom") &&
|
|
|
|
(File.directory?("#{HOMEBREW_LIBRARY}/Taps/homebrew/homebrew-cask") ||
|
|
|
|
!Homebrew::EnvConfig.no_install_from_api?)
|
|
|
|
end
|
|
|
|
|
2025-04-02 17:15:32 +01:00
|
|
|
sig { params(name: String).returns(T::Boolean) }
|
2025-03-24 21:55:47 +08:00
|
|
|
def which_formula(name)
|
|
|
|
formula = Formulary.factory(name)
|
|
|
|
ENV["PATH"] = "#{formula.opt_bin}:#{ENV.fetch("PATH", nil)}" if formula.any_version_installed?
|
|
|
|
which(name).present?
|
|
|
|
end
|
|
|
|
|
2025-04-02 17:15:32 +01:00
|
|
|
sig { params(block: T.proc.returns(T.anything)).returns(T.untyped) }
|
2025-03-24 21:55:47 +08:00
|
|
|
def exchange_uid_if_needed!(&block)
|
|
|
|
euid = Process.euid
|
|
|
|
uid = Process.uid
|
|
|
|
return yield if euid == uid
|
|
|
|
|
|
|
|
old_euid = euid
|
|
|
|
process_reexchangeable = Process::UID.re_exchangeable?
|
|
|
|
if process_reexchangeable
|
|
|
|
Process::UID.re_exchange
|
|
|
|
else
|
|
|
|
Process::Sys.seteuid(uid)
|
|
|
|
end
|
|
|
|
|
|
|
|
home = T.must(Etc.getpwuid(Process.uid)).dir
|
|
|
|
return_value = with_env("HOME" => home, &block)
|
|
|
|
|
|
|
|
if process_reexchangeable
|
|
|
|
Process::UID.re_exchange
|
|
|
|
else
|
|
|
|
Process::Sys.seteuid(old_euid)
|
|
|
|
end
|
|
|
|
|
|
|
|
return_value
|
|
|
|
end
|
2025-03-24 17:34:35 +00:00
|
|
|
|
2025-04-02 17:15:32 +01:00
|
|
|
sig { returns(T::Hash[String, String]) }
|
2025-03-24 17:34:35 +00:00
|
|
|
def formula_versions_from_env
|
|
|
|
@formula_versions_from_env ||= begin
|
|
|
|
formula_versions = {}
|
|
|
|
|
|
|
|
ENV.each do |key, value|
|
2025-04-01 15:35:27 +01:00
|
|
|
match = key.match(/^HOMEBREW_BUNDLE_FORMULA_VERSION_(.+)$/)
|
|
|
|
# odeprecated: get rid of this in Homebrew >=4.5
|
|
|
|
match ||= key.match(/^HOMEBREW_BUNDLE_EXEC_FORMULA_VERSION_(.+)$/)
|
2025-03-24 17:34:35 +00:00
|
|
|
next if match.blank?
|
|
|
|
|
|
|
|
formula_name = match[1]
|
|
|
|
next if formula_name.blank?
|
|
|
|
|
|
|
|
ENV.delete(key)
|
|
|
|
formula_versions[formula_name.downcase] = value
|
|
|
|
end
|
|
|
|
|
|
|
|
formula_versions
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
sig { void }
|
|
|
|
def reset!
|
2025-04-02 17:15:32 +01:00
|
|
|
@mas_installed = T.let(nil, T.nilable(T::Boolean))
|
|
|
|
@vscode_installed = T.let(nil, T.nilable(T::Boolean))
|
|
|
|
@which_vscode = T.let(nil, T.nilable(String))
|
|
|
|
@whalebrew_installed = T.let(nil, T.nilable(T::Boolean))
|
|
|
|
@cask_installed = T.let(nil, T.nilable(T::Boolean))
|
|
|
|
@formula_versions_from_env = T.let(nil, T.nilable(T::Hash[String, String]))
|
|
|
|
@upgrade_formulae = T.let(nil, T.nilable(T::Array[String]))
|
2025-03-24 17:34:35 +00:00
|
|
|
end
|
2025-03-24 21:55:47 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
require "extend/os/bundle/bundle"
|