From 0f267750a42080fb1b3896414fe0c34562d61ef4 Mon Sep 17 00:00:00 2001 From: tami5 Date: Fri, 20 May 2022 15:31:22 +0300 Subject: [PATCH] fix(runner): simctl runner --- lua/xbase/init.lua | 2 +- src/daemon/requests/run.rs | 11 ++++-- src/error.rs | 8 +++++ src/runner.rs | 30 ++++++++-------- src/types/project/platform.rs | 66 ++++++++++++++++++++++++++--------- src/types/simdevice.rs | 38 ++++++++++++-------- 6 files changed, 103 insertions(+), 52 deletions(-) diff --git a/lua/xbase/init.lua b/lua/xbase/init.lua index 36fffcb..048df96 100644 --- a/lua/xbase/init.lua +++ b/lua/xbase/init.lua @@ -70,7 +70,7 @@ M.setup = function(opts) M.try_register(root, opts) vim.api.nvim_create_autocmd({ "BufEnter", "BufWinEnter" }, { - pattern = { "*.m", "*.swift", "*.c" }, + pattern = { "*.m", "*.swift", "*.c", "*.yml" }, callback = function() vim.keymap.set("n", "ef", require("xbase.pickers").actions, { buffer = true }) end, diff --git a/src/daemon/requests/run.rs b/src/daemon/requests/run.rs index 371846e..cc394a8 100644 --- a/src/daemon/requests/run.rs +++ b/src/daemon/requests/run.rs @@ -26,7 +26,6 @@ use { crate::runner::Runner, crate::xcode::{append_build_root, build_with_loggger}, crate::Error, - std::str::FromStr, xcodebuild::runner::build_settings, }; @@ -36,11 +35,13 @@ impl Handler for Run { async fn handle(self) -> Result<()> { let Client { pid, root, .. } = &self.client; + tracing::info!("⚙️ Running command: {:?}", self); tracing::info!("⚙️ Running command: {}", self.config.to_string()); let state = DAEMON_STATE.clone().lock_owned().await; let direction = self.direction.clone(); - let platform = if let Some(d) = self.device.as_ref() { + let platform = if let Some(ref d) = self.device { + tracing::info!("{:#?}", d.platform); Some(d.platform.clone()) } else { None @@ -56,8 +57,12 @@ impl Handler for Run { }; let ref mut logger = nvim.new_logger("Build", &self.config.target, &direction); + let settings = build_settings(&root, &args).await?; - let platform = platform.unwrap_or(Platform::from_str(&settings.platform_display_name)?); + let platform = match platform { + Some(v) => v, + None => Platform::from_display(&settings.platform_display_name)?, + }; let success = build_with_loggger(logger, &root, &args, true, true).await?; if !success { diff --git a/src/error.rs b/src/error.rs index 52bcf20..fca99bd 100644 --- a/src/error.rs +++ b/src/error.rs @@ -34,6 +34,8 @@ pub enum Error { Run(String), #[error("[Error] (WatchError) {0}")] Watch(#[from] WatchError), + #[error("[Error] (Message) {0}")] + Message(String), } #[derive(ThisError, Debug)] @@ -68,6 +70,12 @@ pub enum WatchError { FailToStart, } +impl From for Error { + fn from(s: String) -> Self { + Self::Message(s) + } +} + #[cfg(feature = "daemon")] impl WatchError { pub fn stop(err: Error) -> WatchError { diff --git a/src/runner.rs b/src/runner.rs index ccd315c..ac67728 100644 --- a/src/runner.rs +++ b/src/runner.rs @@ -85,9 +85,12 @@ impl Runner { /// Simctl Runner impl Runner { - pub async fn run_with_simctl(self, settings: BuildSettings) -> Result>> { + pub async fn run_with_simctl( + mut self, + settings: BuildSettings, + ) -> Result>> { let nvim = self.state.clients.get(&self.client.pid)?; - let mut logger = nvim.new_logger("Run", &self.target, &self.direction); + let ref mut logger = nvim.new_logger("Run", &self.target, &self.direction); let app_id = settings.product_bundle_identifier; let path_to_app = settings.metal_library_output_dir; @@ -95,28 +98,23 @@ impl Runner { tracing::debug!("{app_id}: {:?}", path_to_app); logger.log_title().await?; - logger.open_win().await?; + logger.set_running().await?; let mut device = get_device(&self.state, self.udid)?; - // NOTE: This is required so when neovim exist this should also exit - let state = DAEMON_STATE.clone().lock_owned().await; + device.try_boot(logger).await?; + device.try_install(&path_to_app, &app_id, logger).await?; + device.try_launch(&app_id, logger).await?; + // TODO(simctl): device might change outside state + self.state.devices.insert(device); + + // NOTE: This is required so when neovim exist this should also exit tokio::spawn(async move { + let state = DAEMON_STATE.clone().lock_owned().await; let nvim = state.clients.get(&self.client.pid)?; let ref mut logger = nvim.new_logger("Run", &self.target, &self.direction); - logger.set_running().await?; - - device.try_boot(logger).await?; - device.try_install(&path_to_app, &app_id, logger).await?; - device.try_launch(&app_id, logger).await?; - - let mut state = DAEMON_STATE.clone().lock_owned().await; - - // TODO(simctl): device might change outside state - state.devices.insert(device); - // TODO: Remove and replace with app logs logger.set_status_end(true, false).await?; diff --git a/src/types/project/platform.rs b/src/types/project/platform.rs index d7c009e..cb3c5c0 100644 --- a/src/types/project/platform.rs +++ b/src/types/project/platform.rs @@ -1,23 +1,17 @@ use super::*; -use strum::{Display, EnumString}; -#[derive( - Clone, Debug, Default, Deserialize, Serialize, Hash, PartialEq, Eq, Display, EnumString, -)] +use std::str::FromStr; + +#[derive(Clone, Debug, Default, Deserialize, Serialize, Hash, PartialEq, Eq)] pub enum Platform { #[serde(rename = "iOS")] - #[strum(serialize = "iOS")] IOS, #[serde(rename = "watchOS")] - #[strum(serialize = "watchOS")] WatchOS, #[serde(rename = "tvOS")] - #[strum(serialize = "tvOS")] TvOS, - #[strum(serialize = "macOS")] #[serde(rename = "macOS")] MacOS, #[default] - #[strum(serialize = "")] None, } @@ -49,6 +43,24 @@ impl Platform { pub fn is_mac_os(&self) -> bool { matches!(self, Self::MacOS) } + + #[cfg(feature = "daemon")] + pub fn from_display(display: &String) -> Result { + let value = if display.contains("Simulator") { + display + .split(" ") + .map(ToString::to_string) + .collect::>() + .get(0) + .ok_or_else(|| { + crate::Error::Message(format!("Unable to get Platfrom from `{display}`")) + })? + .to_string() + } else { + display.into() + }; + Self::from_str(&value).map_err(|s| crate::Error::Message(s)) + } } #[cfg(feature = "lua")] @@ -58,14 +70,7 @@ use mlua::prelude::*; impl<'a> FromLua<'a> for Platform { fn from_lua(lua_value: LuaValue<'a>, _lua: &'a Lua) -> LuaResult { if let LuaValue::String(value) = lua_value { - match value.to_str()? { - "iOS" => Platform::IOS, - "watchOS" => Platform::WatchOS, - "tvOS" => Platform::TvOS, - "macOS" => Platform::MacOS, - _ => return Err(LuaError::external("Fail to deserialize Platform")), - } - .pipe(Ok) + value.to_str()?.pipe(FromStr::from_str).to_lua_err() } else { Err(LuaError::external( "Fail to deserialize Platform, expected string", @@ -73,3 +78,30 @@ impl<'a> FromLua<'a> for Platform { } } } + +impl FromStr for Platform { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + match s { + "iOS" => Ok(Platform::IOS), + "watchOS" => Ok(Platform::WatchOS), + "tvOS" => Ok(Platform::TvOS), + "macOS" => Ok(Platform::MacOS), + _ => Err(format!("Platfrom {s}")), + } + } +} + +impl ToString for Platform { + fn to_string(&self) -> String { + match self { + Platform::IOS => "iOS", + Platform::WatchOS => "watchOS", + Platform::TvOS => "tvOS", + Platform::MacOS => "macOS", + _ => "", + } + .into() + } +} diff --git a/src/types/simdevice.rs b/src/types/simdevice.rs index 1190e64..ef851ad 100644 --- a/src/types/simdevice.rs +++ b/src/types/simdevice.rs @@ -56,14 +56,22 @@ impl SimDevice { pub async fn try_boot<'a>(&mut self, logger: &mut Logger<'a>) -> Result<()> { // FIX(run): DeviceState can get out of sync when the user shutdown device manually - if let DeviceState::Shutdown = &self.state { - logger.log(format!("[Booting] ({})", self.name)).await?; + logger + .log(string_as_section(format!("Booting: {}", self.name))) + .await?; - self.boot() - .pipe(|res| self.handle_error(res, logger)) - .await?; - self.state = DeviceState::Booted; - } + if let Err(e) = self.boot() { + let err = Error::from(e); + let err_msg = err.to_string(); + if !err_msg.contains("current state Booted") { + logger.log(err_msg).await?; + logger.set_status_end(false, true).await?; + self.is_running = false; + return Err(err); + } + }; + + self.state = DeviceState::Booted; Ok(()) } @@ -74,20 +82,20 @@ impl SimDevice { app_id: &String, logger: &mut Logger<'a>, ) -> Result<()> { + logger + .log(string_as_section(format!("Installing: {app_id}",))) + .await?; self.install(path_to_app) .pipe(|res| self.handle_error(res, logger)) .await?; - logger - .log(format!("[Installing] ({}) {app_id}", self.name)) - .await + Ok(()) } pub async fn try_launch<'a>(&mut self, app_id: &String, logger: &mut Logger<'a>) -> Result<()> { + logger + .log(string_as_section(format!("Launching: {app_id}"))) + .await?; if !self.is_running { - logger - .log(format!("[Launching] ({}) {app_id}", self.name)) - .await?; - self.launch(app_id) .stdout(&"/tmp/wordle_log") .stderr(&"/tmp/wordle_log") @@ -97,7 +105,7 @@ impl SimDevice { self.is_running = true; - logger.log(string_as_section("Launched".into())).await?; + logger.log(string_as_section("Connected".into())).await?; } Ok(())