44package main
55
66import (
7- "context"
87 "errors"
98 "fmt"
109 "os"
11- "os/exec"
1210 "path/filepath"
1311 "runtime"
1412 "strings"
@@ -23,6 +21,8 @@ import (
2321 "github.com/lima-vm/lima/v2/pkg/fsutil"
2422 "github.com/lima-vm/lima/v2/pkg/limatype/dirnames"
2523 "github.com/lima-vm/lima/v2/pkg/osutil"
24+ "github.com/lima-vm/lima/v2/pkg/plugin"
25+ "github.com/lima-vm/lima/v2/pkg/usrlocalsharelima"
2626 "github.com/lima-vm/lima/v2/pkg/version"
2727)
2828
@@ -51,7 +51,7 @@ func main() {
5151 rootCmd := newApp ()
5252 if err := executeWithPluginSupport (rootCmd , os .Args [1 :]); err != nil {
5353 server .StopAllExternalDrivers ()
54- handleExitError (err )
54+ usrlocalsharelima . HandleExitError (err )
5555 logrus .Fatal (err )
5656 }
5757
@@ -165,6 +165,8 @@ func newApp() *cobra.Command {
165165 }
166166 rootCmd .AddGroup (& cobra.Group {ID : "basic" , Title : "Basic Commands:" })
167167 rootCmd .AddGroup (& cobra.Group {ID : "advanced" , Title : "Advanced Commands:" })
168+ rootCmd .AddGroup (& cobra.Group {ID : "plugin" , Title : "Available Plugins (Experimental):" })
169+
168170 rootCmd .AddCommand (
169171 newCreateCommand (),
170172 newStartCommand (),
@@ -201,79 +203,45 @@ func newApp() *cobra.Command {
201203 return rootCmd
202204}
203205
204- func handleExitError (err error ) {
205- if err == nil {
206- return
207- }
208-
209- var exitErr * exec.ExitError
210- if errors .As (err , & exitErr ) {
211- os .Exit (exitErr .ExitCode ()) //nolint:revive // it's intentional to call os.Exit in this function
212- return
213- }
214- }
215-
216- // executeWithPluginSupport handles command execution with plugin support.
217206func executeWithPluginSupport (rootCmd * cobra.Command , args []string ) error {
218- if len (args ) > 0 {
219- cmd , _ , err := rootCmd .Find (args )
220- if err != nil || cmd == rootCmd {
221- // Function calls os.Exit() if it found and executed the plugin
222- runExternalPlugin (rootCmd .Context (), args [0 ], args [1 :])
207+ rootCmd .SetArgs (args )
208+
209+ if err := rootCmd .ParseFlags (args ); err == nil {
210+ if debug , _ := rootCmd .Flags ().GetBool ("debug" ); debug {
211+ logrus .SetLevel (logrus .DebugLevel )
212+ debugutil .Debug = true
223213 }
224214 }
225215
226- rootCmd .SetArgs (args )
216+ addPluginCommands (rootCmd )
217+
227218 return rootCmd .Execute ()
228219}
229220
230- func runExternalPlugin (ctx context.Context , name string , args []string ) {
231- if ctx == nil {
232- ctx = context .Background ()
233- }
234-
235- if err := updatePathEnv (); err != nil {
236- logrus .Warnf ("failed to update PATH environment: %v" , err )
237- // PATH update failure shouldn't prevent plugin execution
238- }
239-
240- externalCmd := "limactl-" + name
241- execPath , err := exec .LookPath (externalCmd )
221+ func addPluginCommands (rootCmd * cobra.Command ) {
222+ plugins , err := plugin .DiscoverPlugins ()
242223 if err != nil {
224+ logrus .Warnf ("Failed to discover plugins: %v" , err )
243225 return
244226 }
245227
246- cmd := exec .CommandContext (ctx , execPath , args ... )
247- cmd .Stdin = os .Stdin
248- cmd .Stdout = os .Stdout
249- cmd .Stderr = os .Stderr
250- cmd .Env = os .Environ ()
251-
252- err = cmd .Run ()
253- handleExitError (err )
254- if err == nil {
255- os .Exit (0 ) //nolint:revive // it's intentional to call os.Exit in this function
256- }
257- logrus .Fatalf ("external command %q failed: %v" , execPath , err )
258- }
259-
260- func updatePathEnv () error {
261- exe , err := os .Executable ()
262- if err != nil {
263- return fmt .Errorf ("failed to get executable path: %w" , err )
264- }
228+ for _ , p := range plugins {
229+ pluginName := p .Name
230+ pluginCmd := & cobra.Command {
231+ Use : pluginName ,
232+ Short : p .Description ,
233+ GroupID : "plugin" ,
234+ DisableFlagParsing : true ,
235+ Run : func (cmd * cobra.Command , args []string ) {
236+ plugin .RunExternalPlugin (cmd .Context (), pluginName , args )
237+ },
238+ }
265239
266- binDir := filepath .Dir (exe )
267- currentPath := os .Getenv ("PATH" )
268- newPath := binDir + string (filepath .ListSeparator ) + currentPath
240+ pluginCmd .SilenceUsage = true
241+ pluginCmd .SilenceErrors = true
269242
270- if err := os .Setenv ("PATH" , newPath ); err != nil {
271- return fmt .Errorf ("failed to set PATH environment: %w" , err )
243+ rootCmd .AddCommand (pluginCmd )
272244 }
273-
274- logrus .Debugf ("updated PATH to prioritize %s" , binDir )
275-
276- return nil
277245}
278246
279247// WrapArgsError annotates cobra args error with some context, so the error message is more user-friendly.
0 commit comments