cascade_cli/config/
mod.rs1pub 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 crate::git::GitRepository;
9use std::fs;
10use std::path::{Path, PathBuf};
11
12pub fn get_config_dir() -> Result<PathBuf> {
14 let home_dir =
15 dirs::home_dir().ok_or_else(|| CascadeError::config("Could not find home directory"))?;
16 let config_dir = home_dir.join(".cascade");
17
18 crate::utils::path_validation::validate_config_path(&config_dir, &home_dir)
20}
21
22pub fn get_repo_config_dir(repo_path: &Path) -> Result<PathBuf> {
26 let canonical_repo = repo_path.canonicalize().map_err(|e| {
28 CascadeError::config(format!("Invalid repository path '{repo_path:?}': {e}"))
29 })?;
30
31 let config_dir = canonical_repo.join(".cascade");
32
33 if config_dir.exists() {
35 return crate::utils::path_validation::validate_config_path(&config_dir, &canonical_repo);
36 }
37
38 if let Ok(repo) = git2::Repository::discover(repo_path) {
40 if let Some(main_workdir) = repo.commondir().parent() {
41 let main_canonical = main_workdir
42 .canonicalize()
43 .unwrap_or(main_workdir.to_path_buf());
44 if main_canonical != canonical_repo {
45 let main_config_dir = main_canonical.join(".cascade");
46 if main_config_dir.exists() {
47 return crate::utils::path_validation::validate_config_path(
48 &main_config_dir,
49 &main_canonical,
50 );
51 }
52 }
53 }
54 }
55
56 crate::utils::path_validation::validate_config_path(&config_dir, &canonical_repo)
58}
59
60pub fn ensure_config_dir(config_dir: &Path) -> Result<()> {
62 if !config_dir.exists() {
63 fs::create_dir_all(config_dir)
64 .map_err(|e| CascadeError::config(format!("Failed to create config directory: {e}")))?;
65 }
66
67 let stacks_dir = config_dir.join("stacks");
69 if !stacks_dir.exists() {
70 fs::create_dir_all(&stacks_dir)
71 .map_err(|e| CascadeError::config(format!("Failed to create stacks directory: {e}")))?;
72 }
73
74 let cache_dir = config_dir.join("cache");
75 if !cache_dir.exists() {
76 fs::create_dir_all(&cache_dir)
77 .map_err(|e| CascadeError::config(format!("Failed to create cache directory: {e}")))?;
78 }
79
80 Ok(())
81}
82
83pub fn is_repo_initialized(repo_path: &Path) -> bool {
85 match get_repo_config_dir(repo_path) {
86 Ok(config_dir) => config_dir.exists() && config_dir.join("config.json").exists(),
87 Err(_) => false,
88 }
89}
90
91pub fn initialize_repo(repo_path: &Path, bitbucket_url: Option<String>) -> Result<()> {
93 let config_dir = get_repo_config_dir(repo_path)?;
94 ensure_config_dir(&config_dir)?;
95
96 let mut settings = Settings::default_for_repo(bitbucket_url);
98
99 if let Ok(git_repo) = GitRepository::open(repo_path) {
101 if let Ok(detected_branch) = git_repo.detect_main_branch() {
102 tracing::debug!("Detected default branch: {}", detected_branch);
103 settings.git.default_branch = detected_branch;
104 } else {
105 tracing::debug!(
106 "Could not detect default branch, using fallback: {}",
107 settings.git.default_branch
108 );
109 }
110 } else {
111 tracing::debug!(
112 "Could not open git repository, using fallback default branch: {}",
113 settings.git.default_branch
114 );
115 }
116
117 settings.save_to_file(&config_dir.join("config.json"))?;
118
119 tracing::debug!("Initialized Cascade repository at {}", repo_path.display());
120 Ok(())
121}