Merge pull request #9268 from reitermarkus/type-signatures

Add more type signatures.
This commit is contained in:
Markus Reiter 2020-11-30 15:16:05 +01:00 committed by GitHub
commit fe2c201d00
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
38 changed files with 433 additions and 142 deletions

View File

@ -213,7 +213,7 @@ begin
args = Homebrew.install_args.parse
Context.current = args.context
error_pipe = UNIXSocket.open(ENV["HOMEBREW_ERROR_PIPE"], &:recv_io)
error_pipe = UNIXSocket.open(ENV.fetch("HOMEBREW_ERROR_PIPE"), &:recv_io)
error_pipe.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
trap("INT", old_trap)

View File

@ -23,7 +23,7 @@ module Cask
def run
require "diagnostic"
success = true
success = T.let(true, T::Boolean)
checks = Homebrew::Diagnostic::Checks.new(verbose: true)
checks.cask_checks.each do |check|

View File

@ -1,7 +1,6 @@
# typed: true
# frozen_string_literal: true
require "cli/named_args"
require "ostruct"
module Homebrew
@ -16,6 +15,8 @@ module Homebrew
sig { void }
def initialize
require "cli/named_args"
super()
@processed_options = []
@ -55,6 +56,7 @@ module Homebrew
sig { returns(NamedArgs) }
def named
require "formula"
self[:named]
end

View File

@ -59,6 +59,164 @@ module Homebrew
sig { returns(T.nilable(T::Boolean)) }
def formula?; end
sig { returns(T.nilable(T::Boolean)) }
def zap?; end
sig { returns(T.nilable(T::Boolean)) }
def ignore_dependencies?; end
sig { returns(T.nilable(T::Boolean)) }
def aliases?; end
sig { returns(T.nilable(T::Boolean)) }
def fix?; end
sig { returns(T.nilable(T::Boolean)) }
def keep_tmp?; end
sig { returns(T.nilable(T::Boolean)) }
def overwrite?; end
sig { returns(T.nilable(T::Boolean)) }
def silent?; end
sig { returns(T.nilable(T::Boolean)) }
def repair?; end
sig { returns(T.nilable(T::Boolean)) }
def prune_prefix?; end
sig { returns(T.nilable(T::Boolean)) }
def upload?; end
sig { returns(T.nilable(T::Boolean)) }
def total?; end
sig { returns(T.nilable(T::Boolean)) }
def dependents?; end
sig { returns(T.nilable(T::Boolean)) }
def installed?; end
sig { returns(T.nilable(T::Boolean)) }
def all?; end
sig { returns(T.nilable(T::Boolean)) }
def full?; end
sig { returns(T.nilable(T::Boolean)) }
def list_pinned?; end
sig { returns(T.nilable(T::Boolean)) }
def display_cop_names?; end
sig { returns(T.nilable(T::Boolean)) }
def syntax?; end
sig { returns(T.nilable(T::Boolean)) }
def ignore_non_pypi_packages?; end
sig { returns(T.nilable(T::Boolean)) }
def test?; end
sig { returns(T.nilable(T::Boolean)) }
def reverse?; end
sig { returns(T.nilable(T::Boolean)) }
def print_only?; end
sig { returns(T.nilable(T::Boolean)) }
def markdown?; end
sig { returns(T.nilable(String)) }
def tag; end
sig { returns(T.nilable(String)) }
def tap; end
sig { returns(T.nilable(String)) }
def macos; end
sig { returns(T.nilable(T::Array[String])) }
def hide; end
sig { returns(T.nilable(String)) }
def version; end
sig { returns(T.nilable(String)) }
def name; end
sig { returns(T.nilable(T::Boolean)) }
def no_publish?; end
sig { returns(T.nilable(T::Boolean)) }
def shallow?; end
sig { returns(T.nilable(T::Boolean)) }
def fail_if_not_changed?; end
sig { returns(T.nilable(String)) }
def limit; end
sig { returns(T.nilable(String)) }
def message; end
sig { returns(T.nilable(String)) }
def issue; end
sig { returns(T.nilable(String)) }
def workflow; end
sig { returns(T.nilable(String)) }
def bintray_org; end
sig { returns(T.nilable(String)) }
def bintray_repo; end
sig { returns(T.nilable(String)) }
def package_name; end
sig { returns(T.nilable(String)) }
def prune; end
sig { returns(T.nilable(T::Array[String])) }
def only_cops; end
sig { returns(T.nilable(T::Array[String])) }
def except_cops; end
sig { returns(T.nilable(T::Array[String])) }
def only; end
sig { returns(T.nilable(T::Array[String])) }
def except; end
sig { returns(T.nilable(T::Array[String])) }
def mirror; end
sig { returns(T.nilable(T::Array[String])) }
def without_labels; end
sig { returns(T.nilable(T::Array[String])) }
def workflows; end
sig { returns(T.nilable(T::Array[String])) }
def ignore_missing_artifacts; end
sig { returns(T.nilable(T::Array[String])) }
def language; end
sig { returns(T.nilable(T::Array[String])) }
def extra_packages; end
sig { returns(T.nilable(T::Array[String])) }
def exclude_packages; end
sig { returns(T.nilable(T::Array[String])) }
def update; end
sig { returns(T.nilable(T::Boolean)) }
def s?; end
end
end
end

