Add CLI commands with structured errors and robot-mode behavior
Three cobra commands forming the CLI surface: - root: fetch and filter weekly deals (--store/--zip with BOGO, category, department, query, and limit filters) - stores: list nearby Publix locations by ZIP code - categories: show available deal categories with counts Structured error system with typed error codes (INVALID_ARGS, NOT_FOUND, UPSTREAM_ERROR, INTERNAL_ERROR) and semantic exit codes (0-4). Errors render as human-readable text or JSON depending on output mode. Robot-mode features: auto-JSON when stdout is not a TTY, compact quick-start help when invoked with no args, and JSON error payloads for programmatic consumers.
This commit is contained in:
51
cmd/categories.go
Normal file
51
cmd/categories.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/tayloree/publix-deals/internal/api"
|
||||
"github.com/tayloree/publix-deals/internal/display"
|
||||
"github.com/tayloree/publix-deals/internal/filter"
|
||||
)
|
||||
|
||||
var categoriesCmd = &cobra.Command{
|
||||
Use: "categories",
|
||||
Short: "List available categories for the current week",
|
||||
Example: ` pubcli categories --store 1425
|
||||
pubcli categories -z 33101 --json`,
|
||||
RunE: runCategories,
|
||||
}
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(categoriesCmd)
|
||||
}
|
||||
|
||||
func runCategories(cmd *cobra.Command, _ []string) error {
|
||||
client := api.NewClient()
|
||||
|
||||
storeNumber, err := resolveStore(cmd, client)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
data, err := client.FetchSavings(cmd.Context(), storeNumber)
|
||||
if err != nil {
|
||||
return upstreamError("fetching deals", err)
|
||||
}
|
||||
|
||||
if len(data.Savings) == 0 {
|
||||
return notFoundError(
|
||||
fmt.Sprintf("no deals found for store #%s", storeNumber),
|
||||
"Try another store with --store.",
|
||||
)
|
||||
}
|
||||
|
||||
cats := filter.Categories(data.Savings)
|
||||
|
||||
if flagJSON {
|
||||
return display.PrintCategoriesJSON(cmd.OutOrStdout(), cats)
|
||||
}
|
||||
display.PrintCategories(cmd.OutOrStdout(), cats, storeNumber)
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user