vtcode_config/loader/
bootstrap.rs1use std::fs;
2use std::path::{Path, PathBuf};
3
4use anyhow::{Context, Result};
5
6use crate::defaults::ConfigDefaultsProvider;
7
8pub const DEFAULT_GITIGNORE_FILE_NAME: &str = ".vtcodegitignore";
9
10pub fn determine_bootstrap_targets(
13 workspace: &Path,
14 use_home_dir: bool,
15 config_file_name: &str,
16 defaults_provider: &dyn ConfigDefaultsProvider,
17) -> Result<(PathBuf, PathBuf)> {
18 if let (true, Some(home_config_path)) = (
19 use_home_dir,
20 select_home_config_path(defaults_provider, config_file_name),
21 ) {
22 let gitignore_path = gitignore_path_for(&home_config_path);
23 return Ok((home_config_path, gitignore_path));
24 }
25
26 let config_path = workspace.join(config_file_name);
27 let gitignore_path = workspace.join(DEFAULT_GITIGNORE_FILE_NAME);
28 Ok((config_path, gitignore_path))
29}
30
31pub fn gitignore_path_for(config_path: &Path) -> PathBuf {
33 config_path
34 .parent()
35 .map(|parent| parent.join(DEFAULT_GITIGNORE_FILE_NAME))
36 .unwrap_or_else(|| PathBuf::from(DEFAULT_GITIGNORE_FILE_NAME))
37}
38
39pub fn ensure_parent_dir(path: &Path) -> Result<()> {
42 if let Some(parent) = path.parent() {
43 if parent.exists() {
44 return Ok(());
45 }
46
47 fs::create_dir_all(parent)
48 .with_context(|| format!("Failed to create directory: {}", parent.display()))?;
49 }
50
51 Ok(())
52}
53
54pub fn select_home_config_path(
57 defaults_provider: &dyn ConfigDefaultsProvider,
58 config_file_name: &str,
59) -> Option<PathBuf> {
60 let home_paths = defaults_provider.home_config_paths(config_file_name);
61 home_paths
62 .into_iter()
63 .next()
64 .or_else(|| default_home_dir().map(|dir| dir.join(config_file_name)))
65}
66
67pub fn default_home_dir() -> Option<PathBuf> {
70 if let Ok(home) = std::env::var("HOME") {
71 return Some(PathBuf::from(home));
72 }
73
74 if let Ok(userprofile) = std::env::var("USERPROFILE") {
75 return Some(PathBuf::from(userprofile));
76 }
77
78 dirs::home_dir()
79}