From 9a77beb582ff3cafcb6cdf22b320473041674bd4 Mon Sep 17 00:00:00 2001 From: Tim Van Baak Date: Thu, 23 Jan 2025 13:22:38 -0800 Subject: [PATCH] Add more information to CLI help text --- cmd/actionAdd.go | 2 +- cmd/actionDelete.go | 2 +- cmd/actionEdit.go | 2 +- cmd/feed.go | 14 ++++---------- cmd/root.go | 29 +++++++++++++++++++++++++---- cmd/sourceAdd.go | 2 +- cmd/sourceDelete.go | 2 +- cmd/sourceFetch.go | 16 ++++++++-------- cmd/sourceList.go | 2 +- cmd/sourceTest.go | 9 +++------ core/action.go | 2 +- core/item.go | 6 ++++++ 12 files changed, 53 insertions(+), 35 deletions(-) diff --git a/cmd/actionAdd.go b/cmd/actionAdd.go index 1c8fa20..8c2bce8 100644 --- a/cmd/actionAdd.go +++ b/cmd/actionAdd.go @@ -45,7 +45,7 @@ func actionAdd(argv []string) { err := core.AddAction(db, actionAddSource, actionAddAction, argv) if err != nil { - log.Fatalf("error: %v", err) + log.Fatalf("error: failed to add action: %v", err) } log.Printf("Added action %s to source %s", actionAddAction, actionAddSource) diff --git a/cmd/actionDelete.go b/cmd/actionDelete.go index ccc7dbb..061fa13 100644 --- a/cmd/actionDelete.go +++ b/cmd/actionDelete.go @@ -43,7 +43,7 @@ func actionDelete() { err := core.DeleteAction(db, actionDeleteSource, actionDeleteAction) if err != nil { - log.Fatalf("error: %v", err) + log.Fatalf("error: failed to delete action: %v", err) } log.Printf("Deleted action %s from source %s", actionDeleteAction, actionDeleteSource) diff --git a/cmd/actionEdit.go b/cmd/actionEdit.go index 9d5a2aa..b1faee0 100644 --- a/cmd/actionEdit.go +++ b/cmd/actionEdit.go @@ -45,7 +45,7 @@ func actionEdit(argv []string) { err := core.UpdateAction(db, actionEditSource, actionEditAction, argv) if err != nil { - log.Fatalf("error: %v", err) + log.Fatalf("error: failed to update action: %v", err) } log.Printf("Updated action %s on source %s", actionEditAction, actionEditSource) diff --git a/cmd/feed.go b/cmd/feed.go index 579eef4..be7239b 100644 --- a/cmd/feed.go +++ b/cmd/feed.go @@ -11,14 +11,10 @@ import ( var feedCmd = &cobra.Command{ Use: "feed", Short: "Display the item feed", - Long: `Display the intake item feed in various formats. + Long: fmt.Sprintf(`Display the intake item feed in various formats. The default format is "headlines". -Available formats: - headlines Only item titles - json Full item JSON - short Item source and id -`, +%s`, makeFormatHelpText()), Run: func(cmd *cobra.Command, args []string) { feed() }, @@ -40,14 +36,12 @@ func init() { } func feed() { - formatter, err := core.FormatAs(feedFormat) - if err != nil { - log.Fatal(err) - } + formatter := formatAs(feedFormat) db := openAndMigrateDb() var items []core.Item + var err error if feedSource != "" { if feedShowInactive { items, err = core.GetAllItemsForSource(db, feedSource) diff --git a/cmd/root.go b/cmd/root.go index b0c06f0..6d97c70 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -33,6 +33,10 @@ func init() { rootCmd.PersistentFlags().StringVarP(&dbPath, "db", "d", "", "Path to the intake sqlite database (default: INTAKE_DB)") } +// +// Common logic shared by multiple commands +// + func getDbPath() string { if dbPath != "" { return dbPath @@ -41,7 +45,8 @@ func getDbPath() string { if env != "" { return env } - fmt.Println("error: No database specified. Either --db or INTAKE_DB must be set.") + fmt.Println("error: no database specified") + fmt.Println("Either --db or the environment variable INTAKE_DB must be set.") os.Exit(1) return "" } @@ -50,7 +55,7 @@ func getDbPath() string { func openDb() *core.DB { db, err := core.OpenDb(getDbPath()) if err != nil { - log.Fatalf("error: Failed to open %s", dbPath) + log.Fatalf("error: failed to open %s", dbPath) } return db } @@ -59,10 +64,10 @@ func openDb() *core.DB { func openAndMigrateDb() *core.DB { db := openDb() if err := core.InitDatabase(db); err != nil { - log.Fatalf("error: Failed to init database: %v", err) + log.Fatalf("error: failed to init database: %v", err) } if err := core.MigrateDatabase(db); err != nil { - log.Fatalf("error: Failed to migrate database: %v", err) + log.Fatalf("error: failed to migrate database: %v", err) } return db } @@ -86,3 +91,19 @@ func actionSort(a string, b string) int { } return strings.Compare(a, b) } + +func makeFormatHelpText() string { + text := "Available formats:\n" + for format, desc := range core.AvailableFormats { + text += fmt.Sprintf(" %-13s %s\n", format, desc) + } + return text +} + +func formatAs(format string) func(item core.Item) string { + formatter, err := core.FormatAs(format) + if err != nil { + log.Fatalf("error: %v", err) + } + return formatter +} diff --git a/cmd/sourceAdd.go b/cmd/sourceAdd.go index b3b13b4..f689479 100644 --- a/cmd/sourceAdd.go +++ b/cmd/sourceAdd.go @@ -34,7 +34,7 @@ func sourceAdd() { db := openAndMigrateDb() if err := core.AddSource(db, sourceAddSource); err != nil { - log.Fatalf("error: %v", err) + log.Fatalf("error: failed to add source: %v", err) } log.Printf("Added source %s", sourceAddSource) diff --git a/cmd/sourceDelete.go b/cmd/sourceDelete.go index 0ffdf58..42c7ffd 100644 --- a/cmd/sourceDelete.go +++ b/cmd/sourceDelete.go @@ -34,7 +34,7 @@ func sourceDelete() { db := openAndMigrateDb() if err := core.DeleteSource(db, sourceDeleteSource); err != nil { - log.Fatalf("error: %v", err) + log.Fatalf("error: failed to delete source: %v", err) } log.Printf("Deleted source %s", sourceDeleteSource) diff --git a/cmd/sourceFetch.go b/cmd/sourceFetch.go index f387b9d..8981d09 100644 --- a/cmd/sourceFetch.go +++ b/cmd/sourceFetch.go @@ -12,13 +12,16 @@ import ( var sourceFetchCmd = &cobra.Command{ Use: "fetch", Short: "Fetch items for a source and update the feed", - Long: `Fetch items from a feed source using the configured "fetch" action. + Long: fmt.Sprintf(`Fetch items from a feed source using the configured "fetch" action. Items returned by a successful fetch will be used to update the source. A fetch is successful if all items output by the fetch are parsed successfully and the exit code is 0. No changes will be made to the source if the fetch does not succeed. -In a dry run, the items will be printed according to the chosen format.`, +In a dry run, the items will be printed according to the chosen format and +the source will not be updated with the fetch result. + +%s`, makeFormatHelpText()), Run: func(cmd *cobra.Command, args []string) { sourceFetch() }, @@ -39,10 +42,7 @@ func init() { } func sourceFetch() { - formatter, err := core.FormatAs(sourceFetchFormat) - if err != nil { - log.Fatalf("error: %v", err) - } + formatter := formatAs(sourceFetchFormat) db := openAndMigrateDb() @@ -53,7 +53,7 @@ func sourceFetch() { items, err := core.Execute(sourceFetchSource, argv, nil, "", time.Minute) if err != nil { - log.Fatalf("error: %v", err) + log.Fatalf("error: failed to execute fetch: %v", err) } if sourceFetchDryRun { @@ -66,7 +66,7 @@ func sourceFetch() { added, deleted, err := core.UpdateWithFetchedItems(db, sourceFetchSource, items) if err != nil { - log.Fatalf("error: %v", err) + 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) } diff --git a/cmd/sourceList.go b/cmd/sourceList.go index cd4e14a..12f07cb 100644 --- a/cmd/sourceList.go +++ b/cmd/sourceList.go @@ -33,7 +33,7 @@ func sourceList() { names, err := core.GetSources(db) if err != nil { - log.Fatalf("error: %v", err) + log.Fatalf("error: failed to get sources: %v", err) } slices.Sort(names) diff --git a/cmd/sourceTest.go b/cmd/sourceTest.go index 00bf823..abf8d0d 100644 --- a/cmd/sourceTest.go +++ b/cmd/sourceTest.go @@ -12,9 +12,9 @@ import ( var sourceTestCmd = &cobra.Command{ Use: "test [flags] -- argv", Short: "Test a fetch action", - Long: `Execute a command as if it were a feed source's fetch action. + Long: fmt.Sprintf(`Execute a command as if it were a feed source's fetch action. -The display format of the returned items is the same as "intake feed".`, +%s`, makeFormatHelpText()), Run: func(cmd *cobra.Command, args []string) { l := cmd.Flags().ArgsLenAtDash() if l == -1 { @@ -36,10 +36,7 @@ func init() { } func sourceTest(cmd []string) { - formatter, err := core.FormatAs(testFormat) - if err != nil { - log.Fatal(err) - } + formatter := formatAs(testFormat) items, err := core.Execute("", cmd, testEnv, "", time.Minute) log.Printf("Returned %d items", len(items)) diff --git a/core/action.go b/core/action.go index 4bce5b9..332593c 100644 --- a/core/action.go +++ b/core/action.go @@ -132,7 +132,7 @@ func Execute( log.Printf("Executing %v", argv) if len(argv) == 0 { - return nil, errors.New("error: empty argv") + return nil, errors.New("empty argv") } env = append(env, "STATE_PATH=") diff --git a/core/item.go b/core/item.go index 3b97755..f805004 100644 --- a/core/item.go +++ b/core/item.go @@ -55,3 +55,9 @@ func FormatAs(format string) (func(item Item) string, error) { return nil, fmt.Errorf("invalid format '%s'", format) } } + +var AvailableFormats = map[string]string{ + "headlines": "Only item titles", + "json": "Full item JSON", + "short": "Item source and id", +}