@@ -17,6 +17,12 @@ import (
1717
1818var ErrUserCancelled = fmt .Errorf ("user cancelled" )
1919
20+ const (
21+ estimatedSecondsPerFormula = 15
22+ estimatedSecondsPerCask = 30
23+ estimatedSecondsPerNpm = 5
24+ )
25+
2026func Run (cfg * config.Config ) error {
2127 if cfg .Update {
2228 return runUpdate (cfg )
@@ -56,18 +62,12 @@ func runCustomInstall(cfg *config.Config) error {
5662 }
5763 fmt .Println ()
5864
59- // Calculate estimated install time
6065 formulaeCount := len (cfg .RemoteConfig .Packages )
6166 caskCount := len (cfg .RemoteConfig .Casks )
6267 npmCount := len (cfg .RemoteConfig .Npm )
6368 totalPackages := formulaeCount + caskCount + npmCount
6469
65- // Heuristic: ~15s per formula, ~30s per cask, ~5s per npm
66- totalSeconds := formulaeCount * 15 + caskCount * 30 + npmCount * 5
67- minutes := totalSeconds / 60
68- if minutes < 1 {
69- minutes = 1
70- }
70+ minutes := estimateInstallMinutes (formulaeCount , caskCount , npmCount )
7171 ui .Info (fmt .Sprintf ("Estimated install time: ~%d min for %d packages" , minutes , totalPackages ))
7272 fmt .Println ()
7373
@@ -285,60 +285,9 @@ func stepInstallPackages(cfg *config.Config) error {
285285 ui .Header ("Step 4: Installation" )
286286 fmt .Println ()
287287
288- var cliPkgs , caskPkgs []string
289-
290- if cfg .RemoteConfig != nil {
291- caskSet := make (map [string ]bool )
292- for _ , c := range cfg .RemoteConfig .Casks {
293- caskSet [c ] = true
294- }
295- npmSet := make (map [string ]bool )
296- for _ , n := range cfg .RemoteConfig .Npm {
297- npmSet [n ] = true
298- }
299- for pkg := range cfg .SelectedPkgs {
300- if npmSet [pkg ] || config .IsNpmPackage (pkg ) {
301- continue
302- } else if caskSet [pkg ] || config .IsCaskPackage (pkg ) {
303- caskPkgs = append (caskPkgs , pkg )
304- } else {
305- cliPkgs = append (cliPkgs , pkg )
306- }
307- }
308- } else {
309- for _ , cat := range config .Categories {
310- for _ , pkg := range cat .Packages {
311- if cfg .SelectedPkgs [pkg .Name ] {
312- if pkg .IsNpm {
313- continue
314- } else if pkg .IsCask {
315- caskPkgs = append (caskPkgs , pkg .Name )
316- } else {
317- cliPkgs = append (cliPkgs , pkg .Name )
318- }
319- }
320- }
321- }
322- seen := make (map [string ]bool )
323- for _ , p := range cliPkgs {
324- seen [p ] = true
325- }
326- for _ , p := range caskPkgs {
327- seen [p ] = true
328- }
329- for _ , pkg := range cfg .OnlinePkgs {
330- if seen [pkg .Name ] {
331- continue
332- }
333- if pkg .IsNpm {
334- continue
335- } else if pkg .IsCask {
336- caskPkgs = append (caskPkgs , pkg .Name )
337- } else {
338- cliPkgs = append (cliPkgs , pkg .Name )
339- }
340- }
341- }
288+ pkgs := categorizeSelectedPackages (cfg )
289+ cliPkgs := pkgs .cli
290+ caskPkgs := pkgs .cask
342291
343292 total := len (cliPkgs ) + len (caskPkgs )
344293 if total == 0 {
@@ -366,22 +315,8 @@ func stepInstallNpm(cfg *config.Config) error {
366315 if cfg .RemoteConfig != nil {
367316 npmPkgs = cfg .RemoteConfig .Npm
368317 } else {
369- for _ , cat := range config .Categories {
370- for _ , pkg := range cat .Packages {
371- if pkg .IsNpm && cfg .SelectedPkgs [pkg .Name ] {
372- npmPkgs = append (npmPkgs , pkg .Name )
373- }
374- }
375- }
376- npmSeen := make (map [string ]bool )
377- for _ , p := range npmPkgs {
378- npmSeen [p ] = true
379- }
380- for _ , pkg := range cfg .OnlinePkgs {
381- if pkg .IsNpm && ! npmSeen [pkg .Name ] {
382- npmPkgs = append (npmPkgs , pkg .Name )
383- }
384- }
318+ pkgs := categorizeSelectedPackages (cfg )
319+ npmPkgs = pkgs .npm
385320 }
386321
387322 if len (npmPkgs ) == 0 {
@@ -691,3 +626,74 @@ func runRollback(cfg *config.Config) error {
691626 ui .Muted ("Rollback functionality coming soon..." )
692627 return nil
693628}
629+
630+ func estimateInstallMinutes (formulaeCount , caskCount , npmCount int ) int {
631+ totalSeconds := formulaeCount * estimatedSecondsPerFormula +
632+ caskCount * estimatedSecondsPerCask +
633+ npmCount * estimatedSecondsPerNpm
634+ minutes := totalSeconds / 60
635+ if minutes < 1 {
636+ minutes = 1
637+ }
638+ return minutes
639+ }
640+
641+ type categorizedPackages struct {
642+ cli []string
643+ cask []string
644+ npm []string
645+ }
646+
647+ func categorizeSelectedPackages (cfg * config.Config ) categorizedPackages {
648+ var result categorizedPackages
649+
650+ if cfg .RemoteConfig != nil {
651+ caskSet := make (map [string ]bool )
652+ for _ , c := range cfg .RemoteConfig .Casks {
653+ caskSet [c ] = true
654+ }
655+ npmSet := make (map [string ]bool )
656+ for _ , n := range cfg .RemoteConfig .Npm {
657+ npmSet [n ] = true
658+ }
659+ for pkg := range cfg .SelectedPkgs {
660+ if npmSet [pkg ] || config .IsNpmPackage (pkg ) {
661+ result .npm = append (result .npm , pkg )
662+ } else if caskSet [pkg ] || config .IsCaskPackage (pkg ) {
663+ result .cask = append (result .cask , pkg )
664+ } else {
665+ result .cli = append (result .cli , pkg )
666+ }
667+ }
668+ return result
669+ }
670+
671+ seen := make (map [string ]bool )
672+ for _ , cat := range config .Categories {
673+ for _ , pkg := range cat .Packages {
674+ if cfg .SelectedPkgs [pkg .Name ] {
675+ seen [pkg .Name ] = true
676+ if pkg .IsNpm {
677+ result .npm = append (result .npm , pkg .Name )
678+ } else if pkg .IsCask {
679+ result .cask = append (result .cask , pkg .Name )
680+ } else {
681+ result .cli = append (result .cli , pkg .Name )
682+ }
683+ }
684+ }
685+ }
686+ for _ , pkg := range cfg .OnlinePkgs {
687+ if seen [pkg .Name ] {
688+ continue
689+ }
690+ if pkg .IsNpm {
691+ result .npm = append (result .npm , pkg .Name )
692+ } else if pkg .IsCask {
693+ result .cask = append (result .cask , pkg .Name )
694+ } else {
695+ result .cli = append (result .cli , pkg .Name )
696+ }
697+ }
698+ return result
699+ }
0 commit comments