use std::path::Path;
use tracing::{warn, Level};
use crate::cli::generator::error::GeneratorResult;
pub fn initialize_git(project_dir: &Path) -> GeneratorResult<()> {
let canonical_path = match project_dir.canonicalize() {
Ok(path) => path,
Err(e) => {
warn!(
target: "generator",
?e,
"Failed to canonicalize project directory path, skipping git init"
);
return Ok(()); }
};
let current_dir = match std::env::current_dir() {
Ok(dir) => dir,
Err(e) => {
warn!(
target: "generator",
?e,
"Failed to get current directory, skipping git init"
);
return Ok(()); }
};
if !canonical_path.starts_with(¤t_dir) {
warn!(
target: "generator",
"Project directory path escapes current directory, skipping git init"
);
return Ok(()); }
let git_init_result = std::process::Command::new("git")
.arg("init")
.arg(project_dir)
.output();
match git_init_result {
Ok(output) => {
if !output.status.success() {
let stderr = String::from_utf8_lossy(&output.stderr);
warn!(
target: "generator",
?stderr,
"Git init failed for project directory"
);
} else {
tracing::event!(Level::INFO, "Git repository initialized");
}
}
Err(e) => {
warn!(
target: "generator",
?e,
"Failed to run git init"
);
}
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use std::fs;
use tempfile::TempDir;
#[test]
fn test_initialize_git_valid_directory() {
let temp_dir = TempDir::new().unwrap();
let project_dir = temp_dir.path();
let result = initialize_git(project_dir);
assert!(result.is_ok());
}
#[test]
fn test_initialize_git_non_existent_directory() {
let temp_dir = TempDir::new().unwrap();
let project_dir = temp_dir.path().join("non-existent");
assert!(initialize_git(&project_dir).is_ok());
}
#[test]
fn test_initialize_git_path_traversal_attempt() {
let temp_dir = TempDir::new().unwrap();
let project_dir = temp_dir.path().join("../../../etc/passwd");
assert!(initialize_git(&project_dir).is_ok());
}
}