Skip to content

Commit

Permalink
Merge branch 'main' into foldseek_default
Browse files Browse the repository at this point in the history
  • Loading branch information
pskvins authored Feb 11, 2025
2 parents cd2534d + 77863df commit e932bfc
Show file tree
Hide file tree
Showing 8 changed files with 333 additions and 127 deletions.
5 changes: 3 additions & 2 deletions path.cfg
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
mmseqs=mmseqs
foldseek=foldseek
foldmason=foldmason
mafft=mafft
mafft-linsi=mafft-linsi
foldmason=foldmason
iqtree=iqtree
#fasttree=fasttree
#fasttree=
#raxml=
20 changes: 14 additions & 6 deletions src/envs/error_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,30 @@ 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>) -> String {
let object = passed_object.unwrap_or_else(|| "".to_string());
match code {
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(),
}
}
Expand Down
8 changes: 6 additions & 2 deletions src/envs/variables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,18 +76,20 @@ pub fn locate_path_cfg() -> 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 {
Expand Down Expand Up @@ -120,8 +122,10 @@ 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;
}
}
Ok(())
Expand Down
3 changes: 3 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
} */
Expand Down
93 changes: 93 additions & 0 deletions src/modules/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
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: &BinaryPaths) -> Result<(), Box<dyn std::error::Error>> {
msg::println_message(&format!("{}", cstr!(r#"<bold><underline>System:</underline></bold>"#)), 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#"<bold><underline>Dependencies:</underline></bold>"#)), 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#"<green>ok</green>"#) } else { cstr!(r#"<red>no</red>"#) } } else { cstr!(r#"<dim>n/a</dim>"#) } } else { cstr!(r#"<dim>n/a</dim>"#) },
), 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#"<green>ok</green>"#) } else { cstr!(r#"<red>no</red>"#) } } else { cstr!(r#"<dim>n/a</dim>"#) } } else { cstr!(r#"<dim>n/a</dim>"#) },
), 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#"<green>ok</green>"#) } else { cstr!(r#"<red>no</red>"#) } } else { cstr!(r#"<dim>n/a</dim>"#) } } else { cstr!(r#"<dim>n/a</dim>"#) },
), 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#"<green>ok</green>"#) } else { cstr!(r#"<red>no</red>"#) } } else { cstr!(r#"<dim>n/a</dim>"#) } } else { cstr!(r#"<dim>n/a</dim>"#) },
), 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#"<green>ok</green>"#) } else { cstr!(r#"<red>no</red>"#) } } else { cstr!(r#"<dim>n/a</dim>"#) } } else { cstr!(r#"<dim>n/a</dim>"#) },
), 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#"<green>ok</green>"#) } else { cstr!(r#"<red>no</red>"#) } } else { cstr!(r#"<dim>n/a</dim>"#) } } else { cstr!(r#"<dim>n/a</dim>"#) },
), 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#"<green>ok</green>"#) } else { cstr!(r#"<red>no</red>"#) } } else { cstr!(r#"<dim>n/a</dim>"#) } } else { cstr!(r#"<dim>n/a</dim>"#) },
), 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" | "mafft-linsi" | "iqtree" => test_command.arg("--version"),
"fasttree" => &mut test_command,
"raxml" => test_command.arg("-v"),
_ => return false,
};
cmd::run_code(test_command) == 0
}

fn set_binary(bin: &BinaryPaths, path: &str, sw: &str) -> Result<(), Box<dyn std::error::Error>> {
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))); }

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(())
}

pub fn run(args: &Args, bin: &BinaryPaths) -> Result<(), Box<dyn std::error::Error>> {
if args.config_check.is_some() && args.config_check.unwrap() { task_check(bin)?; }
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(())
}
3 changes: 2 additions & 1 deletion src/modules/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ pub mod cluster;
pub mod search;
pub mod profile;
pub mod tree;
pub mod genetree;
pub mod genetree;
pub mod config;
Loading

0 comments on commit e932bfc

Please sign in to comment.