use std::io::{self, Write};
use crate::project::{CheckmateProject, ProjectError};
pub struct InitOptions {
pub url: Option<String>,
pub stealth: bool,
}
pub fn run(options: InitOptions) -> Result<(), Box<dyn std::error::Error>> {
let cwd = std::env::current_dir()?;
if CheckmateProject::exists_at(&cwd) {
eprintln!("Error: Checkmate already initialized in this directory.");
eprintln!("Remove .checkmate/ to reinitialize.");
std::process::exit(1);
}
let base_url = match options.url {
Some(url) => url,
None if atty::is(atty::Stream::Stdin) => {
prompt_for_url()?
}
None => {
eprintln!("Error: Base URL required in non-interactive mode.");
eprintln!();
eprintln!("Run with --url flag:");
eprintln!(" cm init --url http://localhost:8080");
eprintln!();
eprintln!("Or run interactively in a terminal.");
std::process::exit(1);
}
};
match CheckmateProject::init(&cwd, &base_url, options.stealth) {
Ok(project) => {
println!("✓ Initialized Checkmate in {}", project.root.display());
println!();
println!("Created:");
println!(" .checkmate/config.toml - Project configuration");
println!(" .checkmate/tests/ - Test specifications");
println!(" .checkmate/runs/ - Test run history");
println!(" .checkmate/hooks/ - Custom hook scripts");
println!();
println!("Next steps:");
println!(" 1. Create test specs in .checkmate/tests/");
println!(" 2. Run tests with: cm test run");
println!();
println!("For help: cm docs");
if options.stealth {
println!();
println!("Stealth mode: .checkmate/ added to .git/info/exclude");
}
Ok(())
}
Err(ProjectError::InvalidUrl(msg)) => {
eprintln!("Error: {}", msg);
std::process::exit(1);
}
Err(e) => Err(e.into()),
}
}
fn prompt_for_url() -> Result<String, io::Error> {
print!("Base URL for API tests: ");
io::stdout().flush()?;
let mut input = String::new();
io::stdin().read_line(&mut input)?;
let url = input.trim().to_string();
if url.is_empty() {
eprintln!("Error: Base URL cannot be empty.");
std::process::exit(1);
}
Ok(url)
}