refactor: updated cache editor implementation

This commit is contained in:
David Allen 2025-06-16 16:19:43 -06:00
parent 389f720ff9
commit 64cca78d24
Signed by: towk
GPG key ID: 0430CDBE22619155
6 changed files with 78 additions and 28 deletions

View file

@ -6,13 +6,18 @@ import (
"os" "os"
"strconv" "strconv"
tea "github.com/charmbracelet/bubbletea"
"github.com/davidallendj/magellan/internal/cache"
"github.com/davidallendj/magellan/internal/cache/sqlite" "github.com/davidallendj/magellan/internal/cache/sqlite"
"github.com/davidallendj/magellan/internal/util"
magellan "github.com/davidallendj/magellan/pkg" magellan "github.com/davidallendj/magellan/pkg"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
var ( var (
cacheOutputFormat string
interactive bool
withHosts []string withHosts []string
withPorts []int withPorts []int
) )
@ -20,13 +25,6 @@ var (
var cacheCmd = &cobra.Command{ var cacheCmd = &cobra.Command{
Use: "cache", Use: "cache",
Short: "Manage found assets in cache.", Short: "Manage found assets in cache.",
Run: func(cmd *cobra.Command, args []string) {
// show the help for cache and exit
if len(args) <= 0 {
cmd.Help()
os.Exit(0)
}
},
} }
var cacheRemoveCmd = &cobra.Command{ var cacheRemoveCmd = &cobra.Command{
@ -88,9 +86,54 @@ var cacheRemoveCmd = &cobra.Command{
}, },
} }
var cacheEditCmd = &cobra.Command{
Use: "edit",
Short: "Modify cache data either interactively or non-interactively.",
Run: func(cmd *cobra.Command, args []string) {
// start the interactive editor
if interactive {
p := tea.NewProgram(cache.NewModel())
if _, err := p.Run(); err != nil {
fmt.Printf("failed to start the cache editor: %v", err)
os.Exit(1)
}
} else {
// only edit data with arguments
}
},
}
var cacheInfoCmd = &cobra.Command{
Use: "info",
Short: "Show cache-related information.",
Run: func(cmd *cobra.Command, args []string) {
printCacheInfo(cacheOutputFormat)
},
}
func init() { func init() {
// remove
cacheRemoveCmd.Flags().StringSliceVar(&withHosts, "with-hosts", []string{}, "Remove all assets with specified hosts") cacheRemoveCmd.Flags().StringSliceVar(&withHosts, "with-hosts", []string{}, "Remove all assets with specified hosts")
cacheRemoveCmd.Flags().IntSliceVar(&withPorts, "with-ports", []int{}, "Remove all assets with specified ports") cacheRemoveCmd.Flags().IntSliceVar(&withPorts, "with-ports", []int{}, "Remove all assets with specified ports")
cacheCmd.AddCommand(cacheRemoveCmd)
// edit
cacheEditCmd.Flags().BoolVarP(&interactive, "interactive", "i", false, "Edit cache data using interactive editor")
cacheInfoCmd.Flags().StringVarP(&cacheOutputFormat, "format", "F", FORMAT_LIST, "Set the output format (list|json|yaml)")
// commands
cacheCmd.AddCommand(cacheRemoveCmd, cacheEditCmd, cacheInfoCmd)
rootCmd.AddCommand(cacheCmd) rootCmd.AddCommand(cacheCmd)
} }
func printCacheInfo(format string) {
assets, err := sqlite.GetScannedAssets(cachePath)
if err != nil {
log.Error().Err(err).Str("path", cachePath).Msg("failed to get assets to print cache info")
}
cacheData := map[string]any{
"path": cachePath,
"assets": len(assets),
}
util.PrintMapWithFormat(cacheData, format)
}

View file

@ -42,9 +42,7 @@ var ListCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
// check if we just want to show cache-related info and exit // check if we just want to show cache-related info and exit
if showCacheInfo { if showCacheInfo {
magellan.PrintMapWithFormat(map[string]any{ printCacheInfo(listOutputFormat)
"path": cachePath,
}, listOutputFormat)
os.Exit(0) os.Exit(0)
} }

View file

@ -15,6 +15,10 @@ type Model struct {
Table table.Model Table table.Model
} }
func NewModel() Model {
return Model{}
}
func (m Model) Init() tea.Cmd { return nil } func (m Model) Init() tea.Cmd { return nil }
func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {

View file

@ -3,6 +3,7 @@ package util
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"strings"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
"gopkg.in/yaml.v2" "gopkg.in/yaml.v2"
@ -23,3 +24,22 @@ func PrintYAML(data any) {
} }
fmt.Print(string(b)) fmt.Print(string(b))
} }
func PrintMap(data map[string]any) {
for k, v := range data {
fmt.Printf("%s: %v\n", k, v)
}
}
func PrintMapWithFormat(data map[string]any, format string) {
switch strings.ToLower(format) {
case "json":
PrintJSON(data)
case "yaml":
PrintYAML(data)
case "list":
PrintMap(data)
default:
log.Error().Msg("PrintMapWithFormat: unrecognized format")
}
}

View file

@ -27,21 +27,6 @@ func PrintRemoteAssets(data []RemoteAsset, format string) {
} }
} }
func PrintMapWithFormat(data map[string]any, format string) {
switch strings.ToLower(format) {
case "json":
util.PrintJSON(data)
case "yaml":
util.PrintYAML(data)
case "list":
for k, v := range data {
fmt.Printf("%s: %v\n", k, v)
}
default:
log.Error().Msg("PrintMapWithFormat: unrecognized format")
}
}
func ListDrives(cc *crawler.CrawlerConfig) ([]*redfish.Drive, error) { func ListDrives(cc *crawler.CrawlerConfig) ([]*redfish.Drive, error) {
user, err := cc.GetUserPass() user, err := cc.GetUserPass()
if err != nil { if err != nil {