feat(cli): add Gear CLI commands
Implement complete CLI interface for managing gear via brewlog CLI. Commands (presentation/cli/gear.rs): - add-gear: Create gear with --category, --make, --model, --notes flags - list-gear: List all gear with optional --category filter - get-gear: Retrieve single gear by --id - update-gear: Update gear fields (make, model, notes) - delete-gear: Delete gear by --id Uses define_get_command! and define_delete_command! macros for get/delete operations to reduce boilerplate. Command Registration: - Register gear module in presentation/cli/mod.rs - Add commands to Commands enum: AddGear, ListGear, GetGear, UpdateGear, DeleteGear - Wire command execution in main.rs All commands output JSON and use BrewlogClient for HTTP API calls. Examples: brewlog add-gear --category grinder --make Baratza --model Encore brewlog list-gear --category brewer brewlog update-gear --id 1 --notes "Updated notes"
This commit is contained in:
parent
1ef447157e
commit
1f5561d7ab
3 changed files with 91 additions and 1 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use brewlog::application::{ServerConfig, serve};
|
use brewlog::application::{ServerConfig, serve};
|
||||||
use brewlog::infrastructure::client::BrewlogClient;
|
use brewlog::infrastructure::client::BrewlogClient;
|
||||||
use brewlog::presentation::cli::{Cli, Commands, ServeCommand, bags, roasters, roasts, tokens};
|
use brewlog::presentation::cli::{Cli, Commands, ServeCommand, bags, gear, roasters, roasts, tokens};
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
|
|
||||||
use tracing::{Subscriber, subscriber::set_global_default};
|
use tracing::{Subscriber, subscriber::set_global_default};
|
||||||
|
|
@ -47,6 +47,13 @@ async fn main() -> Result<()> {
|
||||||
Commands::UpdateBag(cmd) => bags::update_bag(&client, cmd).await,
|
Commands::UpdateBag(cmd) => bags::update_bag(&client, cmd).await,
|
||||||
Commands::DeleteBag(cmd) => bags::delete_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"),
|
Commands::Serve(_) => unreachable!("serve command handled earlier"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
67
src/presentation/cli/gear.rs
Normal file
67
src/presentation/cli/gear.rs
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
use anyhow::Result;
|
||||||
|
use clap::Args;
|
||||||
|
|
||||||
|
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, Args)]
|
||||||
|
pub struct AddGearCommand {
|
||||||
|
#[arg(long)]
|
||||||
|
pub category: String,
|
||||||
|
#[arg(long)]
|
||||||
|
pub make: String,
|
||||||
|
#[arg(long)]
|
||||||
|
pub model: String,
|
||||||
|
#[arg(long)]
|
||||||
|
pub notes: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn add_gear(client: &BrewlogClient, command: AddGearCommand) -> Result<()> {
|
||||||
|
let gear = client
|
||||||
|
.gear()
|
||||||
|
.create(&command.category, command.make, command.model, command.notes)
|
||||||
|
.await?;
|
||||||
|
print_json(&gear)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Args)]
|
||||||
|
pub struct ListGearCommand {
|
||||||
|
#[arg(long)]
|
||||||
|
pub category: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn list_gear(client: &BrewlogClient, command: ListGearCommand) -> Result<()> {
|
||||||
|
let gear = client.gear().list(command.category).await?;
|
||||||
|
print_json(&gear)
|
||||||
|
}
|
||||||
|
|
||||||
|
define_get_command!(GetGearCommand, get_gear, GearId, gear);
|
||||||
|
|
||||||
|
#[derive(Debug, Args)]
|
||||||
|
pub struct UpdateGearCommand {
|
||||||
|
#[arg(long)]
|
||||||
|
pub id: i64,
|
||||||
|
#[arg(long)]
|
||||||
|
pub make: Option<String>,
|
||||||
|
#[arg(long)]
|
||||||
|
pub model: Option<String>,
|
||||||
|
#[arg(long)]
|
||||||
|
pub notes: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn update_gear(client: &BrewlogClient, command: UpdateGearCommand) -> Result<()> {
|
||||||
|
let gear = client
|
||||||
|
.gear()
|
||||||
|
.update(
|
||||||
|
GearId::new(command.id),
|
||||||
|
command.make,
|
||||||
|
command.model,
|
||||||
|
command.notes,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
print_json(&gear)
|
||||||
|
}
|
||||||
|
|
||||||
|
define_delete_command!(DeleteGearCommand, delete_gear, GearId, gear, "gear");
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
pub mod bags;
|
pub mod bags;
|
||||||
|
pub mod gear;
|
||||||
mod macros;
|
mod macros;
|
||||||
pub mod roasters;
|
pub mod roasters;
|
||||||
pub mod roasts;
|
pub mod roasts;
|
||||||
|
|
@ -8,6 +9,9 @@ use std::net::SocketAddr;
|
||||||
|
|
||||||
use bags::{AddBagCommand, DeleteBagCommand, GetBagCommand, ListBagsCommand, UpdateBagCommand};
|
use bags::{AddBagCommand, DeleteBagCommand, GetBagCommand, ListBagsCommand, UpdateBagCommand};
|
||||||
use clap::{Args, Parser, Subcommand};
|
use clap::{Args, Parser, Subcommand};
|
||||||
|
use gear::{
|
||||||
|
AddGearCommand, DeleteGearCommand, GetGearCommand, ListGearCommand, UpdateGearCommand,
|
||||||
|
};
|
||||||
use roasters::{AddRoasterCommand, DeleteRoasterCommand, GetRoasterCommand, UpdateRoasterCommand};
|
use roasters::{AddRoasterCommand, DeleteRoasterCommand, GetRoasterCommand, UpdateRoasterCommand};
|
||||||
use roasts::{AddRoastCommand, DeleteRoastCommand, GetRoastCommand, ListRoastsCommand};
|
use roasts::{AddRoastCommand, DeleteRoastCommand, GetRoastCommand, ListRoastsCommand};
|
||||||
use tokens::{CreateTokenCommand, RevokeTokenCommand};
|
use tokens::{CreateTokenCommand, RevokeTokenCommand};
|
||||||
|
|
@ -73,6 +77,18 @@ pub enum Commands {
|
||||||
UpdateBag(UpdateBagCommand),
|
UpdateBag(UpdateBagCommand),
|
||||||
#[command(name = "delete-bag")]
|
#[command(name = "delete-bag")]
|
||||||
DeleteBag(DeleteBagCommand),
|
DeleteBag(DeleteBagCommand),
|
||||||
|
|
||||||
|
// 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),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Args)]
|
#[derive(Debug, Args)]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue