@@ -13,7 +13,6 @@ import (
1313 "os/signal"
1414 "path/filepath"
1515 "strings"
16- "syscall"
1716
1817 "github.com/Masterminds/semver"
1918 "github.com/pkg/errors"
@@ -58,6 +57,8 @@ const (
5857 errorNoActiveContexForGivenContextType = "there is no active context for the given context type `%v`"
5958)
6059
60+ var totalPluginsToInstall = 0
61+ var pluginsInstalled = 0
6162var execCommand = exec .Command
6263
6364type DeletePluginOptions struct {
@@ -609,24 +610,30 @@ func InstallPluginsFromGroup(pluginName, groupIDAndVersion string, options ...Pl
609610// InstallPluginsFromGivenPluginGroup installs either the specified plugin or all plugins from given plugin group plugins.
610611func InstallPluginsFromGivenPluginGroup (pluginName , groupIDAndVersion string , pg * plugininventory.PluginGroup ) (string , error ) {
611612 numErrors := 0
612- numInstalled := 0
613613 mandatoryPluginsExist := false
614614 pluginExist := false
615+ pluginsInstalled = 0
616+
617+ pluginsToInstall := make ([]* plugininventory.PluginGroupPluginEntry , 0 )
615618 for _ , plugin := range pg .Versions [pg .RecommendedVersion ] {
616619 if pluginName == cli .AllPlugins || pluginName == plugin .Name {
617620 pluginExist = true
618621 if plugin .Mandatory {
619622 mandatoryPluginsExist = true
620- err := InstallStandalonePlugin (plugin .Name , plugin .Version , plugin .Target )
621- if err != nil {
622- numErrors ++
623- log .Warningf ("unable to install plugin '%s': %v" , plugin .Name , err .Error ())
624- } else {
625- numInstalled ++
626- }
623+ pluginsToInstall = append (pluginsToInstall , plugin ) // Add mandatory plugin to the slice
627624 }
628625 }
629626 }
627+ totalPluginsToInstall = len (pluginsToInstall )
628+ for _ , plugin := range pluginsToInstall {
629+ err := InstallStandalonePlugin (plugin .Name , plugin .Version , plugin .Target )
630+ if err != nil {
631+ numErrors ++
632+ log .Warningf ("unable to install plugin '%s': %v" , plugin .Name , err .Error ())
633+ } else {
634+ pluginsInstalled ++
635+ }
636+ }
630637
631638 if ! pluginExist {
632639 return groupIDAndVersion , fmt .Errorf ("plugin '%s' is not part of the group '%s'" , pluginName , groupIDAndVersion )
@@ -643,7 +650,7 @@ func InstallPluginsFromGivenPluginGroup(pluginName, groupIDAndVersion string, pg
643650 return groupIDAndVersion , fmt .Errorf ("could not install %d plugin(s) from group '%s'" , numErrors , groupIDAndVersion )
644651 }
645652
646- if numInstalled == 0 {
653+ if pluginsInstalled == 0 {
647654 return groupIDAndVersion , fmt .Errorf ("plugin '%s' is not part of the group '%s'" , pluginName , groupIDAndVersion )
648655 }
649656
@@ -744,40 +751,31 @@ func installOrUpgradePlugin(p *discovery.Discovered, version string, installTest
744751 }
745752
746753 // Log message based on different installation conditions
747- installingMsg , installedMsg , errMsg := getPluginInstallationMessage (p , version , plugin != nil , isPluginAlreadyInstalled )
754+ installingMsg , _ , errMsg := getPluginInstallationMessage (p , version , plugin != nil , isPluginAlreadyInstalled )
748755
756+ installingMsg = fmt .Sprintf ("[%v/%v] %v" , pluginsInstalled , totalPluginsToInstall , installingMsg )
757+ errMsg = fmt .Sprintf ("[%v/%v] %v" , pluginsInstalled , totalPluginsToInstall , errMsg )
758+ errorMsgAfterSpinnerStop := fmt .Sprintf ("%d plugins installed out of %d" , pluginsInstalled , totalPluginsToInstall )
749759 var spinner component.OutputWriterSpinner
750760
751761 // Initialize the spinner if the spinner is allowed
752762 if component .IsTTYEnabled () {
763+ // Initialize the spinner
764+ spinner = component .NewOutputWriterSpinner (component .WithOutputStream (os .Stderr ),
765+ component .WithSpinnerText (installingMsg ),
766+ component .WithSpinnerStarted ())
767+
753768 // Create a channel to receive OS signals
754769 signalChannel := make (chan os.Signal , 1 )
755- // Register the channel to receive interrupt signals (e.g., Ctrl+C)
756- signal .Notify (signalChannel , syscall .SIGINT , syscall .SIGTERM )
770+ // Initialize the signal catcher
771+ go utils .SignalCatcherInitialization (signalChannel , spinner , errMsg , log .LogTypeERROR , errorMsgAfterSpinnerStop )
772+
757773 defer func () {
758774 signal .Stop (signalChannel )
759775 close (signalChannel )
776+ spinner .StopSpinner ()
777+ component .StopAllSpinners ()
760778 }()
761-
762- // Initialize the spinner
763- spinner = component .NewOutputWriterSpinner (component .WithOutputStream (os .Stderr ),
764- component .WithSpinnerText (installingMsg ),
765- component .WithSpinnerStarted (),
766- component .WithSpinnerFinalText (installedMsg , log .LogTypeINFO ))
767-
768- defer spinner .StopSpinner ()
769-
770- // Start a goroutine that listens for interrupt signals
771- go func (s component.OutputWriterSpinner ) {
772- sig := <- signalChannel
773- if sig != nil {
774- if s != nil {
775- s .SetFinalText (errMsg , log .LogTypeERROR )
776- s .StopSpinner ()
777- }
778- os .Exit (128 + int (sig .(syscall.Signal )))
779- }
780- }(spinner )
781779 } else {
782780 log .Info (installingMsg )
783781 }
@@ -1154,29 +1152,45 @@ func UpdatePluginsInstallationStatus(plugins []discovery.Discovered) {
11541152// InstallDiscoveredContextPlugins installs the given context scope plugins
11551153func InstallDiscoveredContextPlugins (plugins []discovery.Discovered ) error {
11561154 var errList []error
1157- var err error
1158- installed := false
1155+
1156+ // Slice to capture plugins to install
1157+ var pluginsToInstall []discovery.Discovered
1158+
11591159 UpdatePluginsInstallationStatus (plugins )
1160+
1161+ // Capture plugins that need install/update
11601162 for idx := range plugins {
1161- if plugins [idx ].Status == common .PluginStatusNotInstalled || plugins [idx ].Status == common .PluginStatusUpdateAvailable {
1162- installed = true
1163- p := plugins [idx ]
1164- err = InstallPluginFromContext (p .Name , p .RecommendedVersion , p .Target , p .ContextName )
1165- if err != nil {
1166- errList = append (errList , err )
1167- }
1163+ if plugins [idx ].Status == common .PluginStatusNotInstalled ||
1164+ plugins [idx ].Status == common .PluginStatusUpdateAvailable {
1165+ pluginsToInstall = append (pluginsToInstall , plugins [idx ])
11681166 }
11691167 }
1170- err = kerrors .NewAggregate (errList )
1168+ totalPluginsToInstall = len (pluginsToInstall )
1169+ // Now install captured plugins
1170+ for idx := range pluginsToInstall {
1171+ err := InstallPluginFromContext (pluginsToInstall [idx ].Name , pluginsToInstall [idx ].RecommendedVersion , pluginsToInstall [idx ].Target , pluginsToInstall [idx ].ContextName )
1172+ if err != nil {
1173+ errList = append (errList , err )
1174+ } else {
1175+ pluginsInstalled ++
1176+ }
1177+ }
1178+
1179+ // Aggregate errors
1180+ err := kerrors .NewAggregate (errList )
11711181 if err != nil {
11721182 return err
11731183 }
11741184
1175- if ! installed {
1185+ // Output install status
1186+ if len (pluginsToInstall ) == 0 {
11761187 log .Info ("All required plugins are already installed and up-to-date" )
1188+ } else if pluginsInstalled == totalPluginsToInstall {
1189+ log .Infof ("Successfully installed all required %v plugins" , pluginsInstalled )
11771190 } else {
1178- log .Info ("Successfully installed all required plugins" )
1191+ log .Infof ("Successfully installed %v of %v required plugins" , pluginsInstalled , totalPluginsToInstall )
11791192 }
1193+
11801194 return nil
11811195}
11821196
0 commit comments