diff options
Diffstat (limited to 'planetwars-cli/src/commands')
-rw-r--r-- | planetwars-cli/src/commands/build.rs | 27 | ||||
-rw-r--r-- | planetwars-cli/src/commands/init.rs | 38 | ||||
-rw-r--r-- | planetwars-cli/src/commands/mod.rs | 40 | ||||
-rw-r--r-- | planetwars-cli/src/commands/run_match.rs | 51 | ||||
-rw-r--r-- | planetwars-cli/src/commands/serve.rs | 17 |
5 files changed, 173 insertions, 0 deletions
diff --git a/planetwars-cli/src/commands/build.rs b/planetwars-cli/src/commands/build.rs new file mode 100644 index 0000000..1df0bb6 --- /dev/null +++ b/planetwars-cli/src/commands/build.rs @@ -0,0 +1,27 @@ +use clap::Parser; +use std::io; +use tokio::process; + +use crate::workspace::Workspace; + +#[derive(Parser)] +pub struct BuildCommand { + /// Name of the bot to build + bot: String, +} + +impl BuildCommand { + pub async fn run(self) -> io::Result<()> { + let workspace = Workspace::open_current_dir()?; + let bot = workspace.get_bot(&self.bot)?; + if let Some(argv) = bot.config.get_build_argv() { + process::Command::new(&argv[0]) + .args(&argv[1..]) + .current_dir(&bot.path) + .spawn()? + .wait() + .await?; + } + Ok(()) + } +} diff --git a/planetwars-cli/src/commands/init.rs b/planetwars-cli/src/commands/init.rs new file mode 100644 index 0000000..c95626b --- /dev/null +++ b/planetwars-cli/src/commands/init.rs @@ -0,0 +1,38 @@ +use std::path::PathBuf; + +use clap::Parser; +use futures::io; + +#[derive(Parser)] +pub struct InitCommand { + /// workspace root directory + path: String, +} + +macro_rules! copy_asset { + ($path:expr, $file_name:literal) => { + ::std::fs::write( + $path.join($file_name), + include_bytes!(concat!("../../assets/", $file_name)), + )?; + }; +} + +impl InitCommand { + pub async fn run(self) -> io::Result<()> { + let path = PathBuf::from(&self.path); + + // create directories + std::fs::create_dir_all(&path)?; + std::fs::create_dir(path.join("maps"))?; + std::fs::create_dir(path.join("matches"))?; + std::fs::create_dir_all(path.join("bots/simplebot"))?; + + // create files + copy_asset!(path, "pw_workspace.toml"); + copy_asset!(path.join("maps"), "hex.json"); + copy_asset!(path.join("bots/"), "simplebot/botconfig.toml"); + copy_asset!(path.join("bots/"), "simplebot/simplebot.py"); + Ok(()) + } +} diff --git a/planetwars-cli/src/commands/mod.rs b/planetwars-cli/src/commands/mod.rs new file mode 100644 index 0000000..52fed5c --- /dev/null +++ b/planetwars-cli/src/commands/mod.rs @@ -0,0 +1,40 @@ +mod build; +mod init; +mod run_match; +mod serve; + +use clap::{Parser, Subcommand}; +use std::io; + +#[derive(Parser)] +#[clap(name = "pwcli")] +#[clap(author, version, about)] +pub struct Cli { + #[clap(subcommand)] + command: Command, +} + +impl Cli { + pub async fn run() -> io::Result<()> { + let cli = Self::parse(); + + match cli.command { + Command::Init(command) => command.run().await, + Command::RunMatch(command) => command.run().await, + Command::Serve(command) => command.run().await, + Command::Build(command) => command.run().await, + } + } +} + +#[derive(Subcommand)] +enum Command { + /// Initialize a new workspace + Init(init::InitCommand), + /// Run a match + RunMatch(run_match::RunMatchCommand), + /// Host local webserver + Serve(serve::ServeCommand), + /// Run build command for a bot + Build(build::BuildCommand), +} diff --git a/planetwars-cli/src/commands/run_match.rs b/planetwars-cli/src/commands/run_match.rs new file mode 100644 index 0000000..868e87c --- /dev/null +++ b/planetwars-cli/src/commands/run_match.rs @@ -0,0 +1,51 @@ +use std::io; + +use clap::Parser; + +use crate::match_runner::MatchConfig; +use crate::match_runner::{self, MatchPlayer}; +use crate::workspace::Workspace; +#[derive(Parser)] +pub struct RunMatchCommand { + /// map name + map: String, + /// bot names + bots: Vec<String>, +} + +impl RunMatchCommand { + pub async fn run(self) -> io::Result<()> { + let workspace = Workspace::open_current_dir()?; + + let map_path = workspace.map_path(&self.map); + let timestamp = chrono::Local::now().format("%Y-%m-%d-%H-%M-%S"); + let log_path = workspace.match_path(&format!("{}-{}", &self.map, ×tamp)); + + let mut players = Vec::new(); + for bot_name in &self.bots { + let bot = workspace.get_bot(&bot_name)?; + players.push(MatchPlayer { + name: bot_name.clone(), + bot, + }); + } + + let match_config = MatchConfig { + map_name: self.map, + map_path, + log_path: log_path.clone(), + players, + }; + + match_runner::run_match(match_config).await; + println!("match completed successfully"); + // TODO: maybe print the match result as well? + + let relative_path = match log_path.strip_prefix(&workspace.root_path) { + Ok(path) => path.to_str().unwrap(), + Err(_) => log_path.to_str().unwrap(), + }; + println!("wrote match log to {}", relative_path); + Ok(()) + } +} diff --git a/planetwars-cli/src/commands/serve.rs b/planetwars-cli/src/commands/serve.rs new file mode 100644 index 0000000..aa8d149 --- /dev/null +++ b/planetwars-cli/src/commands/serve.rs @@ -0,0 +1,17 @@ +use std::io; + +use clap::Parser; + +use crate::web; +use crate::workspace::Workspace; + +#[derive(Parser)] +pub struct ServeCommand; + +impl ServeCommand { + pub async fn run(self) -> io::Result<()> { + let workspace = Workspace::open_current_dir()?; + web::run(workspace).await; + Ok(()) + } +} |