Eliminate global variables in cmd

This commit is contained in:
Tim Van Baak 2025-01-30 07:54:13 -08:00
parent f5e9277e26
commit 9bf840fcec
17 changed files with 240 additions and 212 deletions

View File

@ -13,28 +13,25 @@ var actionAddCmd = &cobra.Command{
Long: `Add an action to a source.
`,
Run: func(cmd *cobra.Command, args []string) {
actionAdd(getArgv(cmd, args))
actionAdd(stringArg(cmd, "source"), stringArg(cmd, "action"), getArgv(cmd, args))
},
}
var actionAddSource string
var actionAddAction string
func init() {
actionCmd.AddCommand(actionAddCmd)
actionAddCmd.Flags().StringVarP(&actionAddSource, "source", "s", "", "Source to add action")
actionAddCmd.Flags().StringP("source", "s", "", "Source to add action")
actionAddCmd.MarkFlagRequired("source")
actionAddCmd.Flags().StringVarP(&actionAddAction, "action", "a", "", "Action name")
actionAddCmd.Flags().StringP("action", "a", "", "Action name")
actionAddCmd.MarkFlagRequired("action")
}
func actionAdd(argv []string) {
if actionAddSource == "" {
func actionAdd(source string, action string, argv []string) {
if source == "" {
log.Fatal("error: --source is empty")
}
if actionAddAction == "" {
if action == "" {
log.Fatal("error: --action is empty")
}
if len(argv) == 0 {
@ -43,10 +40,10 @@ func actionAdd(argv []string) {
db := openAndMigrateDb()
err := core.AddAction(db, actionAddSource, actionAddAction, argv)
err := core.AddAction(db, source, action, argv)
if err != nil {
log.Fatalf("error: failed to add action: %v", err)
}
log.Printf("Added action %s to source %s", actionAddAction, actionAddSource)
log.Printf("Added action %s to source %s", action, source)
}

View File

@ -14,37 +14,34 @@ var actionDeleteCmd = &cobra.Command{
Long: `Delete an action from a source.
`,
Run: func(cmd *cobra.Command, args []string) {
actionDelete()
actionDelete(stringArg(cmd, "source"), stringArg(cmd, "action"))
},
}
var actionDeleteSource string
var actionDeleteAction string
func init() {
actionCmd.AddCommand(actionDeleteCmd)
actionDeleteCmd.Flags().StringVarP(&actionDeleteSource, "source", "s", "", "Source to add action")
actionDeleteCmd.Flags().StringP("source", "s", "", "Source to add action")
actionDeleteCmd.MarkFlagRequired("source")
actionDeleteCmd.Flags().StringVarP(&actionDeleteAction, "action", "a", "", "Action name")
actionDeleteCmd.Flags().StringP("action", "a", "", "Action name")
actionDeleteCmd.MarkFlagRequired("action")
}
func actionDelete() {
if actionDeleteSource == "" {
func actionDelete(source string, action string) {
if source == "" {
log.Fatal("error: --source is empty")
}
if actionDeleteAction == "" {
if action == "" {
log.Fatal("error: --action is empty")
}
db := openAndMigrateDb()
err := core.DeleteAction(db, actionDeleteSource, actionDeleteAction)
err := core.DeleteAction(db, source, action)
if err != nil {
log.Fatalf("error: failed to delete action: %v", err)
}
log.Printf("Deleted action %s from source %s", actionDeleteAction, actionDeleteSource)
log.Printf("Deleted action %s from source %s", action, source)
}

View File

@ -13,28 +13,25 @@ var actionEditCmd = &cobra.Command{
Long: `Edit an action on a source.
`,
Run: func(cmd *cobra.Command, args []string) {
actionEdit(getArgv(cmd, args))
actionEdit(stringArg(cmd, "source"), stringArg(cmd, "action"), getArgv(cmd, args))
},
}
var actionEditSource string
var actionEditAction string
func init() {
actionCmd.AddCommand(actionEditCmd)
actionEditCmd.Flags().StringVarP(&actionEditSource, "source", "s", "", "Source to edit action")
actionEditCmd.Flags().StringP("source", "s", "", "Source to edit action")
actionEditCmd.MarkFlagRequired("source")
actionEditCmd.Flags().StringVarP(&actionEditAction, "action", "a", "", "Action name")
actionEditCmd.Flags().StringP("action", "a", "", "Action name")
actionEditCmd.MarkFlagRequired("action")
}
func actionEdit(argv []string) {
if actionEditSource == "" {
func actionEdit(source string, action string, argv []string) {
if source == "" {
log.Fatal("error: --source is empty")
}
if actionEditAction == "" {
if action == "" {
log.Fatal("error: --action is empty")
}
if len(argv) == 0 {
@ -43,10 +40,10 @@ func actionEdit(argv []string) {
db := openAndMigrateDb()
err := core.UpdateAction(db, actionEditSource, actionEditAction, argv)
err := core.UpdateAction(db, source, action, argv)
if err != nil {
log.Fatalf("error: failed to update action: %v", err)
}
log.Printf("Updated action %s on source %s", actionEditAction, actionEditSource)
log.Printf("Updated action %s on source %s", action, source)
}

View File

@ -25,77 +25,85 @@ In a dry run, the item will be printed in the chosen format and not updated.
%s`, makeFormatHelpText()),
Run: func(cmd *cobra.Command, args []string) {
actionExecute()
actionExecute(
stringArg(cmd, "source"),
stringArg(cmd, "action"),
stringArg(cmd, "item"),
stringArg(cmd, "format"),
boolArg(cmd, "dry-run"),
boolArg(cmd, "diff"),
boolArg(cmd, "force"),
)
},
}
var actionExecuteSource string
var actionExecuteAction string
var actionExecuteItem string
var actionExecuteFormat string
var actionExecuteDryRun bool
var actionExecuteDiff bool
var actionExecuteForce bool
func init() {
actionCmd.AddCommand(actionExecuteCmd)
actionExecuteCmd.PersistentFlags().StringVarP(&actionExecuteSource, "source", "s", "", "Source of the item")
actionExecuteCmd.PersistentFlags().StringP("source", "s", "", "Source of the item")
actionExecuteCmd.MarkFlagRequired("source")
actionExecuteCmd.PersistentFlags().StringVarP(&actionExecuteItem, "item", "i", "", "Item to run action on")
actionExecuteCmd.PersistentFlags().StringP("item", "i", "", "Item to run action on")
actionExecuteCmd.MarkFlagRequired("item")
actionExecuteCmd.PersistentFlags().StringVarP(&actionExecuteAction, "action", "a", "", "Action to run")
actionExecuteCmd.PersistentFlags().StringP("action", "a", "", "Action to run")
actionExecuteCmd.MarkFlagRequired("action")
actionExecuteCmd.Flags().StringVarP(&actionExecuteFormat, "format", "f", "headlines", "Feed format for returned items")
actionExecuteCmd.Flags().BoolVar(&actionExecuteDryRun, "dry-run", false, "Instead of updating the item, print it")
actionExecuteCmd.Flags().StringP("format", "f", "headlines", "Feed format for returned items")
actionExecuteCmd.Flags().Bool("dry-run", false, "Instead of updating the item, print it")
actionExecuteCmd.Flags().BoolVar(&actionExecuteDiff, "diff", false, "Show which fields of the item changed")
actionExecuteCmd.Flags().Bool("diff", false, "Show which fields of the item changed")
actionExecuteCmd.Flags().BoolVar(&actionExecuteForce, "force", false, "Execute the action even if the item does not support it")
actionExecuteCmd.Flags().Bool("force", false, "Execute the action even if the item does not support it")
}
func actionExecute() {
formatter := formatAs(actionExecuteFormat)
func actionExecute(
source string,
action string,
itemId string,
format string,
dryRun bool,
diff bool,
force bool,
) {
formatter := formatAs(format)
if actionExecuteSource == "" {
if source == "" {
log.Fatal("error: --source is empty")
}
if actionExecuteAction == "" {
if action == "" {
log.Fatal("error: --action is empty")
}
if actionExecuteItem == "" {
if itemId == "" {
log.Fatal("error: --item is empty")
}
db := openAndMigrateDb()
item, err := core.GetItem(db, actionExecuteSource, actionExecuteItem)
item, err := core.GetItem(db, source, itemId)
if err != nil {
log.Fatalf("error: failed to get item: %v", err)
}
if item.Action[actionExecuteAction] == nil {
if actionExecuteForce {
log.Printf("warning: force-executing %s on %s/%s", actionExecuteAction, actionExecuteSource, actionExecuteItem)
if item.Action[action] == nil {
if force {
log.Printf("warning: force-executing %s on %s/%s", action, source, itemId)
} else {
log.Fatalf("error: %s/%s does not support %s", actionExecuteSource, actionExecuteItem, actionExecuteAction)
log.Fatalf("error: %s/%s does not support %s", source, itemId, action)
}
}
argv, err := core.GetArgvForAction(db, actionExecuteSource, actionExecuteAction)
argv, err := core.GetArgvForAction(db, source, action)
if err != nil {
log.Fatalf("error: failed to get action: %v", err)
}
newItem, err := core.ExecuteItemAction(item, actionExecuteSource, argv, nil, "", time.Minute)
newItem, err := core.ExecuteItemAction(item, source, argv, nil, "", time.Minute)
if err != nil {
log.Fatalf("error executing action: %v", err)
}
if actionExecuteDiff {
if diff {
if item.Title != newItem.Title {
log.Printf("title: %s => %s", item.Title, newItem.Title)
}
@ -116,7 +124,7 @@ func actionExecute() {
}
}
if actionExecuteDryRun {
if dryRun {
fmt.Println(formatter(newItem))
return
}

View File

@ -16,41 +16,38 @@ var actionListCmd = &cobra.Command{
Long: `List actions on a source.
`,
Run: func(cmd *cobra.Command, args []string) {
actionList()
actionList(stringArg(cmd, "source"), boolArg(cmd, "argv"))
},
}
var actionListSource string
var actionListArgv bool
func init() {
actionCmd.AddCommand(actionListCmd)
actionListCmd.Flags().StringVarP(&actionListSource, "source", "s", "", "Source to list actions")
actionListCmd.Flags().StringP("source", "s", "", "Source to list actions")
actionListCmd.MarkFlagRequired("source")
actionListCmd.Flags().BoolVarP(&actionListArgv, "argv", "a", false, "Include action command")
actionListCmd.Flags().BoolP("argv", "a", false, "Include action command")
}
func actionList() {
if actionListSource == "" {
func actionList(source string, argv bool) {
if source == "" {
log.Fatal("error: --source is empty")
}
db := openAndMigrateDb()
actions, err := core.GetActionsForSource(db, actionListSource)
actions, err := core.GetActionsForSource(db, source)
if err != nil {
log.Fatal(err)
}
slices.SortFunc(actions, actionSort)
if actionListArgv {
if argv {
actionArgv := make(map[string][]string)
for _, name := range actions {
argv, err := core.GetArgvForAction(db, actionListSource, name)
argv, err := core.GetArgvForAction(db, source, name)
if err != nil {
log.Fatalf("error: could not get argv for source %s action %s: %v", actionListSource, name, err)
log.Fatalf("error: could not get argv for source %s action %s: %v", source, name, err)
}
actionArgv[name] = argv
}

53
cmd/args.go Normal file
View File

@ -0,0 +1,53 @@
package cmd
import (
"log"
"github.com/spf13/cobra"
)
// Get the value of a bool flag.
func boolArg(cmd *cobra.Command, name string) bool {
b, err := cmd.Flags().GetBool(name)
if err != nil {
log.Fatal(err)
}
return b
}
// Get the value of an int flag.
func intArg(cmd *cobra.Command, name string) int {
i, err := cmd.Flags().GetInt(name)
if err != nil {
log.Fatal(err)
}
return i
}
// Get the value of a string flag.
func stringArg(cmd *cobra.Command, name string) string {
str, err := cmd.Flags().GetString(name)
if err != nil {
log.Fatal(err)
}
return str
}
// Get the value of a string array flag.
func stringArrayArg(cmd *cobra.Command, name string) []string {
s, err := cmd.Flags().GetStringArray(name)
if err != nil {
log.Fatal(err)
}
return s
}
// Get the argv after the -- separator.
func getArgv(cmd *cobra.Command, args []string) []string {
lenAtDash := cmd.Flags().ArgsLenAtDash()
if lenAtDash == -1 {
return nil
} else {
return args[lenAtDash:]
}
}

View File

@ -16,45 +16,50 @@ The default format is "headlines".
%s`, makeFormatHelpText()),
Run: func(cmd *cobra.Command, args []string) {
feed()
feed(
stringArg(cmd, "format"),
stringArg(cmd, "source"),
stringArg(cmd, "channel"),
boolArg(cmd, "all"),
)
},
}
var feedFormat string
var feedSource string
var feedChannel string
var feedShowInactive bool
func init() {
rootCmd.AddCommand(feedCmd)
feedCmd.Flags().StringVarP(&feedFormat, "format", "f", "headlines", "Feed format")
feedCmd.Flags().StringVarP(&feedSource, "source", "s", "", "Limit to items from source")
feedCmd.Flags().StringVarP(&feedChannel, "channel", "c", "", "Limit to items from channel")
feedCmd.Flags().StringP("format", "f", "headlines", "Feed format")
feedCmd.Flags().StringP("source", "s", "", "Limit to items from source")
feedCmd.Flags().StringP("channel", "c", "", "Limit to items from channel")
feedCmd.MarkFlagsMutuallyExclusive("source", "channel")
feedCmd.Flags().BoolVar(&feedShowInactive, "all", false, "Show inactive items")
feedCmd.Flags().Bool("all", false, "Show inactive items")
}
func feed() {
formatter := formatAs(feedFormat)
func feed(
format string,
source string,
channel string,
showInactive bool,
) {
formatter := formatAs(format)
db := openAndMigrateDb()
var items []core.Item
var err error
if feedSource != "" {
if feedShowInactive {
items, err = core.GetAllItemsForSource(db, feedSource)
if source != "" {
if showInactive {
items, err = core.GetAllItemsForSource(db, source)
} else {
items, err = core.GetActiveItemsForSource(db, feedSource)
items, err = core.GetActiveItemsForSource(db, source)
}
if err != nil {
log.Fatalf("error: failed to fetch items from %s:, %v", feedSource, err)
log.Fatalf("error: failed to fetch items from %s:, %v", source, err)
}
} else if feedChannel != "" {
} else if channel != "" {
log.Fatal("error: unimplemented")
} else {
if feedShowInactive {
if showInactive {
items, err = core.GetAllItems(db)
} else {
items, err = core.GetAllActiveItems(db)

View File

@ -19,49 +19,58 @@ var itemAddCmd = &cobra.Command{
By default, the item is created in the "default" source, which is created
if it doesn't exist, with a random id.`,
Run: func(cmd *cobra.Command, args []string) {
itemAdd()
itemAdd(
stringArg(cmd, "source"),
stringArg(cmd, "id"),
stringArg(cmd, "title"),
stringArg(cmd, "author"),
stringArg(cmd, "body"),
stringArg(cmd, "link"),
intArg(cmd, "time"),
stringArg(cmd, "action"),
)
},
}
var addItemSource string
var addItemId string
var addItemTitle string
var addItemAuthor string
var addItemBody string
var addItemLink string
var addItemTime int
var addItemActions string
func init() {
itemCmd.AddCommand(itemAddCmd)
itemAddCmd.Flags().StringVarP(&addItemSource, "source", "s", "", "Source in which to create the item (default: default)")
itemAddCmd.Flags().StringVarP(&addItemId, "id", "i", "", "Item id (default: random hex)")
itemAddCmd.Flags().StringVarP(&addItemTitle, "title", "t", "", "Item title")
itemAddCmd.Flags().StringVarP(&addItemAuthor, "author", "a", "", "Item author")
itemAddCmd.Flags().StringVarP(&addItemBody, "body", "b", "", "Item body")
itemAddCmd.Flags().StringVarP(&addItemLink, "link", "l", "", "Item link")
itemAddCmd.Flags().IntVarP(&addItemTime, "time", "m", 0, "Item time as a Unix timestamp")
itemAddCmd.Flags().StringVarP(&addItemActions, "action", "x", "", "Item time as a Unix timestamp")
itemAddCmd.Flags().StringP("source", "s", "", "Source in which to create the item (default: default)")
itemAddCmd.Flags().StringP("id", "i", "", "Item id (default: random hex)")
itemAddCmd.Flags().StringP("title", "t", "", "Item title")
itemAddCmd.Flags().StringP("author", "a", "", "Item author")
itemAddCmd.Flags().StringP("body", "b", "", "Item body")
itemAddCmd.Flags().StringP("link", "l", "", "Item link")
itemAddCmd.Flags().IntP("time", "m", 0, "Item time as a Unix timestamp")
itemAddCmd.Flags().StringP("action", "x", "", "Item action data as JSON")
}
func itemAdd() {
func itemAdd(
source string,
id string,
title string,
author string,
body string,
link string,
time int,
actions string,
) {
// Default to "default" source
if addItemSource == "" {
addItemSource = "default"
if source == "" {
source = "default"
}
// Default id to random hex string
if addItemId == "" {
if id == "" {
bytes := make([]byte, 16)
if _, err := rand.Read(bytes); err != nil {
log.Fatalf("error: failed to generate id: %v", err)
}
addItemId = hex.EncodeToString(bytes)
id = hex.EncodeToString(bytes)
}
var actions core.Actions
if addItemActions != "" {
if err := json.Unmarshal([]byte(addItemActions), &actions); err != nil {
var itemActions core.Actions
if actions != "" {
if err := json.Unmarshal([]byte(actions), &itemActions); err != nil {
log.Fatalf("error: could not parse actions: %v", err)
}
}
@ -69,17 +78,17 @@ func itemAdd() {
db := openAndMigrateDb()
if err := core.AddItems(db, []core.Item{{
Source: addItemSource,
Id: addItemId,
Title: addItemTitle,
Author: addItemAuthor,
Body: addItemBody,
Link: addItemLink,
Time: addItemTime,
Action: actions,
Source: source,
Id: id,
Title: title,
Author: author,
Body: body,
Link: link,
Time: time,
Action: itemActions,
}}); err != nil {
log.Fatalf("error: failed to add item: %s", err)
}
log.Printf("Added %s/%s\n", addItemSource, addItemId)
log.Printf("Added %s/%s\n", source, id)
}

View File

@ -17,30 +17,27 @@ var itemDeactivateCmd = &cobra.Command{
Deactivation is idempotent.`,
Run: func(cmd *cobra.Command, args []string) {
itemDeactivate()
itemDeactivate(stringArg(cmd, "source"), stringArg(cmd, "item"))
},
}
var deacSource string
var deacItem string
func init() {
itemCmd.AddCommand(itemDeactivateCmd)
itemDeactivateCmd.Flags().StringVarP(&deacSource, "source", "s", "", "Source of the item")
itemDeactivateCmd.Flags().StringP("source", "s", "", "Source of the item")
itemDeactivateCmd.MarkFlagRequired("source")
itemDeactivateCmd.Flags().StringVarP(&deacItem, "item", "i", "", "Item id")
itemDeactivateCmd.Flags().StringP("item", "i", "", "Item id")
itemDeactivateCmd.MarkFlagRequired("item")
}
func itemDeactivate() {
func itemDeactivate(source string, item string) {
db := openAndMigrateDb()
active, err := core.DeactivateItem(db, deacSource, deacItem)
active, err := core.DeactivateItem(db, source, item)
if err != nil {
log.Fatalf("Failed to deactivate item: %s", err)
}
if active {
fmt.Printf("Deactivated %s/%s\n", deacSource, deacItem)
fmt.Printf("Deactivated %s/%s\n", source, item)
}
}

View File

@ -16,23 +16,21 @@ var migrateCmd = &cobra.Command{
Note that the database will be created if it does not exist, even with --list.`,
Run: func(cmd *cobra.Command, args []string) {
migrate()
migrate(boolArg(cmd, "list"))
},
}
var migrateListOnly bool
func init() {
rootCmd.AddCommand(migrateCmd)
migrateCmd.Flags().BoolVarP(&migrateListOnly, "list", "l", false, "Show the list of migrations")
migrateCmd.Flags().BoolP("list", "l", false, "Show the list of migrations")
}
func migrate() {
func migrate(listOnly bool) {
db := openDb()
core.InitDatabase(db)
if migrateListOnly {
if listOnly {
pending, err := core.GetPendingMigrations(db)
if err != nil {
log.Fatal(err)

View File

@ -72,15 +72,6 @@ func openAndMigrateDb() *core.DB {
return db
}
func getArgv(cmd *cobra.Command, args []string) []string {
lenAtDash := cmd.Flags().ArgsLenAtDash()
if lenAtDash == -1 {
return nil
} else {
return args[lenAtDash:]
}
}
// Sort "fetch" action ahead of other actions
func actionSort(a string, b string) int {
if a == "fetch" {

View File

@ -11,21 +11,18 @@ var serveCmd = &cobra.Command{
Long: `Serve the intake web interface.
`,
Run: func(cmd *cobra.Command, args []string) {
serve()
serve(stringArg(cmd, "addr"), stringArg(cmd, "port"))
},
}
var serveAddr string
var servePort string
func init() {
rootCmd.AddCommand(serveCmd)
serveCmd.Flags().StringVarP(&serveAddr, "addr", "a", "localhost", "Address to bind to")
serveCmd.Flags().StringVarP(&servePort, "port", "p", "8081", "Port to bind to")
serveCmd.Flags().StringP("addr", "a", "localhost", "Address to bind to")
serveCmd.Flags().StringP("port", "p", "8081", "Port to bind to")
}
func serve() {
func serve(addr string, port string) {
db := openAndMigrateDb()
web.RunServer(db, serveAddr, servePort)
web.RunServer(db, addr, port)
}

View File

@ -13,29 +13,27 @@ var sourceAddCmd = &cobra.Command{
Long: `Create a source.
`,
Run: func(cmd *cobra.Command, args []string) {
sourceAdd()
sourceAdd(stringArg(cmd, "source"))
},
}
var sourceAddSource string
func init() {
sourceCmd.AddCommand(sourceAddCmd)
sourceAddCmd.Flags().StringVarP(&sourceAddSource, "source", "s", "", "Source name")
sourceAddCmd.Flags().StringP("source", "s", "", "Source name")
sourceAddCmd.MarkFlagRequired("source")
}
func sourceAdd() {
if sourceAddSource == "" {
func sourceAdd(source string) {
if source == "" {
log.Fatal("error: --source is empty")
}
db := openAndMigrateDb()
if err := core.AddSource(db, sourceAddSource); err != nil {
if err := core.AddSource(db, source); err != nil {
log.Fatalf("error: failed to add source: %v", err)
}
log.Printf("Added source %s", sourceAddSource)
log.Printf("Added source %s", source)
}

View File

@ -14,28 +14,26 @@ var sourceDeleteCmd = &cobra.Command{
Long: `Delete a source.
`,
Run: func(cmd *cobra.Command, args []string) {
sourceDelete()
sourceDelete(stringArg(cmd, "source"))
},
}
var sourceDeleteSource string
func init() {
sourceCmd.AddCommand(sourceDeleteCmd)
sourceDeleteCmd.Flags().StringVarP(&sourceDeleteSource, "source", "s", "", "Source to delete")
sourceDeleteCmd.Flags().StringP("source", "s", "", "Source to delete")
}
func sourceDelete() {
if sourceDeleteSource == "" {
func sourceDelete(source string) {
if source == "" {
log.Fatal("error: --source is empty")
}
db := openAndMigrateDb()
if err := core.DeleteSource(db, sourceDeleteSource); err != nil {
if err := core.DeleteSource(db, source); err != nil {
log.Fatalf("error: failed to delete source: %v", err)
}
log.Printf("Deleted source %s", sourceDeleteSource)
log.Printf("Deleted source %s", source)
}

View File

@ -23,40 +23,36 @@ the source will not be updated with the fetch result.
%s`, makeFormatHelpText()),
Run: func(cmd *cobra.Command, args []string) {
sourceFetch()
sourceFetch(stringArg(cmd, "source"), stringArg(cmd, "format"), boolArg(cmd, "dry-run"))
},
}
var sourceFetchSource string
var sourceFetchFormat string
var sourceFetchDryRun bool
func init() {
sourceCmd.AddCommand(sourceFetchCmd)
sourceFetchCmd.Flags().StringVarP(&sourceFetchSource, "source", "s", "", "Source name to fetch (required)")
sourceFetchCmd.Flags().StringP("source", "s", "", "Source name to fetch (required)")
sourceFetchCmd.MarkFlagRequired("source")
sourceFetchCmd.Flags().StringVarP(&sourceFetchFormat, "format", "f", "headlines", "Feed format for returned items.")
sourceFetchCmd.Flags().BoolVar(&sourceFetchDryRun, "dry-run", false, "Instead of updating the source, print the fetched items")
sourceFetchCmd.Flags().StringP("format", "f", "headlines", "Feed format for returned items.")
sourceFetchCmd.Flags().Bool("dry-run", false, "Instead of updating the source, print the fetched items")
}
func sourceFetch() {
formatter := formatAs(sourceFetchFormat)
func sourceFetch(source string, format string, dryRun bool) {
formatter := formatAs(format)
db := openAndMigrateDb()
argv, err := core.GetArgvForAction(db, sourceFetchSource, "fetch")
argv, err := core.GetArgvForAction(db, source, "fetch")
if err != nil {
log.Fatalf("error: failed to get fetch action: %v", err)
}
items, err := core.Execute(sourceFetchSource, argv, nil, "", "", time.Minute)
items, err := core.Execute(source, argv, nil, "", "", time.Minute)
if err != nil {
log.Fatalf("error: failed to execute fetch: %v", err)
}
if sourceFetchDryRun {
if dryRun {
log.Printf("Fetch returned %d items", len(items))
for _, item := range items {
fmt.Println(formatter(item))
@ -64,9 +60,9 @@ func sourceFetch() {
return
}
added, deleted, err := core.UpdateWithFetchedItems(db, sourceFetchSource, items)
added, deleted, err := core.UpdateWithFetchedItems(db, source, items)
if err != nil {
log.Fatalf("error: failed to update: %v", err)
}
log.Printf("%s added %d items, updated %d items, and deleted %d items", sourceFetchSource, added, len(items)-added, deleted)
log.Printf("%s added %d items, updated %d items, and deleted %d items", source, added, len(items)-added, deleted)
}

View File

@ -16,19 +16,17 @@ var sourceListCmd = &cobra.Command{
Long: `Print the list of sources.
`,
Run: func(cmd *cobra.Command, args []string) {
sourceList()
sourceList(boolArg(cmd, "actions"))
},
}
var sourceListShowActions bool
func init() {
sourceCmd.AddCommand(sourceListCmd)
sourceListCmd.Flags().BoolVarP(&sourceListShowActions, "actions", "a", false, "Include source actions")
sourceListCmd.Flags().BoolP("actions", "a", false, "Include source actions")
}
func sourceList() {
func sourceList(showActions bool) {
db := openAndMigrateDb()
names, err := core.GetSources(db)
@ -37,7 +35,7 @@ func sourceList() {
}
slices.Sort(names)
if sourceListShowActions {
if showActions {
sourceActions := make(map[string][]string)
for _, name := range names {
actions, err := core.GetActionsForSource(db, name)

View File

@ -16,29 +16,21 @@ var sourceTestCmd = &cobra.Command{
%s`, makeFormatHelpText()),
Run: func(cmd *cobra.Command, args []string) {
l := cmd.Flags().ArgsLenAtDash()
if l == -1 {
sourceTest(nil)
} else {
sourceTest(args[l:])
}
sourceTest(stringArrayArg(cmd, "env"), stringArg(cmd, "format"), getArgv(cmd, args))
},
}
var sourceTestEnv []string
var sourceTestFormat string
func init() {
sourceCmd.AddCommand(sourceTestCmd)
sourceTestCmd.Flags().StringArrayVarP(&sourceTestEnv, "env", "e", nil, "Environment variables to set, in the form KEY=VAL")
sourceTestCmd.Flags().StringVarP(&sourceTestFormat, "format", "f", "headlines", "Feed format for returned items.")
sourceTestCmd.Flags().StringArrayP("env", "e", nil, "Environment variables to set, in the form KEY=VAL")
sourceTestCmd.Flags().StringP("format", "f", "headlines", "Feed format for returned items.")
}
func sourceTest(cmd []string) {
formatter := formatAs(sourceTestFormat)
func sourceTest(env []string, format string, cmd []string) {
formatter := formatAs(format)
items, err := core.Execute("", cmd, sourceTestEnv, "", "", time.Minute)
items, err := core.Execute("test", cmd, env, "", "", time.Minute)
log.Printf("Returned %d items", len(items))
if err != nil {
log.Fatal(err)