123 lines
3.0 KiB
Go
123 lines
3.0 KiB
Go
package cli
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"reflect"
|
|
"strconv"
|
|
|
|
"github.com/DavidGamba/go-getoptions"
|
|
"github.com/DavidGamba/go-getoptions/option"
|
|
|
|
"github.com/hashicorp/vagrant-plugin-sdk/proto/vagrant_plugin_sdk"
|
|
"github.com/hashicorp/vagrant-plugin-sdk/terminal"
|
|
"github.com/hashicorp/vagrant/internal/client"
|
|
"github.com/hashicorp/vagrant/internal/server/proto/vagrant_server"
|
|
)
|
|
|
|
type DynamicCommand struct {
|
|
*baseCommand
|
|
|
|
name string
|
|
synopsis string
|
|
help string
|
|
flags []*option.Option
|
|
flagData map[string]interface{}
|
|
}
|
|
|
|
func (c *DynamicCommand) Run(args []string) int {
|
|
if err := c.Init(
|
|
WithArgs(args),
|
|
WithFlags(c.Flags()),
|
|
); err != nil {
|
|
return 1
|
|
}
|
|
|
|
var r *vagrant_server.Job_RunResult
|
|
err := c.Do(c.Ctx, func(ctx context.Context, tasker Tasker) (err error) {
|
|
tasker.UI().Output("Running "+c.name+"... ", terminal.WithHeaderStyle())
|
|
taskArgs := &vagrant_plugin_sdk.Command_Arguments{
|
|
Args: args,
|
|
Flags: []*vagrant_plugin_sdk.Command_Arguments_Flag{},
|
|
}
|
|
for k, v := range c.flagData {
|
|
f := &vagrant_plugin_sdk.Command_Arguments_Flag{Name: k}
|
|
switch reflect.Indirect(reflect.ValueOf(v)).Kind() {
|
|
case reflect.String:
|
|
f.Value = &vagrant_plugin_sdk.Command_Arguments_Flag_String_{
|
|
String_: *v.(*string),
|
|
}
|
|
f.Type = vagrant_plugin_sdk.Command_Arguments_Flag_STRING
|
|
case reflect.Bool:
|
|
f.Value = &vagrant_plugin_sdk.Command_Arguments_Flag_Bool{
|
|
Bool: *v.(*bool),
|
|
}
|
|
f.Type = vagrant_plugin_sdk.Command_Arguments_Flag_BOOL
|
|
}
|
|
taskArgs.Flags = append(taskArgs.Flags, f)
|
|
}
|
|
r, err = tasker.Task(ctx, &vagrant_server.Job_RunOp{
|
|
Task: &vagrant_server.Task{
|
|
Scope: &vagrant_server.Task_Target{
|
|
Target: tasker.(*client.Target).Ref(),
|
|
},
|
|
Task: c.name,
|
|
Component: &vagrant_server.Component{
|
|
Type: vagrant_server.Component_COMMAND,
|
|
Name: c.name,
|
|
},
|
|
CliArgs: taskArgs,
|
|
CommandName: c.name,
|
|
},
|
|
})
|
|
|
|
if err != nil {
|
|
tasker.UI().Output("Running of task "+c.name+" failed unexpectedly\n", terminal.WithErrorStyle())
|
|
tasker.UI().Output("Error: "+err.Error(), terminal.WithErrorStyle())
|
|
} else if !r.RunResult {
|
|
tasker.UI().Output("Error: "+r.RunError.Message+"\n", terminal.WithErrorStyle())
|
|
err = errors.New("execution failed")
|
|
}
|
|
|
|
c.Log.Debug("result from operation", "task", c.name, "result", r)
|
|
|
|
return err
|
|
})
|
|
|
|
if err != nil {
|
|
return int(r.ExitCode)
|
|
}
|
|
|
|
return int(r.ExitCode)
|
|
}
|
|
|
|
func (c *DynamicCommand) Synopsis() string {
|
|
return c.synopsis
|
|
}
|
|
|
|
func (c *DynamicCommand) Help() string {
|
|
return c.help
|
|
}
|
|
|
|
func (c *DynamicCommand) Flags() *getoptions.GetOpt {
|
|
return c.flagSet(flagSetOperation, func(opts *getoptions.GetOpt) {
|
|
for _, f := range c.flags {
|
|
switch f.OptType {
|
|
case option.BoolType:
|
|
b, _ := strconv.ParseBool(f.DefaultStr)
|
|
c.flagData[f.Name] = opts.Bool(
|
|
f.Name,
|
|
b,
|
|
opts.Description(f.Description),
|
|
)
|
|
case option.StringType:
|
|
c.flagData[f.Name] = opts.String(
|
|
f.Name,
|
|
f.DefaultStr,
|
|
opts.Description(f.Description),
|
|
)
|
|
}
|
|
}
|
|
})
|
|
}
|