4
4
package main
5
5
6
6
import (
7
- "context"
8
7
"errors"
9
8
"fmt"
10
9
"os"
11
- "os/exec"
12
10
"path/filepath"
13
11
"runtime"
14
12
"strings"
@@ -23,6 +21,8 @@ import (
23
21
"github.com/lima-vm/lima/v2/pkg/fsutil"
24
22
"github.com/lima-vm/lima/v2/pkg/limatype/dirnames"
25
23
"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"
26
26
"github.com/lima-vm/lima/v2/pkg/version"
27
27
)
28
28
@@ -51,7 +51,7 @@ func main() {
51
51
rootCmd := newApp ()
52
52
if err := executeWithPluginSupport (rootCmd , os .Args [1 :]); err != nil {
53
53
server .StopAllExternalDrivers ()
54
- handleExitError (err )
54
+ usrlocalsharelima . HandleExitError (err )
55
55
logrus .Fatal (err )
56
56
}
57
57
@@ -165,6 +165,8 @@ func newApp() *cobra.Command {
165
165
}
166
166
rootCmd .AddGroup (& cobra.Group {ID : "basic" , Title : "Basic Commands:" })
167
167
rootCmd .AddGroup (& cobra.Group {ID : "advanced" , Title : "Advanced Commands:" })
168
+ rootCmd .AddGroup (& cobra.Group {ID : "plugin" , Title : "Available Plugins (Experimental):" })
169
+
168
170
rootCmd .AddCommand (
169
171
newCreateCommand (),
170
172
newStartCommand (),
@@ -201,79 +203,45 @@ func newApp() *cobra.Command {
201
203
return rootCmd
202
204
}
203
205
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.
217
206
func 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
223
213
}
224
214
}
225
215
226
- rootCmd .SetArgs (args )
216
+ addPluginCommands (rootCmd )
217
+
227
218
return rootCmd .Execute ()
228
219
}
229
220
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 ()
242
223
if err != nil {
224
+ logrus .Warnf ("Failed to discover plugins: %v" , err )
243
225
return
244
226
}
245
227
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
+ }
265
239
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
269
242
270
- if err := os .Setenv ("PATH" , newPath ); err != nil {
271
- return fmt .Errorf ("failed to set PATH environment: %w" , err )
243
+ rootCmd .AddCommand (pluginCmd )
272
244
}
273
-
274
- logrus .Debugf ("updated PATH to prioritize %s" , binDir )
275
-
276
- return nil
277
245
}
278
246
279
247
// WrapArgsError annotates cobra args error with some context, so the error message is more user-friendly.
0 commit comments