feat: search cmd

chore: raw sql replaced with squirrel
fix: -n is now required for add cmd
This commit is contained in:
abelith committed 2026-08-15 18:38:26 +05:00
1 parent 80a90b65bb
commit 4447b7343f
9 files changed
+142 -27

No files matched your search

+6
View File
@@ -13,6 +13,7 @@ var reservedCommands = map[string]struct{}{
"rm": {},
"help": {},
"completion": {},
"search": {},
}
func NewAddCommand(app Application) *cobra.Command {
@@ -34,6 +35,11 @@ func NewAddCommand(app Application) *cobra.Command {
}
spell.Spell = strings.Join(args, " ")
if spell.Name == "" {
return fmt.Errorf("%w: --name is missing", errors.ErrInsufficientArgs)
}
return app.AddSpell(ctx, spell)
},
}
+3 -2
View File
@@ -18,11 +18,12 @@ type CLI struct {
root *cobra.Command
}
func NewCLI(app Application) *CLI {
root := NewRootCmd(app)
func NewCLI(ver string, app Application) *CLI {
root := NewRootCmd(ver, app)
root.AddCommand(
NewAddCommand(app),
NewRmCommand(app),
NewSearchCmd(app),
)
return &CLI{
+4 -3
View File
@@ -81,15 +81,16 @@ func printTable(cmd *cobra.Command, spells []models.Spell) error {
return nil
}
func NewRootCmd(app Application) *cobra.Command {
func NewRootCmd(ver string, 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,
RunE: rootCmd(app),
Args: cobra.ArbitraryArgs,
Version: ver,
}
return cmd
+47
View File
@@ -0,0 +1,47 @@
package cli
import (
"fmt"
"github.com/abelith/spellbook/internal/errors"
"github.com/abelith/spellbook/internal/models"
"github.com/spf13/cobra"
)
func NewSearchCmd(app Application) *cobra.Command {
query := models.SearchQuery{}
cmd := &cobra.Command{
Use: "search [query]",
Short: "Search for spells",
Long: "WIP",
RunE: func(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()
if query.IsEmpty() {
return errors.ErrEmptyQuery
}
if len(args) > 0 {
query.Text = args[0]
}
spells, err := app.GetSpells(ctx, query)
if err != nil {
return err
}
if len(spells) < 1 {
return fmt.Errorf("%w: spells", errors.ErrNotFound)
}
return printTable(cmd, spells)
},
}
cmd.Flags().StringVarP(&query.Name, "name", "n", "", "Spell name")
cmd.Flags().StringVarP(&query.Command, "cmd", "c", "", "Spell command template")
cmd.Flags().StringVarP(&query.Description, "desc", "d", "", "Spell description")
cmd.Flags().StringSliceVarP(&query.Tags, "tags", "t", nil, "Spell tags")
return cmd
}
+2
View File
@@ -7,4 +7,6 @@ var (
ErrInsufficientArgs = fmt.Errorf("mandatory args are missing")
ErrFailedToCast = fmt.Errorf("failed to cast spell")
ErrNoDBProvided = fmt.Errorf("no db provided")
ErrNotFound = fmt.Errorf("not found")
ErrEmptyQuery = fmt.Errorf("empty search query")
)
+12
View File
@@ -0,0 +1,12 @@
package models
func (sq *SearchQuery) IsEmpty() bool {
isEmpty := sq.Text == "" &&
sq.Name == "" &&
sq.Command == "" &&
sq.Description == "" &&
len(sq.Tags) < 1 &&
sq.Cursor == 0 &&
sq.Limit == 0
return isEmpty
}