use std::io::{self, Write};
use term_colr::{green, red, yellow};
pub mod objects;
pub mod repository;
pub fn run_command(args: &[String]) -> io::Result<()> {
if args.len() < 2 {
println!("{}", yellow!("Usage: xit <command> [<args>]"));
return Ok(());
}
let command = &args[1];
match command.as_str() {
"init" => {
repository::repo::create_repository();
println!("{}", green!("Initialized empty Xit repository."));
}
"setup" => {
if let Err(e) = interactive_setup() {
println!("{}", red!("Error during setup: {}", e));
} else {
println!("{}", green!("Global user setup successful."));
}
}
"add" => {
if args.len() < 3 {
println!("{}", yellow!("Usage: xit add <file>"));
return Ok(());
}
let file_path = &args[2];
if let Err(e) = repository::add::add(file_path) {
println!("{}", red!("Error: {}", e));
} else {
println!("{}", green!("Added '{}' to the index.", file_path));
}
}
"commit" => {
if args.len() < 4 || args[2] != "-m" {
println!("{}", yellow!("Usage: xit commit -m <message>"));
return Ok(());
}
let message = &args[3];
if let Err(e) = repository::commit::commit(message) {
println!("{}", red!("Error: {}", e));
} else {
println!("{}", green!("Committed changes."));
}
}
"status" => {
if let Err(e) = repository::status::check_status() {
println!("{}", red!("Error: {}", e));
}
}
"diff" => {
if args.len() < 3 {
println!("{}", red!("Usage : xit diff "));
}
}
_ => println!("{}", red!("Unknown command: {}", command)),
}
Ok(())
}
pub fn interactive_setup() -> io::Result<()> {
print!("Enter your name: ");
io::stdout().flush()?;
let mut name = String::new();
io::stdin().read_line(&mut name)?;
print!("Enter your email: ");
io::stdout().flush()?;
let mut email = String::new();
io::stdin().read_line(&mut email)?;
repository::config::setup_global_user(name.trim(), email.trim())
}
#[cfg(test)]
mod tests {
use super::repository;
use std::fs;
use std::path::Path;
#[test]
fn test_full_workflow() {
let temp_dir = std::env::temp_dir().join("xit_test_repo");
if temp_dir.exists() {
fs::remove_dir_all(&temp_dir).unwrap();
}
fs::create_dir(&temp_dir).unwrap();
let original_dir = std::env::current_dir().unwrap();
std::env::set_current_dir(&temp_dir).unwrap();
repository::config::setup_global_user("Test User", "test@example.com").unwrap();
repository::repo::create_repository();
assert!(temp_dir.join(".xit").is_dir());
assert!(temp_dir.join(".xit/HEAD").is_file());
let test_file_path = "hello.txt";
fs::write(test_file_path, "hello world").unwrap();
repository::add::add(test_file_path).unwrap();
let index_path = temp_dir.join(".xit/index");
assert!(index_path.is_file());
let index_content = fs::read_to_string(index_path).unwrap();
assert!(index_content.contains("hello.txt"));
let commit_message = "Initial test commit";
repository::commit::commit(commit_message).unwrap();
assert!(!temp_dir.join(".xit/index").exists());
let head_ref_path = temp_dir.join(".xit/refs/heads/main");
assert!(head_ref_path.is_file());
let commit_hash = fs::read_to_string(head_ref_path).unwrap();
assert_eq!(commit_hash.trim().len(), 40);
std::env::set_current_dir(original_dir).unwrap();
fs::remove_dir_all(temp_dir).unwrap();
}
}