diff --git a/src/builders/make.rs b/src/builders/make.rs index db0fe7a..e4e19a1 100644 --- a/src/builders/make.rs +++ b/src/builders/make.rs @@ -10,6 +10,7 @@ use crate::{ pub struct Make { pub configure: bool, pub jobs: usize, + pub prefix_args: Option>, pub configure_flags: Option>, } @@ -47,7 +48,17 @@ impl Make { shell.add_command(&format!("module load {dep}")); } - let mut configure_cmd = format!("{source_path:?}/configure"); + // let mut configure_cmd = format!("{source_path:?}/configure"); + + // Apply prefix args + let mut configure_cmd = String::new(); + if let Some(args) = &self.prefix_args { + for arg in args { + configure_cmd.push_str(&format!("{arg} ")); + } + } + configure_cmd + .push_str(&format!("{}/configure", source_path.to_str().unwrap())); if let Some(flags) = &self.configure_flags { for flag in flags { @@ -123,13 +134,23 @@ impl BuilderImpl for Make { .extract() .map_err(|_| "Failed to convert attribute 'jobs' to Rust usize")?; + let prefix_args: Option> = object + .getattr("prefix_args") + .map_err(|_| { + "Failed to read attribute 'prefix_args' of Builder object" + })? + .extract() + .map_err(|_| { + "Failed to convert attribute 'prefix_args' to Rust Vec" + })?; + let configure_flags: Option> = object .getattr("configure_flags") .map_err(|_| "Failed to read attribute 'configure_flags' of Builder object")? .extract() .map_err(|_| "Failed to convert attribute 'configure_flags' to Rust Vec")?; - Ok(Self { configure, jobs, configure_flags }) + Ok(Self { configure, jobs, prefix_args, configure_flags }) } fn build< diff --git a/src/config.rs b/src/config.rs index 7ae73dc..6ab1c63 100644 --- a/src/config.rs +++ b/src/config.rs @@ -11,6 +11,7 @@ pub struct Config { pub build_root: String, pub install_root: String, pub shell: String, + pub class_no_conflict: Vec, } /// Read the sccmod configuration toml file and return the result. @@ -74,11 +75,28 @@ pub fn read() -> Result { .ok_or_else(|| "`install_root` must be a string".to_string())? .to_string(); + let class_no_conflict: Vec = table["class_no_conflict"] + .as_array() + .ok_or_else(|| { + "`class_no_conflict` must be an array of strings".to_string() + })? + .iter() + .map(|item| { + item.as_str().map(std::string::ToString::to_string).ok_or_else( + || { + "`class_no_conflict` must be an array of strings" + .to_string() + }, + ) + }) + .collect::, String>>()?; + Ok(Config { sccmod_module_paths, modulefile_root, build_root, install_root, shell, + class_no_conflict, }) } diff --git a/src/modulefile.rs b/src/modulefile.rs index ed54513..bcba294 100644 --- a/src/modulefile.rs +++ b/src/modulefile.rs @@ -1,12 +1,24 @@ -use crate::module::{Dependency, Environment, Module}; +use crate::{ + config, + module::{Dependency, Environment, Module}, +}; #[must_use] pub fn generate(module: &Module) -> String { // Generate a modulefile with support for flavours // The modulefile has the following format: + let config = config::read().unwrap(); + let module_class = &module.class; + let module_conflict = + if config.class_no_conflict.contains(&module_class.to_string()) { + String::new() + } else { + format!("::flavours::conflict -class {module_class}\n") + }; + let mut module_metadata_str = String::new(); for (key, value) in &module.metadata { module_metadata_str.push_str(&format!("# {key}: {value}\n")); @@ -53,7 +65,8 @@ pub fn generate(module: &Module) -> String { let mut environment_variables = String::new(); for (key, value) in &module.environment { environment_variables.push_str(&match value { - Environment::Set(val) => format!("setenv \"{key}\" \"{val}\"\n"), + // Environment::Set(val) => format!("setenv \"{key}\" \"{val}\"\n"), + Environment::Set(val) => format!("::flavours::modify-path setenv \"{key}\" \"{val}\"\n"), Environment::Append(val) => format!("::flavours::append-path \"{key}\" \"{val}\"\n"), Environment::Prepend(val) => { format!("::flavours::modify-path prepend-path \"{key}\" \"{val}\"\n") @@ -111,7 +124,8 @@ module-whatis "{module_description}" {class_definitions} # Conflict with other modules of the same class -::flavours::conflict -class {module_class} +# ::flavours::conflict -class {module_class} +{module_conflict} # Evaluate the flavour ::flavours::root {root_dir} diff --git a/src/sccmod/builders.py b/src/sccmod/builders.py index 5b7afaa..4108663 100644 --- a/src/sccmod/builders.py +++ b/src/sccmod/builders.py @@ -1,5 +1,7 @@ class CMake: - def __init__(self, build_type="Release", jobs=8, configure_flags=None, cmake_root=None): + def __init__( + self, build_type="Release", jobs=8, configure_flags=None, cmake_root=None + ): self.build_type = build_type self.jobs = jobs self.configure_flags = configure_flags or [] @@ -7,7 +9,8 @@ def __init__(self, build_type="Release", jobs=8, configure_flags=None, cmake_roo class Make: - def __init__(self, configure=True, jobs=8, configure_flags=None): + def __init__(self, configure=True, jobs=8, prefix_args=None, configure_flags=None): self.configure = configure self.jobs = jobs + self.prefix_args = prefix_args or [] self.configure_flags = configure_flags or []