From 14df3cac0373198f31fb034860297b6e0a814b69 Mon Sep 17 00:00:00 2001 From: Tim Van Baak Date: Thu, 23 Jan 2025 07:55:11 -0800 Subject: [PATCH] Implement source {add,list,delete} --- cmd/source.go | 6 +++++- cmd/sourceAdd.go | 24 ++++++++++++++++++++++-- cmd/sourceDelete.go | 28 ++++++++++++++++++++++++---- cmd/sourceList.go | 40 ++++++++++++++++++++++++++++++++++++++++ core/source.go | 23 +++++++++++++++++++++-- core/source_test.go | 8 +------- 6 files changed, 113 insertions(+), 16 deletions(-) create mode 100644 cmd/sourceList.go diff --git a/cmd/source.go b/cmd/source.go index fe8d90e..07a60df 100644 --- a/cmd/source.go +++ b/cmd/source.go @@ -10,7 +10,11 @@ import ( var sourceCmd = &cobra.Command{ Use: "source", Short: "Manage sources", - Long: ` + Long: `Manage sources. + +A source represents a single content feed that generates discrete feed items. +The command defined in the "fetch" action is used to check for new items to +update the feed. `, } diff --git a/cmd/sourceAdd.go b/cmd/sourceAdd.go index 6682e13..b3b13b4 100644 --- a/cmd/sourceAdd.go +++ b/cmd/sourceAdd.go @@ -3,19 +3,39 @@ package cmd import ( "log" + "github.com/Jaculabilis/intake/core" "github.com/spf13/cobra" ) var sourceAddCmd = &cobra.Command{ Use: "add", Short: "Create a source", - Long: ` + Long: `Create a source. `, Run: func(cmd *cobra.Command, args []string) { - log.Fatal("not implemented") + sourceAdd() }, } +var sourceAddSource string + func init() { sourceCmd.AddCommand(sourceAddCmd) + + sourceAddCmd.Flags().StringVarP(&sourceAddSource, "source", "s", "", "Source name") + sourceAddCmd.MarkFlagRequired("source") +} + +func sourceAdd() { + if sourceAddSource == "" { + log.Fatal("error: --source is empty") + } + + db := openAndMigrateDb() + + if err := core.AddSource(db, sourceAddSource); err != nil { + log.Fatalf("error: %v", err) + } + + log.Printf("Added source %s", sourceAddSource) } diff --git a/cmd/sourceDelete.go b/cmd/sourceDelete.go index 7beb572..0ffdf58 100644 --- a/cmd/sourceDelete.go +++ b/cmd/sourceDelete.go @@ -3,19 +3,39 @@ package cmd import ( "log" + "github.com/Jaculabilis/intake/core" "github.com/spf13/cobra" ) var sourceDeleteCmd = &cobra.Command{ - Use: "delete", - Short: "Delete a source", - Long: ` + Use: "delete", + Aliases: []string{"rm"}, + Short: "Delete a source", + Long: `Delete a source. `, Run: func(cmd *cobra.Command, args []string) { - log.Fatal("not implemented") + sourceDelete() }, } +var sourceDeleteSource string + func init() { sourceCmd.AddCommand(sourceDeleteCmd) + + sourceDeleteCmd.Flags().StringVarP(&sourceDeleteSource, "source", "s", "", "Source to delete") +} + +func sourceDelete() { + if sourceDeleteSource == "" { + log.Fatal("error: --source is empty") + } + + db := openAndMigrateDb() + + if err := core.DeleteSource(db, sourceDeleteSource); err != nil { + log.Fatalf("error: %v", err) + } + + log.Printf("Deleted source %s", sourceDeleteSource) } diff --git a/cmd/sourceList.go b/cmd/sourceList.go new file mode 100644 index 0000000..d6a4e89 --- /dev/null +++ b/cmd/sourceList.go @@ -0,0 +1,40 @@ +package cmd + +import ( + "fmt" + "log" + "slices" + + "github.com/Jaculabilis/intake/core" + "github.com/spf13/cobra" +) + +var sourceListCmd = &cobra.Command{ + Use: "list", + Aliases: []string{"ls"}, + Short: "List sources", + Long: `Print the list of sources. +`, + Run: func(cmd *cobra.Command, args []string) { + sourceList() + }, +} + +func init() { + sourceCmd.AddCommand(sourceListCmd) +} + +func sourceList() { + db := openAndMigrateDb() + + names, err := core.GetSources(db) + if err != nil { + log.Fatalf("error: %v", err) + } + + slices.Sort(names) + + for _, name := range names { + fmt.Println(name) + } +} diff --git a/core/source.go b/core/source.go index 6aafce5..7fe827d 100644 --- a/core/source.go +++ b/core/source.go @@ -17,10 +17,29 @@ func AddSource(db *DB, name string) error { return err } +func GetSources(db *DB) ([]string, error) { + rows, err := db.Query(` + select name + from sources + `) + if err != nil { + return nil, err + } + var names []string + for rows.Next() { + var name string + if err = rows.Scan(&name); err != nil { + return nil, err + } + names = append(names, name) + } + return names, nil +} + func DeleteSource(db *DB, name string) error { _, err := db.Exec(` - delete from sources - where name = ? + delete from sources + where name = ? `, name) return err diff --git a/core/source_test.go b/core/source_test.go index d164584..5f6ec4c 100644 --- a/core/source_test.go +++ b/core/source_test.go @@ -24,17 +24,11 @@ func TestCreateSource(t *testing.T) { t.Fatal(err) } - rows, err := db.Query("select name from sources") + names, err := GetSources(db) if err != nil { t.Fatal(err) } - var names []string expected := []string{"one", "three"} - for rows.Next() { - var name string - rows.Scan(&name) - names = append(names, name) - } for i := 0; i < len(expected); i += 1 { if !slices.Contains(names, expected[i]) { t.Fatalf("missing %s, have: %v", expected[i], names)