@@ -21,7 +21,7 @@ import (
2121 "github.com/lima-vm/lima/v2/pkg/fsutil"
2222 "github.com/lima-vm/lima/v2/pkg/limatype/dirnames"
2323 "github.com/lima-vm/lima/v2/pkg/osutil"
24- "github.com/lima-vm/lima/v2/pkg/plugin "
24+ "github.com/lima-vm/lima/v2/pkg/plugins "
2525 "github.com/lima-vm/lima/v2/pkg/version"
2626)
2727
@@ -47,15 +47,49 @@ func main() {
4747 }
4848 }
4949 }
50- rootCmd := newApp ()
51- err := executeWithPluginSupport (rootCmd , os .Args [1 :])
50+ err := newApp ().Execute ()
5251 server .StopAllExternalDrivers ()
5352 osutil .HandleExitError (err )
5453 if err != nil {
5554 logrus .Fatal (err )
5655 }
5756}
5857
58+ func processGlobalFlags (rootCmd * cobra.Command ) error {
59+ // --log-level will override --debug, but will not reset debugutil.Debug
60+ if debug , _ := rootCmd .Flags ().GetBool ("debug" ); debug {
61+ logrus .SetLevel (logrus .DebugLevel )
62+ debugutil .Debug = true
63+ }
64+
65+ l , _ := rootCmd .Flags ().GetString ("log-level" )
66+ if l != "" {
67+ lvl , err := logrus .ParseLevel (l )
68+ if err != nil {
69+ return err
70+ }
71+ logrus .SetLevel (lvl )
72+ }
73+
74+ logFormat , _ := rootCmd .Flags ().GetString ("log-format" )
75+ switch logFormat {
76+ case "json" :
77+ formatter := new (logrus.JSONFormatter )
78+ logrus .StandardLogger ().SetFormatter (formatter )
79+ case "text" :
80+ // logrus use text format by default.
81+ if runtime .GOOS == "windows" && isatty .IsCygwinTerminal (os .Stderr .Fd ()) {
82+ formatter := new (logrus.TextFormatter )
83+ // the default setting does not recognize cygwin on windows
84+ formatter .ForceColors = true
85+ logrus .StandardLogger ().SetFormatter (formatter )
86+ }
87+ default :
88+ return fmt .Errorf ("unsupported log-format: %q" , logFormat )
89+ }
90+ return nil
91+ }
92+
5993func newApp () * cobra.Command {
6094 templatesDir := "$PREFIX/share/lima/templates"
6195 if exe , err := os .Executable (); err == nil {
@@ -92,30 +126,8 @@ func newApp() *cobra.Command {
92126 rootCmd .PersistentFlags ().Bool ("tty" , isatty .IsTerminal (os .Stdout .Fd ()), "Enable TUI interactions such as opening an editor. Defaults to true when stdout is a terminal. Set to false for automation." )
93127 rootCmd .PersistentFlags ().BoolP ("yes" , "y" , false , "Alias of --tty=false" )
94128 rootCmd .PersistentPreRunE = func (cmd * cobra.Command , _ []string ) error {
95- l , _ := cmd .Flags ().GetString ("log-level" )
96- if l != "" {
97- lvl , err := logrus .ParseLevel (l )
98- if err != nil {
99- return err
100- }
101- logrus .SetLevel (lvl )
102- }
103-
104- logFormat , _ := cmd .Flags ().GetString ("log-format" )
105- switch logFormat {
106- case "json" :
107- formatter := new (logrus.JSONFormatter )
108- logrus .StandardLogger ().SetFormatter (formatter )
109- case "text" :
110- // logrus use text format by default.
111- if runtime .GOOS == "windows" && isatty .IsCygwinTerminal (os .Stderr .Fd ()) {
112- formatter := new (logrus.TextFormatter )
113- // the default setting does not recognize cygwin on windows
114- formatter .ForceColors = true
115- logrus .StandardLogger ().SetFormatter (formatter )
116- }
117- default :
118- return fmt .Errorf ("unsupported log-format: %q" , logFormat )
129+ if err := processGlobalFlags (rootCmd ); err != nil {
130+ return err
119131 }
120132
121133 if osutil .IsBeingRosettaTranslated () && cmd .Parent ().Name () != "completion" && cmd .Name () != "generate-doc" && cmd .Name () != "validate" {
@@ -191,47 +203,58 @@ func newApp() *cobra.Command {
191203 newNetworkCommand (),
192204 newCloneCommand (),
193205 )
206+ addPluginCommands (rootCmd )
194207
195208 return rootCmd
196209}
197210
198- func executeWithPluginSupport (rootCmd * cobra.Command , args []string ) error {
199- rootCmd .SetArgs (args )
200-
201- if err := rootCmd .ParseFlags (args ); err == nil {
202- if debug , _ := rootCmd .Flags ().GetBool ("debug" ); debug {
203- logrus .SetLevel (logrus .DebugLevel )
204- debugutil .Debug = true
205- }
211+ func addPluginCommands (rootCmd * cobra.Command ) {
212+ // The global options are only processed when rootCmd.Execute() is called.
213+ // Let's take a sneak peek here to help debug the plugin discovery code.
214+ if len (os .Args ) > 1 && os .Args [1 ] == "--debug" {
215+ logrus .SetLevel (logrus .DebugLevel )
206216 }
207217
208- addPluginCommands (rootCmd )
209-
210- return rootCmd .Execute ()
211- }
212-
213- func addPluginCommands (rootCmd * cobra.Command ) {
214- plugins , err := plugin .DiscoverPlugins ()
218+ allPlugins , err := plugins .Discover ()
215219 if err != nil {
216220 logrus .Warnf ("Failed to discover plugins: %v" , err )
217221 return
218222 }
219223
220- for _ , p := range plugins {
221- pluginName := p .Name
224+ for _ , plugin := range allPlugins {
222225 pluginCmd := & cobra.Command {
223- Use : pluginName ,
224- Short : p .Description ,
226+ Use : plugin . Name ,
227+ Short : plugin .Description ,
225228 GroupID : "plugin" ,
226229 DisableFlagParsing : true ,
227- Run : func (cmd * cobra.Command , args []string ) {
228- plugin .RunExternalPlugin (cmd .Context (), pluginName , args )
230+ SilenceErrors : true ,
231+ SilenceUsage : true ,
232+ PreRunE : func (* cobra.Command , []string ) error {
233+ for i , arg := range os .Args {
234+ if arg == plugin .Name {
235+ // parse global options but ignore plugin options
236+ err := rootCmd .ParseFlags (os .Args [1 :i ])
237+ if err == nil {
238+ err = processGlobalFlags (rootCmd )
239+ }
240+ return err
241+ }
242+ }
243+ // unreachable
244+ return nil
245+ },
246+ Run : func (cmd * cobra.Command , _ []string ) {
247+ for i , arg := range os .Args {
248+ if arg == plugin .Name {
249+ // ignore global options
250+ plugin .Run (cmd .Context (), os .Args [i + 1 :])
251+ // plugin.Run() never returns because it calls os.Exit()
252+ }
253+ }
254+ // unreachable
229255 },
230256 }
231257
232- pluginCmd .SilenceUsage = true
233- pluginCmd .SilenceErrors = true
234-
235258 rootCmd .AddCommand (pluginCmd )
236259 }
237260}
0 commit comments