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.
51 lines
1.1 KiB
Go
51 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"
|
|
)
|
|
|
|
var storesCmd = &cobra.Command{
|
|
Use: "stores",
|
|
Short: "List nearby Publix stores",
|
|
Long: "Find Publix stores near a zip code. Use this to discover store numbers for fetching deals.",
|
|
Example: ` pubcli stores --zip 33101
|
|
pubcli stores -z 32801 --json`,
|
|
RunE: runStores,
|
|
}
|
|
|
|
func init() {
|
|
rootCmd.AddCommand(storesCmd)
|
|
}
|
|
|
|
func runStores(cmd *cobra.Command, _ []string) error {
|
|
if flagZip == "" {
|
|
return invalidArgsError(
|
|
"--zip is required for store lookup",
|
|
"pubcli stores --zip 33101",
|
|
"pubcli stores -z 33101 --json",
|
|
)
|
|
}
|
|
|
|
client := api.NewClient()
|
|
stores, err := client.FetchStores(cmd.Context(), flagZip, 5)
|
|
if err != nil {
|
|
return upstreamError("fetching stores", err)
|
|
}
|
|
if len(stores) == 0 {
|
|
return notFoundError(
|
|
fmt.Sprintf("no stores found near %s", flagZip),
|
|
"Try a nearby ZIP code.",
|
|
)
|
|
}
|
|
|
|
if flagJSON {
|
|
return display.PrintStoresJSON(cmd.OutOrStdout(), stores)
|
|
}
|
|
display.PrintStores(cmd.OutOrStdout(), stores, flagZip)
|
|
return nil
|
|
}
|