16
16
module Homebrew
17
17
module Cmd
18
18
class Info < AbstractCommand
19
+ class NameSize < T ::Struct
20
+ const :name , String
21
+ const :size , Integer
22
+ end
23
+ private_constant :NameSize
24
+
19
25
VALID_DAYS = %w[ 30 90 365 ] . freeze
20
26
VALID_FORMULA_CATEGORIES = %w[ install install-on-request build-error ] . freeze
21
27
VALID_CATEGORIES = T . let ( ( VALID_FORMULA_CATEGORIES + %w[ cask-install os-version ] ) . freeze , T ::Array [ String ] )
@@ -67,6 +73,8 @@ class Info < AbstractCommand
67
73
description : "Treat all named arguments as formulae."
68
74
switch "--cask" , "--casks" ,
69
75
description : "Treat all named arguments as casks."
76
+ switch "--sizes" ,
77
+ description : "Show the size of installed formulae and casks."
70
78
71
79
conflicts "--installed" , "--eval-all"
72
80
conflicts "--installed" , "--all"
@@ -79,7 +87,15 @@ class Info < AbstractCommand
79
87
80
88
sig { override . void }
81
89
def run
82
- if args . analytics?
90
+ if args . sizes?
91
+ if args . no_named?
92
+ print_sizes
93
+ else
94
+ formulae , casks = args . named . to_formulae_to_casks
95
+ formulae = T . cast ( formulae , T ::Array [ Formula ] )
96
+ print_sizes ( formulae :, casks :)
97
+ end
98
+ elsif args . analytics?
83
99
if args . days . present? && VALID_DAYS . exclude? ( args . days )
84
100
raise UsageError , "`--days` must be one of #{ VALID_DAYS . join ( ", " ) } ."
85
101
end
@@ -401,6 +417,64 @@ def info_cask(cask)
401
417
402
418
Cask ::Info . info ( cask , args :)
403
419
end
420
+
421
+ sig { params ( title : String , items : T ::Array [ NameSize ] ) . void }
422
+ def print_sizes_table ( title , items )
423
+ return if items . blank?
424
+
425
+ ohai title
426
+
427
+ total_size = items . sum ( &:size )
428
+ total_size_str = disk_usage_readable ( total_size )
429
+
430
+ name_width = ( items . map { |item | item . name . length } + [ 5 ] ) . max
431
+ size_width = ( items . map { |item | disk_usage_readable ( item . size ) . length } + [ total_size_str . length ] ) . max
432
+
433
+ items . each do |item |
434
+ puts format ( "%-#{ name_width } s %#{ size_width } s" , item . name ,
435
+ disk_usage_readable ( item . size ) )
436
+ end
437
+
438
+ puts format ( "%-#{ name_width } s %#{ size_width } s" , "Total" , total_size_str )
439
+ end
440
+
441
+ sig { params ( formulae : T ::Array [ Formula ] , casks : T ::Array [ Cask ::Cask ] ) . void }
442
+ def print_sizes ( formulae : [ ] , casks : [ ] )
443
+ if formulae . blank? &&
444
+ ( args . formulae? || ( !args . casks? && args . no_named? ) )
445
+ formulae = Formula . installed
446
+ end
447
+
448
+ if casks . blank? &&
449
+ ( args . casks? || ( !args . formulae? && args . no_named? ) )
450
+ casks = Cask ::Caskroom . casks
451
+ end
452
+
453
+ unless args . casks?
454
+ formula_sizes = formulae . map do |formula |
455
+ kegs = formula . installed_kegs
456
+ size = kegs . sum ( &:disk_usage )
457
+ NameSize . new ( name : formula . full_name , size :)
458
+ end
459
+ formula_sizes . sort_by! { |f | -f . size }
460
+ print_sizes_table ( "Formulae sizes:" , formula_sizes )
461
+ end
462
+
463
+ return if casks . blank? || args . formulae?
464
+
465
+ cask_sizes = casks . filter_map do |cask |
466
+ installed_version = cask . installed_version
467
+ next unless installed_version . present?
468
+
469
+ versioned_staged_path = cask . caskroom_path . join ( installed_version )
470
+ next unless versioned_staged_path . exist?
471
+
472
+ size = versioned_staged_path . children . sum ( &:disk_usage )
473
+ NameSize . new ( name : cask . full_name , size :)
474
+ end
475
+ cask_sizes . sort_by! { |c | -c . size }
476
+ print_sizes_table ( "Casks sizes:" , cask_sizes )
477
+ end
404
478
end
405
479
end
406
480
end
0 commit comments