From 4f559243c1f17694dd6bf43c4716273638a5e9c9 Mon Sep 17 00:00:00 2001 From: ReeseHatfield Date: Sat, 5 Sep 2026 09:31:01 -0400 Subject: [PATCH 1/3] pull in spinner lib --- Cargo.lock | 71 ++++++++++++++++++++++++++++++++++++++++++++++--- Cargo.toml | 1 + src/cmd/init.rs | 9 ++++++- 3 files changed, 76 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 541f513..d9e4a3b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -218,7 +218,7 @@ version = "4.5.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro2", "quote", "syn 2.0.101", @@ -508,6 +508,12 @@ version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + [[package]] name = "heck" version = "0.5.0" @@ -847,6 +853,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + [[package]] name = "libc" version = "0.2.172" @@ -890,6 +902,12 @@ version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +[[package]] +name = "maplit" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" + [[package]] name = "memchr" version = "2.7.4" @@ -1071,8 +1089,9 @@ dependencies = [ "reqwest", "serde", "serde_json", - "strum", - "strum_macros", + "spinners", + "strum 0.27.1", + "strum_macros 0.27.1", "tempfile", ] @@ -1445,6 +1464,17 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "spinners" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071af1a9d34b78b8db3ca4424b0ea4d87052d607dbe96287aebaccd596cabc86" +dependencies = [ + "lazy_static", + "maplit", + "strum 0.24.1", +] + [[package]] name = "stable_deref_trait" version = "1.2.0" @@ -1457,19 +1487,41 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "strum" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" +dependencies = [ + "strum_macros 0.24.3", +] + [[package]] name = "strum" version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f64def088c51c9510a8579e3c5d67c65349dcf755e5479ad3d010aa6454e2c32" +[[package]] +name = "strum_macros" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "rustversion", + "syn 1.0.109", +] + [[package]] name = "strum_macros" version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c77a8c5abcaf0f9ce05d62342b7d298c346515365c36b673df4ebe3ced01fde8" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro2", "quote", "rustversion", @@ -1482,6 +1534,17 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "syn" version = "2.0.101" diff --git a/Cargo.toml b/Cargo.toml index 79233ee..e803546 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,6 +26,7 @@ open = "5.3.3" reqwest = { version = "0.12.20", features = ["blocking"] } serde = { version = "1.0.219", features = ["derive"] } serde_json = "1.0.140" +spinners = "4.2.0" strum = "0.27.1" strum_macros = "0.27.1" tempfile = "3.20.0" diff --git a/src/cmd/init.rs b/src/cmd/init.rs index 2234b18..f7ee874 100644 --- a/src/cmd/init.rs +++ b/src/cmd/init.rs @@ -2,7 +2,7 @@ use std::{ error::Error, fs::{self}, process::Command, - str::FromStr, + str::FromStr, sync::{Arc, atomic::AtomicBool}, }; use clap::Args; @@ -105,6 +105,7 @@ pub fn init(opts: InitOptions) -> Result<(), Box> { ]; for c in npm_commands { + let args: Vec<&str> = c.split(' ').collect(); let output = Command::new("npm") .args(&args) @@ -119,6 +120,7 @@ pub fn init(opts: InitOptions) -> Result<(), Box> { ); return Err(format!("npm {} failed", c).into()); } + println!("Bootstrapped npm {}", c); } @@ -179,3 +181,8 @@ fn prompt_template() -> Result> { Ok(chosen_template) } + + +fn spinner(stop_flag: Arc) { + let mut sp = Spinner::new(Spinners::Dots9, "Waiting for 3 seconds".into()); +} \ No newline at end of file From 10c1bba5458ecbfa00ae9e18a6f9269c89c2f33d Mon Sep 17 00:00:00 2001 From: ReeseHatfield Date: Sat, 5 Sep 2026 09:36:10 -0400 Subject: [PATCH 2/3] pretending I know how to do concurrent rust --- src/cmd/init.rs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/cmd/init.rs b/src/cmd/init.rs index f7ee874..b618614 100644 --- a/src/cmd/init.rs +++ b/src/cmd/init.rs @@ -2,10 +2,12 @@ use std::{ error::Error, fs::{self}, process::Command, - str::FromStr, sync::{Arc, atomic::AtomicBool}, + str::FromStr, + sync::{Arc, atomic::{AtomicBool, Ordering}}, time::Duration, }; use clap::Args; +use spinners::{Spinner, Spinners}; use strum::IntoEnumIterator; use crate::{config, template::Template}; @@ -105,7 +107,9 @@ pub fn init(opts: InitOptions) -> Result<(), Box> { ]; for c in npm_commands { + let stop_spinning_flag = Arc::new(AtomicBool::new(false)); + spinner(stop_spinning_flag); let args: Vec<&str> = c.split(' ').collect(); let output = Command::new("npm") .args(&args) @@ -182,7 +186,12 @@ fn prompt_template() -> Result> { Ok(chosen_template) } +fn spinner(stop_flag: Arc) { + let mut spinner = Spinner::new(Spinners::Dots9, "Waiting...".into()); -fn spinner(stop_flag: Arc) { - let mut sp = Spinner::new(Spinners::Dots9, "Waiting for 3 seconds".into()); -} \ No newline at end of file + while !stop_flag.load(Ordering::SeqCst) { + std::thread::sleep(Duration::from_millis(25)); + } + + spinner.stop(); +} From c71d95a3111826355b158f39030207b5186032c5 Mon Sep 17 00:00:00 2001 From: ReeseHatfield Date: Sat, 5 Sep 2026 09:42:42 -0400 Subject: [PATCH 3/3] stop overengineering the problem --- src/cmd/check.rs | 5 ++--- src/cmd/init.rs | 20 +++++++------------- src/cmd/run.rs | 28 ++++++++++++++++++++-------- 3 files changed, 29 insertions(+), 24 deletions(-) diff --git a/src/cmd/check.rs b/src/cmd/check.rs index 17fb832..9a0dac2 100644 --- a/src/cmd/check.rs +++ b/src/cmd/check.rs @@ -14,7 +14,6 @@ use crate::config; use crate::net::{self, kill_port}; - /// Options for the `oseda check` command #[derive(Args, Debug)] pub struct CheckOptions { @@ -127,7 +126,7 @@ fn verify_project(port_num: u16) -> OsedaProjectStatus { let status = match status { Some(status) => status, None => { - // if could not get status, ensure process dies + // if could not get status, ensure process dies shutdown_flag.store(true, Ordering::SeqCst); let _ = run_handle.join(); return OsedaProjectStatus::NotDeploymentReady( @@ -169,4 +168,4 @@ fn verify_project(port_num: u16) -> OsedaProjectStatus { } OsedaProjectStatus::DeployReady -} \ No newline at end of file +} diff --git a/src/cmd/init.rs b/src/cmd/init.rs index b618614..9f4e17c 100644 --- a/src/cmd/init.rs +++ b/src/cmd/init.rs @@ -3,7 +3,11 @@ use std::{ fs::{self}, process::Command, str::FromStr, - sync::{Arc, atomic::{AtomicBool, Ordering}}, time::Duration, + sync::{ + atomic::{AtomicBool, Ordering}, + Arc, + }, + time::Duration, }; use clap::Args; @@ -107,9 +111,8 @@ pub fn init(opts: InitOptions) -> Result<(), Box> { ]; for c in npm_commands { - let stop_spinning_flag = Arc::new(AtomicBool::new(false)); + let mut spinner = Spinner::new(Spinners::Dots9, "Initializing...".into()); - spinner(stop_spinning_flag); let args: Vec<&str> = c.split(' ').collect(); let output = Command::new("npm") .args(&args) @@ -124,6 +127,7 @@ pub fn init(opts: InitOptions) -> Result<(), Box> { ); return Err(format!("npm {} failed", c).into()); } + spinner.stop(); println!("Bootstrapped npm {}", c); } @@ -185,13 +189,3 @@ fn prompt_template() -> Result> { Ok(chosen_template) } - -fn spinner(stop_flag: Arc) { - let mut spinner = Spinner::new(Spinners::Dots9, "Waiting...".into()); - - while !stop_flag.load(Ordering::SeqCst) { - std::thread::sleep(Duration::from_millis(25)); - } - - spinner.stop(); -} diff --git a/src/cmd/run.rs b/src/cmd/run.rs index de5d977..1cf625c 100644 --- a/src/cmd/run.rs +++ b/src/cmd/run.rs @@ -1,7 +1,11 @@ use std::{ - path::Path, process::Command, sync::{ - Arc, atomic::{AtomicBool, Ordering} - }, time::Duration + path::Path, + process::Command, + sync::{ + atomic::{AtomicBool, Ordering}, + Arc, + }, + time::Duration, }; use crate::config::{self}; @@ -20,7 +24,11 @@ impl std::fmt::Display for OsedaRunError { match self { Self::BuildError(msg) => write!(f, "Oseda Build Error: {}", msg), Self::ServeError(msg) => write!(f, "Oseda Serve Error: {}", msg), - Self::NotOsedaProjectError(msg) => write!(f, "Current working directory is not an Oseda project: {}", msg) + Self::NotOsedaProjectError(msg) => write!( + f, + "Current working directory is not an Oseda project: {}", + msg + ), } } } @@ -41,15 +49,19 @@ pub fn run() -> Result<(), OsedaRunError> { } pub fn is_cwd_oseda_project() -> bool { - Path::new(config::CONFIG_FILE_NAME).try_exists().is_ok_and(|exists| exists) + Path::new(config::CONFIG_FILE_NAME) + .try_exists() + .is_ok_and(|exists| exists) } pub fn run_with_shutdown(shutdown_flag: Arc) -> Result<(), OsedaRunError> { // command run failure and command status are considered different, handled accordingly - if !is_cwd_oseda_project(){ - return Err(OsedaRunError::NotOsedaProjectError("oseda-config.json not found".to_string())); + if !is_cwd_oseda_project() { + return Err(OsedaRunError::NotOsedaProjectError( + "oseda-config.json not found".to_string(), + )); } - + match Command::new("npx").arg("vite").arg("build").status() { Ok(status) => { if !status.success() {