package cmd import ( "fmt" "log" "time" "github.com/Jaculabilis/intake/core" "github.com/spf13/cobra" ) var actionExecuteCmd = &cobra.Command{ Use: "execute", Aliases: []string{"exec"}, Short: "Run a source action for an item", Long: fmt.Sprintf(`Execute a source action for an item. The item must declare support for the action by having the action's name in its "action" field. Use --force to execute the action anyway. The "fetch" action is special and does not execute for any specific item. Use "intake source fetch" to run the fetch action. 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( stringArg(cmd, "source"), stringArg(cmd, "action"), stringArg(cmd, "item"), stringArg(cmd, "format"), boolArg(cmd, "dry-run"), boolArg(cmd, "diff"), boolArg(cmd, "force"), ) }, } func init() { actionCmd.AddCommand(actionExecuteCmd) actionExecuteCmd.PersistentFlags().StringP("source", "s", "", "Source of the item") actionExecuteCmd.MarkFlagRequired("source") actionExecuteCmd.PersistentFlags().StringP("item", "i", "", "Item to run action on") actionExecuteCmd.MarkFlagRequired("item") actionExecuteCmd.PersistentFlags().StringP("action", "a", "", "Action to run") actionExecuteCmd.MarkFlagRequired("action") 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().Bool("diff", false, "Show which fields of the item changed") actionExecuteCmd.Flags().Bool("force", false, "Execute the action even if the item does not support it") } func actionExecute( source string, action string, itemId string, format string, dryRun bool, diff bool, force bool, ) { formatter := formatAs(format) if source == "" { log.Fatal("error: --source is empty") } if action == "" { log.Fatal("error: --action is empty") } if itemId == "" { log.Fatal("error: --item is empty") } db := openAndMigrateDb() item, err := core.GetItem(db, source, itemId) if err != nil { log.Fatalf("error: failed to get item: %v", err) } 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", source, itemId, action) } } argv, err := core.GetArgvForAction(db, source, action) if err != nil { log.Fatalf("error: failed to get action: %v", err) } newItem, err := core.ExecuteItemAction(item, argv, nil, "", time.Minute) if err != nil { log.Fatalf("error executing %s: %v", action, err) } if diff { if item.Title != newItem.Title { log.Printf("title: %s => %s", item.Title, newItem.Title) } if item.Author != newItem.Author { log.Printf("author: %s => %s", item.Author, newItem.Author) } if item.Body != newItem.Body { log.Printf("body: %s => %s", item.Body, newItem.Body) } if item.Link != newItem.Link { log.Printf("link: %s => %s", item.Link, newItem.Link) } if item.Time != newItem.Time { log.Printf("time: %d => %d", item.Time, newItem.Time) } if core.ItemsAreEqual(item, newItem) { log.Printf("no changes\n") } } if dryRun { fmt.Println(formatter(newItem)) return } if err = core.UpdateItems(db, []core.Item{newItem}); err != nil { log.Fatalf("error: failed to update item: %v", err) } }