Files
pubcli/cmd/categories.go
teernisse cca04bc11c 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.
2026-02-22 21:42:01 -05:00

52 lines
1.1 KiB
Go

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
}