From 8eadb12fff2aa0b4e35abf64452164bdc9929fee Mon Sep 17 00:00:00 2001 From: Daniel DW Kim Date: Mon, 10 Feb 2025 15:13:03 +0900 Subject: [PATCH 1/3] config module init --- path.cfg | 5 +-- src/main.rs | 3 ++ src/modules/config.rs | 5 +++ src/modules/mod.rs | 3 +- src/util/arg_parser.rs | 81 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 94 insertions(+), 3 deletions(-) create mode 100644 src/modules/config.rs diff --git a/path.cfg b/path.cfg index dd711ee..2e2a049 100644 --- a/path.cfg +++ b/path.cfg @@ -1,7 +1,8 @@ mmseqs=mmseqs foldseek=foldseek +foldmason=foldmason mafft=mafft mafft-linsi=mafft-linsi -foldmason=foldmason iqtree=iqtree -#fasttree=fasttree \ No newline at end of file +#fasttree= +#raxml= \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index c367a8c..b857fbf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -44,6 +44,9 @@ fn run(args: &parser::Args, bin: &var::BinaryPaths, test: bool) -> Result<(), Bo Some(parser::Commands::EasySearch { .. }) => { workflow::easy_search::run(args, bin).unwrap_or_else(|e| err::error(err::ERR_GENERAL, Some(e.to_string()))); } + Some(parser::Commands::Config { .. }) => { + modules::config::run(args, bin).unwrap_or_else(|e| err::error(err::ERR_GENERAL, Some(e.to_string()))); + }, /* Some(_) => { err::error(err::ERR_MODULE_NOT_IMPLEMENTED, std::env::args().nth(1)); } */ diff --git a/src/modules/config.rs b/src/modules/config.rs new file mode 100644 index 0000000..7815fe3 --- /dev/null +++ b/src/modules/config.rs @@ -0,0 +1,5 @@ +use crate::util::arg_parser::Args; + +pub fn run(args: &Args, bin: &crate::envs::variables::BinaryPaths) -> Result<(), Box> { + Ok(()) +} \ No newline at end of file diff --git a/src/modules/mod.rs b/src/modules/mod.rs index 4d3c15b..23c1bd7 100644 --- a/src/modules/mod.rs +++ b/src/modules/mod.rs @@ -4,4 +4,5 @@ pub mod cluster; pub mod search; pub mod profile; pub mod tree; -pub mod genetree; \ No newline at end of file +pub mod genetree; +pub mod config; \ No newline at end of file diff --git a/src/util/arg_parser.rs b/src/util/arg_parser.rs index f3ffc19..c9b71f0 100644 --- a/src/util/arg_parser.rs +++ b/src/util/arg_parser.rs @@ -362,6 +362,43 @@ pub enum Commands { #[arg(short='v', long, default_value="3")] verbosity: u8, }, + /// Runtime environment configuration + #[clap(arg_required_else_help = true, allow_hyphen_values = true)] + Config { + /// Show current environment + #[arg(short='s', long)] + show: bool, + /// Check dependencies + #[arg(short='c', long)] + check: bool, + /// Set mmseqs binary path + #[arg(long)] + set_mmseqs: Option, + /// Set foldseek binary path + #[arg(long)] + set_foldseek: Option, + /// Set foldmason binary path + #[arg(long)] + set_foldmason: Option, + /// Set mafft binary path + #[arg(long)] + set_mafft: Option, + /// Set mafft-linsi binary path + #[arg(long)] + set_mafft_linsi: Option, + /// Set iqtree binary path + #[arg(long)] + set_iqtree: Option, + /// Set fasttree binary path + #[arg(long)] + set_fasttree: Option, + /// Set raxml binary path + #[arg(long)] + set_raxml: Option, + /// Verbosity (0: quiet, 1: +errors, 2: +warnings, 3: +info, 4: +debug) + #[arg(short='v', long, default_value="3")] + verbosity: u8, + }, } #[derive(Default)] @@ -419,6 +456,17 @@ pub struct Args { pub genetree_realign: Option, pub genetree_aligner: Option, pub genetree_aligner_options: Option>, + + pub config_show: Option, + pub config_check: Option, + pub config_set_mmseqs: Option, + pub config_set_foldseek: Option, + pub config_set_foldmason: Option, + pub config_set_mafft: Option, + pub config_set_mafft_linsi: Option, + pub config_set_iqtree: Option, + pub config_set_fasttree: Option, + pub config_set_raxml: Option, } fn own(path: &PathBuf) -> String { path.clone().to_string_lossy().into_owned() } impl Args { @@ -433,6 +481,7 @@ impl Args { Some(GeneTree { verbosity, .. }) => *verbosity, Some(EasyCore { verbosity, .. }) => *verbosity, Some(EasySearch { verbosity, .. }) => *verbosity, + Some(Config { verbosity, .. }) => *verbosity, _ => 3, }; let threads = match &args.command { @@ -641,6 +690,37 @@ impl Args { Some(GeneTree { threshold, .. }) => Some(*threshold), _ => None, }; + let config_show = match &args.command { + Some(Config { show, .. }) => Some(*show), _ => None, + }; + let config_check = match &args.command { + Some(Config { check, .. }) => Some(*check), _ => None, + }; + let config_set_mmseqs = match &args.command { + Some(Config { set_mmseqs, .. }) => match set_mmseqs { Some(p) => Some(own(p)), _ => None }, _ => None, + }; + let config_set_foldseek = match &args.command { + Some(Config { set_foldseek, .. }) => match set_foldseek { Some(p) => Some(own(p)), _ => None }, _ => None, + }; + let config_set_foldmason = match &args.command { + Some(Config { set_foldmason, .. }) => match set_foldmason { Some(p) => Some(own(p)), _ => None }, _ => None, + }; + let config_set_mafft = match &args.command { + Some(Config { set_mafft, .. }) => match set_mafft { Some(p) => Some(own(p)), _ => None }, _ => None, + }; + let config_set_mafft_linsi = match &args.command { + Some(Config { set_mafft_linsi, .. }) => match set_mafft_linsi { Some(p) => Some(own(p)), _ => None }, _ => None, + }; + let config_set_iqtree = match &args.command { + Some(Config { set_iqtree, .. }) => match set_iqtree { Some(p) => Some(own(p)), _ => None }, _ => None, + }; + let config_set_fasttree = match &args.command { + Some(Config { set_fasttree, .. }) => match set_fasttree { Some(p) => Some(own(p)), _ => None }, _ => None, + }; + let config_set_raxml = match &args.command { + Some(Config { set_raxml, .. }) => match set_raxml { Some(p) => Some(own(p)), _ => None }, _ => None, + }; + Args { command: args.command, version: args.version, threads, verbosity, createdb_input, createdb_output, createdb_model, createdb_keep, createdb_overwrite, createdb_max_len, createdb_gpu, createdb_use_python, createdb_use_foldseek, createdb_afdb_lookup, createdb_afdb_local, @@ -649,6 +729,7 @@ impl Args { cluster_input, cluster_output, cluster_tmp, cluster_keep_cluster_db, cluster_cluster_options, tree_db, tree_input, tree_output, tree_aligner, tree_tree_builder, tree_aligner_options, tree_tree_options, tree_threshold, genetree_input, genetree_names, genetree_tree_builder, genetree_tree_options, genetree_realign, genetree_aligner, genetree_aligner_options, genetree_threshold, + config_show, config_check, config_set_mmseqs, config_set_foldseek, config_set_foldmason, config_set_mafft, config_set_mafft_linsi, config_set_iqtree, config_set_fasttree, config_set_raxml, } } } \ No newline at end of file From 1bbafc9865162773ee0a601c087a9f0a516bc5c3 Mon Sep 17 00:00:00 2001 From: Daniel DW Kim Date: Mon, 10 Feb 2025 18:03:13 +0900 Subject: [PATCH 2/3] config check route --- src/envs/variables.rs | 7 ++-- src/modules/config.rs | 82 ++++++++++++++++++++++++++++++++++++++++++ src/util/arg_parser.rs | 11 ++---- src/util/command.rs | 20 +++++++++++ 4 files changed, 109 insertions(+), 11 deletions(-) diff --git a/src/envs/variables.rs b/src/envs/variables.rs index 577a668..4f04f6c 100644 --- a/src/envs/variables.rs +++ b/src/envs/variables.rs @@ -85,18 +85,20 @@ pub fn locate_encoder_py() -> String { } // binary paths -const VALID_BINARY: [&str; 7] = [ - "mmseqs", "foldseek", "mafft", "mafft-linsi", "foldmason", "iqtree", "fasttree", +pub const VALID_BINARY: [&str; 8] = [ + "mmseqs", "foldseek", "mafft", "mafft-linsi", "foldmason", "iqtree", "fasttree", "raxml" ]; pub struct Binary { name: String, pub path: String, + pub set: bool, } impl Binary { fn new(name: &str, path: &str) -> Self { Binary { name: name.to_string(), path: path.to_string(), + set: false, } } fn test(&self, args: Vec<&str>) -> bool { @@ -131,6 +133,7 @@ impl BinaryPaths { let path = split.next().unwrap_or(""); if let Some(&i) = self.map.get(name) { self.bin[i].path = path.to_string(); + self.bin[i].set = true; } } Ok(()) diff --git a/src/modules/config.rs b/src/modules/config.rs index 7815fe3..6f06a8c 100644 --- a/src/modules/config.rs +++ b/src/modules/config.rs @@ -1,5 +1,87 @@ +use crate::envs::error_handler as err; +use crate::envs::variables as var; +use crate::util::command as cmd; +use crate::util::message as msg; use crate::util::arg_parser::Args; +use color_print::cstr; + +fn task_check(bin: &crate::envs::variables::BinaryPaths) -> Result<(), Box> { + msg::println_message(&format!("{}", cstr!(r#"System:"#)), 3); + msg::println_message(&format!("Unicore version: {}", var::VERSION), 3); + msg::println_message(&format!("OS: {}", std::env::consts::OS), 3); + msg::println_message(&format!("Threads: {}", var::threads()), 3); + println!(); + msg::println_message(&format!("{}", cstr!(r#"Dependencies:"#)), 3); + msg::println_message(&format!("MMseqs2: {} .. {}", + if let Some(&ref bin) = &bin.get("mmseqs") { if bin.set { bin.path.clone() } else { "Unset".to_string() } } else { "Undefined".to_string() }, + if let Some(&ref bin) = &bin.get("mmseqs") { if bin.set { if binary_run_test(&bin.path, "mmseqs") { cstr!(r#"ok"#) } else { cstr!(r#"no"#) } } else { cstr!(r#"n/a"#) } } else { cstr!(r#"n/a"#) }, + ), 3); + msg::println_message(&format!("Foldseek: {} .. {}", + if let Some(&ref bin) = &bin.get("foldseek") { if bin.set { bin.path.clone() } else { "Unset".to_string() } } else { "Undefined".to_string() }, + if let Some(&ref bin) = &bin.get("foldseek") { if bin.set { if binary_run_test(&bin.path, "foldseek") { cstr!(r#"ok"#) } else { cstr!(r#"no"#) } } else { cstr!(r#"n/a"#) } } else { cstr!(r#"n/a"#) }, + ), 3); + msg::println_message(&format!("FoldMason: {} .. {}", + if let Some(&ref bin) = &bin.get("foldmason") { if bin.set { bin.path.clone() } else { "Unset".to_string() } } else { "Undefined".to_string() }, + if let Some(&ref bin) = &bin.get("foldmason") { if bin.set { if binary_run_test(&bin.path, "foldmason") { cstr!(r#"ok"#) } else { cstr!(r#"no"#) } } else { cstr!(r#"n/a"#) } } else { cstr!(r#"n/a"#) }, + ), 3); + msg::println_message(&format!("MAFFT: {} .. {}", + if let Some(&ref bin) = &bin.get("mafft") { if bin.set { bin.path.clone() } else { "Unset".to_string() } } else { "Undefined".to_string() }, + if let Some(&ref bin) = &bin.get("mafft") { if bin.set { if binary_run_test(&bin.path, "mafft") { cstr!(r#"ok"#) } else { cstr!(r#"no"#) } } else { cstr!(r#"n/a"#) } } else { cstr!(r#"n/a"#) }, + ), 3); + msg::println_message(&format!("IQ-TREE: {} .. {}", + if let Some(&ref bin) = &bin.get("iqtree") { if bin.set { bin.path.clone() } else { "Unset".to_string() } } else { "Undefined".to_string() }, + if let Some(&ref bin) = &bin.get("iqtree") { if bin.set { if binary_run_test(&bin.path, "iqtree") { cstr!(r#"ok"#) } else { cstr!(r#"no"#) } } else { cstr!(r#"n/a"#) } } else { cstr!(r#"n/a"#) }, + ), 3); + msg::println_message(&format!("FastTree: {} .. {}", + if let Some(&ref bin) = &bin.get("fasttree") { if bin.set { bin.path.clone() } else { "Unset".to_string() } } else { "Undefined".to_string() }, + if let Some(&ref bin) = &bin.get("fasttree") { if bin.set { if binary_run_test(&bin.path, "fasttree") { cstr!(r#"ok"#) } else { cstr!(r#"no"#) } } else { cstr!(r#"n/a"#) } } else { cstr!(r#"n/a"#) }, + ), 3); + msg::println_message(&format!("RAxML: {} .. {}", + if let Some(&ref bin) = &bin.get("raxml") { if bin.set { bin.path.clone() } else { "Unset".to_string() } } else { "Undefined".to_string() }, + if let Some(&ref bin) = &bin.get("raxml") { if bin.set { if binary_run_test(&bin.path, "raxml") { cstr!(r#"ok"#) } else { cstr!(r#"no"#) } } else { cstr!(r#"n/a"#) } } else { cstr!(r#"n/a"#) }, + ), 3); + Ok(()) +} + +fn binary_run_test(path: &str, sw: &str) -> bool { + if !var::VALID_BINARY.contains(&sw) { return false; } + let mut test_command = std::process::Command::new(path); + let test_command = match sw { + "mmseqs" | "foldseek" | "foldmason" => test_command.arg("version"), + "mafft" | "iqtree" => test_command.arg("--version"), + "fasttree" => &mut test_command, + "raxml" => test_command.arg("-v"), + _ => return false, + }; + cmd::run_code(test_command) == 0 +} + +fn binary_status(bin: &crate::envs::variables::BinaryPaths, sw: &str) -> u8 { + if let Some(&ref bin) = &bin.get(sw) { + if !std::path::Path::new(&bin.path).exists() { return 1; } // Binary path does not exist + } else { return 2; } // Binary path is not set + + 0 +} +const TASK_SET_MMSEQS: u8 = 0x02; +const TASK_SET_FOLDSEEK: u8 = 0x03; +const TASK_SET_FOLDMASON: u8 = 0x04; +const TASK_SET_MAFFT: u8 = 0x05; +const TASK_SET_MAFFT_LINSI: u8 = 0x06; +const TASK_SET_IQTREE: u8 = 0x07; +const TASK_SET_FASTTREE: u8 = 0x08; +const TASK_SET_RAXML: u8 = 0x09; pub fn run(args: &Args, bin: &crate::envs::variables::BinaryPaths) -> Result<(), Box> { + if args.config_check.is_some() && args.config_check.unwrap() { task_check(bin)?; } + else if args.config_set_mmseqs.is_some() { TASK_SET_MMSEQS; } + else if args.config_set_foldseek.is_some() { TASK_SET_FOLDSEEK; } + else if args.config_set_foldmason.is_some() { TASK_SET_FOLDMASON; } + else if args.config_set_mafft.is_some() { TASK_SET_MAFFT; } + else if args.config_set_mafft_linsi.is_some() { TASK_SET_MAFFT_LINSI; } + else if args.config_set_iqtree.is_some() { TASK_SET_IQTREE; } + else if args.config_set_fasttree.is_some() { TASK_SET_FASTTREE; } + else if args.config_set_raxml.is_some() { TASK_SET_RAXML; } + else { err::error(err::ERR_ARGPARSE, Some("No task specified".to_string())) }; Ok(()) } \ No newline at end of file diff --git a/src/util/arg_parser.rs b/src/util/arg_parser.rs index c9b71f0..512d9a9 100644 --- a/src/util/arg_parser.rs +++ b/src/util/arg_parser.rs @@ -365,10 +365,7 @@ pub enum Commands { /// Runtime environment configuration #[clap(arg_required_else_help = true, allow_hyphen_values = true)] Config { - /// Show current environment - #[arg(short='s', long)] - show: bool, - /// Check dependencies + /// Check current environment configuration #[arg(short='c', long)] check: bool, /// Set mmseqs binary path @@ -457,7 +454,6 @@ pub struct Args { pub genetree_aligner: Option, pub genetree_aligner_options: Option>, - pub config_show: Option, pub config_check: Option, pub config_set_mmseqs: Option, pub config_set_foldseek: Option, @@ -690,9 +686,6 @@ impl Args { Some(GeneTree { threshold, .. }) => Some(*threshold), _ => None, }; - let config_show = match &args.command { - Some(Config { show, .. }) => Some(*show), _ => None, - }; let config_check = match &args.command { Some(Config { check, .. }) => Some(*check), _ => None, }; @@ -729,7 +722,7 @@ impl Args { cluster_input, cluster_output, cluster_tmp, cluster_keep_cluster_db, cluster_cluster_options, tree_db, tree_input, tree_output, tree_aligner, tree_tree_builder, tree_aligner_options, tree_tree_options, tree_threshold, genetree_input, genetree_names, genetree_tree_builder, genetree_tree_options, genetree_realign, genetree_aligner, genetree_aligner_options, genetree_threshold, - config_show, config_check, config_set_mmseqs, config_set_foldseek, config_set_foldmason, config_set_mafft, config_set_mafft_linsi, config_set_iqtree, config_set_fasttree, config_set_raxml, + config_check, config_set_mmseqs, config_set_foldseek, config_set_foldmason, config_set_mafft, config_set_mafft_linsi, config_set_iqtree, config_set_fasttree, config_set_raxml, } } } \ No newline at end of file diff --git a/src/util/command.rs b/src/util/command.rs index c54a00a..169436a 100644 --- a/src/util/command.rs +++ b/src/util/command.rs @@ -23,6 +23,26 @@ pub fn run(cmd: &mut std::process::Command) { } } +pub fn run_code(cmd: &mut std::process::Command) -> i32 { + let cmd = cmd.stdout(std::process::Stdio::null()).stderr(std::process::Stdio::null()); + let cmdstr = format!("{:?}", cmd).replace("\"", ""); + msg::println_message(&format!("Running command: {}", cmdstr), 4); + if let Ok(mut child) = cmd.spawn() { + let wait = child.wait(); + if let Ok(status) = wait { + if let Some(code) = status.code() { + code + } else { + 1 + } + } else { + 1 + } + } else { + 1 + } +} + pub fn _run_at(cmd: &mut std::process::Command, path: &std::path::Path) { let cmdstr = format!("{:?}", cmd); if let Ok(mut child) = cmd.current_dir(path).spawn() { From 2dcbcdbc352481350cf2ec0f4acf0fd9668fba76 Mon Sep 17 00:00:00 2001 From: Daniel DW Kim Date: Tue, 11 Feb 2025 13:46:36 +0900 Subject: [PATCH 3/3] set binary dependency --- src/envs/error_handler.rs | 20 ++++++++++----- src/envs/variables.rs | 1 + src/modules/config.rs | 54 ++++++++++++++++++++++----------------- 3 files changed, 45 insertions(+), 30 deletions(-) diff --git a/src/envs/error_handler.rs b/src/envs/error_handler.rs index 2d383ec..e677e25 100644 --- a/src/envs/error_handler.rs +++ b/src/envs/error_handler.rs @@ -4,11 +4,15 @@ use crate::util::message; pub const WRN_GENERAL: i32 = 0x00; pub const ERR_GENERAL: i32 = 0x01; -pub const ERR_FILE_NOT_FOUND: i32 = 0x02; -pub const ERR_MODULE_NOT_IMPLEMENTED: i32 = 0x03; -pub const ERR_ARGPARSE: i32 = 0x04; -pub const ERR_BINARY_NOT_FOUND: i32 = 0x05; -pub const ERR_OUTPUT_EXISTS: i32 = 0x06; +pub const ERR_FILE_NOT_FOUND: i32 = 0x10; +pub const ERR_FILE_INVALID: i32 = 0x11; +pub const ERR_BINARY_NOT_FOUND: i32 = 0x20; +pub const ERR_BINARY_NOT_EXECUTABLE: i32 = 0x21; +pub const ERR_BINARY_INVALID: i32 = 0x22; +pub const ERR_MODULE_NOT_IMPLEMENTED: i32 = 0x30; +pub const ERR_ARGPARSE: i32 = 0x40; +pub const ERR_OUTPUT_EXISTS: i32 = 0x50; + fn build_message(code: i32, passed_object: Option) -> String { let object = passed_object.unwrap_or_else(|| "".to_string()); @@ -16,10 +20,14 @@ fn build_message(code: i32, passed_object: Option) -> String { WRN_GENERAL => format!("Warning: {}", object), ERR_GENERAL => format!("Error: {}", object), ERR_FILE_NOT_FOUND => format!("File not found: {}", object), + ERR_FILE_INVALID => format!("Invalid file given: {}", object), + ERR_BINARY_NOT_FOUND => format!("Binary not found: {}", object), + ERR_BINARY_NOT_EXECUTABLE => format!("Binary not executable: {}", object), + ERR_BINARY_INVALID => format!("Invalid binary given: {}", object), ERR_MODULE_NOT_IMPLEMENTED => format!("Module not implemented: {}", object), ERR_ARGPARSE => format!("Argument parsing error: {}", object), - ERR_BINARY_NOT_FOUND => format!("Binary not found: {}", object), ERR_OUTPUT_EXISTS => format!("Output file already exists: {}; use -o to overwrite", object), + _ => "Unknown error".to_string(), } } diff --git a/src/envs/variables.rs b/src/envs/variables.rs index 4f04f6c..45809cc 100644 --- a/src/envs/variables.rs +++ b/src/envs/variables.rs @@ -131,6 +131,7 @@ impl BinaryPaths { let mut split = line.split('='); let name = split.next().unwrap_or(""); let path = split.next().unwrap_or(""); + if path.len() == 0 { continue; } if let Some(&i) = self.map.get(name) { self.bin[i].path = path.to_string(); self.bin[i].set = true; diff --git a/src/modules/config.rs b/src/modules/config.rs index 6f06a8c..4467cf9 100644 --- a/src/modules/config.rs +++ b/src/modules/config.rs @@ -1,11 +1,14 @@ +use std::os::unix::fs::MetadataExt; +use std::io::Write; use crate::envs::error_handler as err; use crate::envs::variables as var; +use crate::envs::variables::BinaryPaths; use crate::util::command as cmd; use crate::util::message as msg; use crate::util::arg_parser::Args; use color_print::cstr; -fn task_check(bin: &crate::envs::variables::BinaryPaths) -> Result<(), Box> { +fn task_check(bin: &BinaryPaths) -> Result<(), Box> { msg::println_message(&format!("{}", cstr!(r#"System:"#)), 3); msg::println_message(&format!("Unicore version: {}", var::VERSION), 3); msg::println_message(&format!("OS: {}", std::env::consts::OS), 3); @@ -48,7 +51,7 @@ fn binary_run_test(path: &str, sw: &str) -> bool { let mut test_command = std::process::Command::new(path); let test_command = match sw { "mmseqs" | "foldseek" | "foldmason" => test_command.arg("version"), - "mafft" | "iqtree" => test_command.arg("--version"), + "mafft" | "mafft-linsi" | "iqtree" => test_command.arg("--version"), "fasttree" => &mut test_command, "raxml" => test_command.arg("-v"), _ => return false, @@ -56,32 +59,35 @@ fn binary_run_test(path: &str, sw: &str) -> bool { cmd::run_code(test_command) == 0 } -fn binary_status(bin: &crate::envs::variables::BinaryPaths, sw: &str) -> u8 { - if let Some(&ref bin) = &bin.get(sw) { - if !std::path::Path::new(&bin.path).exists() { return 1; } // Binary path does not exist - } else { return 2; } // Binary path is not set +fn set_binary(bin: &BinaryPaths, path: &str, sw: &str) -> Result<(), Box> { + if !std::fs::File::open(path).is_ok() { err::error(err::ERR_BINARY_NOT_FOUND, Some(format!("{}", path))); } + if std::fs::metadata(path)?.is_dir() { err::error(err::ERR_FILE_INVALID, Some(format!("{}", path))); } + if std::fs::metadata(path)?.mode() & 0o111 == 0 { err::error(err::ERR_BINARY_NOT_EXECUTABLE, Some(format!("{}", path))); } + if !binary_run_test(path, sw) { err::error(err::ERR_BINARY_INVALID, Some(format!("{}", path))); } - 0 + let path = std::fs::canonicalize(path)?.to_str().unwrap().to_string(); + msg::println_message(&format!("Setting dependency {} to {}...", sw, path), 3); + let mut cfg = std::fs::File::create(var::locate_path_cfg())?; + for &prog in var::VALID_BINARY.iter() { + if prog == sw { cfg.write_all(format!("{}={}\n", prog, path).as_bytes())?; } + else if bin.get(prog).is_none() || !bin.get(prog).unwrap().set { cfg.write_all(format!("#{}=\n", prog).as_bytes())?; } + else { cfg.write_all(format!("{}={}\n", prog, bin.get(prog).unwrap().path).as_bytes())?; } + } + msg::println_message(&"Done. Please run \"unicore config -c\" to check".to_string(), 3); + + Ok(()) } -const TASK_SET_MMSEQS: u8 = 0x02; -const TASK_SET_FOLDSEEK: u8 = 0x03; -const TASK_SET_FOLDMASON: u8 = 0x04; -const TASK_SET_MAFFT: u8 = 0x05; -const TASK_SET_MAFFT_LINSI: u8 = 0x06; -const TASK_SET_IQTREE: u8 = 0x07; -const TASK_SET_FASTTREE: u8 = 0x08; -const TASK_SET_RAXML: u8 = 0x09; -pub fn run(args: &Args, bin: &crate::envs::variables::BinaryPaths) -> Result<(), Box> { +pub fn run(args: &Args, bin: &BinaryPaths) -> Result<(), Box> { if args.config_check.is_some() && args.config_check.unwrap() { task_check(bin)?; } - else if args.config_set_mmseqs.is_some() { TASK_SET_MMSEQS; } - else if args.config_set_foldseek.is_some() { TASK_SET_FOLDSEEK; } - else if args.config_set_foldmason.is_some() { TASK_SET_FOLDMASON; } - else if args.config_set_mafft.is_some() { TASK_SET_MAFFT; } - else if args.config_set_mafft_linsi.is_some() { TASK_SET_MAFFT_LINSI; } - else if args.config_set_iqtree.is_some() { TASK_SET_IQTREE; } - else if args.config_set_fasttree.is_some() { TASK_SET_FASTTREE; } - else if args.config_set_raxml.is_some() { TASK_SET_RAXML; } + else if args.config_set_mmseqs.is_some() { set_binary(bin, args.config_set_mmseqs.clone().unwrap().as_str(), "mmseqs")?; } + else if args.config_set_foldseek.is_some() { set_binary(bin, args.config_set_foldseek.clone().unwrap().as_str(), "foldseek")?; } + else if args.config_set_foldmason.is_some() { set_binary(bin, args.config_set_foldmason.clone().unwrap().as_str(), "foldmason")?; } + else if args.config_set_mafft.is_some() { set_binary(bin, args.config_set_mafft.clone().unwrap().as_str(), "mafft")?; } + else if args.config_set_mafft_linsi.is_some() { set_binary(bin, args.config_set_mafft_linsi.clone().unwrap().as_str(), "mafft-linsi")?; } + else if args.config_set_iqtree.is_some() { set_binary(bin, args.config_set_iqtree.clone().unwrap().as_str(), "iqtree")?; } + else if args.config_set_fasttree.is_some() { set_binary(bin, args.config_set_fasttree.clone().unwrap().as_str(), "fasttree")?; } + else if args.config_set_raxml.is_some() { set_binary(bin, args.config_set_raxml.clone().unwrap().as_str(), "raxml")?; } else { err::error(err::ERR_ARGPARSE, Some("No task specified".to_string())) }; Ok(()) } \ No newline at end of file