From 02fd0422aaaedd16b6a6f1bfee15a32ac787f07e Mon Sep 17 00:00:00 2001 From: Douglas Eichelberger Date: Tue, 7 Mar 2023 17:24:20 -0800 Subject: [PATCH 1/4] Enable typing in a few more files --- Library/Homebrew/cask/metadata.rb | 2 +- Library/Homebrew/cask/metdata.rbi | 7 +++++++ Library/Homebrew/cask/url.rbi | 1 - Library/Homebrew/diagnostic.rb | 8 +++++--- Library/Homebrew/formula_assertions.rb | 2 +- Library/Homebrew/formula_assertions.rbi | 5 +++++ Library/Homebrew/keg_relocate.rb | 10 +++++----- Library/Homebrew/language/python.rb | 2 +- Library/Homebrew/language/python.rbi | 11 +++++++++++ Library/Homebrew/test.rb | 8 +++----- Library/Homebrew/unlink.rb | 8 +++----- Library/Homebrew/utils/analytics.rb | 11 +++++------ Library/Homebrew/utils/github/api.rb | 6 +++--- Library/Homebrew/utils/github/api.rbi | 5 +++++ Library/Homebrew/utils/repology.rb | 2 +- Library/Homebrew/utils/repology.rbi | 6 ++++++ 16 files changed, 62 insertions(+), 32 deletions(-) create mode 100644 Library/Homebrew/cask/metdata.rbi create mode 100644 Library/Homebrew/formula_assertions.rbi create mode 100644 Library/Homebrew/language/python.rbi create mode 100644 Library/Homebrew/utils/github/api.rbi create mode 100644 Library/Homebrew/utils/repology.rbi diff --git a/Library/Homebrew/cask/metadata.rb b/Library/Homebrew/cask/metadata.rb index c2db2e2cc0..123dc6e0b5 100644 --- a/Library/Homebrew/cask/metadata.rb +++ b/Library/Homebrew/cask/metadata.rb @@ -1,4 +1,4 @@ -# typed: false +# typed: true # frozen_string_literal: true module Cask diff --git a/Library/Homebrew/cask/metdata.rbi b/Library/Homebrew/cask/metdata.rbi new file mode 100644 index 0000000000..1b92e9ce74 --- /dev/null +++ b/Library/Homebrew/cask/metdata.rbi @@ -0,0 +1,7 @@ +# typed: strict + +module Cask + module Metadata + requires_ancestor { Cask } + end +end diff --git a/Library/Homebrew/cask/url.rbi b/Library/Homebrew/cask/url.rbi index 6f32e1b3b2..9070b2fc01 100644 --- a/Library/Homebrew/cask/url.rbi +++ b/Library/Homebrew/cask/url.rbi @@ -1,5 +1,4 @@ # typed: strict -# typed: false class URL include Kernel diff --git a/Library/Homebrew/diagnostic.rb b/Library/Homebrew/diagnostic.rb index 821564e658..455bfed241 100644 --- a/Library/Homebrew/diagnostic.rb +++ b/Library/Homebrew/diagnostic.rb @@ -1,4 +1,4 @@ -# typed: false +# typed: true # frozen_string_literal: true require "keg" @@ -31,7 +31,7 @@ module Homebrew def self.checks(type, fatal: true) @checks ||= Checks.new - failed = false + failed = T.let(false, T::Boolean) @checks.public_send(type).each do |check| out = @checks.public_send(check) next if out.nil? @@ -64,6 +64,7 @@ module Homebrew end end + sig { params(list: T::Array[String], string: String).returns(String) } def inject_file_list(list, string) list.reduce(string.dup) { |acc, elem| acc << " #{elem}\n" } .freeze @@ -642,10 +643,11 @@ module Homebrew EOS end + sig { returns(T.nilable(String)) } def check_git_status return unless Utils::Git.available? - message = nil + message = T.let(nil, T.nilable(String)) repos = { "Homebrew/brew" => HOMEBREW_REPOSITORY, diff --git a/Library/Homebrew/formula_assertions.rb b/Library/Homebrew/formula_assertions.rb index 382bb085ca..8f84f6479b 100644 --- a/Library/Homebrew/formula_assertions.rb +++ b/Library/Homebrew/formula_assertions.rb @@ -1,4 +1,4 @@ -# typed: false +# typed: true # frozen_string_literal: true module Homebrew diff --git a/Library/Homebrew/formula_assertions.rbi b/Library/Homebrew/formula_assertions.rbi new file mode 100644 index 0000000000..3e75262939 --- /dev/null +++ b/Library/Homebrew/formula_assertions.rbi @@ -0,0 +1,5 @@ +# typed: strict + +module Homebrew::Assertions + include Kernel +end diff --git a/Library/Homebrew/keg_relocate.rb b/Library/Homebrew/keg_relocate.rb index 961d3f27fc..083529719b 100644 --- a/Library/Homebrew/keg_relocate.rb +++ b/Library/Homebrew/keg_relocate.rb @@ -1,4 +1,4 @@ -# typed: false +# typed: true # frozen_string_literal: true class Keg @@ -44,7 +44,7 @@ class Keg key.is_a?(String) ? key.length : 999 end.reverse - any_changed = false + any_changed = T.let(nil, T.nilable(String)) sorted_keys.each do |key| changed = text.gsub!(key, replacements[key]) any_changed ||= changed @@ -144,7 +144,7 @@ class Keg def replace_text_in_files(relocation, files: nil) files ||= text_files | libtool_files - changed_files = [] + changed_files = T.let([], Array) files.map(&path.method(:join)).group_by { |f| f.stat.ino }.each_value do |first, *rest| s = first.open("rb", &:read) @@ -179,11 +179,11 @@ class Keg binary = File.binread file odebug "Replacing build prefix in: #{file}" binary_strings = binary.split(/#{NULL_BYTE}/o, -1) - match_indices = binary_strings.each_index.select { |i| binary_strings[i].include?(old_prefix) } + match_indices = binary_strings.each_index.select { |i| binary_strings.fetch(i).include?(old_prefix) } # Only perform substitution on strings which match prefix regex. match_indices.each do |i| - s = binary_strings[i] + s = binary_strings.fetch(i) binary_strings[i] = s.gsub(old_prefix, new_prefix) .ljust(s.size, NULL_BYTE) end diff --git a/Library/Homebrew/language/python.rb b/Library/Homebrew/language/python.rb index c0df766d43..506865790a 100644 --- a/Library/Homebrew/language/python.rb +++ b/Library/Homebrew/language/python.rb @@ -1,4 +1,4 @@ -# typed: false +# typed: true # frozen_string_literal: true module Language diff --git a/Library/Homebrew/language/python.rbi b/Library/Homebrew/language/python.rbi new file mode 100644 index 0000000000..ab011b8db7 --- /dev/null +++ b/Library/Homebrew/language/python.rbi @@ -0,0 +1,11 @@ +# typed: strict + +module Language::Python + module Shebang + include Kernel + end + + module Virtualenv + requires_ancestor { Formula } + end +end diff --git a/Library/Homebrew/test.rb b/Library/Homebrew/test.rb index b22b8c218a..55a46e63d2 100644 --- a/Library/Homebrew/test.rb +++ b/Library/Homebrew/test.rb @@ -1,4 +1,4 @@ -# typed: false +# typed: true # frozen_string_literal: true raise "#{__FILE__} must not be loaded via `require`." if $PROGRAM_NAME != __FILE__ @@ -38,12 +38,10 @@ begin formula.extend(Debrew::Formula) if args.debug? ENV.extend(Stdenv) - T.cast(ENV, Stdenv).setup_build_environment(formula: formula, testing_formula: true) + ENV.setup_build_environment(formula: formula, testing_formula: true) # tests can also return false to indicate failure - run_test = proc do - raise "test returned false" if formula.run_test(keep_tmp: args.keep_tmp?) == false - end + run_test = proc { |_ = nil| raise "test returned false" if formula.run_test(keep_tmp: args.keep_tmp?) == false } if args.debug? # --debug is interactive run_test.call else diff --git a/Library/Homebrew/unlink.rb b/Library/Homebrew/unlink.rb index ef9ce40722..043cadffc2 100644 --- a/Library/Homebrew/unlink.rb +++ b/Library/Homebrew/unlink.rb @@ -1,12 +1,10 @@ -# typed: false +# typed: true # frozen_string_literal: true module Homebrew # Provides helper methods for unlinking formulae and kegs with consistent output. module Unlink - module_function - - def unlink_versioned_formulae(formula, verbose: false) + def self.unlink_versioned_formulae(formula, verbose: false) formula.versioned_formulae .select(&:keg_only?) .select(&:linked?) @@ -18,7 +16,7 @@ module Homebrew end end - def unlink(keg, dry_run: false, verbose: false) + def self.unlink(keg, dry_run: false, verbose: false) options = { dry_run: dry_run, verbose: verbose } keg.lock do diff --git a/Library/Homebrew/utils/analytics.rb b/Library/Homebrew/utils/analytics.rb index 1c1fd04adc..3fb59c4e68 100644 --- a/Library/Homebrew/utils/analytics.rb +++ b/Library/Homebrew/utils/analytics.rb @@ -1,4 +1,4 @@ -# typed: false +# typed: true # frozen_string_literal: true require "context" @@ -42,7 +42,6 @@ module Utils --data av=#{HOMEBREW_VERSION} ] metadata.each do |key, value| - next unless key next unless value key = ERB::Util.url_encode key @@ -146,13 +145,13 @@ module Utils report_influx(measurement, package_and_options, on_request, additional_tags_influx) end - sig { params(exception: Exception).void } + sig { params(exception: BuildError).void } def report_build_error(exception) report_google_build_error(exception) report_influx_error(exception) end - sig { params(exception: Exception).void } + sig { params(exception: BuildError).void } def report_google_build_error(exception) return if not_this_run? || disabled? @@ -165,10 +164,10 @@ module Utils else formula_full_name end - report_google_event("BuildError", package_and_options) + report_google_event(:BuildError, package_and_options) end - sig { params(exception: Exception).void } + sig { params(exception: BuildError).void } def report_influx_error(exception) return if not_this_run? || disabled? diff --git a/Library/Homebrew/utils/github/api.rb b/Library/Homebrew/utils/github/api.rb index a49773a167..0d122975a9 100644 --- a/Library/Homebrew/utils/github/api.rb +++ b/Library/Homebrew/utils/github/api.rb @@ -1,4 +1,4 @@ -# typed: false +# typed: true # frozen_string_literal: true require "tempfile" @@ -214,7 +214,7 @@ module GitHub headers_tmpfile = Tempfile.new("github_api_headers", HOMEBREW_TEMP) begin - if data + if data_tmpfile data_tmpfile.write data data_tmpfile.close args += ["--data", "@#{data_tmpfile.path}"] @@ -222,7 +222,7 @@ module GitHub args += ["--request", request_method.to_s] if request_method end - args += ["--dump-header", headers_tmpfile.path] + args += ["--dump-header", T.must(headers_tmpfile.path)] output, errors, status = curl_output("--location", url.to_s, *args, secrets: [token]) output, _, http_code = output.rpartition("\n") diff --git a/Library/Homebrew/utils/github/api.rbi b/Library/Homebrew/utils/github/api.rbi new file mode 100644 index 0000000000..bb72675c19 --- /dev/null +++ b/Library/Homebrew/utils/github/api.rbi @@ -0,0 +1,5 @@ +# typed: strict + +module GitHub::API + include Kernel +end diff --git a/Library/Homebrew/utils/repology.rb b/Library/Homebrew/utils/repology.rb index 14396de368..dc9fc61cec 100644 --- a/Library/Homebrew/utils/repology.rb +++ b/Library/Homebrew/utils/repology.rb @@ -1,4 +1,4 @@ -# typed: false +# typed: true # frozen_string_literal: true require "utils/curl" diff --git a/Library/Homebrew/utils/repology.rbi b/Library/Homebrew/utils/repology.rbi new file mode 100644 index 0000000000..57ed1c467f --- /dev/null +++ b/Library/Homebrew/utils/repology.rbi @@ -0,0 +1,6 @@ +# typed: strict + +module Repology + include Kernel + requires_ancestor { Utils::Curl } +end From 0b04b99e687a49b5c569e7e64ad31c330f644b9a Mon Sep 17 00:00:00 2001 From: Douglas Eichelberger Date: Thu, 9 Mar 2023 20:32:46 -0800 Subject: [PATCH 2/4] brew typecheck --suggest-typed --update --- Library/Homebrew/dev-cmd/bump-formula-pr.rb | 2 +- Library/Homebrew/dev-cmd/bump-unversioned-casks.rb | 2 +- Library/Homebrew/dev-cmd/irb.rb | 2 +- Library/Homebrew/dev-cmd/pr-automerge.rb | 2 +- Library/Homebrew/dev-cmd/pr-upload.rb | 2 +- Library/Homebrew/dev-cmd/prof.rb | 2 +- Library/Homebrew/dev-cmd/ruby.rb | 2 +- Library/Homebrew/dev-cmd/tests.rb | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Library/Homebrew/dev-cmd/bump-formula-pr.rb b/Library/Homebrew/dev-cmd/bump-formula-pr.rb index f7e94e5e23..0b15f93628 100644 --- a/Library/Homebrew/dev-cmd/bump-formula-pr.rb +++ b/Library/Homebrew/dev-cmd/bump-formula-pr.rb @@ -1,4 +1,4 @@ -# typed: false +# typed: true # frozen_string_literal: true require "formula" diff --git a/Library/Homebrew/dev-cmd/bump-unversioned-casks.rb b/Library/Homebrew/dev-cmd/bump-unversioned-casks.rb index 293ca7ee7d..ed363ed391 100644 --- a/Library/Homebrew/dev-cmd/bump-unversioned-casks.rb +++ b/Library/Homebrew/dev-cmd/bump-unversioned-casks.rb @@ -1,4 +1,4 @@ -# typed: false +# typed: true # frozen_string_literal: true require "timeout" diff --git a/Library/Homebrew/dev-cmd/irb.rb b/Library/Homebrew/dev-cmd/irb.rb index 45e9abc27a..f7a7a48231 100644 --- a/Library/Homebrew/dev-cmd/irb.rb +++ b/Library/Homebrew/dev-cmd/irb.rb @@ -1,4 +1,4 @@ -# typed: false +# typed: true # frozen_string_literal: true require "formulary" diff --git a/Library/Homebrew/dev-cmd/pr-automerge.rb b/Library/Homebrew/dev-cmd/pr-automerge.rb index e2e302b6c9..ce5c442c81 100644 --- a/Library/Homebrew/dev-cmd/pr-automerge.rb +++ b/Library/Homebrew/dev-cmd/pr-automerge.rb @@ -1,4 +1,4 @@ -# typed: false +# typed: true # frozen_string_literal: true require "cli/parser" diff --git a/Library/Homebrew/dev-cmd/pr-upload.rb b/Library/Homebrew/dev-cmd/pr-upload.rb index f0296d4f75..c966dcde1c 100644 --- a/Library/Homebrew/dev-cmd/pr-upload.rb +++ b/Library/Homebrew/dev-cmd/pr-upload.rb @@ -1,4 +1,4 @@ -# typed: false +# typed: true # frozen_string_literal: true require "cli/parser" diff --git a/Library/Homebrew/dev-cmd/prof.rb b/Library/Homebrew/dev-cmd/prof.rb index 0b595e9113..0d02cdb26a 100644 --- a/Library/Homebrew/dev-cmd/prof.rb +++ b/Library/Homebrew/dev-cmd/prof.rb @@ -1,4 +1,4 @@ -# typed: false +# typed: true # frozen_string_literal: true require "cli/parser" diff --git a/Library/Homebrew/dev-cmd/ruby.rb b/Library/Homebrew/dev-cmd/ruby.rb index c353921188..5db9c72641 100644 --- a/Library/Homebrew/dev-cmd/ruby.rb +++ b/Library/Homebrew/dev-cmd/ruby.rb @@ -1,4 +1,4 @@ -# typed: false +# typed: true # frozen_string_literal: true require "cli/parser" diff --git a/Library/Homebrew/dev-cmd/tests.rb b/Library/Homebrew/dev-cmd/tests.rb index 9698c62833..e49b62cf6d 100644 --- a/Library/Homebrew/dev-cmd/tests.rb +++ b/Library/Homebrew/dev-cmd/tests.rb @@ -1,4 +1,4 @@ -# typed: false +# typed: true # frozen_string_literal: true require "cli/parser" From 76671ef55507f7aaa5e7ba8df0afc70f666eea9f Mon Sep 17 00:00:00 2001 From: Douglas Eichelberger Date: Thu, 9 Mar 2023 20:51:01 -0800 Subject: [PATCH 3/4] Typecheck ENV extensions --- Library/Homebrew/extend/os/mac/extend/ENV/std.rb | 4 ++-- Library/Homebrew/extend/os/mac/extend/ENV/super.rb | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Library/Homebrew/extend/os/mac/extend/ENV/std.rb b/Library/Homebrew/extend/os/mac/extend/ENV/std.rb index d17b35c64d..cb42b054a9 100644 --- a/Library/Homebrew/extend/os/mac/extend/ENV/std.rb +++ b/Library/Homebrew/extend/os/mac/extend/ENV/std.rb @@ -1,4 +1,4 @@ -# typed: false +# typed: true # frozen_string_literal: true module Stdenv @@ -7,7 +7,7 @@ module Stdenv undef homebrew_extra_pkg_config_paths def homebrew_extra_pkg_config_paths - ["#{HOMEBREW_LIBRARY}/Homebrew/os/mac/pkgconfig/#{MacOS.version}"] + [Pathname("#{HOMEBREW_LIBRARY}/Homebrew/os/mac/pkgconfig/#{MacOS.version}")] end def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false, diff --git a/Library/Homebrew/extend/os/mac/extend/ENV/super.rb b/Library/Homebrew/extend/os/mac/extend/ENV/super.rb index e141f559dd..bb032b370e 100644 --- a/Library/Homebrew/extend/os/mac/extend/ENV/super.rb +++ b/Library/Homebrew/extend/os/mac/extend/ENV/super.rb @@ -1,4 +1,4 @@ -# typed: false +# typed: true # frozen_string_literal: true module Superenv @@ -29,7 +29,7 @@ module Superenv # @private def homebrew_extra_pkg_config_paths - ["/usr/lib/pkgconfig", "#{HOMEBREW_LIBRARY}/Homebrew/os/mac/pkgconfig/#{MacOS.version}"] + [Pathname("/usr/lib/pkgconfig"), Pathname("#{HOMEBREW_LIBRARY}/Homebrew/os/mac/pkgconfig/#{MacOS.version}")] end # @private @@ -68,7 +68,7 @@ module Superenv end def homebrew_extra_cmake_library_paths - ["#{self["HOMEBREW_SDKROOT"]}/System/Library/Frameworks/OpenGL.framework/Versions/Current/Libraries"] + [Pathname("#{self["HOMEBREW_SDKROOT"]}/System/Library/Frameworks/OpenGL.framework/Versions/Current/Libraries")] end def homebrew_extra_cmake_frameworks_paths @@ -96,7 +96,7 @@ module Superenv end self["HOMEBREW_DEVELOPER_DIR"] = if is_xcode_sdk - MacOS::Xcode.prefix + MacOS::Xcode.prefix.to_s else MacOS::CLT::PKG_PATH end From 9446db772025d91d5ae5df0944fc86da7e0e5c1a Mon Sep 17 00:00:00 2001 From: Douglas Eichelberger Date: Thu, 9 Mar 2023 21:10:44 -0800 Subject: [PATCH 4/4] Typecheck some utils --- Library/Homebrew/utils/autoremove.rb | 6 +++--- Library/Homebrew/utils/curl.rb | 14 +++++++------- Library/Homebrew/utils/curl.rbi | 6 ++++++ Library/Homebrew/utils/formatter.rb | 14 +++++++------- Library/Homebrew/utils/formatter.rbi | 5 +++++ 5 files changed, 28 insertions(+), 17 deletions(-) create mode 100644 Library/Homebrew/utils/curl.rbi create mode 100644 Library/Homebrew/utils/formatter.rbi diff --git a/Library/Homebrew/utils/autoremove.rb b/Library/Homebrew/utils/autoremove.rb index cb34473286..3a53c5d745 100644 --- a/Library/Homebrew/utils/autoremove.rb +++ b/Library/Homebrew/utils/autoremove.rb @@ -1,4 +1,4 @@ -# typed: false +# typed: true # frozen_string_literal: true module Utils @@ -25,7 +25,7 @@ module Utils def formulae_with_no_formula_dependents(formulae) return [] if formulae.blank? - dependents = [] + dependents = T.let([], T::Array[Formula]) formulae.each do |formula| dependents += formula.runtime_formula_dependencies @@ -33,7 +33,7 @@ module Utils next if Tab.for_keg(formula.any_installed_keg).poured_from_bottle formula.deps.select(&:build?).each do |dep| - suppress(FormulaUnavailableError) { dependents << dep.to_formula } + Kernel.suppress(FormulaUnavailableError) { dependents << dep.to_formula } end end formulae - dependents diff --git a/Library/Homebrew/utils/curl.rb b/Library/Homebrew/utils/curl.rb index 80cf0517dc..049f889e96 100644 --- a/Library/Homebrew/utils/curl.rb +++ b/Library/Homebrew/utils/curl.rb @@ -1,4 +1,4 @@ -# typed: false +# typed: true # frozen_string_literal: true require "open3" @@ -243,8 +243,8 @@ module Utils return unless url.start_with? "http" secure_url = url.sub(/\Ahttp:/, "https:") - secure_details = nil - hash_needed = false + secure_details = T.let(nil, T.nilable(T::Hash[Symbol, T.untyped])) + hash_needed = T.let(false, T::Boolean) if url != secure_url user_agents.each do |user_agent| secure_details = begin @@ -267,7 +267,7 @@ module Utils end end - details = nil + details = T.let(nil, T.nilable(T::Hash[Symbol, T.untyped])) user_agents.each do |user_agent| details = curl_http_content_headers_and_checksum( @@ -414,7 +414,7 @@ module Utils # Unknown charset in Content-Type header end end - file_contents = File.read(file.path, **open_args) + file_contents = File.read(T.must(file.path), **open_args) file_hash = Digest::SHA2.hexdigest(file_contents) if hash_needed end @@ -430,7 +430,7 @@ module Utils responses: responses, } ensure - file.unlink + T.must(file).unlink end def curl_supports_tls13? @@ -547,7 +547,7 @@ module Utils return response unless response_text.match?(HTTP_STATUS_LINE_REGEX) # Parse the status line and remove it - match = response_text.match(HTTP_STATUS_LINE_REGEX) + match = T.must(response_text.match(HTTP_STATUS_LINE_REGEX)) response[:status_code] = match["code"] if match["code"].present? response[:status_text] = match["text"] if match["text"].present? response_text = response_text.sub(%r{^HTTP/.* (\d+).*$\s*}, "") diff --git a/Library/Homebrew/utils/curl.rbi b/Library/Homebrew/utils/curl.rbi new file mode 100644 index 0000000000..e69d89d750 --- /dev/null +++ b/Library/Homebrew/utils/curl.rbi @@ -0,0 +1,6 @@ +# typed: strict + +module Utils::Curl + include Kernel + requires_ancestor { SystemCommand::Mixin } +end diff --git a/Library/Homebrew/utils/formatter.rb b/Library/Homebrew/utils/formatter.rb index 3b7caae2b3..870364c142 100644 --- a/Library/Homebrew/utils/formatter.rb +++ b/Library/Homebrew/utils/formatter.rb @@ -1,4 +1,4 @@ -# typed: false +# typed: true # frozen_string_literal: true require "utils/tty" @@ -91,11 +91,11 @@ module Formatter end fallback.call if objects.empty? - fallback.call if respond_to?(:tty?) ? !tty? : !$stdout.tty? + fallback.call if respond_to?(:tty?) ? !T.unsafe(self).tty? : !$stdout.tty? console_width = Tty.width object_lengths = objects.map { |obj| Tty.strip_ansi(obj).length } - cols = (console_width + gap_size) / (object_lengths.max + gap_size) + cols = (console_width + gap_size) / (T.must(object_lengths.max) + gap_size) fallback.call if cols < 2 @@ -109,14 +109,14 @@ module Formatter output = +"" rows.times do |row_index| - item_indices_for_row = row_index.step(objects.size - 1, rows).to_a + item_indices_for_row = T.cast(row_index.step(objects.size - 1, rows).to_a, T::Array[Integer]) - first_n = item_indices_for_row[0...-1].map do |index| - objects[index] + "".rjust(col_width - object_lengths[index]) + first_n = T.must(item_indices_for_row[0...-1]).map do |index| + objects[index] + "".rjust(col_width - object_lengths.fetch(index)) end # don't add trailing whitespace to last column - last = objects.values_at(item_indices_for_row.last) + last = objects.values_at(item_indices_for_row.fetch(-1)) output.concat((first_n + last) .join(gap_string)) diff --git a/Library/Homebrew/utils/formatter.rbi b/Library/Homebrew/utils/formatter.rbi new file mode 100644 index 0000000000..e9038dd0f3 --- /dev/null +++ b/Library/Homebrew/utils/formatter.rbi @@ -0,0 +1,5 @@ +# typed: strict + +module Formatter + include Kernel +end