mod client;
mod commands;
mod config;
mod output;
use anyhow::Result;
use clap::{Parser, Subcommand};
use commands::{auth, config as config_cmd, db, env, org, scope};
#[derive(Parser)]
#[command(name = "cinch", version, about, propagate_version = true)]
struct Cli {
#[arg(long, global = true)]
json: bool,
#[arg(long, global = true, env = "CINCH_API_URL")]
api_url: Option<String>,
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
Auth {
#[command(subcommand)]
command: auth::AuthCommands,
},
Db {
#[command(subcommand)]
command: db::DbCommands,
},
Scope {
#[command(subcommand)]
command: scope::ScopeCommands,
},
Org {
#[command(subcommand)]
command: org::OrgCommands,
},
Config {
#[command(subcommand)]
command: Option<config_cmd::ConfigCommands>,
},
Env {
name: String,
#[arg(long)]
scope: Option<String>,
},
Quickstart,
Update,
}
#[tokio::main]
async fn main() -> Result<()> {
let cli = Cli::parse();
let json_output = cli.json;
let result = run(cli).await;
if let Err(ref e) = result {
if json_output {
let err = serde_json::json!({ "error": format!("{e:#}") });
eprintln!("{}", serde_json::to_string_pretty(&err).expect("json serialization failed"));
} else {
eprintln!("{}: {e:#}", colored::Colorize::red("error"));
}
std::process::exit(1);
}
Ok(())
}
async fn run(cli: Cli) -> Result<()> {
let api_url = match cli.api_url {
Some(url) => url,
None => config::resolve_api_url()?,
};
match cli.command {
Commands::Auth { command } => auth::run(command, &api_url, cli.json).await,
Commands::Db { command } => db::run(command, &api_url, cli.json).await,
Commands::Scope { command } => scope::run(command, &api_url, cli.json).await,
Commands::Org { command } => org::run(command, &api_url, cli.json).await,
Commands::Config { command } => config_cmd::run(command, cli.json),
Commands::Env { name, scope } => env::run(&name, scope.as_deref(), &api_url, cli.json).await,
Commands::Quickstart => {
open::that("https://cinchdb.dev/docs/quickstart")?;
println!("Opened quickstart docs in your browser.");
Ok(())
}
Commands::Update => {
println!("Self-update not yet implemented.");
Ok(())
}
}
}