aboutsummaryrefslogtreecommitdiff
path: root/planetwars-cli/src/workspace
diff options
context:
space:
mode:
Diffstat (limited to 'planetwars-cli/src/workspace')
-rw-r--r--planetwars-cli/src/workspace/bot.rs50
-rw-r--r--planetwars-cli/src/workspace/mod.rs77
2 files changed, 127 insertions, 0 deletions
diff --git a/planetwars-cli/src/workspace/bot.rs b/planetwars-cli/src/workspace/bot.rs
new file mode 100644
index 0000000..a0ecb90
--- /dev/null
+++ b/planetwars-cli/src/workspace/bot.rs
@@ -0,0 +1,50 @@
+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
new file mode 100644
index 0000000..5a1a4ae
--- /dev/null
+++ b/planetwars-cli/src/workspace/mod.rs
@@ -0,0 +1,77 @@
+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))
+ }
+}