summaryrefslogtreecommitdiff
path: root/makima/src/daemon/cli/config.rs
diff options
context:
space:
mode:
Diffstat (limited to 'makima/src/daemon/cli/config.rs')
-rw-r--r--makima/src/daemon/cli/config.rs128
1 files changed, 128 insertions, 0 deletions
diff --git a/makima/src/daemon/cli/config.rs b/makima/src/daemon/cli/config.rs
new file mode 100644
index 0000000..8199b88
--- /dev/null
+++ b/makima/src/daemon/cli/config.rs
@@ -0,0 +1,128 @@
+//! CLI configuration management.
+//!
+//! Handles loading and saving CLI configuration from ~/.makima/config.toml.
+//! This is separate from daemon configuration and is used for interactive CLI commands.
+
+use clap::Args;
+use serde::{Deserialize, Serialize};
+use std::fs;
+use std::path::PathBuf;
+
+/// Arguments for setting the API key
+#[derive(Args, Debug, Clone)]
+pub struct SetKeyArgs {
+ /// The API key to save
+ pub api_key: String,
+}
+
+/// Arguments for setting the API URL
+#[derive(Args, Debug, Clone)]
+pub struct SetUrlArgs {
+ /// The API URL to save
+ pub api_url: String,
+}
+
+/// CLI configuration stored in ~/.makima/config.toml
+#[derive(Debug, Clone, Serialize, Deserialize, Default)]
+pub struct CliConfig {
+ /// API URL for the makima server
+ #[serde(default = "default_api_url")]
+ pub api_url: String,
+
+ /// API key for authentication
+ #[serde(default)]
+ pub api_key: Option<String>,
+}
+
+fn default_api_url() -> String {
+ "https://api.makima.jp".to_string()
+}
+
+impl CliConfig {
+ /// Get the config directory path (~/.makima)
+ pub fn config_dir() -> Option<PathBuf> {
+ dirs::home_dir().map(|h| h.join(".makima"))
+ }
+
+ /// Get the config file path (~/.makima/config.toml)
+ pub fn config_path() -> Option<PathBuf> {
+ Self::config_dir().map(|d| d.join("config.toml"))
+ }
+
+ /// Load CLI config from ~/.makima/config.toml
+ /// Returns default config if file doesn't exist
+ pub fn load() -> Self {
+ let Some(path) = Self::config_path() else {
+ return Self::default();
+ };
+
+ if !path.exists() {
+ return Self::default();
+ }
+
+ match fs::read_to_string(&path) {
+ Ok(contents) => {
+ toml::from_str(&contents).unwrap_or_else(|e| {
+ eprintln!("Warning: Failed to parse {}: {}", path.display(), e);
+ Self::default()
+ })
+ }
+ Err(e) => {
+ eprintln!("Warning: Failed to read {}: {}", path.display(), e);
+ Self::default()
+ }
+ }
+ }
+
+ /// Save CLI config to ~/.makima/config.toml
+ pub fn save(&self) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
+ let Some(dir) = Self::config_dir() else {
+ return Err("Could not determine home directory".into());
+ };
+
+ let Some(path) = Self::config_path() else {
+ return Err("Could not determine config path".into());
+ };
+
+ // Create config directory if it doesn't exist
+ if !dir.exists() {
+ fs::create_dir_all(&dir)?;
+ }
+
+ let contents = toml::to_string_pretty(self)
+ .map_err(|e| format!("Failed to serialize config: {}", e))?;
+ fs::write(&path, contents)?;
+
+ Ok(())
+ }
+
+ /// Get API key, preferring environment variable over config file
+ pub fn get_api_key(&self) -> Option<String> {
+ // Environment variable takes precedence
+ if let Ok(key) = std::env::var("MAKIMA_API_KEY") {
+ if !key.is_empty() {
+ return Some(key);
+ }
+ }
+
+ // Fall back to config file
+ self.api_key.clone()
+ }
+
+ /// Get API URL, preferring environment variable over config file
+ pub fn get_api_url(&self) -> String {
+ // Environment variable takes precedence
+ if let Ok(url) = std::env::var("MAKIMA_API_URL") {
+ if !url.is_empty() {
+ return url;
+ }
+ }
+
+ // Fall back to config file, or default if empty
+ if self.api_url.is_empty() {
+ default_api_url()
+ } else {
+ self.api_url.clone()
+ }
+ }
+}