diff --git a/src/args.rs b/src/args.rs index d9a44dd..df2da1c 100644 --- a/src/args.rs +++ b/src/args.rs @@ -23,11 +23,12 @@ pub enum Commands { Import(ImportArgs), /// Bootstrap a new app. - /// - /// Requires internet connection. #[clap(alias("create"), alias("bootstrap"))] New(NewArgs), + /// Launch firefly-emulator. + Emulator(EmulatorArgs), + /// List all badges (aka achievements) defined in the given app. #[clap(alias("badge"), alias("achievements"), alias("achievement"))] Badges(BadgesArgs), @@ -232,6 +233,12 @@ pub struct NewArgs { pub lang: String, } +#[derive(Debug, Parser)] +pub struct EmulatorArgs { + /// Arguments to pass into the emulator. + pub args: Vec, +} + #[derive(Debug, Parser)] pub struct MonitorArgs {} diff --git a/src/cli.rs b/src/cli.rs index 984893e..3bf223c 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -9,6 +9,7 @@ pub fn run_command(vfs: PathBuf, command: &Commands) -> anyhow::Result<()> { Commands::Export(args) => cmd_export(&vfs, args), Commands::Import(args) => cmd_import(&vfs, args), Commands::New(args) => cmd_new(args), + Commands::Emulator(args) => cmd_emulator(args), Commands::Badges(args) => cmd_badges(&vfs, args), Commands::Boards(args) => cmd_boards(&vfs, args), Commands::Cheat(args) => cmd_cheat(args), diff --git a/src/commands/emulator.rs b/src/commands/emulator.rs new file mode 100644 index 0000000..6a30f5a --- /dev/null +++ b/src/commands/emulator.rs @@ -0,0 +1,70 @@ +use crate::{args::EmulatorArgs, langs::check_output}; +use anyhow::{bail, Context, Result}; +use std::process::Command; + +pub fn cmd_emulator(args: &EmulatorArgs) -> Result<()> { + let executed_dev = run_dev(args)?; + if executed_dev { + return Ok(()); + } + let bins = [ + "./firefly_emulator", + "./firefly_emulator.exe", + "firefly_emulator", + "firefly_emulator.exe", + "firefly-emulator", + "firefly-emulator.exe", + ]; + for bin in bins { + if binary_exists(bin) { + println!("running {bin}..."); + let output = Command::new(bin).args(&args.args).output()?; + check_output(&output).context("run emulator")?; + } + } + bail!("emulator not installed"); +} + +fn run_dev(args: &EmulatorArgs) -> Result { + // Check common places where firefly repo might be clonned. + // If found, run the dev version using cargo. + let Some(base_dirs) = directories::BaseDirs::new() else { + return Ok(false); + }; + if !binary_exists("cargo") { + return Ok(false); + } + let home = base_dirs.home_dir(); + let paths = [ + home.join("Documents").join("firefly"), + home.join("ff").join("firefly"), + home.join("github").join("firefly"), + home.join("firefly"), + ]; + for dir_path in paths { + let cargo_path = dir_path.join("Cargo.toml"); + if !cargo_path.is_file() { + continue; + } + println!("running dev version from {}...", dir_path.to_str().unwrap()); + let output = Command::new("cargo") + .arg("run") + .arg("--") + .args(&args.args) + .current_dir(dir_path) + .output()?; + check_output(&output).context("run emulator")?; + return Ok(true); + } + Ok(false) +} + +fn binary_exists(bin: &str) -> bool { + let output = Command::new(bin).arg("--help").output(); + if let Ok(output) = output { + if output.status.success() { + return true; + } + } + false +} diff --git a/src/commands/mod.rs b/src/commands/mod.rs index c2fd632..0c0539f 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -3,6 +3,7 @@ mod boards; mod build; mod catalog; mod cheat; +mod emulator; mod export; mod import; mod inspect; @@ -18,6 +19,7 @@ pub use boards::cmd_boards; pub use build::cmd_build; pub use catalog::{cmd_catalog_list, cmd_catalog_show}; pub use cheat::cmd_cheat; +pub use emulator::cmd_emulator; pub use export::cmd_export; pub use import::cmd_import; pub use inspect::cmd_inspect;