Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 38 additions & 10 deletions src/app_dir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 = "";
Expand Down Expand Up @@ -85,18 +87,44 @@ pub fn app_user_data_file_path(filename: &str) -> Result<PathBuf, std::io::Error
Ok(app_data_dir.join(filename))
}

/// If .env file does not exist in the application data directory,
/// copy the bundled `.env.example` file to that directory.
pub fn copy_env_file_if_not_exists() {
let app_data_dir =
app_user_data_dir_path().expect("Failed to determine application data directory");
let env_file_in_app_dir = app_data_dir.join(".env");
if !env_file_in_app_dir.exists() || !env_file_in_app_dir.is_file() {
let env_example_file_in_exe_dir = PathBuf::from(".env.example");
if env_example_file_in_exe_dir.exists() && env_example_file_in_exe_dir.is_file() {
fs::copy(&env_example_file_in_exe_dir, env_file_in_app_dir)
.expect("Failed to copy env file");
} else {
let env_file_in_exe_dir = PathBuf::from(".env");
fs::copy(&env_file_in_exe_dir, env_file_in_app_dir).expect("Failed to copy env file");
// try to write bundled .env.example file to `env_file_in_app_dir`; it will return false if the file already exists
// what we can safely ignore
BundledResource::DotEnvExample
.write_to_file(&env_file_in_app_dir, false)
.expect("Failed to write bundled .env.example file");
}

/// For a given network, create dash core config file in the application data directory if it does not exist.
///
/// Returns the path to the config file or an error if it fails.
pub fn create_dash_core_config_if_not_exists(network: Network) -> Result<PathBuf, io::Error> {
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)
}
20 changes: 3 additions & 17 deletions src/backend_task/core/start_dash_qt.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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");
Expand Down
44 changes: 44 additions & 0 deletions src/bundled.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/// 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<bool> {
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)
}
}
}
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use std::env;
mod app;
mod app_dir;
mod backend_task;
mod bundled;
mod components;
mod config;
mod context;
Expand Down
Loading