posh-providers/grafana/k6/command.go
2024-09-10 13:44:15 +02:00

150 lines
3.9 KiB
Go

package k6
import (
"context"
"fmt"
"os"
"path"
"strings"
"github.com/foomo/posh-providers/onepassword"
"github.com/foomo/posh/pkg/command/tree"
"github.com/foomo/posh/pkg/log"
"github.com/foomo/posh/pkg/prompt/goprompt"
"github.com/foomo/posh/pkg/readline"
"github.com/foomo/posh/pkg/shell"
"github.com/foomo/posh/pkg/util/suggests"
"github.com/spf13/viper"
)
type (
Command struct {
l log.Logger
op *onepassword.OnePassword
name string
cfg Config
configKey string
commandTree tree.Root
}
CommandOption func(*Command)
)
// ------------------------------------------------------------------------------------------------
// ~ Options
// ------------------------------------------------------------------------------------------------
func CommandWithName(v string) CommandOption {
return func(o *Command) {
o.name = v
}
}
func CommandWithConfigKey(v string) CommandOption {
return func(o *Command) {
o.name = v
}
}
// ------------------------------------------------------------------------------------------------
// ~ Constructor
// ------------------------------------------------------------------------------------------------
func NewCommand(l log.Logger, op *onepassword.OnePassword, opts ...CommandOption) (*Command, error) {
inst := &Command{
l: l.Named("k6"),
name: "k6",
configKey: "k6",
op: op,
}
for _, opt := range opts {
if opt != nil {
opt(inst)
}
}
if err := viper.UnmarshalKey(inst.configKey, &inst.cfg); err != nil {
return nil, err
}
if err := os.MkdirAll(inst.cfg.Path, 0700); err != nil {
return nil, err
}
inst.commandTree = tree.New(&tree.Node{
Name: inst.name,
Description: "Run k6",
Flags: func(ctx context.Context, r *readline.Readline, fs *readline.FlagSets) error {
fs.Default().Bool("debug", false, "show debug output")
return nil
},
Args: tree.Args{
{
Name: "env",
Description: "Env name",
Suggest: func(ctx context.Context, t tree.Root, r *readline.Readline) []goprompt.Suggest {
return suggests.List(inst.cfg.EnvNames())
},
},
{
Name: "scenario",
Description: "Scenario name",
Suggest: func(ctx context.Context, t tree.Root, r *readline.Readline) []goprompt.Suggest {
scenarios, err := inst.cfg.Scenarios()
if err != nil {
return nil
}
return suggests.List(scenarios)
},
},
},
Execute: inst.execute,
})
return inst, nil
}
// ------------------------------------------------------------------------------------------------
// ~ Public methods
// ------------------------------------------------------------------------------------------------
func (c *Command) Name() string {
return c.commandTree.Node().Name
}
func (c *Command) Description() string {
return c.commandTree.Node().Description
}
func (c *Command) Complete(ctx context.Context, r *readline.Readline) []goprompt.Suggest {
return c.commandTree.Complete(ctx, r)
}
func (c *Command) Execute(ctx context.Context, r *readline.Readline) error {
return c.commandTree.Execute(ctx, r)
}
func (c *Command) Help(ctx context.Context, r *readline.Readline) string {
return c.commandTree.Help(ctx, r)
}
// ------------------------------------------------------------------------------------------------
// ~ Private methods
// ------------------------------------------------------------------------------------------------
func (c *Command) execute(ctx context.Context, r *readline.Readline) error {
fs := r.FlagSets().Default()
env, scenario := r.Args().At(0), r.Args().At(1)
var envs []string
for k, v := range c.cfg.Env(env) {
envs = append(envs, fmt.Sprintf("%s=%s", strings.ToUpper(k), v))
}
return shell.New(ctx, c.l, "k6", "run", "--out", "web-dashboard", path.Join(c.cfg.Path, scenario)).
Args(fs.Visited().Args()...).
Args(r.AdditionalArgs()...).
Args(r.AdditionalFlags()...).
Env(envs...).
Run()
}