View File

@ -3,11 +3,7 @@
require "delegate"
require "cask/cask_loader"
require "cli/args"
require "formulary"
require "keg"
require "missing_formula"
module Homebrew
module CLI
@ -18,6 +14,12 @@ module Homebrew
extend T::Sig
def initialize(*args, parent: Args.new, override_spec: nil, force_bottle: false, flags: [])
require "cask/cask"
require "cask/cask_loader"
require "formulary"
require "keg"
require "missing_formula"
@args = args
@override_spec = override_spec
@force_bottle = force_bottle
@ -99,6 +101,7 @@ module Homebrew
end
private :resolve_formula
sig { returns(T::Array[Formula]) }
def to_resolved_formulae
@to_resolved_formulae ||= to_formulae_and_casks(only: :formula, method: :resolve)
.freeze
@ -157,7 +160,7 @@ module Homebrew
@to_kegs ||= begin
to_formulae_and_casks(only: :formula, method: :keg).freeze
rescue NoSuchKegError => e
if (reason = Homebrew::MissingFormula.suggest_command(e.name, "uninstall"))
if (reason = MissingFormula.suggest_command(e.name, "uninstall"))
$stderr.puts reason
end
raise e

View File

@ -264,6 +264,7 @@ module Homebrew
[remaining, non_options]
end
sig { params(argv: T::Array[String], ignore_invalid_options: T::Boolean).returns(Args) }
def parse(argv = ARGV.freeze, ignore_invalid_options: false)
raise "Arguments were already parsed!" if @args_parsed

View File

@ -35,6 +35,7 @@ module Homebrew
end
end
sig { void }
def __cache
args = __cache_args.parse
@ -60,6 +61,7 @@ module Homebrew
end
end
sig { params(formula: Formula, args: CLI::Args).void }
def print_formula_cache(formula, args:)
if fetch_bottle?(formula, args: args)
puts formula.bottle.cached_download
@ -68,6 +70,7 @@ module Homebrew
end
end
sig { params(cask: Cask::Cask).void }
def print_cask_cache(cask)
puts Cask::Download.new(cask).downloader.cached_location
end

View File

@ -30,6 +30,7 @@ module Homebrew
end
end
sig { void }
def __env
args = __env_args.parse
@ -51,7 +52,7 @@ module Homebrew
BuildEnvironment.dump ENV
else
BuildEnvironment.keys(ENV).each do |key|
puts Utils::Shell.export_value(key, ENV[key], shell)
puts Utils::Shell.export_value(key, ENV.fetch(key), shell)
end
end
end

View File

@ -1,4 +1,4 @@
# typed: true
# typed: false
# frozen_string_literal: true
require "cleanup"
@ -37,11 +37,18 @@ module Homebrew
def cleanup
args = cleanup_args.parse
if args.prune.present? && !Integer(args.prune, exception: false) && args.prune != "all"
days = args.prune.presence&.yield_self do |prune|
case prune
when /\A\d+\Z/
prune.to_i
when "all"
0
else
raise UsageError, "--prune= expects an integer or 'all'."
end
end
cleanup = Cleanup.new(*args.named, dry_run: args.dry_run?, scrub: args.s?, days: args.prune&.to_i)
cleanup = Cleanup.new(*args.named, dry_run: args.dry_run?, scrub: args.s?, days: days)
if args.prune_prefix?
cleanup.prune_prefix_symlinks_and_directories
return

View File

@ -45,6 +45,7 @@ module Homebrew
end
end
sig { void }
def tap
args = tap_args.parse

View File

