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:
50
cmd/stores.go
Normal file
50
cmd/stores.go
Normal file
@@ -0,0 +1,50 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user