refactor(cli): restructure commands from flat to nested subcommands
Change CLI structure from `brewlog {verb}-{entity}` to `brewlog {entity} {verb}`:
- brewlog add-roaster → brewlog roaster add
- brewlog list-bags → brewlog bag list
- brewlog create-token → brewlog token create
- etc.
Each entity module now owns its subcommand enum and dispatch logic,
simplifying main.rs and improving discoverability via `brewlog {entity} --help`.
- Add RoasterCommands, RoastCommands, BagCommands, GearCommands, TokenCommands enums
- Add run() dispatcher to each entity module
- Simplify top-level Commands enum to delegate to entity modules
- Update all CLI tests and bootstrap script
This commit is contained in:
parent
4edc66f44a
commit
0090c4ba43
14 changed files with 392 additions and 285 deletions
|
|
@ -3,7 +3,7 @@ set -euo pipefail
|
|||
|
||||
cargo build
|
||||
|
||||
BREWLOG_TOKEN="$(./target/debug/brewlog create-token --name "bootstrap-token" --username admin --password password | grep -Po "BREWLOG_TOKEN=\K.+$")"
|
||||
BREWLOG_TOKEN="$(./target/debug/brewlog token create --name "bootstrap-token" --username admin --password password | grep -Po "BREWLOG_TOKEN=\K.+$")"
|
||||
export BREWLOG_TOKEN
|
||||
|
||||
if [[ -z "$BREWLOG_TOKEN" ]]; then
|
||||
|
|
@ -12,15 +12,15 @@ if [[ -z "$BREWLOG_TOKEN" ]]; then
|
|||
fi
|
||||
|
||||
# Tim Wendelboe (Norway)
|
||||
./target/debug/brewlog add-roaster \
|
||||
./target/debug/brewlog roaster add \
|
||||
--name "Tim Wendelboe" \
|
||||
--country "Norway" \
|
||||
--city "Oslo" \
|
||||
--homepage "https://timwendelboe.no" \
|
||||
--notes "World-renowned Nordic micro-roastery dedicated to clarity and sustainability."
|
||||
|
||||
./target/debug/brewlog add-roast \
|
||||
--roaster-id "$(./target/debug/brewlog list-roasters | jq -r '.[] | select(.name=="Tim Wendelboe") | .id')" \
|
||||
./target/debug/brewlog roast add \
|
||||
--roaster-id "$(./target/debug/brewlog roaster list | jq -r '.[] | select(.name=="Tim Wendelboe") | .id')" \
|
||||
--name "Ben Saïd Natural" \
|
||||
--origin "Ethiopia" \
|
||||
--region "Sidamo" \
|
||||
|
|
@ -28,8 +28,8 @@ fi
|
|||
--process "Natural" \
|
||||
--tasting-notes "Bergamot, Apricot, Floral"
|
||||
|
||||
./target/debug/brewlog add-roast \
|
||||
--roaster-id "$(./target/debug/brewlog list-roasters | jq -r '.[] | select(.name=="Tim Wendelboe") | .id')" \
|
||||
./target/debug/brewlog roast add \
|
||||
--roaster-id "$(./target/debug/brewlog roaster list | jq -r '.[] | select(.name=="Tim Wendelboe") | .id')" \
|
||||
--name "Finca Tamana Washed" \
|
||||
--origin "Colombia" \
|
||||
--region "El Pital, Huila" \
|
||||
|
|
@ -39,15 +39,15 @@ fi
|
|||
|
||||
|
||||
# Coffee Collective (Denmark)
|
||||
./target/debug/brewlog add-roaster \
|
||||
./target/debug/brewlog roaster add \
|
||||
--name "Coffee Collective" \
|
||||
--country "Denmark" \
|
||||
--city "Copenhagen" \
|
||||
--homepage "https://coffeecollective.dk" \
|
||||
--notes "Pioneers of transparency and sustainability; multi-time Nordic roaster award winners."
|
||||
|
||||
./target/debug/brewlog add-roast \
|
||||
--roaster-id "$(./target/debug/brewlog list-roasters | jq -r '.[] | select(.name=="Coffee Collective") | .id')" \
|
||||
./target/debug/brewlog roast add \
|
||||
--roaster-id "$(./target/debug/brewlog roaster list | jq -r '.[] | select(.name=="Coffee Collective") | .id')" \
|
||||
--name "Daterra Sweet Collection" \
|
||||
--origin "Brazil" \
|
||||
--region "Cerrado" \
|
||||
|
|
@ -55,8 +55,8 @@ fi
|
|||
--process "Pulped Natural" \
|
||||
--tasting-notes "Hazelnut, Milk Chocolate, Yellow Fruit"
|
||||
|
||||
./target/debug/brewlog add-roast \
|
||||
--roaster-id "$(./target/debug/brewlog list-roasters | jq -r '.[] | select(.name=="Coffee Collective") | .id')" \
|
||||
./target/debug/brewlog roast add \
|
||||
--roaster-id "$(./target/debug/brewlog roaster list | jq -r '.[] | select(.name=="Coffee Collective") | .id')" \
|
||||
--name "Kieni" \
|
||||
--origin "Kenya" \
|
||||
--region "Nyeri" \
|
||||
|
|
@ -66,15 +66,15 @@ fi
|
|||
|
||||
|
||||
# Drop Coffee (Sweden)
|
||||
./target/debug/brewlog add-roaster \
|
||||
./target/debug/brewlog roaster add \
|
||||
--name "Drop Coffee" \
|
||||
--country "Sweden" \
|
||||
--city "Stockholm" \
|
||||
--homepage "https://dropcoffee.com" \
|
||||
--notes "Award-winning Swedish roastery prized for its elegance and clean Scandinavian style."
|
||||
|
||||
./target/debug/brewlog add-roast \
|
||||
--roaster-id "$(./target/debug/brewlog list-roasters | jq -r '.[] | select(.name=="Drop Coffee") | .id')" \
|
||||
./target/debug/brewlog roast add \
|
||||
--roaster-id "$(./target/debug/brewlog roaster list | jq -r '.[] | select(.name=="Drop Coffee") | .id')" \
|
||||
--name "La Linda" \
|
||||
--origin "Bolivia" \
|
||||
--region "Caranavi" \
|
||||
|
|
@ -82,8 +82,8 @@ fi
|
|||
--process "Washed" \
|
||||
--tasting-notes "Red Apple, Caramel, Floral"
|
||||
|
||||
./target/debug/brewlog add-roast \
|
||||
--roaster-id "$(./target/debug/brewlog list-roasters | jq -r '.[] | select(.name=="Drop Coffee") | .id')" \
|
||||
./target/debug/brewlog roast add \
|
||||
--roaster-id "$(./target/debug/brewlog roaster list | jq -r '.[] | select(.name=="Drop Coffee") | .id')" \
|
||||
--name "El Sunzita" \
|
||||
--origin "El Salvador" \
|
||||
--region "Ahuachapan" \
|
||||
|
|
@ -93,15 +93,15 @@ fi
|
|||
|
||||
|
||||
# La Cabra (Denmark)
|
||||
./target/debug/brewlog add-roaster \
|
||||
./target/debug/brewlog roaster add \
|
||||
--name "La Cabra" \
|
||||
--country "Denmark" \
|
||||
--city "Aarhus" \
|
||||
--homepage "https://www.lacabra.dk" \
|
||||
--notes "Scandinavian minimalist roastery known for clarity and innovative sourcing."
|
||||
|
||||
./target/debug/brewlog add-roast \
|
||||
--roaster-id "$(./target/debug/brewlog list-roasters | jq -r '.[] | select(.name=="La Cabra") | .id')" \
|
||||
./target/debug/brewlog roast add \
|
||||
--roaster-id "$(./target/debug/brewlog roaster list | jq -r '.[] | select(.name=="La Cabra") | .id')" \
|
||||
--name "Halo Beriti" \
|
||||
--origin "Ethiopia" \
|
||||
--region "Yirgacheffe" \
|
||||
|
|
@ -109,8 +109,8 @@ fi
|
|||
--process "Washed" \
|
||||
--tasting-notes "Jasmine, Lemon, Stone Fruit"
|
||||
|
||||
./target/debug/brewlog add-roast \
|
||||
--roaster-id "$(./target/debug/brewlog list-roasters | jq -r '.[] | select(.name=="La Cabra") | .id')" \
|
||||
./target/debug/brewlog roast add \
|
||||
--roaster-id "$(./target/debug/brewlog roaster list | jq -r '.[] | select(.name=="La Cabra") | .id')" \
|
||||
--name "Cerro Azul" \
|
||||
--origin "Colombia" \
|
||||
--region "Valle del Cauca" \
|
||||
|
|
@ -120,15 +120,15 @@ fi
|
|||
|
||||
|
||||
# April Coffee (Denmark)
|
||||
./target/debug/brewlog add-roaster \
|
||||
./target/debug/brewlog roaster add \
|
||||
--name "April Coffee" \
|
||||
--country "Denmark" \
|
||||
--city "Copenhagen" \
|
||||
--homepage "https://aprilcoffeeroasters.com" \
|
||||
--notes "Modern approach to Nordic coffee, emphasizing transparency and traceability."
|
||||
|
||||
./target/debug/brewlog add-roast \
|
||||
--roaster-id "$(./target/debug/brewlog list-roasters | jq -r '.[] | select(.name=="April Coffee") | .id')" \
|
||||
./target/debug/brewlog roast add \
|
||||
--roaster-id "$(./target/debug/brewlog roaster list | jq -r '.[] | select(.name=="April Coffee") | .id')" \
|
||||
--name "El Salvador Pacamara" \
|
||||
--origin "El Salvador" \
|
||||
--region "Santa Ana" \
|
||||
|
|
@ -136,8 +136,8 @@ fi
|
|||
--process "Honey" \
|
||||
--tasting-notes "Grapefruit, Sugar Cane, Plum"
|
||||
|
||||
./target/debug/brewlog add-roast \
|
||||
--roaster-id "$(./target/debug/brewlog list-roasters | jq -r '.[] | select(.name=="April Coffee") | .id')" \
|
||||
./target/debug/brewlog roast add \
|
||||
--roaster-id "$(./target/debug/brewlog roaster list | jq -r '.[] | select(.name=="April Coffee") | .id')" \
|
||||
--name "Guji Highland" \
|
||||
--origin "Ethiopia" \
|
||||
--region "Guji" \
|
||||
|
|
@ -147,15 +147,15 @@ fi
|
|||
|
||||
|
||||
# Assembly Coffee (UK)
|
||||
./target/debug/brewlog add-roaster \
|
||||
./target/debug/brewlog roaster add \
|
||||
--name "Assembly Coffee" \
|
||||
--country "UK" \
|
||||
--city "London" \
|
||||
--homepage "https://assemblycoffee.co.uk" \
|
||||
--notes "Based in Brixton, Assembly focuses on collaborative sourcing and education."
|
||||
|
||||
./target/debug/brewlog add-roast \
|
||||
--roaster-id "$(./target/debug/brewlog list-roasters | jq -r '.[] | select(.name=="Assembly Coffee") | .id')" \
|
||||
./target/debug/brewlog roast add \
|
||||
--roaster-id "$(./target/debug/brewlog roaster list | jq -r '.[] | select(.name=="Assembly Coffee") | .id')" \
|
||||
--name "Kochere" \
|
||||
--origin "Ethiopia" \
|
||||
--region "Yirgacheffe" \
|
||||
|
|
@ -163,8 +163,8 @@ fi
|
|||
--process "Washed" \
|
||||
--tasting-notes "Peach, Lemon, Jasmine"
|
||||
|
||||
./target/debug/brewlog add-roast \
|
||||
--roaster-id "$(./target/debug/brewlog list-roasters | jq -r '.[] | select(.name=="Assembly Coffee") | .id')" \
|
||||
./target/debug/brewlog roast add \
|
||||
--roaster-id "$(./target/debug/brewlog roaster list | jq -r '.[] | select(.name=="Assembly Coffee") | .id')" \
|
||||
--name "La Laja" \
|
||||
--origin "Mexico" \
|
||||
--region "Veracruz" \
|
||||
|
|
@ -174,15 +174,15 @@ fi
|
|||
|
||||
|
||||
# Square Mile (UK)
|
||||
./target/debug/brewlog add-roaster \
|
||||
./target/debug/brewlog roaster add \
|
||||
--name "Square Mile Coffee" \
|
||||
--country "UK" \
|
||||
--city "London" \
|
||||
--homepage "https://squaremilecoffee.com" \
|
||||
--notes "One of London's pioneers; delivers balanced and clear, fruit-forward coffees."
|
||||
|
||||
./target/debug/brewlog add-roast \
|
||||
--roaster-id "$(./target/debug/brewlog list-roasters | jq -r '.[] | select(.name=="Square Mile Coffee") | .id')" \
|
||||
./target/debug/brewlog roast add \
|
||||
--roaster-id "$(./target/debug/brewlog roaster list | jq -r '.[] | select(.name=="Square Mile Coffee") | .id')" \
|
||||
--name "Red Brick Espresso" \
|
||||
--origin "Blend" \
|
||||
--region "Multiple Origins" \
|
||||
|
|
@ -190,8 +190,8 @@ fi
|
|||
--process "Washed, Natural" \
|
||||
--tasting-notes "Berry, Chocolate, Citrus"
|
||||
|
||||
./target/debug/brewlog add-roast \
|
||||
--roaster-id "$(./target/debug/brewlog list-roasters | jq -r '.[] | select(.name=="Square Mile Coffee") | .id')" \
|
||||
./target/debug/brewlog roast add \
|
||||
--roaster-id "$(./target/debug/brewlog roaster list | jq -r '.[] | select(.name=="Square Mile Coffee") | .id')" \
|
||||
--name "Kamwangi" \
|
||||
--origin "Kenya" \
|
||||
--region "Kirinyaga" \
|
||||
|
|
@ -201,15 +201,15 @@ fi
|
|||
|
||||
|
||||
# Dak Coffee Roasters (Netherlands)
|
||||
./target/debug/brewlog add-roaster \
|
||||
./target/debug/brewlog roaster add \
|
||||
--name "Dak Coffee Roasters" \
|
||||
--country "Netherlands" \
|
||||
--city "Amsterdam" \
|
||||
--homepage "https://www.dakcoffeeroasters.com" \
|
||||
--notes "Highly experimental Dutch roastery; celebrates vibrant acidity and alternative processing."
|
||||
|
||||
./target/debug/brewlog add-roast \
|
||||
--roaster-id "$(./target/debug/brewlog list-roasters | jq -r '.[] | select(.name=="Dak Coffee Roasters") | .id')" \
|
||||
./target/debug/brewlog roast add \
|
||||
--roaster-id "$(./target/debug/brewlog roaster list | jq -r '.[] | select(.name=="Dak Coffee Roasters") | .id')" \
|
||||
--name "El Paraiso 92 Anaerobic" \
|
||||
--origin "Colombia" \
|
||||
--region "Cauca" \
|
||||
|
|
@ -217,8 +217,8 @@ fi
|
|||
--process "Thermal Shock Anaerobic" \
|
||||
--tasting-notes "Passionfruit, Raspberry, Yogurt"
|
||||
|
||||
./target/debug/brewlog add-roast \
|
||||
--roaster-id "$(./target/debug/brewlog list-roasters | jq -r '.[] | select(.name=="Dak Coffee Roasters") | .id')" \
|
||||
./target/debug/brewlog roast add \
|
||||
--roaster-id "$(./target/debug/brewlog roaster list | jq -r '.[] | select(.name=="Dak Coffee Roasters") | .id')" \
|
||||
--name "Oreti SL28" \
|
||||
--origin "Kenya" \
|
||||
--region "Kirinyaga" \
|
||||
|
|
@ -228,15 +228,15 @@ fi
|
|||
|
||||
|
||||
# Bonanza Coffee (Germany)
|
||||
./target/debug/brewlog add-roaster \
|
||||
./target/debug/brewlog roaster add \
|
||||
--name "Bonanza Coffee" \
|
||||
--country "Germany" \
|
||||
--city "Berlin" \
|
||||
--homepage "https://www.bonanzacoffee.de" \
|
||||
--notes "Pioneering Berlin roastery focused on brightness, balance, and freshness."
|
||||
|
||||
./target/debug/brewlog add-roast \
|
||||
--roaster-id "$(./target/debug/brewlog list-roasters | jq -r '.[] | select(.name=="Bonanza Coffee") | .id')" \
|
||||
./target/debug/brewlog roast add \
|
||||
--roaster-id "$(./target/debug/brewlog roaster list | jq -r '.[] | select(.name=="Bonanza Coffee") | .id')" \
|
||||
--name "Gatomboya" \
|
||||
--origin "Kenya" \
|
||||
--region "Nyeri" \
|
||||
|
|
@ -244,8 +244,8 @@ fi
|
|||
--process "Washed" \
|
||||
--tasting-notes "Blackcurrant, Lime, Tomato"
|
||||
|
||||
./target/debug/brewlog add-roast \
|
||||
--roaster-id "$(./target/debug/brewlog list-roasters | jq -r '.[] | select(.name=="Bonanza Coffee") | .id')" \
|
||||
./target/debug/brewlog roast add \
|
||||
--roaster-id "$(./target/debug/brewlog roaster list | jq -r '.[] | select(.name=="Bonanza Coffee") | .id')" \
|
||||
--name "Los Pirineos" \
|
||||
--origin "El Salvador" \
|
||||
--region "Usulután" \
|
||||
|
|
@ -255,15 +255,15 @@ fi
|
|||
|
||||
|
||||
# Friedhats (Netherlands)
|
||||
./target/debug/brewlog add-roaster \
|
||||
./target/debug/brewlog roaster add \
|
||||
--name "Friedhats" \
|
||||
--country "Netherlands" \
|
||||
--city "Amsterdam" \
|
||||
--homepage "https://friedhats.com" \
|
||||
--notes "Quirky branding meets serious, awarded, fruit-forward coffees from Amsterdam."
|
||||
|
||||
./target/debug/brewlog add-roast \
|
||||
--roaster-id "$(./target/debug/brewlog list-roasters | jq -r '.[] | select(.name=="Friedhats") | .id')" \
|
||||
./target/debug/brewlog roast add \
|
||||
--roaster-id "$(./target/debug/brewlog roaster list | jq -r '.[] | select(.name=="Friedhats") | .id')" \
|
||||
--name "Sidamo Guji" \
|
||||
--origin "Ethiopia" \
|
||||
--region "Guji" \
|
||||
|
|
@ -271,8 +271,8 @@ fi
|
|||
--process "Natural" \
|
||||
--tasting-notes "Peach, Raspberry, Rosehip"
|
||||
|
||||
./target/debug/brewlog add-roast \
|
||||
--roaster-id "$(./target/debug/brewlog list-roasters | jq -r '.[] | select(.name=="Friedhats") | .id')" \
|
||||
./target/debug/brewlog roast add \
|
||||
--roaster-id "$(./target/debug/brewlog roaster list | jq -r '.[] | select(.name=="Friedhats") | .id')" \
|
||||
--name "La Esmeralda Geisha" \
|
||||
--origin "Panama" \
|
||||
--region "Boquete" \
|
||||
|
|
@ -282,15 +282,15 @@ fi
|
|||
|
||||
|
||||
# Origin Coffee (UK)
|
||||
./target/debug/brewlog add-roaster \
|
||||
./target/debug/brewlog roaster add \
|
||||
--name "Origin Coffee" \
|
||||
--country "UK" \
|
||||
--city "Porthleven" \
|
||||
--homepage "https://origincoffee.co.uk" \
|
||||
--notes "Specialty roaster with close partnerships at origin; leading UK scene with cutting-edge lots."
|
||||
|
||||
./target/debug/brewlog add-roast \
|
||||
--roaster-id "$(./target/debug/brewlog list-roasters | jq -r '.[] | select(.name=="Origin Coffee") | .id')" \
|
||||
./target/debug/brewlog roast add \
|
||||
--roaster-id "$(./target/debug/brewlog roaster list | jq -r '.[] | select(.name=="Origin Coffee") | .id')" \
|
||||
--name "San Fermin" \
|
||||
--origin "Colombia" \
|
||||
--region "Tolima" \
|
||||
|
|
@ -298,8 +298,8 @@ fi
|
|||
--process "Washed" \
|
||||
--tasting-notes "Red Grape, Caramel, Blood Orange"
|
||||
|
||||
./target/debug/brewlog add-roast \
|
||||
--roaster-id "$(./target/debug/brewlog list-roasters | jq -r '.[] | select(.name=="Origin Coffee") | .id')" \
|
||||
./target/debug/brewlog roast add \
|
||||
--roaster-id "$(./target/debug/brewlog roaster list | jq -r '.[] | select(.name=="Origin Coffee") | .id')" \
|
||||
--name "Aricha" \
|
||||
--origin "Ethiopia" \
|
||||
--region "Yirgacheffe" \
|
||||
|
|
@ -309,15 +309,15 @@ fi
|
|||
|
||||
|
||||
# Dark Arts Coffee (UK)
|
||||
./target/debug/brewlog add-roaster \
|
||||
./target/debug/brewlog roaster add \
|
||||
--name "Dark Arts Coffee" \
|
||||
--country "UK" \
|
||||
--city "London" \
|
||||
--homepage "https://www.darkartscoffee.co.uk" \
|
||||
--notes "Playful, disruptive roaster with a cult following and flavor-forward offerings."
|
||||
|
||||
./target/debug/brewlog add-roast \
|
||||
--roaster-id "$(./target/debug/brewlog list-roasters | jq -r '.[] | select(.name=="Dark Arts Coffee") | .id')" \
|
||||
./target/debug/brewlog roast add \
|
||||
--roaster-id "$(./target/debug/brewlog roaster list | jq -r '.[] | select(.name=="Dark Arts Coffee") | .id')" \
|
||||
--name "Death to Decaf" \
|
||||
--origin "Brazil" \
|
||||
--region "Minas Gerais" \
|
||||
|
|
@ -325,8 +325,8 @@ fi
|
|||
--process "Swiss Water Decaf" \
|
||||
--tasting-notes "Cocoa, Cherry, Almond"
|
||||
|
||||
./target/debug/brewlog add-roast \
|
||||
--roaster-id "$(./target/debug/brewlog list-roasters | jq -r '.[] | select(.name=="Dark Arts Coffee") | .id')" \
|
||||
./target/debug/brewlog roast add \
|
||||
--roaster-id "$(./target/debug/brewlog roaster list | jq -r '.[] | select(.name=="Dark Arts Coffee") | .id')" \
|
||||
--name "Snoop" \
|
||||
--origin "Guatemala" \
|
||||
--region "Huehuetenango" \
|
||||
|
|
@ -336,15 +336,15 @@ fi
|
|||
|
||||
|
||||
# KAWA Coffee (France)
|
||||
./target/debug/brewlog add-roaster \
|
||||
./target/debug/brewlog roaster add \
|
||||
--name "KAWA Coffee" \
|
||||
--country "France" \
|
||||
--city "Paris" \
|
||||
--homepage "https://www.kawa.coffee" \
|
||||
--notes "One of Paris’ most exciting specialty roasteries, known for unusual and competition-level lots."
|
||||
|
||||
./target/debug/brewlog add-roast \
|
||||
--roaster-id "$(./target/debug/brewlog list-roasters | jq -r '.[] | select(.name=="KAWA Coffee") | .id')" \
|
||||
./target/debug/brewlog roast add \
|
||||
--roaster-id "$(./target/debug/brewlog roaster list | jq -r '.[] | select(.name=="KAWA Coffee") | .id')" \
|
||||
--name "Sudan Rume" \
|
||||
--origin "Colombia" \
|
||||
--region "Cauca" \
|
||||
|
|
@ -352,8 +352,8 @@ fi
|
|||
--process "Natural" \
|
||||
--tasting-notes "Strawberry, Cinnamon, Grape"
|
||||
|
||||
./target/debug/brewlog add-roast \
|
||||
--roaster-id "$(./target/debug/brewlog list-roasters | jq -r '.[] | select(.name=="KAWA Coffee") | .id')" \
|
||||
./target/debug/brewlog roast add \
|
||||
--roaster-id "$(./target/debug/brewlog roaster list | jq -r '.[] | select(.name=="KAWA Coffee") | .id')" \
|
||||
--name "Arbegona" \
|
||||
--origin "Ethiopia" \
|
||||
--region "Sidama" \
|
||||
|
|
@ -363,15 +363,15 @@ fi
|
|||
|
||||
|
||||
# Stow Coffee (Slovenia)
|
||||
./target/debug/brewlog add-roaster \
|
||||
./target/debug/brewlog roaster add \
|
||||
--name "Stow Coffee" \
|
||||
--country "Slovenia" \
|
||||
--city "Ljubljana" \
|
||||
--homepage "https://www.stowcoffee.com" \
|
||||
--notes "Slovenia’s specialty leader, awarded for pure, brightly acidic profiles and innovation."
|
||||
|
||||
./target/debug/brewlog add-roast \
|
||||
--roaster-id "$(./target/debug/brewlog list-roasters | jq -r '.[] | select(.name=="Stow Coffee") | .id')" \
|
||||
./target/debug/brewlog roast add \
|
||||
--roaster-id "$(./target/debug/brewlog roaster list | jq -r '.[] | select(.name=="Stow Coffee") | .id')" \
|
||||
--name "Santa Barbara" \
|
||||
--origin "Honduras" \
|
||||
--region "Santa Barbara" \
|
||||
|
|
@ -379,8 +379,8 @@ fi
|
|||
--process "Honey" \
|
||||
--tasting-notes "Red Currant, Honeydew, Cocoa"
|
||||
|
||||
./target/debug/brewlog add-roast \
|
||||
--roaster-id "$(./target/debug/brewlog list-roasters | jq -r '.[] | select(.name=="Stow Coffee") | .id')" \
|
||||
./target/debug/brewlog roast add \
|
||||
--roaster-id "$(./target/debug/brewlog roaster list | jq -r '.[] | select(.name=="Stow Coffee") | .id')" \
|
||||
--name "Suke Quto" \
|
||||
--origin "Ethiopia" \
|
||||
--region "Guji" \
|
||||
|
|
@ -390,15 +390,15 @@ fi
|
|||
|
||||
|
||||
# Bows Coffee (Canada)
|
||||
./target/debug/brewlog add-roaster \
|
||||
./target/debug/brewlog roaster add \
|
||||
--name "Bows Coffee" \
|
||||
--country "Canada" \
|
||||
--city "Victoria" \
|
||||
--homepage "https://bowscoffee.com" \
|
||||
--notes "Canadian micro-roaster with focus on clarity, complexity, and ethical sourcing."
|
||||
|
||||
./target/debug/brewlog add-roast \
|
||||
--roaster-id "$(./target/debug/brewlog list-roasters | jq -r '.[] | select(.name=="Bows Coffee") | .id')" \
|
||||
./target/debug/brewlog roast add \
|
||||
--roaster-id "$(./target/debug/brewlog roaster list | jq -r '.[] | select(.name=="Bows Coffee") | .id')" \
|
||||
--name "La Chumeca" \
|
||||
--origin "Costa Rica" \
|
||||
--region "Tarrazú" \
|
||||
|
|
@ -406,8 +406,8 @@ fi
|
|||
--process "White Honey" \
|
||||
--tasting-notes "Mandarin, Honeycomb, Almond"
|
||||
|
||||
./target/debug/brewlog add-roast \
|
||||
--roaster-id "$(./target/debug/brewlog list-roasters | jq -r '.[] | select(.name=="Bows Coffee") | .id')" \
|
||||
./target/debug/brewlog roast add \
|
||||
--roaster-id "$(./target/debug/brewlog roaster list | jq -r '.[] | select(.name=="Bows Coffee") | .id')" \
|
||||
--name "Simbi" \
|
||||
--origin "Rwanda" \
|
||||
--region "Huye" \
|
||||
|
|
@ -420,74 +420,74 @@ fi
|
|||
# ============================================================================
|
||||
|
||||
# Tim Wendelboe - Ben Saïd Natural (250g)
|
||||
./target/debug/brewlog add-bag \
|
||||
--roast-id "$(./target/debug/brewlog list-roasts | jq -r '.[] | select(.name=="Ben Saïd Natural") | .id')" \
|
||||
./target/debug/brewlog bag add \
|
||||
--roast-id "$(./target/debug/brewlog roast list | jq -r '.[] | select(.name=="Ben Saïd Natural") | .id')" \
|
||||
--roast-date "2026-01-15" \
|
||||
--amount 250
|
||||
|
||||
# Tim Wendelboe - Finca Tamana Washed (350g)
|
||||
./target/debug/brewlog add-bag \
|
||||
--roast-id "$(./target/debug/brewlog list-roasts | jq -r '.[] | select(.name=="Finca Tamana Washed") | .id')" \
|
||||
./target/debug/brewlog bag add \
|
||||
--roast-id "$(./target/debug/brewlog roast list | jq -r '.[] | select(.name=="Finca Tamana Washed") | .id')" \
|
||||
--roast-date "2026-01-18" \
|
||||
--amount 350
|
||||
|
||||
# Coffee Collective - Daterra Sweet Collection (200g)
|
||||
./target/debug/brewlog add-bag \
|
||||
--roast-id "$(./target/debug/brewlog list-roasts | jq -r '.[] | select(.name=="Daterra Sweet Collection") | .id')" \
|
||||
./target/debug/brewlog bag add \
|
||||
--roast-id "$(./target/debug/brewlog roast list | jq -r '.[] | select(.name=="Daterra Sweet Collection") | .id')" \
|
||||
--roast-date "2026-01-10" \
|
||||
--amount 200
|
||||
|
||||
# Drop Coffee - La Linda (500g)
|
||||
./target/debug/brewlog add-bag \
|
||||
--roast-id "$(./target/debug/brewlog list-roasts | jq -r '.[] | select(.name=="La Linda") | .id')" \
|
||||
./target/debug/brewlog bag add \
|
||||
--roast-id "$(./target/debug/brewlog roast list | jq -r '.[] | select(.name=="La Linda") | .id')" \
|
||||
--roast-date "2026-01-20" \
|
||||
--amount 500
|
||||
|
||||
# La Cabra - Halo Beriti (150g)
|
||||
./target/debug/brewlog add-bag \
|
||||
--roast-id "$(./target/debug/brewlog list-roasts | jq -r '.[] | select(.name=="Halo Beriti") | .id')" \
|
||||
./target/debug/brewlog bag add \
|
||||
--roast-id "$(./target/debug/brewlog roast list | jq -r '.[] | select(.name=="Halo Beriti") | .id')" \
|
||||
--roast-date "2026-01-12" \
|
||||
--amount 150
|
||||
|
||||
# April Coffee - Guji Highland (300g)
|
||||
./target/debug/brewlog add-bag \
|
||||
--roast-id "$(./target/debug/brewlog list-roasts | jq -r '.[] | select(.name=="Guji Highland") | .id')" \
|
||||
./target/debug/brewlog bag add \
|
||||
--roast-id "$(./target/debug/brewlog roast list | jq -r '.[] | select(.name=="Guji Highland") | .id')" \
|
||||
--roast-date "2026-01-22" \
|
||||
--amount 300
|
||||
|
||||
# Assembly Coffee - Kochere (250g)
|
||||
./target/debug/brewlog add-bag \
|
||||
--roast-id "$(./target/debug/brewlog list-roasts | jq -r '.[] | select(.name=="Kochere") | .id')" \
|
||||
./target/debug/brewlog bag add \
|
||||
--roast-id "$(./target/debug/brewlog roast list | jq -r '.[] | select(.name=="Kochere") | .id')" \
|
||||
--roast-date "2026-01-08" \
|
||||
--amount 250
|
||||
|
||||
# Square Mile Coffee - Red Brick Espresso (400g)
|
||||
./target/debug/brewlog add-bag \
|
||||
--roast-id "$(./target/debug/brewlog list-roasts | jq -r '.[] | select(.name=="Red Brick Espresso") | .id')" \
|
||||
./target/debug/brewlog bag add \
|
||||
--roast-id "$(./target/debug/brewlog roast list | jq -r '.[] | select(.name=="Red Brick Espresso") | .id')" \
|
||||
--roast-date "2026-01-25" \
|
||||
--amount 400
|
||||
|
||||
# Dak Coffee Roasters - El Paraiso 92 Anaerobic (100g - small competition lot)
|
||||
./target/debug/brewlog add-bag \
|
||||
--roast-id "$(./target/debug/brewlog list-roasts | jq -r '.[] | select(.name=="El Paraiso 92 Anaerobic") | .id')" \
|
||||
./target/debug/brewlog bag add \
|
||||
--roast-id "$(./target/debug/brewlog roast list | jq -r '.[] | select(.name=="El Paraiso 92 Anaerobic") | .id')" \
|
||||
--roast-date "2026-01-28" \
|
||||
--amount 100
|
||||
|
||||
# Bonanza Coffee - Gatomboya (175g)
|
||||
./target/debug/brewlog add-bag \
|
||||
--roast-id "$(./target/debug/brewlog list-roasts | jq -r '.[] | select(.name=="Gatomboya") | .id')" \
|
||||
./target/debug/brewlog bag add \
|
||||
--roast-id "$(./target/debug/brewlog roast list | jq -r '.[] | select(.name=="Gatomboya") | .id')" \
|
||||
--roast-date "2026-01-05" \
|
||||
--amount 175
|
||||
|
||||
# Stow Coffee - Suke Quto (225g)
|
||||
./target/debug/brewlog add-bag \
|
||||
--roast-id "$(./target/debug/brewlog list-roasts | jq -r '.[] | select(.name=="Suke Quto") | .id')" \
|
||||
./target/debug/brewlog bag add \
|
||||
--roast-id "$(./target/debug/brewlog roast list | jq -r '.[] | select(.name=="Suke Quto") | .id')" \
|
||||
--roast-date "2026-01-30" \
|
||||
--amount 225
|
||||
|
||||
# Bows Coffee - Simbi (450g)
|
||||
./target/debug/brewlog add-bag \
|
||||
--roast-id "$(./target/debug/brewlog list-roasts | jq -r '.[] | select(.name=="Simbi") | .id')" \
|
||||
./target/debug/brewlog bag add \
|
||||
--roast-id "$(./target/debug/brewlog roast list | jq -r '.[] | select(.name=="Simbi") | .id')" \
|
||||
--roast-date "2026-01-14" \
|
||||
--amount 450
|
||||
|
||||
|
|
@ -496,26 +496,26 @@ fi
|
|||
# ============================================================================
|
||||
|
||||
# Finish Gatomboya bag (oldest - Jan 5)
|
||||
./target/debug/brewlog update-bag \
|
||||
--id "$(./target/debug/brewlog list-bags | jq -r '.[] | select(.roast_name=="Gatomboya") | .id')" \
|
||||
./target/debug/brewlog bag update \
|
||||
--id "$(./target/debug/brewlog bag list | jq -r '.[] | select(.roast_name=="Gatomboya") | .id')" \
|
||||
--closed true \
|
||||
--finished-at "2026-01-20"
|
||||
|
||||
# Finish Kochere bag (Jan 8)
|
||||
./target/debug/brewlog update-bag \
|
||||
--id "$(./target/debug/brewlog list-bags | jq -r '.[] | select(.roast_name=="Kochere") | .id')" \
|
||||
./target/debug/brewlog bag update \
|
||||
--id "$(./target/debug/brewlog bag list | jq -r '.[] | select(.roast_name=="Kochere") | .id')" \
|
||||
--closed true \
|
||||
--finished-at "2026-01-22"
|
||||
|
||||
# Finish Daterra Sweet Collection bag (Jan 10)
|
||||
./target/debug/brewlog update-bag \
|
||||
--id "$(./target/debug/brewlog list-bags | jq -r '.[] | select(.roast_name=="Daterra Sweet Collection") | .id')" \
|
||||
./target/debug/brewlog bag update \
|
||||
--id "$(./target/debug/brewlog bag list | jq -r '.[] | select(.roast_name=="Daterra Sweet Collection") | .id')" \
|
||||
--closed true \
|
||||
--finished-at "2026-01-25"
|
||||
|
||||
# Finish Halo Beriti bag (Jan 12)
|
||||
./target/debug/brewlog update-bag \
|
||||
--id "$(./target/debug/brewlog list-bags | jq -r '.[] | select(.roast_name=="Halo Beriti") | .id')" \
|
||||
./target/debug/brewlog bag update \
|
||||
--id "$(./target/debug/brewlog bag list | jq -r '.[] | select(.roast_name=="Halo Beriti") | .id')" \
|
||||
--closed true \
|
||||
--finished-at "2026-01-28"
|
||||
|
||||
|
|
@ -524,32 +524,33 @@ fi
|
|||
# ============================================================================
|
||||
|
||||
# Grinders
|
||||
./target/debug/brewlog add-gear \
|
||||
./target/debug/brewlog gear add \
|
||||
--category "grinder" \
|
||||
--make "Comandante" \
|
||||
--model "C40 MK4"
|
||||
|
||||
./target/debug/brewlog add-gear \
|
||||
./target/debug/brewlog gear add \
|
||||
--category "grinder" \
|
||||
--make "1Zpresso" \
|
||||
--model "J-Max"
|
||||
|
||||
# Brewers
|
||||
./target/debug/brewlog add-gear \
|
||||
./target/debug/brewlog gear add \
|
||||
--category "brewer" \
|
||||
--make "Hario" \
|
||||
--model "V60 02"
|
||||
|
||||
./target/debug/brewlog add-gear \
|
||||
./target/debug/brewlog gear add \
|
||||
--category "brewer" \
|
||||
--make "AeroPress" \
|
||||
--model "Original"
|
||||
|
||||
./target/debug/brewlog add-gear \
|
||||
./target/debug/brewlog gear add \
|
||||
--category "brewer" \
|
||||
--make "Fellow" \
|
||||
--model "Stagg XF"
|
||||
|
||||
echo
|
||||
echo "Bootstrapped database"
|
||||
echo
|
||||
echo "Set token $BREWLOG_TOKEN to use the data added here."
|
||||
52
src/main.rs
52
src/main.rs
|
|
@ -21,43 +21,25 @@ async fn main() -> Result<()> {
|
|||
|
||||
match cli.command {
|
||||
Commands::Serve(cmd) => run_server(cmd).await,
|
||||
command => {
|
||||
Commands::Roaster { command } => {
|
||||
let client = BrewlogClient::from_base_url(&cli.api_url)?;
|
||||
match command {
|
||||
// Tokens
|
||||
Commands::CreateToken(cmd) => tokens::create_token(&client, cmd).await,
|
||||
Commands::ListTokens => tokens::list_tokens(&client).await,
|
||||
Commands::RevokeToken(cmd) => tokens::revoke_token(&client, cmd).await,
|
||||
|
||||
// Roasters
|
||||
Commands::AddRoaster(cmd) => roasters::add_roaster(&client, cmd).await,
|
||||
Commands::ListRoasters => roasters::list_roasters(&client).await,
|
||||
Commands::GetRoaster(cmd) => roasters::get_roaster(&client, cmd).await,
|
||||
Commands::UpdateRoaster(cmd) => roasters::update_roaster(&client, cmd).await,
|
||||
Commands::DeleteRoaster(cmd) => roasters::delete_roaster(&client, cmd).await,
|
||||
|
||||
// Roasts
|
||||
Commands::AddRoast(cmd) => roasts::add_roast(&client, cmd).await,
|
||||
Commands::ListRoasts(cmd) => roasts::list_roasts(&client, cmd).await,
|
||||
Commands::GetRoast(cmd) => roasts::get_roast(&client, cmd).await,
|
||||
Commands::DeleteRoast(cmd) => roasts::delete_roast(&client, cmd).await,
|
||||
|
||||
// Bags
|
||||
Commands::AddBag(cmd) => bags::add_bag(&client, cmd).await,
|
||||
Commands::ListBags(cmd) => bags::list_bags(&client, cmd).await,
|
||||
Commands::GetBag(cmd) => bags::get_bag(&client, cmd).await,
|
||||
Commands::UpdateBag(cmd) => bags::update_bag(&client, cmd).await,
|
||||
Commands::DeleteBag(cmd) => bags::delete_bag(&client, cmd).await,
|
||||
|
||||
// Gear
|
||||
Commands::AddGear(cmd) => gear::add_gear(&client, cmd).await,
|
||||
Commands::ListGear(cmd) => gear::list_gear(&client, cmd).await,
|
||||
Commands::GetGear(cmd) => gear::get_gear(&client, cmd).await,
|
||||
Commands::UpdateGear(cmd) => gear::update_gear(&client, cmd).await,
|
||||
Commands::DeleteGear(cmd) => gear::delete_gear(&client, cmd).await,
|
||||
|
||||
Commands::Serve(_) => unreachable!("serve command handled earlier"),
|
||||
roasters::run(&client, command).await
|
||||
}
|
||||
Commands::Roast { command } => {
|
||||
let client = BrewlogClient::from_base_url(&cli.api_url)?;
|
||||
roasts::run(&client, command).await
|
||||
}
|
||||
Commands::Bag { command } => {
|
||||
let client = BrewlogClient::from_base_url(&cli.api_url)?;
|
||||
bags::run(&client, command).await
|
||||
}
|
||||
Commands::Gear { command } => {
|
||||
let client = BrewlogClient::from_base_url(&cli.api_url)?;
|
||||
gear::run(&client, command).await
|
||||
}
|
||||
Commands::Token { command } => {
|
||||
let client = BrewlogClient::from_base_url(&cli.api_url)?;
|
||||
tokens::run(&client, command).await
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,35 @@
|
|||
use anyhow::Result;
|
||||
use clap::Args;
|
||||
use clap::{Args, Subcommand};
|
||||
|
||||
use super::macros::{define_delete_command, define_get_command};
|
||||
use super::print_json;
|
||||
use crate::domain::ids::{BagId, RoastId};
|
||||
use crate::infrastructure::client::BrewlogClient;
|
||||
|
||||
#[derive(Debug, Subcommand)]
|
||||
pub enum BagCommands {
|
||||
/// Add a new bag
|
||||
Add(AddBagCommand),
|
||||
/// List all bags
|
||||
List(ListBagsCommand),
|
||||
/// Get a bag by ID
|
||||
Get(GetBagCommand),
|
||||
/// Update a bag
|
||||
Update(UpdateBagCommand),
|
||||
/// Delete a bag
|
||||
Delete(DeleteBagCommand),
|
||||
}
|
||||
|
||||
pub async fn run(client: &BrewlogClient, cmd: BagCommands) -> Result<()> {
|
||||
match cmd {
|
||||
BagCommands::Add(c) => add_bag(client, c).await,
|
||||
BagCommands::List(c) => list_bags(client, c).await,
|
||||
BagCommands::Get(c) => get_bag(client, c).await,
|
||||
BagCommands::Update(c) => update_bag(client, c).await,
|
||||
BagCommands::Delete(c) => delete_bag(client, c).await,
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Args)]
|
||||
pub struct AddBagCommand {
|
||||
#[arg(long)]
|
||||
|
|
|
|||
|
|
@ -1,11 +1,35 @@
|
|||
use anyhow::Result;
|
||||
use clap::Args;
|
||||
use clap::{Args, Subcommand};
|
||||
|
||||
use super::macros::{define_delete_command, define_get_command};
|
||||
use super::print_json;
|
||||
use crate::domain::ids::GearId;
|
||||
use crate::infrastructure::client::BrewlogClient;
|
||||
|
||||
#[derive(Debug, Subcommand)]
|
||||
pub enum GearCommands {
|
||||
/// Add new gear
|
||||
Add(AddGearCommand),
|
||||
/// List all gear
|
||||
List(ListGearCommand),
|
||||
/// Get gear by ID
|
||||
Get(GetGearCommand),
|
||||
/// Update gear
|
||||
Update(UpdateGearCommand),
|
||||
/// Delete gear
|
||||
Delete(DeleteGearCommand),
|
||||
}
|
||||
|
||||
pub async fn run(client: &BrewlogClient, cmd: GearCommands) -> Result<()> {
|
||||
match cmd {
|
||||
GearCommands::Add(c) => add_gear(client, c).await,
|
||||
GearCommands::List(c) => list_gear(client, c).await,
|
||||
GearCommands::Get(c) => get_gear(client, c).await,
|
||||
GearCommands::Update(c) => update_gear(client, c).await,
|
||||
GearCommands::Delete(c) => delete_gear(client, c).await,
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Args)]
|
||||
pub struct AddGearCommand {
|
||||
#[arg(long)]
|
||||
|
|
|
|||
|
|
@ -7,12 +7,12 @@ pub mod tokens;
|
|||
|
||||
use std::net::SocketAddr;
|
||||
|
||||
use bags::{AddBagCommand, DeleteBagCommand, GetBagCommand, ListBagsCommand, UpdateBagCommand};
|
||||
use bags::BagCommands;
|
||||
use clap::{Args, Parser, Subcommand};
|
||||
use gear::{AddGearCommand, DeleteGearCommand, GetGearCommand, ListGearCommand, UpdateGearCommand};
|
||||
use roasters::{AddRoasterCommand, DeleteRoasterCommand, GetRoasterCommand, UpdateRoasterCommand};
|
||||
use roasts::{AddRoastCommand, DeleteRoastCommand, GetRoastCommand, ListRoastsCommand};
|
||||
use tokens::{CreateTokenCommand, RevokeTokenCommand};
|
||||
use gear::GearCommands;
|
||||
use roasters::RoasterCommands;
|
||||
use roasts::RoastCommands;
|
||||
use tokens::TokenCommands;
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
#[command(author, version, about = "Track coffee roasts, brews, and cups", long_about = None)]
|
||||
|
|
@ -31,62 +31,38 @@ pub struct Cli {
|
|||
|
||||
#[derive(Debug, Subcommand)]
|
||||
pub enum Commands {
|
||||
#[command(name = "serve")]
|
||||
/// Run the HTTP server
|
||||
Serve(ServeCommand),
|
||||
|
||||
// Tokens
|
||||
#[command(name = "create-token")]
|
||||
CreateToken(CreateTokenCommand),
|
||||
#[command(name = "list-tokens")]
|
||||
ListTokens,
|
||||
#[command(name = "revoke-token")]
|
||||
RevokeToken(RevokeTokenCommand),
|
||||
/// Manage roasters
|
||||
Roaster {
|
||||
#[command(subcommand)]
|
||||
command: RoasterCommands,
|
||||
},
|
||||
|
||||
// Roasters
|
||||
#[command(name = "add-roaster")]
|
||||
AddRoaster(AddRoasterCommand),
|
||||
#[command(name = "list-roasters")]
|
||||
ListRoasters,
|
||||
#[command(name = "get-roaster")]
|
||||
GetRoaster(GetRoasterCommand),
|
||||
#[command(name = "update-roaster")]
|
||||
UpdateRoaster(UpdateRoasterCommand),
|
||||
#[command(name = "delete-roaster")]
|
||||
DeleteRoaster(DeleteRoasterCommand),
|
||||
/// Manage roasts
|
||||
Roast {
|
||||
#[command(subcommand)]
|
||||
command: RoastCommands,
|
||||
},
|
||||
|
||||
// Roasts
|
||||
#[command(name = "add-roast")]
|
||||
AddRoast(AddRoastCommand),
|
||||
#[command(name = "list-roasts")]
|
||||
ListRoasts(ListRoastsCommand),
|
||||
#[command(name = "get-roast")]
|
||||
GetRoast(GetRoastCommand),
|
||||
#[command(name = "delete-roast")]
|
||||
DeleteRoast(DeleteRoastCommand),
|
||||
/// Manage bags
|
||||
Bag {
|
||||
#[command(subcommand)]
|
||||
command: BagCommands,
|
||||
},
|
||||
|
||||
// Bags
|
||||
#[command(name = "add-bag")]
|
||||
AddBag(AddBagCommand),
|
||||
#[command(name = "list-bags")]
|
||||
ListBags(ListBagsCommand),
|
||||
#[command(name = "get-bag")]
|
||||
GetBag(GetBagCommand),
|
||||
#[command(name = "update-bag")]
|
||||
UpdateBag(UpdateBagCommand),
|
||||
#[command(name = "delete-bag")]
|
||||
DeleteBag(DeleteBagCommand),
|
||||
/// Manage gear
|
||||
Gear {
|
||||
#[command(subcommand)]
|
||||
command: GearCommands,
|
||||
},
|
||||
|
||||
// Gear
|
||||
#[command(name = "add-gear")]
|
||||
AddGear(AddGearCommand),
|
||||
#[command(name = "list-gear")]
|
||||
ListGear(ListGearCommand),
|
||||
#[command(name = "get-gear")]
|
||||
GetGear(GetGearCommand),
|
||||
#[command(name = "update-gear")]
|
||||
UpdateGear(UpdateGearCommand),
|
||||
#[command(name = "delete-gear")]
|
||||
DeleteGear(DeleteGearCommand),
|
||||
/// Manage API tokens
|
||||
Token {
|
||||
#[command(subcommand)]
|
||||
command: TokenCommands,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Args)]
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use anyhow::Result;
|
||||
use clap::Args;
|
||||
use clap::{Args, Subcommand};
|
||||
|
||||
use super::macros::{define_delete_command, define_get_command};
|
||||
use super::print_json;
|
||||
|
|
@ -7,6 +7,30 @@ use crate::domain::ids::RoasterId;
|
|||
use crate::domain::roasters::{NewRoaster, UpdateRoaster};
|
||||
use crate::infrastructure::client::BrewlogClient;
|
||||
|
||||
#[derive(Debug, Subcommand)]
|
||||
pub enum RoasterCommands {
|
||||
/// Add a new roaster
|
||||
Add(AddRoasterCommand),
|
||||
/// List all roasters
|
||||
List,
|
||||
/// Get a roaster by ID
|
||||
Get(GetRoasterCommand),
|
||||
/// Update a roaster
|
||||
Update(UpdateRoasterCommand),
|
||||
/// Delete a roaster
|
||||
Delete(DeleteRoasterCommand),
|
||||
}
|
||||
|
||||
pub async fn run(client: &BrewlogClient, cmd: RoasterCommands) -> Result<()> {
|
||||
match cmd {
|
||||
RoasterCommands::Add(c) => add_roaster(client, c).await,
|
||||
RoasterCommands::List => list_roasters(client).await,
|
||||
RoasterCommands::Get(c) => get_roaster(client, c).await,
|
||||
RoasterCommands::Update(c) => update_roaster(client, c).await,
|
||||
RoasterCommands::Delete(c) => delete_roaster(client, c).await,
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Args)]
|
||||
pub struct AddRoasterCommand {
|
||||
#[arg(long)]
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use anyhow::Result;
|
||||
use clap::Args;
|
||||
use clap::{Args, Subcommand};
|
||||
|
||||
use super::macros::{define_delete_command, define_get_command};
|
||||
use super::print_json;
|
||||
|
|
@ -7,6 +7,27 @@ use crate::domain::ids::{RoastId, RoasterId};
|
|||
use crate::domain::roasts::NewRoast;
|
||||
use crate::infrastructure::client::BrewlogClient;
|
||||
|
||||
#[derive(Debug, Subcommand)]
|
||||
pub enum RoastCommands {
|
||||
/// Add a new roast
|
||||
Add(AddRoastCommand),
|
||||
/// List all roasts
|
||||
List(ListRoastsCommand),
|
||||
/// Get a roast by ID
|
||||
Get(GetRoastCommand),
|
||||
/// Delete a roast
|
||||
Delete(DeleteRoastCommand),
|
||||
}
|
||||
|
||||
pub async fn run(client: &BrewlogClient, cmd: RoastCommands) -> Result<()> {
|
||||
match cmd {
|
||||
RoastCommands::Add(c) => add_roast(client, c).await,
|
||||
RoastCommands::List(c) => list_roasts(client, c).await,
|
||||
RoastCommands::Get(c) => get_roast(client, c).await,
|
||||
RoastCommands::Delete(c) => delete_roast(client, c).await,
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Args)]
|
||||
pub struct AddRoastCommand {
|
||||
#[arg(long)]
|
||||
|
|
|
|||
|
|
@ -1,11 +1,29 @@
|
|||
use anyhow::{Context, Result};
|
||||
use clap::Args;
|
||||
use clap::{Args, Subcommand};
|
||||
use std::io::{self, Write};
|
||||
|
||||
use super::print_json;
|
||||
use crate::domain::ids::TokenId;
|
||||
use crate::infrastructure::client::BrewlogClient;
|
||||
|
||||
#[derive(Debug, Subcommand)]
|
||||
pub enum TokenCommands {
|
||||
/// Create a new API token
|
||||
Create(CreateTokenCommand),
|
||||
/// List all tokens
|
||||
List,
|
||||
/// Revoke a token
|
||||
Revoke(RevokeTokenCommand),
|
||||
}
|
||||
|
||||
pub async fn run(client: &BrewlogClient, cmd: TokenCommands) -> Result<()> {
|
||||
match cmd {
|
||||
TokenCommands::Create(c) => create_token(client, c).await,
|
||||
TokenCommands::List => list_tokens(client).await,
|
||||
TokenCommands::Revoke(c) => revoke_token(client, c).await,
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Args)]
|
||||
pub struct CreateTokenCommand {
|
||||
/// A descriptive name for this token
|
||||
|
|
|
|||
|
|
@ -5,9 +5,12 @@ use serde_json::Value;
|
|||
fn test_add_bag_requires_authentication() {
|
||||
let _ = server_info();
|
||||
|
||||
let output = run_brewlog(&["add-bag", "--roast-id", "123", "--amount", "250.0"], &[]);
|
||||
let output = run_brewlog(
|
||||
&["bag", "add", "--roast-id", "123", "--amount", "250.0"],
|
||||
&[],
|
||||
);
|
||||
|
||||
assert!(!output.status.success(), "add-bag without auth should fail");
|
||||
assert!(!output.status.success(), "bag add without auth should fail");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -21,7 +24,8 @@ fn test_add_bag_with_authentication() {
|
|||
// Test: Add Bag
|
||||
let output = run_brewlog(
|
||||
&[
|
||||
"add-bag",
|
||||
"bag",
|
||||
"add",
|
||||
"--roast-id",
|
||||
&roast_id,
|
||||
"--amount",
|
||||
|
|
@ -44,11 +48,14 @@ fn test_add_bag_with_authentication() {
|
|||
fn test_update_bag_requires_authentication() {
|
||||
let _ = server_info();
|
||||
|
||||
let output = run_brewlog(&["update-bag", "--id", "123", "--remaining", "100.0"], &[]);
|
||||
let output = run_brewlog(
|
||||
&["bag", "update", "--id", "123", "--remaining", "100.0"],
|
||||
&[],
|
||||
);
|
||||
|
||||
assert!(
|
||||
!output.status.success(),
|
||||
"update-bag without auth should fail"
|
||||
"bag update without auth should fail"
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -61,7 +68,7 @@ fn test_update_bag_with_authentication() {
|
|||
let roast_id = create_roast(&roaster_id, "Bag Update Roast", &token);
|
||||
|
||||
let bag_output = run_brewlog(
|
||||
&["add-bag", "--roast-id", &roast_id, "--amount", "250.0"],
|
||||
&["bag", "add", "--roast-id", &roast_id, "--amount", "250.0"],
|
||||
&[("BREWLOG_TOKEN", &token)],
|
||||
);
|
||||
let bag: Value = serde_json::from_slice(&bag_output.stdout).unwrap();
|
||||
|
|
@ -70,7 +77,8 @@ fn test_update_bag_with_authentication() {
|
|||
// Test: Update Bag
|
||||
let output = run_brewlog(
|
||||
&[
|
||||
"update-bag",
|
||||
"bag",
|
||||
"update",
|
||||
"--id",
|
||||
&bag_id,
|
||||
"--remaining",
|
||||
|
|
@ -92,7 +100,7 @@ fn test_update_bag_with_authentication() {
|
|||
fn test_list_bags_works_without_authentication() {
|
||||
let _ = server_info();
|
||||
// Listing without roast_id might return all or empty, but should succeed (200 OK)
|
||||
let output = run_brewlog(&["list-bags"], &[]);
|
||||
let output = run_brewlog(&["bag", "list"], &[]);
|
||||
assert!(output.status.success());
|
||||
}
|
||||
|
||||
|
|
@ -105,7 +113,7 @@ fn test_list_bags_shows_added_bag() {
|
|||
let roast_id = create_roast(&roaster_id, "Bag List Roast", &token);
|
||||
|
||||
let bag_output = run_brewlog(
|
||||
&["add-bag", "--roast-id", &roast_id, "--amount", "250.0"],
|
||||
&["bag", "add", "--roast-id", &roast_id, "--amount", "250.0"],
|
||||
&[("BREWLOG_TOKEN", &token)],
|
||||
);
|
||||
let bag: Value = serde_json::from_slice(&bag_output.stdout).unwrap();
|
||||
|
|
@ -113,7 +121,7 @@ fn test_list_bags_shows_added_bag() {
|
|||
|
||||
// Test: List Bags (Authenticated)
|
||||
let output = run_brewlog(
|
||||
&["list-bags", "--roast-id", &roast_id],
|
||||
&["bag", "list", "--roast-id", &roast_id],
|
||||
&[("BREWLOG_TOKEN", &token)],
|
||||
);
|
||||
|
||||
|
|
@ -133,14 +141,14 @@ fn test_list_bags_without_roast_id_shows_all_bags() {
|
|||
let roast_id = create_roast(&roaster_id, "Bag List All Roast", &token);
|
||||
|
||||
let bag_output = run_brewlog(
|
||||
&["add-bag", "--roast-id", &roast_id, "--amount", "250.0"],
|
||||
&["bag", "add", "--roast-id", &roast_id, "--amount", "250.0"],
|
||||
&[("BREWLOG_TOKEN", &token)],
|
||||
);
|
||||
let bag: Value = serde_json::from_slice(&bag_output.stdout).unwrap();
|
||||
let bag_id = bag["id"].as_i64().unwrap();
|
||||
|
||||
// Test: List Bags (Authenticated)
|
||||
let output = run_brewlog(&["list-bags"], &[("BREWLOG_TOKEN", &token)]);
|
||||
let output = run_brewlog(&["bag", "list"], &[("BREWLOG_TOKEN", &token)]);
|
||||
|
||||
assert!(output.status.success());
|
||||
let bags: Value = serde_json::from_slice(&output.stdout).unwrap();
|
||||
|
|
@ -159,7 +167,7 @@ fn test_list_bags_shows_open_and_closed_bags() {
|
|||
|
||||
// Create Open Bag
|
||||
let open_bag_output = run_brewlog(
|
||||
&["add-bag", "--roast-id", &roast_id, "--amount", "250.0"],
|
||||
&["bag", "add", "--roast-id", &roast_id, "--amount", "250.0"],
|
||||
&[("BREWLOG_TOKEN", &token)],
|
||||
);
|
||||
let open_bag: Value = serde_json::from_slice(&open_bag_output.stdout).unwrap();
|
||||
|
|
@ -167,7 +175,7 @@ fn test_list_bags_shows_open_and_closed_bags() {
|
|||
|
||||
// Create Closed Bag
|
||||
let closed_bag_output = run_brewlog(
|
||||
&["add-bag", "--roast-id", &roast_id, "--amount", "250.0"],
|
||||
&["bag", "add", "--roast-id", &roast_id, "--amount", "250.0"],
|
||||
&[("BREWLOG_TOKEN", &token)],
|
||||
);
|
||||
let closed_bag: Value = serde_json::from_slice(&closed_bag_output.stdout).unwrap();
|
||||
|
|
@ -176,7 +184,8 @@ fn test_list_bags_shows_open_and_closed_bags() {
|
|||
// Close the second bag
|
||||
let _ = run_brewlog(
|
||||
&[
|
||||
"update-bag",
|
||||
"bag",
|
||||
"update",
|
||||
"--id",
|
||||
&closed_bag_id.to_string(),
|
||||
"--closed",
|
||||
|
|
@ -186,7 +195,7 @@ fn test_list_bags_shows_open_and_closed_bags() {
|
|||
);
|
||||
|
||||
// Test: List Bags (Authenticated)
|
||||
let output = run_brewlog(&["list-bags"], &[("BREWLOG_TOKEN", &token)]);
|
||||
let output = run_brewlog(&["bag", "list"], &[("BREWLOG_TOKEN", &token)]);
|
||||
|
||||
assert!(output.status.success());
|
||||
let bags: Value = serde_json::from_slice(&output.stdout).unwrap();
|
||||
|
|
@ -210,7 +219,7 @@ fn test_list_bags_shows_open_and_closed_bags() {
|
|||
#[test]
|
||||
fn test_delete_bag_requires_authentication() {
|
||||
let _ = server_info();
|
||||
let output = run_brewlog(&["delete-bag", "--id", "123"], &[]);
|
||||
let output = run_brewlog(&["bag", "delete", "--id", "123"], &[]);
|
||||
assert!(!output.status.success());
|
||||
}
|
||||
|
||||
|
|
@ -223,7 +232,7 @@ fn test_delete_bag_with_authentication() {
|
|||
let roast_id = create_roast(&roaster_id, "Bag Delete Roast", &token);
|
||||
|
||||
let bag_output = run_brewlog(
|
||||
&["add-bag", "--roast-id", &roast_id, "--amount", "250.0"],
|
||||
&["bag", "add", "--roast-id", &roast_id, "--amount", "250.0"],
|
||||
&[("BREWLOG_TOKEN", &token)],
|
||||
);
|
||||
let bag: Value = serde_json::from_slice(&bag_output.stdout).unwrap();
|
||||
|
|
@ -231,12 +240,12 @@ fn test_delete_bag_with_authentication() {
|
|||
|
||||
// Test: Delete Bag
|
||||
let output = run_brewlog(
|
||||
&["delete-bag", "--id", &bag_id],
|
||||
&["bag", "delete", "--id", &bag_id],
|
||||
&[("BREWLOG_TOKEN", &token)],
|
||||
);
|
||||
assert!(output.status.success());
|
||||
|
||||
// Verify deletion
|
||||
let get_output = run_brewlog(&["get-bag", "--id", &bag_id], &[]);
|
||||
let get_output = run_brewlog(&["bag", "get", "--id", &bag_id], &[]);
|
||||
assert!(!get_output.status.success());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@ fn test_add_gear_requires_authentication() {
|
|||
|
||||
let output = run_brewlog(
|
||||
&[
|
||||
"add-gear",
|
||||
"gear",
|
||||
"add",
|
||||
"--category",
|
||||
"grinder",
|
||||
"--make",
|
||||
|
|
@ -20,7 +21,7 @@ fn test_add_gear_requires_authentication() {
|
|||
|
||||
assert!(
|
||||
!output.status.success(),
|
||||
"add-gear without auth should fail"
|
||||
"gear add without auth should fail"
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -30,7 +31,8 @@ fn test_add_gear_with_authentication() {
|
|||
|
||||
let output = run_brewlog(
|
||||
&[
|
||||
"add-gear",
|
||||
"gear",
|
||||
"add",
|
||||
"--category",
|
||||
"grinder",
|
||||
"--make",
|
||||
|
|
@ -54,11 +56,11 @@ fn test_add_gear_with_authentication() {
|
|||
fn test_list_gear_works_without_authentication() {
|
||||
let _ = server_info();
|
||||
|
||||
let output = run_brewlog(&["list-gear"], &[]);
|
||||
let output = run_brewlog(&["gear", "list"], &[]);
|
||||
|
||||
assert!(
|
||||
output.status.success(),
|
||||
"list-gear should work without auth"
|
||||
"gear list should work without auth"
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -69,7 +71,8 @@ fn test_list_gear_shows_added_gear() {
|
|||
// Add gear
|
||||
let add_output = run_brewlog(
|
||||
&[
|
||||
"add-gear",
|
||||
"gear",
|
||||
"add",
|
||||
"--category",
|
||||
"grinder",
|
||||
"--make",
|
||||
|
|
@ -82,7 +85,7 @@ fn test_list_gear_shows_added_gear() {
|
|||
assert!(add_output.status.success());
|
||||
|
||||
// List gear
|
||||
let list_output = run_brewlog(&["list-gear"], &[]);
|
||||
let list_output = run_brewlog(&["gear", "list"], &[]);
|
||||
assert!(list_output.status.success());
|
||||
|
||||
let gear_list: Value = serde_json::from_slice(&list_output.stdout).unwrap();
|
||||
|
|
@ -103,7 +106,8 @@ fn test_list_gear_filtered_by_category() {
|
|||
// Add grinder
|
||||
run_brewlog(
|
||||
&[
|
||||
"add-gear",
|
||||
"gear",
|
||||
"add",
|
||||
"--category",
|
||||
"grinder",
|
||||
"--make",
|
||||
|
|
@ -117,7 +121,8 @@ fn test_list_gear_filtered_by_category() {
|
|||
// Add brewer
|
||||
run_brewlog(
|
||||
&[
|
||||
"add-gear",
|
||||
"gear",
|
||||
"add",
|
||||
"--category",
|
||||
"brewer",
|
||||
"--make",
|
||||
|
|
@ -129,7 +134,7 @@ fn test_list_gear_filtered_by_category() {
|
|||
);
|
||||
|
||||
// List only grinders
|
||||
let output = run_brewlog(&["list-gear", "--category", "grinder"], &[]);
|
||||
let output = run_brewlog(&["gear", "list", "--category", "grinder"], &[]);
|
||||
assert!(output.status.success());
|
||||
|
||||
let gear_list: Value = serde_json::from_slice(&output.stdout).unwrap();
|
||||
|
|
@ -151,7 +156,8 @@ fn test_get_gear_by_id() {
|
|||
// Add gear
|
||||
let add_output = run_brewlog(
|
||||
&[
|
||||
"add-gear",
|
||||
"gear",
|
||||
"add",
|
||||
"--category",
|
||||
"grinder",
|
||||
"--make",
|
||||
|
|
@ -165,7 +171,7 @@ fn test_get_gear_by_id() {
|
|||
let gear_id = gear["id"].as_i64().unwrap().to_string();
|
||||
|
||||
// Get gear by ID
|
||||
let output = run_brewlog(&["get-gear", "--id", &gear_id], &[]);
|
||||
let output = run_brewlog(&["gear", "get", "--id", &gear_id], &[]);
|
||||
assert!(output.status.success());
|
||||
|
||||
let retrieved_gear: Value = serde_json::from_slice(&output.stdout).unwrap();
|
||||
|
|
@ -177,11 +183,11 @@ fn test_get_gear_by_id() {
|
|||
fn test_update_gear_requires_authentication() {
|
||||
let _ = server_info();
|
||||
|
||||
let output = run_brewlog(&["update-gear", "--id", "123", "--make", "Updated"], &[]);
|
||||
let output = run_brewlog(&["gear", "update", "--id", "123", "--make", "Updated"], &[]);
|
||||
|
||||
assert!(
|
||||
!output.status.success(),
|
||||
"update-gear without auth should fail"
|
||||
"gear update without auth should fail"
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -192,7 +198,8 @@ fn test_update_gear_with_authentication() {
|
|||
// Add gear
|
||||
let add_output = run_brewlog(
|
||||
&[
|
||||
"add-gear",
|
||||
"gear",
|
||||
"add",
|
||||
"--category",
|
||||
"grinder",
|
||||
"--make",
|
||||
|
|
@ -207,7 +214,7 @@ fn test_update_gear_with_authentication() {
|
|||
|
||||
// Update gear
|
||||
let output = run_brewlog(
|
||||
&["update-gear", "--id", &gear_id, "--model", "Mini II"],
|
||||
&["gear", "update", "--id", &gear_id, "--model", "Mini II"],
|
||||
&[("BREWLOG_TOKEN", &token)],
|
||||
);
|
||||
|
||||
|
|
@ -221,11 +228,11 @@ fn test_update_gear_with_authentication() {
|
|||
fn test_delete_gear_requires_authentication() {
|
||||
let _ = server_info();
|
||||
|
||||
let output = run_brewlog(&["delete-gear", "--id", "123"], &[]);
|
||||
let output = run_brewlog(&["gear", "delete", "--id", "123"], &[]);
|
||||
|
||||
assert!(
|
||||
!output.status.success(),
|
||||
"delete-gear without auth should fail"
|
||||
"gear delete without auth should fail"
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -236,7 +243,8 @@ fn test_delete_gear_with_authentication() {
|
|||
// Add gear
|
||||
let add_output = run_brewlog(
|
||||
&[
|
||||
"add-gear",
|
||||
"gear",
|
||||
"add",
|
||||
"--category",
|
||||
"grinder",
|
||||
"--make",
|
||||
|
|
@ -251,12 +259,12 @@ fn test_delete_gear_with_authentication() {
|
|||
|
||||
// Delete gear
|
||||
let delete_output = run_brewlog(
|
||||
&["delete-gear", "--id", &gear_id],
|
||||
&["gear", "delete", "--id", &gear_id],
|
||||
&[("BREWLOG_TOKEN", &token)],
|
||||
);
|
||||
assert!(delete_output.status.success());
|
||||
|
||||
// Verify deletion - get should fail
|
||||
let get_output = run_brewlog(&["get-gear", "--id", &gear_id], &[]);
|
||||
let get_output = run_brewlog(&["gear", "get", "--id", &gear_id], &[]);
|
||||
assert!(!get_output.status.success());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -119,7 +119,8 @@ pub fn create_token(name: &str) -> String {
|
|||
|
||||
let output = run_brewlog(
|
||||
&[
|
||||
"create-token",
|
||||
"token",
|
||||
"create",
|
||||
"--name",
|
||||
name,
|
||||
"--username",
|
||||
|
|
@ -165,7 +166,7 @@ pub fn run_brewlog(args: &[&str], env: &[(&str, &str)]) -> std::process::Output
|
|||
/// Helper to create a roaster and return its ID
|
||||
pub fn create_roaster(name: &str, token: &str) -> String {
|
||||
let output = run_brewlog(
|
||||
&["add-roaster", "--name", name, "--country", "UK"],
|
||||
&["roaster", "add", "--name", name, "--country", "UK"],
|
||||
&[("BREWLOG_TOKEN", token)],
|
||||
);
|
||||
|
||||
|
|
@ -189,7 +190,8 @@ pub fn create_roaster(name: &str, token: &str) -> String {
|
|||
pub fn create_roast(roaster_id: &str, name: &str, token: &str) -> String {
|
||||
let output = run_brewlog(
|
||||
&[
|
||||
"add-roast",
|
||||
"roast",
|
||||
"add",
|
||||
"--roaster-id",
|
||||
roaster_id,
|
||||
"--name",
|
||||
|
|
|
|||
|
|
@ -6,13 +6,20 @@ fn test_add_roaster_requires_authentication() {
|
|||
let _ = server_info(); // Ensure server is started
|
||||
|
||||
let output = run_brewlog(
|
||||
&["add-roaster", "--name", "Test Roasters", "--country", "UK"],
|
||||
&[
|
||||
"roaster",
|
||||
"add",
|
||||
"--name",
|
||||
"Test Roasters",
|
||||
"--country",
|
||||
"UK",
|
||||
],
|
||||
&[],
|
||||
);
|
||||
|
||||
assert!(
|
||||
!output.status.success(),
|
||||
"add-roaster without auth should fail"
|
||||
"roaster add without auth should fail"
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -21,13 +28,20 @@ fn test_add_roaster_with_authentication() {
|
|||
let token = create_token("test-add-roaster");
|
||||
|
||||
let output = run_brewlog(
|
||||
&["add-roaster", "--name", "Test Roasters", "--country", "UK"],
|
||||
&[
|
||||
"roaster",
|
||||
"add",
|
||||
"--name",
|
||||
"Test Roasters",
|
||||
"--country",
|
||||
"UK",
|
||||
],
|
||||
&[("BREWLOG_TOKEN", &token)],
|
||||
);
|
||||
|
||||
assert!(
|
||||
output.status.success(),
|
||||
"add-roaster with auth should succeed: {}",
|
||||
"roaster add with auth should succeed: {}",
|
||||
String::from_utf8_lossy(&output.stderr)
|
||||
);
|
||||
|
||||
|
|
@ -44,11 +58,11 @@ fn test_add_roaster_with_authentication() {
|
|||
fn test_list_roasters_works_without_authentication() {
|
||||
let _ = server_info();
|
||||
|
||||
let output = run_brewlog(&["list-roasters"], &[]);
|
||||
let output = run_brewlog(&["roaster", "list"], &[]);
|
||||
|
||||
assert!(
|
||||
output.status.success(),
|
||||
"list-roasters should work without auth"
|
||||
"roaster list should work without auth"
|
||||
);
|
||||
|
||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
||||
|
|
@ -65,7 +79,7 @@ fn test_list_roasters_shows_added_roaster() {
|
|||
let roaster_id = create_roaster("Example Roasters", &token);
|
||||
|
||||
// List roasters
|
||||
let list_output = run_brewlog(&["list-roasters"], &[]);
|
||||
let list_output = run_brewlog(&["roaster", "list"], &[]);
|
||||
|
||||
assert!(list_output.status.success());
|
||||
|
||||
|
|
@ -87,11 +101,11 @@ fn test_list_roasters_shows_added_roaster() {
|
|||
fn test_delete_roaster_requires_authentication() {
|
||||
let _ = server_info();
|
||||
|
||||
let output = run_brewlog(&["delete-roaster", "--id", "some-id"], &[]);
|
||||
let output = run_brewlog(&["roaster", "delete", "--id", "some-id"], &[]);
|
||||
|
||||
assert!(
|
||||
!output.status.success(),
|
||||
"delete-roaster without auth should fail"
|
||||
"roaster delete without auth should fail"
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -101,7 +115,8 @@ fn test_update_roaster_requires_authentication() {
|
|||
|
||||
let output = run_brewlog(
|
||||
&[
|
||||
"update-roaster",
|
||||
"roaster",
|
||||
"update",
|
||||
"--id",
|
||||
"some-id",
|
||||
"--name",
|
||||
|
|
@ -112,6 +127,6 @@ fn test_update_roaster_requires_authentication() {
|
|||
|
||||
assert!(
|
||||
!output.status.success(),
|
||||
"update-roaster without auth should fail"
|
||||
"roaster update without auth should fail"
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@ fn test_add_roast_requires_authentication() {
|
|||
|
||||
let output = run_brewlog(
|
||||
&[
|
||||
"add-roast",
|
||||
"roast",
|
||||
"add",
|
||||
"--roaster-id",
|
||||
"some-id",
|
||||
"--name",
|
||||
|
|
@ -26,7 +27,7 @@ fn test_add_roast_requires_authentication() {
|
|||
|
||||
assert!(
|
||||
!output.status.success(),
|
||||
"add-roast without auth should fail"
|
||||
"roast add without auth should fail"
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -40,7 +41,8 @@ fn test_add_roast_with_authentication() {
|
|||
// Now add a roast
|
||||
let output = run_brewlog(
|
||||
&[
|
||||
"add-roast",
|
||||
"roast",
|
||||
"add",
|
||||
"--roaster-id",
|
||||
&roaster_id,
|
||||
"--name",
|
||||
|
|
@ -61,7 +63,7 @@ fn test_add_roast_with_authentication() {
|
|||
|
||||
assert!(
|
||||
output.status.success(),
|
||||
"add-roast with auth should succeed: {}",
|
||||
"roast add with auth should succeed: {}",
|
||||
String::from_utf8_lossy(&output.stderr)
|
||||
);
|
||||
|
||||
|
|
@ -80,11 +82,11 @@ fn test_add_roast_with_authentication() {
|
|||
fn test_list_roasts_works_without_authentication() {
|
||||
let _ = server_info();
|
||||
|
||||
let output = run_brewlog(&["list-roasts"], &[]);
|
||||
let output = run_brewlog(&["roast", "list"], &[]);
|
||||
|
||||
assert!(
|
||||
output.status.success(),
|
||||
"list-roasts should work without auth"
|
||||
"roast list should work without auth"
|
||||
);
|
||||
|
||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
||||
|
|
@ -103,7 +105,8 @@ fn test_list_roasts_shows_added_roast() {
|
|||
// Add a roast
|
||||
let add_output = run_brewlog(
|
||||
&[
|
||||
"add-roast",
|
||||
"roast",
|
||||
"add",
|
||||
"--roaster-id",
|
||||
&roaster_id,
|
||||
"--name",
|
||||
|
|
@ -131,7 +134,7 @@ fn test_list_roasts_shows_added_roast() {
|
|||
.expect("roast id should be numeric");
|
||||
|
||||
// List roasts
|
||||
let list_output = run_brewlog(&["list-roasts"], &[]);
|
||||
let list_output = run_brewlog(&["roast", "list"], &[]);
|
||||
|
||||
assert!(list_output.status.success());
|
||||
|
||||
|
|
@ -157,10 +160,10 @@ fn test_list_roasts_shows_added_roast() {
|
|||
fn test_delete_roast_requires_authentication() {
|
||||
let _ = server_info();
|
||||
|
||||
let output = run_brewlog(&["delete-roast", "--id", "some-id"], &[]);
|
||||
let output = run_brewlog(&["roast", "delete", "--id", "some-id"], &[]);
|
||||
|
||||
assert!(
|
||||
!output.status.success(),
|
||||
"delete-roast without auth should fail"
|
||||
"roast delete without auth should fail"
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,11 +4,11 @@ use crate::helpers::{create_token, run_brewlog, server_info};
|
|||
fn test_list_tokens_requires_authentication() {
|
||||
let _ = server_info();
|
||||
|
||||
let output = run_brewlog(&["list-tokens"], &[]);
|
||||
let output = run_brewlog(&["token", "list"], &[]);
|
||||
|
||||
assert!(
|
||||
!output.status.success(),
|
||||
"list-tokens without auth should fail"
|
||||
"token list without auth should fail"
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -16,11 +16,11 @@ fn test_list_tokens_requires_authentication() {
|
|||
fn test_list_tokens_with_authentication() {
|
||||
let token = create_token("test-list-tokens");
|
||||
|
||||
let output = run_brewlog(&["list-tokens"], &[("BREWLOG_TOKEN", &token)]);
|
||||
let output = run_brewlog(&["token", "list"], &[("BREWLOG_TOKEN", &token)]);
|
||||
|
||||
assert!(
|
||||
output.status.success(),
|
||||
"list-tokens with auth should succeed"
|
||||
"token list with auth should succeed"
|
||||
);
|
||||
|
||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
||||
|
|
@ -34,11 +34,11 @@ fn test_list_tokens_with_authentication() {
|
|||
fn test_revoke_token_requires_authentication() {
|
||||
let _ = server_info();
|
||||
|
||||
let output = run_brewlog(&["revoke-token", "--id", "1"], &[]);
|
||||
let output = run_brewlog(&["token", "revoke", "--id", "1"], &[]);
|
||||
|
||||
assert!(
|
||||
!output.status.success(),
|
||||
"revoke-token without auth should fail"
|
||||
"token revoke without auth should fail"
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -47,7 +47,7 @@ fn test_revoke_token_with_authentication() {
|
|||
let token = create_token("test-revoke-token");
|
||||
|
||||
// List tokens to get the ID
|
||||
let list_output = run_brewlog(&["list-tokens"], &[("BREWLOG_TOKEN", &token)]);
|
||||
let list_output = run_brewlog(&["token", "list"], &[("BREWLOG_TOKEN", &token)]);
|
||||
assert!(list_output.status.success());
|
||||
|
||||
let list_stdout = String::from_utf8_lossy(&list_output.stdout);
|
||||
|
|
@ -66,7 +66,7 @@ fn test_revoke_token_with_authentication() {
|
|||
.expect("Token should have ID");
|
||||
|
||||
let revoke_output = run_brewlog(
|
||||
&["revoke-token", "--id", &token_id.to_string()],
|
||||
&["token", "revoke", "--id", &token_id.to_string()],
|
||||
&[("BREWLOG_TOKEN", &token)],
|
||||
);
|
||||
|
||||
|
|
@ -85,7 +85,7 @@ fn test_revoked_token_cannot_be_used() {
|
|||
let admin_token = create_token("test-admin-token");
|
||||
|
||||
// List tokens to get the ID of the token we want to revoke
|
||||
let list_output = run_brewlog(&["list-tokens"], &[("BREWLOG_TOKEN", &admin_token)]);
|
||||
let list_output = run_brewlog(&["token", "list"], &[("BREWLOG_TOKEN", &admin_token)]);
|
||||
assert!(list_output.status.success());
|
||||
|
||||
let list_stdout = String::from_utf8_lossy(&list_output.stdout);
|
||||
|
|
@ -105,7 +105,7 @@ fn test_revoked_token_cannot_be_used() {
|
|||
|
||||
// Revoke the token
|
||||
let revoke_output = run_brewlog(
|
||||
&["revoke-token", "--id", &token_id.to_string()],
|
||||
&["token", "revoke", "--id", &token_id.to_string()],
|
||||
&[("BREWLOG_TOKEN", &admin_token)],
|
||||
);
|
||||
assert!(
|
||||
|
|
@ -115,7 +115,7 @@ fn test_revoked_token_cannot_be_used() {
|
|||
|
||||
// Try to use the revoked token - it should fail
|
||||
let list_with_revoked_output =
|
||||
run_brewlog(&["list-tokens"], &[("BREWLOG_TOKEN", &token_to_revoke)]);
|
||||
run_brewlog(&["token", "list"], &[("BREWLOG_TOKEN", &token_to_revoke)]);
|
||||
|
||||
assert!(
|
||||
!list_with_revoked_output.status.success(),
|
||||
|
|
|
|||
Loading…
Reference in a new issue