105 lines
2.5 KiB
Go
105 lines
2.5 KiB
Go
package cli
|
|
|
|
import (
|
|
"context"
|
|
"github.com/abelith/spellbook/internal/models"
|
|
"github.com/olekukonko/tablewriter"
|
|
"github.com/spf13/cobra"
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
type Application interface {
|
|
AddSpell(ctx context.Context, spell models.Spell) error
|
|
GetSpell(ctx context.Context, spellName string) (models.Spell, error)
|
|
GetSpells(ctx context.Context, query models.SearchQuery) ([]models.Spell, error)
|
|
DeleteSpell(ctx context.Context, spellName string) error
|
|
CastSpell(ctx context.Context, spellCast models.SpellCast) (models.CastResult, error)
|
|
}
|
|
|
|
func rootCmd(app Application) func(*cobra.Command, []string) error {
|
|
return func(cmd *cobra.Command, args []string) error {
|
|
ctx := cmd.Context()
|
|
|
|
if len(args) < 1 {
|
|
return listCommands(ctx, cmd, app)
|
|
}
|
|
|
|
return runCommand(ctx, app, args)
|
|
}
|
|
}
|
|
|
|
func runCommand(ctx context.Context, app Application, args []string) error {
|
|
spell, err := app.GetSpell(ctx, args[0])
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
m := make(map[string]string, len(args[1:]))
|
|
for _, pair := range args[1:] {
|
|
keyVal := strings.Split(pair, "=")
|
|
m[keyVal[0]] = keyVal[1]
|
|
}
|
|
|
|
_, err = app.CastSpell(ctx, models.SpellCast{
|
|
Spell: spell,
|
|
Args: m,
|
|
Stdin: os.Stdin,
|
|
Stdout: os.Stdout,
|
|
Stderr: os.Stderr,
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func listCommands(ctx context.Context, cmd *cobra.Command, app Application) error {
|
|
spells, err := app.GetSpells(ctx, models.SearchQuery{})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if len(spells) == 0 {
|
|
cmd.Println("Spell book is empty. Try `spellbook add` to add your first spell")
|
|
return nil
|
|
}
|
|
|
|
return printTable(cmd, spells)
|
|
}
|
|
|
|
func printTable(cmd *cobra.Command, spells []models.Spell) error {
|
|
table := tablewriter.NewTable(cmd.OutOrStdout())
|
|
|
|
rows := make([][]string, 0, len(spells))
|
|
for _, spell := range spells {
|
|
row := []string{
|
|
spell.Name, spell.Spell, spell.ShortDesc, strings.Join(spell.Tags, ", "),
|
|
}
|
|
rows = append(rows, row)
|
|
}
|
|
|
|
table.Header("Name", "Spell", "Short description", "Tags")
|
|
_ = table.Bulk(rows)
|
|
if err := table.Render(); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func NewRootCmd(app Application) *cobra.Command {
|
|
cmd := &cobra.Command{
|
|
Use: "spellbook",
|
|
Short: "CLI tool to store, manage and execute command templates",
|
|
Long: `Spellbook is a lightweight binary command manager written in Go.
|
|
It allows you to save complex shell commands as parametrized templates (spells)
|
|
and execute them instantly with custom arguments from anywhere in your terminal`,
|
|
RunE: rootCmd(app),
|
|
Args: cobra.ArbitraryArgs,
|
|
}
|
|
|
|
return cmd
|
|
}
|