From 5525944659c8e71ecb30d174996cc1575d4266c3 Mon Sep 17 00:00:00 2001 From: gram Date: Fri, 26 Jun 2026 17:44:22 +0200 Subject: [PATCH 1/2] ff config get --- src/args.rs | 19 +++++++++++++++++ src/cli.rs | 3 +++ src/commands/config.rs | 46 ++++++++++++++++++++++++++++++++++++++++++ src/commands/mod.rs | 2 ++ 4 files changed, 70 insertions(+) create mode 100644 src/commands/config.rs diff --git a/src/args.rs b/src/args.rs index d845ab2..b1381d1 100644 --- a/src/args.rs +++ b/src/args.rs @@ -61,6 +61,11 @@ pub enum Commands { /// Show the full path to the virtual filesystem. Vfs, + /// Access device config. + #[command(subcommand)] + #[clap(alias("conf"), alias("settings"))] + Config(ConfigCommands), + /// Control a running device or emulator. Runtime(RuntimeArgs), @@ -318,6 +323,20 @@ pub struct RuntimeArgs { pub command: RuntimeCommands, } +#[derive(Debug, Parser)] +pub enum ConfigCommands { + /// Get config as JSON. + #[clap(alias("list"), alias("dump"), alias("export"), alias("json"))] + Get(ConfigGetArgs), +} + +#[derive(Debug, Parser)] +pub struct ConfigGetArgs { + /// Option name to get. + #[arg(long, default_value = None)] + pub key: Option, +} + #[derive(Debug, Parser)] pub enum RuntimeCommands { /// Send a cheat code. diff --git a/src/cli.rs b/src/cli.rs index 7b3021d..1be089d 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -23,6 +23,9 @@ pub fn run_command(vfs: PathBuf, command: &Commands) -> anyhow::Result<()> { CatalogCommands::List(args) => cmd_catalog_list(args), CatalogCommands::Show(args) => cmd_catalog_show(args), }, + Config(command) => match command { + ConfigCommands::Get(args) => cmd_config_get(&vfs, args), + }, Runtime(root_args) => match &root_args.command { RuntimeCommands::Launch(args) => cmd_launch(root_args, args), RuntimeCommands::Restart => cmd_restart(root_args), diff --git a/src/commands/config.rs b/src/commands/config.rs new file mode 100644 index 0000000..577f2c2 --- /dev/null +++ b/src/commands/config.rs @@ -0,0 +1,46 @@ +use crate::args::ConfigGetArgs; +use anyhow::{Context, Result, bail}; +use firefly_types::Encode; +use std::path::Path; + +pub fn cmd_config_get(vfs: &Path, _args: &ConfigGetArgs) -> Result<()> { + if !vfs.exists() { + bail!("vfs is not created yet") + } + let settings_path = vfs.join("sys").join("config"); + if !settings_path.exists() { + bail!("settings file not found") + } + let raw = std::fs::read(settings_path).context("read settings")?; + let s = firefly_types::Settings::decode(&raw).context("parse settings")?; + println!("{{"); + println!(r#" "xp": {},"#, s.xp); + println!(r#" "badges": {},"#, s.badges); + println!(r#" "country": "{}","#, p(&s.country)); + println!(r#" "lang": "{}","#, p(&s.lang)); + println!(r#" "name": "{}","#, s.name); + println!(r#" "timezone": "{}","#, s.timezone); + + println!(); + println!(r#" "auto_lock": {},"#, s.auto_lock); + println!(r#" "font_size": {},"#, s.font_size); + println!(r#" "headphones_volume": {},"#, s.headphones_volume); + println!(r#" "leds_brightness": {},"#, s.leds_brightness); + println!(r#" "screen_brightness": {},"#, s.screen_brightness); + println!(r#" "speakers_volume": {},"#, s.speakers_volume); + + println!(); + println!(r#" "contrast": {},"#, s.contrast); + println!(r#" "easter_eggs": {},"#, s.easter_eggs); + println!(r#" "gamepad_mode": {},"#, s.gamepad_mode); + println!(r#" "reduce_flashing": {},"#, s.reduce_flashing); + println!(r#" "rotate_screen": {},"#, s.rotate_screen); + println!(r#" "telemetry": {}"#, s.telemetry); + + println!("}}"); + Ok(()) +} + +fn p(r: &[u8]) -> &str { + str::from_utf8(r).unwrap_or_default() +} diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 945e28f..82f04be 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -3,6 +3,7 @@ mod boards; mod build; mod catalog; mod cheat; +mod config; mod emulator; mod export; mod import; @@ -23,6 +24,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 config::cmd_config_get; pub use emulator::cmd_emulator; pub use export::cmd_export; pub use import::cmd_import; From d967cd6771e17a670958008f55b6dd67a8abc047 Mon Sep 17 00:00:00 2001 From: gram Date: Fri, 26 Jun 2026 17:55:47 +0200 Subject: [PATCH 2/2] get config key --- src/args.rs | 2 +- src/commands/config.rs | 40 +++++++++++++++++++++++++++++++++------- 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/src/args.rs b/src/args.rs index b1381d1..371aafd 100644 --- a/src/args.rs +++ b/src/args.rs @@ -333,7 +333,7 @@ pub enum ConfigCommands { #[derive(Debug, Parser)] pub struct ConfigGetArgs { /// Option name to get. - #[arg(long, default_value = None)] + #[arg(default_value = None)] pub key: Option, } diff --git a/src/commands/config.rs b/src/commands/config.rs index 577f2c2..508678b 100644 --- a/src/commands/config.rs +++ b/src/commands/config.rs @@ -3,7 +3,7 @@ use anyhow::{Context, Result, bail}; use firefly_types::Encode; use std::path::Path; -pub fn cmd_config_get(vfs: &Path, _args: &ConfigGetArgs) -> Result<()> { +pub fn cmd_config_get(vfs: &Path, args: &ConfigGetArgs) -> Result<()> { if !vfs.exists() { bail!("vfs is not created yet") } @@ -13,6 +13,32 @@ pub fn cmd_config_get(vfs: &Path, _args: &ConfigGetArgs) -> Result<()> { } let raw = std::fs::read(settings_path).context("read settings")?; let s = firefly_types::Settings::decode(&raw).context("parse settings")?; + + if let Some(key) = &args.key { + match key.as_str() { + "xp" => println!("{}", s.xp), + "badges" => println!("{}", s.badges), + "country" => println!("{}", p(&s.country)), + "lang" => println!("{}", p(&s.lang)), + "name" => println!("{}", s.name), + "timezone" => println!("{}", s.timezone), + "auto_lock" => println!("{}", s.auto_lock), + "font_size" => println!("{}", s.font_size), + "headphones_volume" => println!("{}", s.headphones_volume), + "leds_brightness" => println!("{}", s.leds_brightness), + "screen_brightness" => println!("{}", s.screen_brightness), + "speakers_volume" => println!("{}", s.speakers_volume), + "contrast" => println!("{}", s.contrast), + "easter_eggs" => println!("{}", s.easter_eggs), + "gamepad_mode" => println!("{}", s.gamepad_mode), + "reduce_flashing" => println!("{}", s.reduce_flashing), + "rotate_screen" => println!("{}", s.rotate_screen), + "telemetry" => println!("{}", s.telemetry), + _ => bail!("unsupported key"), + } + return Ok(()); + } + println!("{{"); println!(r#" "xp": {},"#, s.xp); println!(r#" "badges": {},"#, s.badges); @@ -22,12 +48,12 @@ pub fn cmd_config_get(vfs: &Path, _args: &ConfigGetArgs) -> Result<()> { println!(r#" "timezone": "{}","#, s.timezone); println!(); - println!(r#" "auto_lock": {},"#, s.auto_lock); - println!(r#" "font_size": {},"#, s.font_size); - println!(r#" "headphones_volume": {},"#, s.headphones_volume); - println!(r#" "leds_brightness": {},"#, s.leds_brightness); - println!(r#" "screen_brightness": {},"#, s.screen_brightness); - println!(r#" "speakers_volume": {},"#, s.speakers_volume); + println!(r#" "auto_lock": {:>3},"#, s.auto_lock); + println!(r#" "font_size": {:>3},"#, s.font_size); + println!(r#" "headphones_volume": {:>3},"#, s.headphones_volume); + println!(r#" "leds_brightness": {:>3},"#, s.leds_brightness); + println!(r#" "screen_brightness": {:>3},"#, s.screen_brightness); + println!(r#" "speakers_volume": {:>3},"#, s.speakers_volume); println!(); println!(r#" "contrast": {},"#, s.contrast);