From 0c788756165bb3fe9a466c414ca05e925578e757 Mon Sep 17 00:00:00 2001 From: Luka Rajic Date: Fri, 1 Aug 2025 16:57:38 -0400 Subject: [PATCH] Add a way to view the size of each installed formula/cask Change styling based on output of brew typecheck and brew style Changes as per PR comments Remove --leaves flag functionality Simplify formulae and cask parsing as well as style changes as per PR comments Update cask and formulae parsing as per PR comment suggestion Add column formatting function as well as PR comment suggestions Add Sorbet struct for printing and minor logic changes as per PR comments Minor changes as per PR comments and fix formatting issue in output --- Library/Homebrew/cmd/info.rb | 76 ++++++++++++++++++- .../sorbet/rbi/dsl/homebrew/cmd/info.rbi | 3 + 2 files changed, 78 insertions(+), 1 deletion(-) diff --git a/Library/Homebrew/cmd/info.rb b/Library/Homebrew/cmd/info.rb index eb92087faa..5040ebb361 100644 --- a/Library/Homebrew/cmd/info.rb +++ b/Library/Homebrew/cmd/info.rb @@ -16,6 +16,12 @@ require "api" module Homebrew module Cmd class Info < AbstractCommand + class NameSize < T::Struct + const :name, String + const :size, Integer + end + private_constant :NameSize + VALID_DAYS = %w[30 90 365].freeze VALID_FORMULA_CATEGORIES = %w[install install-on-request build-error].freeze VALID_CATEGORIES = T.let((VALID_FORMULA_CATEGORIES + %w[cask-install os-version]).freeze, T::Array[String]) @@ -67,6 +73,8 @@ module Homebrew description: "Treat all named arguments as formulae." switch "--cask", "--casks", description: "Treat all named arguments as casks." + switch "--sizes", + description: "Show the size of installed formulae and casks." conflicts "--installed", "--eval-all" conflicts "--installed", "--all" @@ -79,7 +87,15 @@ module Homebrew sig { override.void } def run - if args.analytics? + if args.sizes? + if args.no_named? + print_sizes + else + formulae, casks = args.named.to_formulae_to_casks + formulae = T.cast(formulae, T::Array[Formula]) + print_sizes(formulae:, casks:) + end + elsif args.analytics? if args.days.present? && VALID_DAYS.exclude?(args.days) raise UsageError, "`--days` must be one of #{VALID_DAYS.join(", ")}." end @@ -401,6 +417,64 @@ module Homebrew Cask::Info.info(cask, args:) end + + sig { params(title: String, items: T::Array[NameSize]).void } + def print_sizes_table(title, items) + return if items.blank? + + ohai title + + total_size = items.sum(&:size) + total_size_str = disk_usage_readable(total_size) + + name_width = (items.map { |item| item.name.length } + [5]).max + size_width = (items.map { |item| disk_usage_readable(item.size).length } + [total_size_str.length]).max + + items.each do |item| + puts format("%-#{name_width}s %#{size_width}s", item.name, + disk_usage_readable(item.size)) + end + + puts format("%-#{name_width}s %#{size_width}s", "Total", total_size_str) + end + + sig { params(formulae: T::Array[Formula], casks: T::Array[Cask::Cask]).void } + def print_sizes(formulae: [], casks: []) + if formulae.blank? && + (args.formulae? || (!args.casks? && args.no_named?)) + formulae = Formula.installed + end + + if casks.blank? && + (args.casks? || (!args.formulae? && args.no_named?)) + casks = Cask::Caskroom.casks + end + + unless args.casks? + formula_sizes = formulae.map do |formula| + kegs = formula.installed_kegs + size = kegs.sum(&:disk_usage) + NameSize.new(name: formula.full_name, size:) + end + formula_sizes.sort_by! { |f| -f.size } + print_sizes_table("Formulae sizes:", formula_sizes) + end + + return if casks.blank? || args.formulae? + + cask_sizes = casks.filter_map do |cask| + installed_version = cask.installed_version + next unless installed_version.present? + + versioned_staged_path = cask.caskroom_path.join(installed_version) + next unless versioned_staged_path.exist? + + size = versioned_staged_path.children.sum(&:disk_usage) + NameSize.new(name: cask.full_name, size:) + end + cask_sizes.sort_by! { |c| -c.size } + print_sizes_table("Casks sizes:", cask_sizes) + end end end end diff --git a/Library/Homebrew/sorbet/rbi/dsl/homebrew/cmd/info.rbi b/Library/Homebrew/sorbet/rbi/dsl/homebrew/cmd/info.rbi index db897357c8..b1fb21788b 100644 --- a/Library/Homebrew/sorbet/rbi/dsl/homebrew/cmd/info.rbi +++ b/Library/Homebrew/sorbet/rbi/dsl/homebrew/cmd/info.rbi @@ -50,6 +50,9 @@ class Homebrew::Cmd::Info::Args < Homebrew::CLI::Args sig { returns(T.nilable(String)) } def json; end + sig { returns(T::Boolean) } + def sizes?; end + sig { returns(T::Boolean) } def variations?; end end