use std::{ env, net::TcpStream, path::{Path, PathBuf}, process::Command, thread::sleep, time::Duration, }; type DynError = Box; fn main() { if let Err(e) = try_main() { eprintln!("{e}"); std::process::exit(-1) } } fn try_main() -> Result<(), DynError> { let task = env::args().nth(1); match task.as_deref() { Some("local") => local()?, _ => print_help(), } Ok(()) } fn print_help() { eprintln!( "Tasks: local runs the snake on a local game " ) } fn local() -> Result<(), DynError> { let cargo = env::var("CARGO").unwrap_or_else(|_| "cargo".to_string()); let mut snake = Command::new(cargo) .current_dir(project_root()) .args( ["run", "--bin", "battlesnake"] .map(str::to_string) .into_iter() .chain(env::args().skip(1)), ) .spawn()?; while snake.try_wait()?.is_none() { // check if port 8000 has been opened. Only then the game can be started if TcpStream::connect(("127.0.0.1", 8000)).is_ok() { let _game = Command::new("./battlesnake-cli") .current_dir(project_root()) .args([ "play", "-W", "11", "-H", "11", "--name", "local test", "--url", "http://localhost:8000", "-g", "solo", "--browser", ]) .status(); break; } else { sleep(Duration::from_secs(1)); } } snake.kill()?; Ok(()) } fn project_root() -> PathBuf { Path::new(&env!("CARGO_MANIFEST_DIR")) .ancestors() .nth(1) .unwrap() .to_path_buf() }