@@ -13,7 +13,6 @@ import (
13
13
"os/signal"
14
14
"path/filepath"
15
15
"strings"
16
- "syscall"
17
16
18
17
"github.com/Masterminds/semver"
19
18
"github.com/pkg/errors"
@@ -58,6 +57,8 @@ const (
58
57
errorNoActiveContexForGivenContextType = "there is no active context for the given context type `%v`"
59
58
)
60
59
60
+ var totalPluginsToInstall = 0
61
+ var pluginsInstalled = 0
61
62
var execCommand = exec .Command
62
63
63
64
type DeletePluginOptions struct {
@@ -609,24 +610,30 @@ func InstallPluginsFromGroup(pluginName, groupIDAndVersion string, options ...Pl
609
610
// InstallPluginsFromGivenPluginGroup installs either the specified plugin or all plugins from given plugin group plugins.
610
611
func InstallPluginsFromGivenPluginGroup (pluginName , groupIDAndVersion string , pg * plugininventory.PluginGroup ) (string , error ) {
611
612
numErrors := 0
612
- numInstalled := 0
613
613
mandatoryPluginsExist := false
614
614
pluginExist := false
615
+ pluginsInstalled = 0
616
+
617
+ pluginsToInstall := make ([]* plugininventory.PluginGroupPluginEntry , 0 )
615
618
for _ , plugin := range pg .Versions [pg .RecommendedVersion ] {
616
619
if pluginName == cli .AllPlugins || pluginName == plugin .Name {
617
620
pluginExist = true
618
621
if plugin .Mandatory {
619
622
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
627
624
}
628
625
}
629
626
}
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
+ }
630
637
631
638
if ! pluginExist {
632
639
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
643
650
return groupIDAndVersion , fmt .Errorf ("could not install %d plugin(s) from group '%s'" , numErrors , groupIDAndVersion )
644
651
}
645
652
646
- if numInstalled == 0 {
653
+ if pluginsInstalled == 0 {
647
654
return groupIDAndVersion , fmt .Errorf ("plugin '%s' is not part of the group '%s'" , pluginName , groupIDAndVersion )
648
655
}
649
656
@@ -744,40 +751,31 @@ func installOrUpgradePlugin(p *discovery.Discovered, version string, installTest
744
751
}
745
752
746
753
// 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 )
748
755
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 )
749
759
var spinner component.OutputWriterSpinner
750
760
751
761
// Initialize the spinner if the spinner is allowed
752
762
if component .IsTTYEnabled () {
763
+ // Initialize the spinner
764
+ spinner = component .NewOutputWriterSpinner (component .WithOutputStream (os .Stderr ),
765
+ component .WithSpinnerText (installingMsg ),
766
+ component .WithSpinnerStarted ())
767
+
753
768
// Create a channel to receive OS signals
754
769
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
+
757
773
defer func () {
758
774
signal .Stop (signalChannel )
759
775
close (signalChannel )
776
+ spinner .StopSpinner ()
777
+ component .StopAllSpinners ()
760
778
}()
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 )
781
779
} else {
782
780
log .Info (installingMsg )
783
781
}
@@ -1154,29 +1152,45 @@ func UpdatePluginsInstallationStatus(plugins []discovery.Discovered) {
1154
1152
// InstallDiscoveredContextPlugins installs the given context scope plugins
1155
1153
func InstallDiscoveredContextPlugins (plugins []discovery.Discovered ) error {
1156
1154
var errList []error
1157
- var err error
1158
- installed := false
1155
+
1156
+ // Slice to capture plugins to install
1157
+ var pluginsToInstall []discovery.Discovered
1158
+
1159
1159
UpdatePluginsInstallationStatus (plugins )
1160
+
1161
+ // Capture plugins that need install/update
1160
1162
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 ])
1168
1166
}
1169
1167
}
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 )
1171
1181
if err != nil {
1172
1182
return err
1173
1183
}
1174
1184
1175
- if ! installed {
1185
+ // Output install status
1186
+ if len (pluginsToInstall ) == 0 {
1176
1187
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 )
1177
1190
} else {
1178
- log .Info ("Successfully installed all required plugins" )
1191
+ log .Infof ("Successfully installed %v of %v required plugins" , pluginsInstalled , totalPluginsToInstall )
1179
1192
}
1193
+
1180
1194
return nil
1181
1195
}
1182
1196
0 commit comments