vaguerent/internal/cli/dynamic.go
2022-04-25 12:24:06 -05:00

122 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
}
err := c.Do(c.Ctx, func(ctx context.Context, tasker Tasker) 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)
}
result, 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 !result.RunResult {
tasker.UI().Output("Error: "+result.RunError.Message+"\n", terminal.WithErrorStyle())
err = errors.New("execution failed")
}
c.Log.Debug("result from operation", "task", c.name, "result", result)
return err
})
if err != nil {
return 1
}
return 0
}
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),
)
}
}
})
}