auths_cli/factories/storage.rs
1use std::path::Path;
2
3use auths_core::ports::storage::StorageError;
4use auths_infra_git::GitRepo;
5
6/// Opens an existing Git repository at the given path.
7///
8/// Args:
9/// * `path`: Filesystem path to the repository root.
10///
11/// Usage:
12/// ```ignore
13/// use auths_cli::factories::storage::open_git_repo;
14///
15/// let repo = open_git_repo(Path::new("/home/user/.auths"))?;
16/// ```
17pub fn open_git_repo(path: &Path) -> Result<GitRepo, StorageError> {
18 GitRepo::open(path)
19}
20
21/// Initializes a new Git repository at the given path.
22///
23/// Args:
24/// * `path`: Filesystem path where the repository will be created.
25///
26/// Usage:
27/// ```ignore
28/// let repo = init_git_repo(Path::new("/tmp/new-repo"))?;
29/// ```
30pub fn init_git_repo(path: &Path) -> Result<GitRepo, StorageError> {
31 GitRepo::init(path)
32}
33
34/// Opens an existing Git repository or initializes a new one.
35///
36/// If the path exists and contains a Git repository, opens it.
37/// If the path exists but is not a Git repository, initializes one.
38/// If the path does not exist, creates directories and initializes.
39///
40/// Args:
41/// * `path`: Filesystem path to open or create a repository at.
42///
43/// Usage:
44/// ```ignore
45/// let repo = ensure_git_repo(Path::new("/data/auths"))?;
46/// ```
47pub fn ensure_git_repo(path: &Path) -> Result<GitRepo, StorageError> {
48 if path.exists() {
49 match GitRepo::open(path) {
50 Ok(repo) => Ok(repo),
51 Err(_) => GitRepo::init(path),
52 }
53 } else {
54 std::fs::create_dir_all(path)
55 .map_err(|e| StorageError::Io(format!("failed to create directory: {}", e)))?;
56 GitRepo::init(path)
57 }
58}
59
60/// Discovers a Git repository starting from the given path, walking up parent directories.
61///
62/// Returns the working directory of the discovered repository.
63///
64/// Args:
65/// * `start_path`: Directory to begin searching from.
66///
67/// Usage:
68/// ```ignore
69/// let repo_root = discover_git_repo(Path::new("."))?;
70/// ```
71pub fn discover_git_repo(start_path: &Path) -> Result<std::path::PathBuf, StorageError> {
72 let repo = git2::Repository::discover(start_path)
73 .map_err(|e| StorageError::not_found(format!("no Git repository found: {}", e)))?;
74 let path: &Path = repo
75 .workdir()
76 .or_else(|| repo.path().parent())
77 .ok_or_else(|| StorageError::Io("could not determine repository path".into()))?;
78 Ok(path.to_path_buf())
79}
80
81/// Reads a Git configuration value from the default config.
82///
83/// Args:
84/// * `key`: The Git configuration key (e.g. "gpg.ssh.allowedSignersFile").
85///
86/// Usage:
87/// ```ignore
88/// let value = read_git_config("user.email")?;
89/// ```
90pub fn read_git_config(key: &str) -> Result<Option<String>, StorageError> {
91 let config = git2::Config::open_default()
92 .map_err(|e| StorageError::Io(format!("failed to open git config: {}", e)))?;
93 match config.get_string(key) {
94 Ok(value) => Ok(Some(value)),
95 Err(_) => Ok(None),
96 }
97}