diff options
author | Ilion Beyst <ilion.beyst@gmail.com> | 2022-07-21 19:19:40 +0200 |
---|---|---|
committer | Ilion Beyst <ilion.beyst@gmail.com> | 2022-07-21 19:19:40 +0200 |
commit | c6293d8e328bb96c368921fe922092d4f27f0bc9 (patch) | |
tree | 1c374345ba911b79167ae70a654dd0618efa9446 /planetwars-cli/src | |
parent | 31f8271db6735a1c7abea4d93bb3b8d7a3ce4628 (diff) | |
download | planetwars.dev-c6293d8e328bb96c368921fe922092d4f27f0bc9.tar.xz planetwars.dev-c6293d8e328bb96c368921fe922092d4f27f0bc9.zip |
delete old planetwars-cli code
Diffstat (limited to 'planetwars-cli/src')
-rw-r--r-- | planetwars-cli/src/bin/pwcli.rs | 6 | ||||
-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 | ||||
-rw-r--r-- | planetwars-cli/src/lib.rs | 11 | ||||
-rw-r--r-- | planetwars-cli/src/web/mod.rs | 175 | ||||
-rw-r--r-- | planetwars-cli/src/workspace/bot.rs | 50 | ||||
-rw-r--r-- | planetwars-cli/src/workspace/mod.rs | 77 |
10 files changed, 0 insertions, 492 deletions
diff --git a/planetwars-cli/src/bin/pwcli.rs b/planetwars-cli/src/bin/pwcli.rs deleted file mode 100644 index 438d3bc..0000000 --- a/planetwars-cli/src/bin/pwcli.rs +++ /dev/null @@ -1,6 +0,0 @@ -use planetwars_cli; - -#[tokio::main] -async fn main() { - planetwars_cli::run().await -} diff --git a/planetwars-cli/src/commands/build.rs b/planetwars-cli/src/commands/build.rs deleted file mode 100644 index 1df0bb6..0000000 --- a/planetwars-cli/src/commands/build.rs +++ /dev/null @@ -1,27 +0,0 @@ -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 deleted file mode 100644 index c95626b..0000000 --- a/planetwars-cli/src/commands/init.rs +++ /dev/null @@ -1,38 +0,0 @@ -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 deleted file mode 100644 index 52fed5c..0000000 --- a/planetwars-cli/src/commands/mod.rs +++ /dev/null @@ -1,40 +0,0 @@ -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 deleted file mode 100644 index 03868ae..0000000 --- a/planetwars-cli/src/commands/run_match.rs +++ /dev/null @@ -1,51 +0,0 @@ -use std::io; - -use clap::Parser; -use planetwars_matchrunner::{run_match, MatchConfig, 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(), - path: bot.path.clone(), - argv: bot.config.get_run_argv(), - }); - } - - let match_config = MatchConfig { - map_name: self.map, - map_path, - log_path: log_path.clone(), - players, - }; - - 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 deleted file mode 100644 index aa8d149..0000000 --- a/planetwars-cli/src/commands/serve.rs +++ /dev/null @@ -1,17 +0,0 @@ -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(()) - } -} diff --git a/planetwars-cli/src/lib.rs b/planetwars-cli/src/lib.rs deleted file mode 100644 index f67b67f..0000000 --- a/planetwars-cli/src/lib.rs +++ /dev/null @@ -1,11 +0,0 @@ -mod commands; -mod web; -mod workspace; - -pub async fn run() { - let res = commands::Cli::run().await; - if let Err(err) = res { - eprintln!("{}", err); - std::process::exit(1); - } -} diff --git a/planetwars-cli/src/web/mod.rs b/planetwars-cli/src/web/mod.rs deleted file mode 100644 index f66b0c6..0000000 --- a/planetwars-cli/src/web/mod.rs +++ /dev/null @@ -1,175 +0,0 @@ -use axum::{ - body::{boxed, Full}, - extract::{ws::WebSocket, Extension, Path, WebSocketUpgrade}, - handler::Handler, - http::{header, StatusCode, Uri}, - response::{IntoResponse, Response}, - routing::{get, Router}, - AddExtensionLayer, Json, -}; -use mime_guess; -use planetwars_matchrunner::MatchMeta; -use rust_embed::RustEmbed; -use serde::{Deserialize, Serialize}; -use std::{ - fs, - io::{self, BufRead}, - net::SocketAddr, - path, - sync::Arc, -}; - -use crate::workspace::Workspace; - -struct State { - workspace: Workspace, -} - -impl State { - fn new(workspace: Workspace) -> Self { - Self { workspace } - } -} - -pub async fn run(workspace: Workspace) { - let shared_state = Arc::new(State::new(workspace)); - - // build our application with a route - let app = Router::new() - .route("/", get(index_handler)) - .route("/ws", get(ws_handler)) - .route("/api/matches", get(list_matches)) - .route("/api/matches/:match_id", get(get_match)) - .fallback(static_handler.into_service()) - .layer(AddExtensionLayer::new(shared_state)); - - // run it - let addr = SocketAddr::from(([127, 0, 0, 1], 5000)); - println!("serving at http://{}", addr); - axum::Server::bind(&addr) - .serve(app.into_make_service()) - .await - .unwrap(); -} - -async fn ws_handler(ws: WebSocketUpgrade) -> impl IntoResponse { - ws.on_upgrade(handle_socket) -} - -async fn handle_socket(mut socket: WebSocket) { - while let Some(msg) = socket.recv().await { - let msg = if let Ok(msg) = msg { - msg - } else { - // client disconnected - return; - }; - - if socket.send(msg).await.is_err() { - // client disconnected - return; - } - } -} - -#[derive(Serialize, Deserialize)] -struct MatchData { - name: String, - #[serde(flatten)] - meta: MatchMeta, -} - -async fn list_matches(Extension(state): Extension<Arc<State>>) -> Json<Vec<MatchData>> { - let mut matches = state - .workspace - .matches_dir() - .read_dir() - .unwrap() - .filter_map(|entry| { - let entry = entry.unwrap(); - get_match_data(&entry).ok() - }) - .collect::<Vec<_>>(); - matches.sort_by(|a, b| { - let a = a.meta.timestamp; - let b = b.meta.timestamp; - a.cmp(&b).reverse() - }); - Json(matches) -} - -// extracts 'filename' if the entry matches'$filename.log'. -fn get_match_data(entry: &fs::DirEntry) -> io::Result<MatchData> { - let file_name = entry.file_name(); - let path = path::Path::new(&file_name); - - let name = get_match_name(&path) - .ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "invalid match name"))?; - - let meta = read_match_meta(&entry.path())?; - - Ok(MatchData { name, meta }) -} - -fn get_match_name(path: &path::Path) -> Option<String> { - if path.extension() != Some("log".as_ref()) { - return None; - } - - path.file_stem() - .and_then(|name| name.to_str()) - .map(|name| name.to_string()) -} - -fn read_match_meta(path: &path::Path) -> io::Result<MatchMeta> { - let file = fs::File::open(path)?; - let mut reader = io::BufReader::new(file); - let mut line = String::new(); - reader.read_line(&mut line)?; - let meta: MatchMeta = serde_json::from_str(&line)?; - Ok(meta) -} - -async fn get_match(Extension(state): Extension<Arc<State>>, Path(id): Path<String>) -> String { - let mut match_path = state.workspace.matches_dir().join(id); - match_path.set_extension("log"); - fs::read_to_string(match_path).unwrap() -} - -async fn index_handler() -> impl IntoResponse { - static_handler("/index.html".parse::<Uri>().unwrap()).await -} - -// static_handler is a handler that serves static files from the -async fn static_handler(uri: Uri) -> impl IntoResponse { - let path = uri.path().trim_start_matches('/').to_string(); - StaticFile(path) -} - -#[derive(RustEmbed)] -#[folder = "../web/pw-frontend/dist/"] -struct Asset; -pub struct StaticFile<T>(pub T); - -impl<T> IntoResponse for StaticFile<T> -where - T: Into<String>, -{ - fn into_response(self) -> Response { - let path = self.0.into(); - match Asset::get(path.as_str()) { - Some(content) => { - let body = boxed(Full::from(content.data)); - let mime = mime_guess::from_path(path).first_or_octet_stream(); - Response::builder() - .header(header::CONTENT_TYPE, mime.as_ref()) - .body(body) - .unwrap() - } - None => Response::builder() - .status(StatusCode::NOT_FOUND) - .body(boxed(Full::from("404"))) - .unwrap(), - } - } -} diff --git a/planetwars-cli/src/workspace/bot.rs b/planetwars-cli/src/workspace/bot.rs deleted file mode 100644 index a0ecb90..0000000 --- a/planetwars-cli/src/workspace/bot.rs +++ /dev/null @@ -1,50 +0,0 @@ -use shlex; -use std::fs; -use std::io; -use std::path::{Path, PathBuf}; - -use serde::{Deserialize, Serialize}; - -const BOT_CONFIG_FILENAME: &str = "botconfig.toml"; - -pub struct WorkspaceBot { - pub path: PathBuf, - pub config: BotConfig, -} - -impl WorkspaceBot { - pub fn open(path: &Path) -> io::Result<Self> { - let config_path = path.join(BOT_CONFIG_FILENAME); - let config_str = fs::read_to_string(config_path)?; - let bot_config: BotConfig = toml::from_str(&config_str)?; - - Ok(WorkspaceBot { - path: path.to_path_buf(), - config: bot_config, - }) - } -} - -#[derive(Serialize, Deserialize)] -pub struct BotConfig { - pub name: String, - pub run_command: String, - pub build_command: Option<String>, -} - -impl BotConfig { - // TODO: these commands should not be here - pub fn get_run_argv(&self) -> Vec<String> { - // TODO: proper error handling - shlex::split(&self.run_command) - .expect("Failed to parse bot run command. Check for unterminated quotes.") - } - - pub fn get_build_argv(&self) -> Option<Vec<String>> { - // TODO: proper error handling - self.build_command.as_ref().map(|cmd| { - shlex::split(cmd) - .expect("Failed to parse bot build command. Check for unterminated quotes.") - }) - } -} diff --git a/planetwars-cli/src/workspace/mod.rs b/planetwars-cli/src/workspace/mod.rs deleted file mode 100644 index 5a1a4ae..0000000 --- a/planetwars-cli/src/workspace/mod.rs +++ /dev/null @@ -1,77 +0,0 @@ -use serde::{Deserialize, Serialize}; -use std::collections::HashMap; -use std::env; -use std::fs; -use std::io; -use std::path::{Path, PathBuf}; - -use self::bot::WorkspaceBot; - -const WORKSPACE_CONFIG_FILENAME: &str = "pw_workspace.toml"; - -pub mod bot; - -pub struct Workspace { - pub root_path: PathBuf, - pub config: WorkspaceConfig, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct WorkspaceConfig { - paths: WorkspacePaths, - bots: HashMap<String, BotEntry>, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct WorkspacePaths { - maps_dir: PathBuf, - matches_dir: PathBuf, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct BotEntry { - path: PathBuf, -} - -impl Workspace { - pub fn open(root_path: &Path) -> io::Result<Workspace> { - let config_path = root_path.join(WORKSPACE_CONFIG_FILENAME); - let config_str = fs::read_to_string(config_path)?; - let workspace_config: WorkspaceConfig = toml::from_str(&config_str)?; - - Ok(Workspace { - root_path: root_path.to_path_buf(), - config: workspace_config, - }) - } - - pub fn open_current_dir() -> io::Result<Workspace> { - Workspace::open(&env::current_dir()?) - } - - pub fn maps_dir(&self) -> PathBuf { - self.root_path.join(&self.config.paths.maps_dir) - } - - pub fn map_path(&self, map_name: &str) -> PathBuf { - self.maps_dir().join(format!("{}.json", map_name)) - } - - pub fn matches_dir(&self) -> PathBuf { - self.root_path.join(&self.config.paths.matches_dir) - } - - pub fn match_path(&self, match_name: &str) -> PathBuf { - self.matches_dir().join(format!("{}.log", match_name)) - } - - pub fn get_bot(&self, bot_name: &str) -> io::Result<WorkspaceBot> { - let bot_entry = self.config.bots.get(bot_name).ok_or_else(|| { - io::Error::new( - io::ErrorKind::NotFound, - format!("no such bot: {}", bot_name), - ) - })?; - WorkspaceBot::open(&self.root_path.join(&bot_entry.path)) - } -} |