feat(config): persist database URL to ~/.config/secrets/config.toml

- Add 'secrets config set-db/show/path' subcommands
- Remove dotenvy and DATABASE_URL env var support
- Config file created with 0600 permission
- Bump version to 0.3.0

Made-with: Cursor
This commit is contained in:
voson
2026-03-18 16:19:11 +08:00
parent e6db23bd6d
commit 9620ff1923
6 changed files with 202 additions and 16 deletions

View File

@@ -1,10 +1,10 @@
mod commands;
mod config;
mod db;
mod models;
use anyhow::Result;
use clap::{Parser, Subcommand};
use dotenvy::dotenv;
#[derive(Parser)]
#[command(
@@ -13,8 +13,8 @@ use dotenvy::dotenv;
about = "Secrets & config manager backed by PostgreSQL"
)]
struct Cli {
/// Database URL (or set DATABASE_URL env var)
#[arg(long, env = "DATABASE_URL", global = true, default_value = "")]
/// Database URL, overrides saved config (one-time override)
#[arg(long, global = true, default_value = "")]
db_url: String,
#[command(subcommand)]
@@ -107,22 +107,44 @@ enum Commands {
#[arg(long = "remove-secret")]
remove_secrets: Vec<String>,
},
/// Manage CLI configuration (database connection, etc.)
Config {
#[command(subcommand)]
action: ConfigAction,
},
}
#[derive(Subcommand)]
enum ConfigAction {
/// Save database URL to config file (~/.config/secrets/config.toml)
SetDb {
/// PostgreSQL connection string
url: String,
},
/// Show current configuration
Show,
/// Print path to config file
Path,
}
#[tokio::main]
async fn main() -> Result<()> {
dotenv().ok();
let cli = Cli::parse();
let db_url = if cli.db_url.is_empty() {
std::env::var("DATABASE_URL").map_err(|_| {
anyhow::anyhow!("DATABASE_URL not set. Use --db-url or set DATABASE_URL env var.")
})?
} else {
cli.db_url.clone()
};
// config 子命令不需要数据库连接,提前处理
if let Commands::Config { action } = &cli.command {
let cmd_action = match action {
ConfigAction::SetDb { url } => {
commands::config::ConfigAction::SetDb { url: url.clone() }
}
ConfigAction::Show => commands::config::ConfigAction::Show,
ConfigAction::Path => commands::config::ConfigAction::Path,
};
return commands::config::run(cmd_action).await;
}
let db_url = config::resolve_db_url(&cli.db_url)?;
let pool = db::create_pool(&db_url).await?;
db::migrate(&pool).await?;
@@ -188,6 +210,7 @@ async fn main() -> Result<()> {
)
.await?;
}
Commands::Config { .. } => unreachable!(),
}
Ok(())