cascade_cli/config/
mod.rs

1pub mod auth;
2pub mod settings;
3
4pub use auth::{AuthConfig, AuthManager};
5pub use settings::{BitbucketConfig, CascadeConfig, CascadeSettings, GitConfig, Settings};
6
7use crate::errors::{CascadeError, Result};
8use std::fs;
9use std::path::{Path, PathBuf};
10
11/// Get the Cascade configuration directory (~/.cascade/)
12pub fn get_config_dir() -> Result<PathBuf> {
13    let home_dir =
14        dirs::home_dir().ok_or_else(|| CascadeError::config("Could not find home directory"))?;
15    let config_dir = home_dir.join(".cascade");
16
17    // Validate the path to ensure it's within the home directory
18    crate::utils::path_validation::validate_config_path(&config_dir, &home_dir)
19}
20
21/// Get the Cascade configuration directory for a specific repository
22pub fn get_repo_config_dir(repo_path: &Path) -> Result<PathBuf> {
23    // Validate that repo_path is a real directory
24    let canonical_repo = repo_path.canonicalize().map_err(|e| {
25        CascadeError::config(format!("Invalid repository path '{repo_path:?}': {e}"))
26    })?;
27
28    let config_dir = canonical_repo.join(".cascade");
29
30    // Validate that config dir would be within the repo directory
31    crate::utils::path_validation::validate_config_path(&config_dir, &canonical_repo)
32}
33
34/// Ensure the configuration directory exists
35pub fn ensure_config_dir(config_dir: &Path) -> Result<()> {
36    if !config_dir.exists() {
37        fs::create_dir_all(config_dir)
38            .map_err(|e| CascadeError::config(format!("Failed to create config directory: {e}")))?;
39    }
40
41    // Create subdirectories
42    let stacks_dir = config_dir.join("stacks");
43    if !stacks_dir.exists() {
44        fs::create_dir_all(&stacks_dir)
45            .map_err(|e| CascadeError::config(format!("Failed to create stacks directory: {e}")))?;
46    }
47
48    let cache_dir = config_dir.join("cache");
49    if !cache_dir.exists() {
50        fs::create_dir_all(&cache_dir)
51            .map_err(|e| CascadeError::config(format!("Failed to create cache directory: {e}")))?;
52    }
53
54    Ok(())
55}
56
57/// Check if a repository is initialized for Cascade
58pub fn is_repo_initialized(repo_path: &Path) -> bool {
59    let config_dir = repo_path.join(".cascade");
60    config_dir.exists() && config_dir.join("config.json").exists()
61}
62
63/// Initialize a repository for Cascade
64pub fn initialize_repo(repo_path: &Path, bitbucket_url: Option<String>) -> Result<()> {
65    let config_dir = get_repo_config_dir(repo_path)?;
66    ensure_config_dir(&config_dir)?;
67
68    // Create default configuration
69    let settings = Settings::default_for_repo(bitbucket_url);
70    settings.save_to_file(&config_dir.join("config.json"))?;
71
72    tracing::info!("Initialized Cascade repository at {}", repo_path.display());
73    Ok(())
74}