@ -61,13 +61,13 @@ module Homebrew
)
if args.zap?
Cask::Cmd::Zap.zap_casks(
T.unsafe(Cask::Cmd::Zap).zap_casks(
*casks,
verbose: args.verbose?,
force: args.force?,
)
else
Cask::Cmd::Uninstall.uninstall_casks(
T.unsafe(Cask::Cmd::Uninstall).uninstall_casks(
*casks,
binaries: EnvConfig.cask_opts_binaries?,
verbose: args.verbose?,

View File

@ -261,8 +261,8 @@ module Homebrew
formula_and_runtime_deps_names = [f.name] + f.runtime_dependencies.map(&:name)
keg = Keg.new(f.prefix)
relocatable = false
skip_relocation = false
relocatable = T.let(false, T::Boolean)
skip_relocation = T.let(false, T::Boolean)
keg.lock do
original_tab = nil
@ -472,7 +472,7 @@ module Homebrew
if args.write?
path = Pathname.new((HOMEBREW_REPOSITORY/bottle_hash["formula"]["path"]).to_s)
update_or_add = nil
update_or_add = T.let(nil, T.nilable(String))
Utils::Inreplace.inreplace(path) do |s|
if s.inreplace_string.include? "bottle do"

View File

@ -35,14 +35,14 @@ module Homebrew
def dispatch_build_bottle
args = dispatch_build_bottle_args.parse
odie "Must specify --macos option" unless args.macos
macos = begin
MacOS::Version.from_symbol(args.macos.to_sym)
macos = args.macos&.yield_self do |s|
MacOS::Version.from_symbol(s.to_sym)
rescue MacOSVersionError
MacOS::Version.new(args.macos)
MacOS::Version.new(s)
end
raise UsageError, "Must specify --macos option" unless macos
tap = Tap.fetch(args.tap || CoreTap.instance.name)
user, repo = tap.full_name.split("/")

View File

@ -57,7 +57,7 @@ module Homebrew
options[:only_cops] = only_cops
elsif except_cops
options[:except_cops] = except_cops
elsif only_cops.nil? && except_cops.nil?
else
options[:except_cops] = %w[FormulaAuditStrict]
end

View File

@ -93,7 +93,14 @@ module Homebrew
srb_exec = %w[bundle exec srb tc]
srb_exec << "--error-black-list" << "5061"
srb_exec << "--quiet" if args.quiet?
srb_exec << "--autocorrect" if args.fix?
if args.fix?
# Auto-correcting method names is almost always wrong.
srb_exec << "--error-black-list" << "7003"
srb_exec << "--autocorrect"
end
srb_exec += ["--ignore", args.ignore] if args.ignore.present?
if args.file.present? || args.dir.present?
cd("sorbet")

View File

@ -33,11 +33,7 @@ module Homebrew
Formulary.enable_factory_cache!
@bottle_tag = if args.tag.present?
args.tag.to_sym
else
Utils::Bottles.tag
end
@bottle_tag = args.tag.presence&.to_sym || Utils::Bottles.tag
if args.named.blank?
ohai "Getting formulae..."

View File

@ -1,7 +1,6 @@
# typed: true
# frozen_string_literal: true
require "formula"
require "os/linux/glibc"
require "system_command"
@ -48,7 +47,7 @@ module SystemConfig
out.puts "/usr/bin/gcc: #{host_gcc_version}"
out.puts "/usr/bin/ruby: #{host_ruby_version}" if RUBY_PATH != HOST_RUBY_PATH
["glibc", "gcc", "xorg"].each do |f|
out.puts "#{f}: #{formula_linked_version f}"
out.puts "#{f}: #{formula_linked_version(f)}"
end
end
end

View File

@ -1,4 +1,4 @@
# typed: false
# typed: true
# frozen_string_literal: true
require "resource"
@ -7,15 +7,17 @@ require "metafiles"
module DiskUsageExtension
extend T::Sig
sig { returns(Integer) }
def disk_usage
return @disk_usage if @disk_usage
return @disk_usage if defined?(@disk_usage)
compute_disk_usage
@disk_usage
end
sig { returns(Integer) }
def file_count
return @file_count if @file_count
return @file_count if defined?(@file_count)
compute_disk_usage
@file_count
@ -32,6 +34,7 @@ module DiskUsageExtension
private
sig { void }
def compute_disk_usage
if symlink? && !exist?
@file_count = 1
@ -82,6 +85,12 @@ class Pathname
BOTTLE_EXTNAME_RX = /(\.[a-z0-9_]+\.bottle\.(\d+\.)?tar\.gz)$/.freeze
# Moves a file from the original location to the {Pathname}'s.
sig do
params(sources: T.any(
Resource, Resource::Partial, String, Pathname,
T::Array[T.any(String, Pathname)], T::Hash[T.any(String, Pathname), String]
)).void
end
def install(*sources)
sources.each do |src|
case src
@ -107,6 +116,7 @@ class Pathname
end
end
sig { params(src: T.any(String, Pathname), new_basename: String).void }
def install_p(src, new_basename)
raise Errno::ENOENT, src.to_s unless File.symlink?(src) || File.exist?(src)
@ -130,6 +140,11 @@ class Pathname
private :install_p
# Creates symlinks to sources in this folder.
sig do
params(
sources: T.any(String, Pathname, T::Array[T.any(String, Pathname)], T::Hash[T.any(String, Pathname), String]),
).void
end
def install_symlink(*sources)
sources.each do |src|
case src
@ -156,21 +171,25 @@ class Pathname
alias old_write write
# We assume this pathname object is a file, obviously.
def write(content, *open_args)
sig { params(content: String, offset: Integer, open_args: T::Hash[Symbol, T.untyped]).returns(Integer) }
def write(content, offset = 0, open_args = {})
raise "Will not overwrite #{self}" if exist?
dirname.mkpath
open("w", *open_args) { |f| f.write(content) }
old_write(content, offset, open_args)
end
# Only appends to a file that is already created.
def append_lines(content, *open_args)
sig { params(content: String, open_args: T.untyped).void }
def append_lines(content, **open_args)
raise "Cannot append file that doesn't exist: #{self}" unless exist?
open("a", *open_args) { |f| f.puts(content) }
T.unsafe(self).open("a", **open_args) { |f| f.puts(content) }
end
# @note This always overwrites.
sig { params(content: String).void }
def atomic_write(content)
old_stat = stat if exist?
File.atomic_write(self) do |file|
@ -220,8 +239,9 @@ class Pathname
alias extname_old extname
# Extended to support common double extensions.
def extname(path = to_s)
basename = File.basename(path)
sig { returns(String) }
def extname
basename = File.basename(self)
bottle_ext = basename[BOTTLE_EXTNAME_RX, 1]
return bottle_ext if bottle_ext
@ -236,14 +256,16 @@ class Pathname
end
# For filetypes we support, returns basename without extension.
sig { returns(String) }
def stem
File.basename((path = to_s), extname(path))
File.basename(self, extname)
end
# I don't trust the children.length == 0 check particularly, not to mention
# it is slow to enumerate the whole directory just to see if it is empty,
# instead rely on good ol' libc and the filesystem
# @private
sig { returns(T::Boolean) }
def rmdir_if_possible
rmdir
true
@ -259,21 +281,25 @@ class Pathname
end
# @private
sig { returns(Version) }
def version
require "version"
Version.parse(basename)
end
# @private
sig { returns(T::Boolean) }
def text_executable?
/^#!\s*\S+/ =~ open("r") { |f| f.read(1024) }
/^#!\s*\S+/.match?(open("r") { |f| f.read(1024) })
end
sig { returns(String) }
def sha256
require "digest/sha2"
Digest::SHA256.file(self).hexdigest
end
sig { params(expected: T.nilable(Checksum)).void }
def verify_checksum(expected)
raise ChecksumMissingError if expected.nil? || expected.empty?
@ -283,7 +309,12 @@ class Pathname
alias to_str to_s
def cd
sig do
type_parameters(:U).params(
_block: T.proc.params(path: Pathname).returns(T.type_parameter(:U)),
).returns(T.type_parameter(:U))
end
def cd(&_block)
Dir.chdir(self) { yield self }
end
@ -382,6 +413,14 @@ class Pathname
end
# Writes an exec script that invokes a Java jar.
sig do
params(
target_jar: T.any(String, Pathname),
script_name: T.any(String, Pathname),
java_opts: String,
java_version: T.nilable(String),
).returns(Integer)
end
def write_jar_script(target_jar, script_name, java_opts = "", java_version: nil)
(self/script_name).write <<~EOS
#!/bin/bash
@ -431,11 +470,14 @@ require "extend/os/pathname"
# @private
module ObserverPathnameExtension
extend T::Sig
class << self
extend T::Sig
include Context
sig { returns(Integer) }
attr_accessor :n, :d
sig { void }
@ -444,16 +486,21 @@ module ObserverPathnameExtension
@put_verbose_trimmed_warning = false
end
sig { returns(Integer) }
def total
n + d
end
sig { returns([Integer, Integer]) }
def counts
[n, d]
end
MAXIMUM_VERBOSE_OUTPUT = 100
private_constant :MAXIMUM_VERBOSE_OUTPUT
sig { returns(T::Boolean) }
def verbose?
return super unless ENV["CI"]
return false unless super
@ -470,34 +517,40 @@ module ObserverPathnameExtension
end
end
sig { void }
def unlink
super
puts "rm #{self}" if ObserverPathnameExtension.verbose?
ObserverPathnameExtension.n += 1
end
sig { void }
def mkpath
super
puts "mkdir -p #{self}" if ObserverPathnameExtension.verbose?
end
sig { void }
def rmdir
super
puts "rmdir #{self}" if ObserverPathnameExtension.verbose?
ObserverPathnameExtension.d += 1
end
sig { params(src: Pathname).void }
def make_relative_symlink(src)
super
puts "ln -s #{src.relative_path_from(dirname)} #{basename}" if ObserverPathnameExtension.verbose?
ObserverPathnameExtension.n += 1
end
sig { void }
def install_info
super
puts "info #{self}" if ObserverPathnameExtension.verbose?
end
sig { void }
def uninstall_info
super
puts "uninfo #{self}" if ObserverPathnameExtension.verbose?

View File

@ -0,0 +1,19 @@
# typed: strict
module DiskUsageExtension
include Kernel
def exist?; end
def symlink?; end
def resolved_path; end
end
module ObserverPathnameExtension
include Kernel
def dirname; end
def basename; end
end

View File

@ -4,11 +4,16 @@
module Homebrew
# @api private
module Fetch
extend T::Sig
sig { params(f: Formula, args: CLI::Args).returns(T::Boolean) }
def fetch_bottle?(f, args:)
return true if args.force_bottle? && f.bottle
return false unless f.bottle && f.pour_bottle?
bottle = f.bottle
return true if args.force_bottle? && bottle
return false unless bottle && f.pour_bottle?
return false if args.build_from_source_formulae.include?(f.full_name)
return false unless f.bottle.compatible_cellar?
return false unless bottle.compatible_cellar?
true
end

View File

@ -9,6 +9,11 @@ require "ostruct"
require "pp"
require "forwardable"
require "rbconfig"
RUBY_PATH = Pathname.new(RbConfig.ruby).freeze
RUBY_BIN = RUBY_PATH.dirname.freeze
require_relative "load_path"
require "rubygems"
@ -41,26 +46,11 @@ HOMEBREW_DEFAULT_CACHE = ENV["HOMEBREW_DEFAULT_CACHE"]
HOMEBREW_DEFAULT_LOGS = ENV["HOMEBREW_DEFAULT_LOGS"]
HOMEBREW_DEFAULT_TEMP = ENV["HOMEBREW_DEFAULT_TEMP"]
HOMEBREW_REQUIRED_RUBY_VERSION = ENV["HOMEBREW_REQUIRED_RUBY_VERSION"]
require "env_config"
require "config"
require "os"
require "context"
require "extend/pathname"
require "extend/predicable"
require "extend/module"
require "cli/args"
require "messages"
HOMEBREW_PRODUCT = ENV["HOMEBREW_PRODUCT"]
HOMEBREW_VERSION = ENV["HOMEBREW_VERSION"]
HOMEBREW_WWW = "https://brew.sh"
require "rbconfig"
RUBY_PATH = Pathname.new(RbConfig.ruby).freeze
RUBY_BIN = RUBY_PATH.dirname.freeze
HOMEBREW_USER_AGENT_CURL = ENV["HOMEBREW_USER_AGENT_CURL"]
HOMEBREW_USER_AGENT_RUBY =
"#{ENV["HOMEBREW_USER_AGENT"]} ruby/#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}"
@ -72,8 +62,18 @@ HOMEBREW_DEFAULT_PREFIX = "/usr/local"
HOMEBREW_MACOS_ARM_DEFAULT_PREFIX = "/opt/homebrew"
HOMEBREW_LINUX_DEFAULT_PREFIX = "/home/linuxbrew/.linuxbrew"
HOMEBREW_PULL_API_REGEX =
%r{https://api\.github\.com/repos/([\w-]+)/([\w-]+)?/pulls/(\d+)}.freeze
HOMEBREW_PULL_OR_COMMIT_URL_REGEX =
%r[https://github\.com/([\w-]+)/([\w-]+)?/(?:pull/(\d+)|commit/[0-9a-fA-F]{4,40})].freeze
HOMEBREW_RELEASES_URL_REGEX =
%r{https://github\.com/([\w-]+)/([\w-]+)?/releases/download/(.+)}.freeze
require "fileutils"
require "os"
require "os/global"
require "messages"
module Homebrew
extend FileUtils
@ -111,12 +111,14 @@ module Homebrew
end
end
HOMEBREW_PULL_API_REGEX =
%r{https://api\.github\.com/repos/([\w-]+)/([\w-]+)?/pulls/(\d+)}.freeze
HOMEBREW_PULL_OR_COMMIT_URL_REGEX =
%r[https://github\.com/([\w-]+)/([\w-]+)?/(?:pull/(\d+)|commit/[0-9a-fA-F]{4,40})].freeze
HOMEBREW_RELEASES_URL_REGEX =
%r{https://github\.com/([\w-]+)/([\w-]+)?/releases/download/(.+)}.freeze
require "env_config"
require "config"
require "context"
require "extend/pathname"
require "extend/predicable"
require "extend/module"
require "cli/args"
require "PATH"

View File

@ -234,7 +234,7 @@ class Migrator
return unless old_cellar.exist?
if new_cellar.exist?
conflicted = false
conflicted = T.let(false, T::Boolean)
old_cellar.each_child do |c|
next unless (new_cellar/c.basename).exist?

View File

@ -94,7 +94,7 @@ module Homebrew
alias generic_disallowed_reason disallowed_reason
def tap_migration_reason(name)
message = nil
message = T.let(nil, T.nilable(String))
Tap.each do |old_tap|
new_tap = old_tap.tap_migrations[name]

View File

@ -5,9 +5,12 @@
#
# @api private
module OS
extend T::Sig
# Check if the operating system is macOS.
#
# @api public
sig { returns(T::Boolean) }
def self.mac?
return false if ENV["HOMEBREW_TEST_GENERIC_OS"]
@ -17,6 +20,7 @@ module OS
# Check if the operating system is Linux.
#
# @api public
sig { returns(T::Boolean) }
def self.linux?
return false if ENV["HOMEBREW_TEST_GENERIC_OS"]
@ -26,6 +30,7 @@ module OS
# Get the kernel version.
#
# @api public
sig { returns(Version) }
def self.kernel_version
@kernel_version ||= Version.new(Utils.safe_popen_read("uname", "-r").chomp)
end

View File

@ -1,6 +1,8 @@
# typed: false
# frozen_string_literal: true
require "env_config"
# Enables experimental `patchelf.rb` write support.
HOMEBREW_PATCHELF_RB_WRITE = (
ENV["HOMEBREW_NO_PATCHELF_RB_WRITE"].blank? &&
@ -8,7 +10,7 @@ HOMEBREW_PATCHELF_RB_WRITE = (
).freeze
module Homebrew
DEFAULT_PREFIX ||= if Homebrew::EnvConfig.force_homebrew_on_linux?
DEFAULT_PREFIX ||= if EnvConfig.force_homebrew_on_linux?
HOMEBREW_DEFAULT_PREFIX
else
HOMEBREW_LINUX_DEFAULT_PREFIX

View File

@ -1,4 +1,4 @@
# typed: false
# typed: strict
# frozen_string_literal: true
old_trap = trap("INT") { exit! 130 }
@ -12,12 +12,12 @@ require "cmd/postinstall"
begin
args = Homebrew.postinstall_args.parse
error_pipe = UNIXSocket.open(ENV["HOMEBREW_ERROR_PIPE"], &:recv_io)
error_pipe = UNIXSocket.open(ENV.fetch("HOMEBREW_ERROR_PIPE"), &:recv_io)
error_pipe.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
trap("INT", old_trap)
formula = args.named.to_resolved_formulae.first
formula = T.must(args.named.to_resolved_formulae.first)
formula.extend(Debrew::Formula) if args.debug?
formula.run_post_install
rescue Exception => e # rubocop:disable Lint/RescueException

View File

@ -10,7 +10,7 @@ require "cask/cask_loader"
module Readall
class << self
def valid_ruby_syntax?(ruby_files)
failed = false
failed = T.let(false, T::Boolean)
ruby_files.each do |ruby_file|
# As a side effect, print syntax errors/warnings to `$stderr`.
failed = true if syntax_errors_or_warnings?(ruby_file)
@ -21,7 +21,7 @@ module Readall
def valid_aliases?(alias_dir, formula_dir)
return true unless alias_dir.directory?
failed = false
failed = T.let(false, T::Boolean)
alias_dir.each_child do |f|
if !f.symlink?
onoe "Non-symlink alias: #{f}"
@ -40,7 +40,7 @@ module Readall
end
def valid_formulae?(formulae)
success = true
success = T.let(true, T::Boolean)
formulae.each do |file|
Formulary.factory(file)
rescue Interrupt
@ -54,7 +54,7 @@ module Readall
end
def valid_casks?(casks)
success = true
success = T.let(true, T::Boolean)
casks.each do |file|
Cask::CaskLoader.load(file)
rescue Interrupt

View File

@ -46,7 +46,7 @@ module RuboCop
next if node.nil?
reason_found = false
reason_found = T.let(false, T::Boolean)
reason(node) do |reason_node|
reason_found = true
next if reason_node.sym_type?

View File

@ -1,4 +1,4 @@
# typed: false
# typed: true
# frozen_string_literal: true
require "erb"
@ -56,12 +56,12 @@ class Sandbox
end
def allow_cvs
allow_write_path "#{Dir.home(ENV["USER"])}/.cvspass"
allow_write_path "#{Dir.home(ENV.fetch("USER"))}/.cvspass"
end
def allow_fossil
allow_write_path "#{Dir.home(ENV["USER"])}/.fossil"
allow_write_path "#{Dir.home(ENV["USER"])}/.fossil-journal"
allow_write_path "#{Dir.home(ENV.fetch("USER"))}/.fossil"
allow_write_path "#{Dir.home(ENV.fetch("USER"))}/.fossil-journal"
end
def allow_write_cellar(formula)
@ -72,7 +72,7 @@ class Sandbox
# Xcode projects expect access to certain cache/archive dirs.
def allow_write_xcode
allow_write_path "#{Dir.home(ENV["USER"])}/Library/Developer"
allow_write_path "#{Dir.home(ENV.fetch("USER"))}/Library/Developer"
end
def allow_write_log(formula)
@ -94,7 +94,9 @@ class Sandbox
seatbelt.write(@profile.dump)
seatbelt.close
@start = Time.now
safe_system SANDBOX_EXEC, "-f", seatbelt.path, *args
begin
T.unsafe(self).safe_system SANDBOX_EXEC, "-f", seatbelt.path, *args
rescue
@failed = true
raise
@ -131,6 +133,7 @@ class Sandbox
end
end
end
end
private

View File

@ -1,13 +1,31 @@
# typed: strict
class Pathname
# https://github.com/sorbet/sorbet/pull/3676
sig { params(p1: T.any(String, Pathname), p2: String).returns(T::Array[Pathname]) }
def self.glob(p1, p2 = T.unsafe(nil)); end
# This file contains temporary definitions for fixes that have
# been submitted upstream to https://github.com/sorbet/sorbet.
# https://github.com/sorbet/sorbet/pull/3678
sig { params(with_directory: T::Boolean).returns(T::Array[Pathname]) }
def children(with_directory = true); end
class IO
# https://github.com/sorbet/sorbet/pull/3722
sig do
type_parameters(:U).params(
fd: T.any(String, Integer),
mode: T.any(Integer, String),
opt: T.nilable(T::Hash[Symbol, T.untyped]),
blk: T.proc.params(io: T.attached_class).returns(T.type_parameter(:U))
).returns(T.type_parameter(:U))
end
def self.open(fd, mode='r', opt=nil, &blk); end
end
class Pathname
# https://github.com/sorbet/sorbet/pull/3729
sig do
params(
owner: T.nilable(Integer),
group: T.nilable(Integer),
)
.returns(Integer)
end
def chown(owner, group); end
end
module FileUtils

View File

@ -1,6 +1,8 @@
# typed: true
# frozen_string_literal: true
require "config"
# Match taps' formulae, e.g. `someuser/sometap/someformula`
HOMEBREW_TAP_FORMULA_REGEX = %r{^([\w-]+)/([\w-]+)/([\w+-.@]+)$}.freeze
# Match taps' casks, e.g. `someuser/sometap/somecask`

View File

@ -20,7 +20,7 @@ begin
args = Homebrew.test_args.parse
Context.current = args.context
error_pipe = UNIXSocket.open(ENV["HOMEBREW_ERROR_PIPE"], &:recv_io)
error_pipe = UNIXSocket.open(ENV.fetch("HOMEBREW_ERROR_PIPE"), &:recv_io)
error_pipe.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
trap("INT", old_trap)
@ -30,13 +30,13 @@ begin
raise "cannot kill child processes without `pkill`, please install!" unless which("pkill")
end
formula = args.named.to_resolved_formulae.first
formula = T.must(args.named.to_resolved_formulae.first)
formula.extend(Homebrew::Assertions)
formula.extend(Homebrew::FreePort)
formula.extend(Debrew::Formula) if args.debug?
ENV.extend(Stdenv)
ENV.setup_build_environment(formula: formula)
T.cast(ENV, Stdenv).setup_build_environment(formula: formula)
# tests can also return false to indicate failure
Timeout.timeout TEST_TIMEOUT_SECONDS do

View File

@ -2,7 +2,6 @@
# frozen_string_literal: true
require "keg"
require "formula"
module Homebrew
# Helper module for uninstalling kegs.

View File

@ -34,7 +34,7 @@ module Homebrew
end
exit! 1 # never gets here unless exec failed
end
Process.wait(pid)
Process.wait(T.must(pid))
$CHILD_STATUS.success?
end
@ -58,6 +58,8 @@ module Homebrew
method = instance_method(name)
define_method(name) do |*args, &block|
time = Time.now
begin
method.bind(self).call(*args, &block)
ensure
$times[name] ||= 0
@ -65,6 +67,7 @@ module Homebrew
end
end
end
end
return unless $times.nil?
@ -190,7 +193,7 @@ module Kernel
line.include?("/.metadata/")
end
tap_message = nil
tap_message = T.let(nil, T.nilable(String))
backtrace.each do |line|
next unless match = line.match(HOMEBREW_TAP_PATH_REGEX)
@ -263,12 +266,12 @@ module Kernel
ENV["HOMEBREW_DEBUG_INSTALL"] = f.full_name
end
if ENV["SHELL"].include?("zsh") && ENV["HOME"].start_with?(HOMEBREW_TEMP.resolved_path.to_s)
FileUtils.mkdir_p ENV["HOME"]
FileUtils.touch "#{ENV["HOME"]}/.zshrc"
if ENV["SHELL"].include?("zsh") && (home = ENV["HOME"])&.start_with?(HOMEBREW_TEMP.resolved_path.to_s)
FileUtils.mkdir_p home
FileUtils.touch "#{home}/.zshrc"
end
Process.wait fork { exec ENV["SHELL"] }
Process.wait fork { exec ENV.fetch("SHELL") }
return if $CHILD_STATUS.success?
raise "Aborted due to non-zero exit status (#{$CHILD_STATUS.exitstatus})" if $CHILD_STATUS.exited?

View File

@ -58,7 +58,7 @@ module Utils
"--silent", "--output", "/dev/null",
"https://www.google-analytics.com/collect"
end
Process.detach pid
Process.detach T.must(pid)
end
end

View File

@ -64,7 +64,7 @@ module Utils
begin
socket = server.accept_nonblock
rescue Errno::EAGAIN, Errno::EWOULDBLOCK, Errno::ECONNABORTED, Errno::EPROTO, Errno::EINTR
retry unless Process.waitpid(pid, Process::WNOHANG)
retry unless Process.waitpid(T.must(pid), Process::WNOHANG)
else
socket.send_io(write)
socket.close
@ -72,7 +72,7 @@ module Utils
write.close
data = read.read
read.close
Process.wait(pid) unless socket.nil?
Process.wait(T.must(pid)) unless socket.nil?
# 130 is the exit status for a process interrupted via Ctrl-C.
# We handle it here because of the possibility of an interrupted process terminating
@ -80,7 +80,7 @@ module Utils
raise Interrupt if $CHILD_STATUS.exitstatus == 130
if data && !data.empty?
error_hash = JSON.parse(data.lines.first)
error_hash = JSON.parse(T.must(data.lines.first))
e = ChildProcessError.new(error_hash)

View File

@ -122,9 +122,9 @@ module PyPI
package_name: T.nilable(String),
extra_packages: T.nilable(T::Array[String]),
exclude_packages: T.nilable(T::Array[String]),
print_only: T::Boolean,
silent: T::Boolean,
ignore_non_pypi_packages: T::Boolean,
print_only: T.nilable(T::Boolean),
silent: T.nilable(T::Boolean),
ignore_non_pypi_packages: T.nilable(T::Boolean),
).returns(T.nilable(T::Boolean))
end
def update_python_resources!(formula, version: nil, package_name: nil, extra_packages: nil, exclude_packages: nil,

View File

@ -1,6 +1,8 @@
# typed: true
# frozen_string_literal: true
require "env_config"
# Various helper functions for interacting with TTYs.
#
# @api private