From f60c80917caca85343b96cdd544abe99eea3dbcd Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Thu, 5 Jun 2025 13:53:34 +0200 Subject: [PATCH 1/3] feat: embed .env.example and core configs into the binary --- src/app_dir.rs | 48 ++++++++++++++++++++------ src/backend_task/core/start_dash_qt.rs | 20 ++--------- src/bundled.rs | 45 ++++++++++++++++++++++++ src/main.rs | 1 + 4 files changed, 87 insertions(+), 27 deletions(-) create mode 100644 src/bundled.rs diff --git a/src/app_dir.rs b/src/app_dir.rs index 6dd4e7258..7e8b0def9 100644 --- a/src/app_dir.rs +++ b/src/app_dir.rs @@ -2,8 +2,10 @@ use dash_sdk::dpp::dashcore::Network; use directories::ProjectDirs; #[cfg(target_os = "linux")] use directories::UserDirs; -use std::fs; use std::path::PathBuf; +use std::{fs, io}; + +use crate::bundled::BundledResource; const QUALIFIER: &str = ""; // Typically empty on macOS and Linux const ORGANIZATION: &str = ""; @@ -85,18 +87,44 @@ pub fn app_user_data_file_path(filename: &str) -> Result Result { + let (resource, filename) = match network { + Network::Dash => (BundledResource::CoreConfigMainnet, "mainnet.conf"), + Network::Testnet => (BundledResource::CoreConfigTestnet, "testnet.conf"), + Network::Devnet => (BundledResource::CoreConfigDevnet, "devnet.conf"), + Network::Regtest => { + return Err(io::Error::new( + io::ErrorKind::InvalidInput, + "Local network does not support overwriting dash.conf", + )); } - } + _ => { + return Err(io::Error::new( + io::ErrorKind::InvalidInput, + "Unsupported network", + )) + } + }; + // Construct the full path to the config file + let dir = app_user_data_dir_path().expect("Failed to get app user data directory path"); + let config_path = dir.join("dash_core_configs").join(filename); + resource.write_to_file(&config_path, false)?; + + Ok(config_path) } diff --git a/src/backend_task/core/start_dash_qt.rs b/src/backend_task/core/start_dash_qt.rs index db998cafc..e3a6f7b24 100644 --- a/src/backend_task/core/start_dash_qt.rs +++ b/src/backend_task/core/start_dash_qt.rs @@ -1,3 +1,5 @@ +use crate::app_dir::create_dash_core_config_if_not_exists; + use crate::context::AppContext; use dash_sdk::dpp::dashcore::Network; use std::path::PathBuf; @@ -36,27 +38,11 @@ impl AppContext { )); } - // Determine the config file based on the network - let config_file: &str = match network { - Network::Dash => "dash_core_configs/mainnet.conf", - Network::Testnet => "dash_core_configs/testnet.conf", - Network::Devnet => "dash_core_configs/devnet.conf", - Network::Regtest => "dash_core_configs/local.conf", - _ => { - return Err(io::Error::new( - io::ErrorKind::InvalidInput, - "Unsupported network", - )) - } - }; - let mut command = Command::new(&dash_qt_path); command.stdout(Stdio::null()).stderr(Stdio::null()); // Suppress output if overwrite_dash_conf { - // Construct the full path to the config file - let current_dir = env::current_dir()?; - let config_path = current_dir.join(config_file); + let config_path = create_dash_core_config_if_not_exists(network)?; command.arg(format!("-conf={}", config_path.display())); } else if network == Network::Testnet { command.arg("-testnet"); diff --git a/src/bundled.rs b/src/bundled.rs new file mode 100644 index 000000000..d208b47b6 --- /dev/null +++ b/src/bundled.rs @@ -0,0 +1,45 @@ +/// Load some resource that is bundled with the application. +/// +/// Supported paths: +/// - `.env.example`: Loads the bundled `.env.example` file. + +pub(crate) enum BundledResource { + DotEnvExample, + CoreConfigMainnet, + CoreConfigTestnet, + CoreConfigDevnet, +} + +impl BundledResource { + /// Loads the resource as a byte slice. + pub(crate) fn load(&self) -> &'static [u8] { + match self { + Self::DotEnvExample => include_bytes!("../.env.example"), + Self::CoreConfigMainnet => include_bytes!("../dash_core_configs/mainnet.conf"), + Self::CoreConfigTestnet => include_bytes!("../dash_core_configs/testnet.conf"), + Self::CoreConfigDevnet => include_bytes!("../dash_core_configs/devnet.conf"), + } + } + + /// Writes the resource to a file. Creates directories if they do not exist. + /// When overwriting, it will replace the file if it exists. + /// + /// Returns `Ok(true)` if the file was written, `Ok(false)` if it already existed and was not overwritten, + /// or an `io::Error` if there was an issue writing the file. + pub(crate) fn write_to_file( + &self, + path: &std::path::Path, + overwrite: bool, + ) -> std::io::Result { + let exists = path.exists(); + if !exists || overwrite { + if let Some(parent) = path.parent() { + std::fs::create_dir_all(parent)?; + } + std::fs::write(path, self.load())?; + Ok(true) + } else { + Ok(false) + } + } +} diff --git a/src/main.rs b/src/main.rs index 6a228442e..9f9c34218 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,7 @@ use std::env; mod app; mod app_dir; mod backend_task; +mod bundled; mod components; mod config; mod context; From 6f6ce4bd9d6690ce1e1d08a66f78e34b265522bb Mon Sep 17 00:00:00 2001 From: lklimek <842586+lklimek@users.noreply.github.com> Date: Thu, 5 Jun 2025 14:00:28 +0200 Subject: [PATCH 2/3] Update src/app_dir.rs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/app_dir.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app_dir.rs b/src/app_dir.rs index 7e8b0def9..b526b998d 100644 --- a/src/app_dir.rs +++ b/src/app_dir.rs @@ -87,7 +87,7 @@ pub fn app_user_data_file_path(filename: &str) -> Result Date: Thu, 5 Jun 2025 14:11:57 +0200 Subject: [PATCH 3/3] chore: fix clippy --- src/bundled.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/bundled.rs b/src/bundled.rs index d208b47b6..56ff7f5b9 100644 --- a/src/bundled.rs +++ b/src/bundled.rs @@ -2,7 +2,6 @@ /// /// Supported paths: /// - `.env.example`: Loads the bundled `.env.example` file. - pub(crate) enum BundledResource { DotEnvExample, CoreConfigMainnet,