From 9397afbdbd6306335cd2c6b509e0f56bd60744fa Mon Sep 17 00:00:00 2001 From: borngraced Date: Mon, 4 Dec 2023 23:24:27 +0100 Subject: [PATCH] introduce KOMODEFI_CLI_ROOT for managing cli conf file and binary Signed-off-by: borngraced --- .../init_activation_scheme.rs | 4 +-- mm2src/komodefi_cli/src/cli.rs | 29 ++++++++++++++++-- .../src/cli_cmd_args/cmd_set_config.rs | 15 ++++++---- mm2src/komodefi_cli/src/config.rs | 30 +++++-------------- .../src/scenarios/download_helper.rs | 28 ++++++++--------- .../src/scenarios/init_mm2_cfg.rs | 4 +-- .../src/scenarios/mm2_proc_mng.rs | 16 +++++----- mm2src/komodefi_cli/src/scenarios/mod.rs | 6 ++-- 8 files changed, 74 insertions(+), 58 deletions(-) diff --git a/mm2src/komodefi_cli/src/activation_scheme_db/init_activation_scheme.rs b/mm2src/komodefi_cli/src/activation_scheme_db/init_activation_scheme.rs index ae6ad7370d..6ee447f8cf 100644 --- a/mm2src/komodefi_cli/src/activation_scheme_db/init_activation_scheme.rs +++ b/mm2src/komodefi_cli/src/activation_scheme_db/init_activation_scheme.rs @@ -7,7 +7,7 @@ use std::fs::OpenOptions; use std::io::Write; use std::path::PathBuf; -use crate::config::KomodefiConfigImpl; +use crate::cli::get_cli_root; use crate::error_anyhow; const ACTIVATION_SCHEME_FILE: &str = "activation_scheme.json"; @@ -31,7 +31,7 @@ pub(crate) async fn init_activation_scheme() -> Result<()> { } pub(crate) fn get_activation_scheme_path() -> Result { - let mut config_path = KomodefiConfigImpl::get_config_dir()?; + let mut config_path = get_cli_root()?; config_path.push(ACTIVATION_SCHEME_FILE); Ok(config_path) } diff --git a/mm2src/komodefi_cli/src/cli.rs b/mm2src/komodefi_cli/src/cli.rs index 32347d96fc..30fcbd8400 100644 --- a/mm2src/komodefi_cli/src/cli.rs +++ b/mm2src/komodefi_cli/src/cli.rs @@ -1,6 +1,11 @@ -use anyhow::Result; +use crate::logging::error_anyhow; +use anyhow::{anyhow, Result}; use clap::{Parser, Subcommand}; +use common::log::error; +use directories::ProjectDirs; +use std::fs; use std::mem::take; +use std::path::PathBuf; use crate::config::{get_config, set_config, KomodefiConfig}; use crate::komodefi_proc::{KomodefiProc, ResponseHandler}; @@ -9,8 +14,11 @@ use crate::transport::SlurpTransport; use super::cli_cmd_args::prelude::*; -const MM2_CONFIG_FILE_DEFAULT: &str = "MM2.json"; const COINS_FILE_DEFAULT: &str = "coins"; +const MM2_CONFIG_FILE_DEFAULT: &str = "MM2.json"; +const PROJECT_QUALIFIER: &str = "com"; +const PROJECT_COMPANY: &str = "komodoplatform"; +const PROJECT_APP: &str = "komodefi-cli"; #[derive(Subcommand)] enum Command { @@ -191,6 +199,23 @@ impl Cli { } } +pub fn get_cli_root() -> Result { + if let Ok(cli_root) = std::env::var("KOMODEFI_CLI_ROOT") { + let cli_root = PathBuf::from(cli_root); + fs::create_dir_all(&cli_root) + .map_err(|error| error_anyhow!("Failed to create config_dir: {cli_root:?}, error: {error}"))?; + Ok(cli_root) + } else { + let project_dirs = ProjectDirs::from(PROJECT_QUALIFIER, PROJECT_COMPANY, PROJECT_APP) + .ok_or_else(|| error_anyhow!("Failed to get project_dirs"))?; + let cli_root: PathBuf = project_dirs.config_dir().into(); + fs::create_dir_all(&cli_root) + .map_err(|error| error_anyhow!("Failed to create config_dir: {cli_root:?}, error: {error}"))?; + + Ok(cli_root) + } +} + #[derive(Debug, clap::Parser)] pub(crate) struct GetOption { #[arg(long, short)] diff --git a/mm2src/komodefi_cli/src/cli_cmd_args/cmd_set_config.rs b/mm2src/komodefi_cli/src/cli_cmd_args/cmd_set_config.rs index 6eb829aef2..2bc14a77ee 100644 --- a/mm2src/komodefi_cli/src/cli_cmd_args/cmd_set_config.rs +++ b/mm2src/komodefi_cli/src/cli_cmd_args/cmd_set_config.rs @@ -1,4 +1,6 @@ +use crate::cli::get_cli_root; use crate::error_anyhow; + use anyhow::{anyhow, Result}; use clap::Args; use common::log::error; @@ -22,7 +24,7 @@ pub(crate) struct SetConfigArgs { )] pub(crate) secure_conn: Option, #[arg(long, short, help = "Set configuration from path")] - pub(crate) from_path: Option, + pub(crate) from_path: bool, } impl SetConfigArgs { @@ -70,14 +72,17 @@ impl SetConfigArgs { Ok(()) } - pub fn source_from_path(&self, path: &str) -> Result<(String, String)> { - let mut file = File::open(path).map_err(|error| error_anyhow!("Failed to get rpc_uri: {error}"))?; + pub(crate) fn source_from_path(&self) -> Result<(String, String)> { + let mut root = get_cli_root()?; + root.push("MM2.json"); + + let mut file = File::open(root).map_err(|error| error_anyhow!("Failed to open path: {error}"))?; let mut buffer = Vec::new(); file.read_to_end(&mut buffer) - .map_err(|error| error_anyhow!("Failed to get rpc_uri: {error}"))?; + .map_err(|error| error_anyhow!("Failed to read file: {error}"))?; let mm2: Mm2Config = serde_json::from_str(&String::from_utf8_lossy(&buffer)) - .map_err(|error| error_anyhow!("Failed to get rpc_uri: {error}"))?; + .map_err(|error| error_anyhow!("Failed to write json: {error}"))?; let scheme = if mm2.secure_conn.unwrap_or_default() { "https://" diff --git a/mm2src/komodefi_cli/src/config.rs b/mm2src/komodefi_cli/src/config.rs index 81e6b94817..9c54d6fcde 100644 --- a/mm2src/komodefi_cli/src/config.rs +++ b/mm2src/komodefi_cli/src/config.rs @@ -1,3 +1,4 @@ +use crate::cli::get_cli_root; use crate::cli_cmd_args::prelude::SetConfigArgs; use crate::helpers::rewrite_json_file; use crate::komodefi_proc::SmartFractPrecision; @@ -5,7 +6,6 @@ use crate::logging::{error_anyhow, warn_bail}; use anyhow::{anyhow, bail, Result}; use common::log::{debug, error, info, warn}; -use directories::ProjectDirs; use inquire::Password; use serde::{Deserialize, Serialize}; use std::fmt::{Display, Formatter}; @@ -14,9 +14,6 @@ use std::fs; use std::path::{Path, PathBuf}; use url::{ParseError, Url}; -const PROJECT_QUALIFIER: &str = "com"; -const PROJECT_COMPANY: &str = "komodoplatform"; -const PROJECT_APP: &str = "komodefi-cli"; const KOMODEFI_CFG: &str = "komodefi_cfg.json"; const PRICE_PRECISION_MIN: usize = 8; @@ -31,7 +28,7 @@ const CFG_FILE_PERM_MODE: u32 = 0o660; pub(super) fn get_config(option: &crate::cli::GetOption) { let Ok(komodefi_cfg) = KomodefiConfigImpl::from_config_path() else { return; }; if option.unhide { - komodefi_cfg.print_config_with_password_on_tty() + komodefi_cfg.print_config_with_password() } else { println!("{}", komodefi_cfg) } @@ -40,8 +37,8 @@ pub(super) fn get_config(option: &crate::cli::GetOption) { pub(super) fn set_config(config: &mut SetConfigArgs) -> Result<()> { let mut komodefi_cfg = KomodefiConfigImpl::from_config_path().unwrap_or_else(|_| KomodefiConfigImpl::default()); - if let Some(path) = &config.from_path { - let (uri, password) = config.source_from_path(path)?; + if config.from_path { + let (uri, password) = config.source_from_path()?; komodefi_cfg.set_rpc_uri(uri); komodefi_cfg.set_rpc_password(password); } else { @@ -154,23 +151,10 @@ impl KomodefiConfigImpl { fn is_set(&self) -> bool { self.rpc_uri.is_some() && self.rpc_password.is_some() } - pub(super) fn get_config_dir() -> Result { - let project_dirs = ProjectDirs::from(PROJECT_QUALIFIER, PROJECT_COMPANY, PROJECT_APP) - .ok_or_else(|| error_anyhow!("Failed to get project_dirs"))?; - let config_path: PathBuf = project_dirs.config_dir().into(); - fs::create_dir_all(&config_path) - .map_err(|error| error_anyhow!("Failed to create config_dir: {config_path:?}, error: {error}"))?; - Ok(config_path) - } - pub(crate) fn get_config_path() -> Result { - let config_path = if let Ok(config_path) = std::env::var("KOMODO_CLI_CFG") { - PathBuf::from(config_path) - } else { - let mut config_path = KomodefiConfigImpl::get_config_dir()?; - config_path.push(KOMODEFI_CFG); - config_path - }; + let mut config_path = get_cli_root()?; + config_path.push(KOMODEFI_CFG); + Ok(config_path) } diff --git a/mm2src/komodefi_cli/src/scenarios/download_helper.rs b/mm2src/komodefi_cli/src/scenarios/download_helper.rs index 45714eda2e..da42e094f6 100644 --- a/mm2src/komodefi_cli/src/scenarios/download_helper.rs +++ b/mm2src/komodefi_cli/src/scenarios/download_helper.rs @@ -1,3 +1,5 @@ +use crate::cli::get_cli_root; + use anyhow::Result; use common::log::{debug, error, info}; use serde::Deserialize; @@ -51,17 +53,18 @@ pub(crate) async fn download_binary_and_extract_to_bin_folder() -> Result<()> { // Download the ZIP file let zip_data = client.get(download_url).send().await?.bytes().await?; // Create directories if they don't exist - let bin_dir = std::env::current_dir()?.join("bin"); - if !bin_dir.exists() { - fs::create_dir_all(&bin_dir)?; - } + let cli_root = get_cli_root()?; + let mut zip_path = cli_root.clone(); + zip_path.push("mm2.zip"); // Save the ZIP file - let zip_path = bin_dir.join("downloaded_file.zip"); let mut zip_file = File::create(&zip_path)?; zip_file.write_all(&zip_data)?; // Extract only mm2 binary file from the folder extract_file_from_zip(&zip_path, BINARY_NAME).await?; - info!("Binary downloaded and extracted to the bin folder!"); + info!( + "Binary downloaded and extracted to {} folder!", + cli_root.to_string_lossy() + ); Ok(()) } else { error!("No matching release found"); @@ -76,19 +79,16 @@ async fn extract_file_from_zip(zip_path: &std::path::Path, file_name: &str) -> R let mut archive = ZipArchive::new(reader)?; // Create directories if they don't exist and extract binary - let bin_dir = std::env::current_dir()?.join("bin"); - if !bin_dir.exists() { - fs::create_dir_all(&bin_dir)?; - } - archive.extract(&bin_dir)?; + let mut config_path = get_cli_root()?; + archive.extract(&config_path)?; // Check binary version - let version = get_binary_version(&format!("{}/{file_name}", bin_dir.to_string_lossy())).await?; + let version = get_binary_version(&format!("{}/{file_name}", config_path.to_string_lossy())).await?; info!("running {version}"); // Delete zip - let file_path = bin_dir.join("downloaded_file.zip"); - fs::remove_file(file_path)?; + config_path.push("mm2.zip"); + fs::remove_file(config_path)?; debug!("deleted downloaded_file.zip after use"); Ok(()) diff --git a/mm2src/komodefi_cli/src/scenarios/init_mm2_cfg.rs b/mm2src/komodefi_cli/src/scenarios/init_mm2_cfg.rs index 231460f9ee..ba84f1276a 100644 --- a/mm2src/komodefi_cli/src/scenarios/init_mm2_cfg.rs +++ b/mm2src/komodefi_cli/src/scenarios/init_mm2_cfg.rs @@ -21,14 +21,14 @@ const DEFAULT_GID: &str = "komodefi-cli"; const DEFAULT_OPTION_PLACEHOLDER: &str = "Tap enter to skip"; const RPC_PORT_MIN: u16 = 1024; const RPC_PORT_MAX: u16 = 49151; -const DEFAULT_RPC_PORT: u16 = 7789; +const DEFAULT_RPC_PORT: u16 = 7783; const DEFAULT_RPC_IP: Ipv4Addr = Ipv4Addr::new(127, 0, 0, 1); pub(crate) fn init_mm2_cfg(cfg_file: &str) -> Result<()> { let mut mm2_cfg = Mm2Cfg::new(); info!("Start collecting mm2_cfg into: {cfg_file}"); mm2_cfg.inquire()?; - // write default config args(dbdir, ip, port) + // write default config(dbdir, ip, port) mm2_cfg.write_default_args()?; helpers::rewrite_json_file(&mm2_cfg, cfg_file)?; info!("mm2_cfg has been writen into: {cfg_file}"); diff --git a/mm2src/komodefi_cli/src/scenarios/mm2_proc_mng.rs b/mm2src/komodefi_cli/src/scenarios/mm2_proc_mng.rs index f533491042..3d8a2c73dc 100644 --- a/mm2src/komodefi_cli/src/scenarios/mm2_proc_mng.rs +++ b/mm2src/komodefi_cli/src/scenarios/mm2_proc_mng.rs @@ -3,6 +3,7 @@ use common::log::{error, info}; use std::env; use std::path::PathBuf; +use crate::cli::get_cli_root; use crate::error_anyhow; #[cfg(not(target_os = "macos"))] @@ -77,10 +78,10 @@ fn find_proc_by_name(pname: &'_ str) -> Vec { } fn get_mm2_binary_path() -> Result { - let mut dir = env::current_exe().map_err(|error| error_anyhow!("Failed to get current binary dir: {error}"))?; - dir.pop(); - dir.push(MM2_BINARY); - Ok(dir) + let mut mm2_base_path = + get_cli_root().map_err(|error| error_anyhow!("Failed to get current binary dir: {error}"))?; + mm2_base_path.push(MM2_BINARY); + Ok(mm2_base_path) } #[cfg(not(target_os = "macos"))] @@ -204,9 +205,8 @@ pub(crate) fn stop_process() { #[cfg(target_os = "macos")] pub(crate) fn start_process(mm2_cfg_file: &Option, coins_file: &Option, log_file: &Option) { let Ok(mm2_binary) = get_mm2_binary_path() else { return; }; - - let Ok(current_dir) = env::current_dir() else { - error!("Failed to get current_dir"); + let Ok(cli_root_dir) = get_cli_root() else { + error!("Failed to get cli_root_dir"); return }; @@ -239,7 +239,7 @@ pub(crate) fn start_process(mm2_cfg_file: &Option, coins_file: &Option"#, LAUNCHCTL_MM2_ID, mm2_binary.display(), - current_dir.display(), + cli_root_dir.display(), log_file .as_deref() .map(|log_file| format!("MM_LOG{log_file}")) diff --git a/mm2src/komodefi_cli/src/scenarios/mod.rs b/mm2src/komodefi_cli/src/scenarios/mod.rs index 49b87591db..8e169b5332 100644 --- a/mm2src/komodefi_cli/src/scenarios/mod.rs +++ b/mm2src/komodefi_cli/src/scenarios/mod.rs @@ -11,6 +11,7 @@ use init_coins::init_coins; use init_mm2_cfg::init_mm2_cfg; use super::activation_scheme_db::init_activation_scheme; +use crate::cli::get_cli_root; pub(super) use download_helper::download_binary_and_extract_to_bin_folder; pub(super) use mm2_proc_mng::{get_status, start_process, stop_process}; @@ -18,8 +19,9 @@ pub(super) use mm2_proc_mng::{get_status, start_process, stop_process}; pub(super) async fn init(cfg_file: &str, coins_file: &str) { let _ = init_impl(cfg_file, coins_file).await; } async fn init_impl(cfg_file: &str, coins_file: &str) -> Result<()> { - init_mm2_cfg(cfg_file)?; - init_coins(coins_file).await?; + let root = get_cli_root()?; + init_mm2_cfg(&root.join(cfg_file).to_string_lossy())?; + init_coins(&root.join(coins_file).to_string_lossy()).await?; init_activation_scheme().await?; info!("Initialization done"); Ok(())