use crate::{
config,
module::{Dependency, Environment, Module},
};
#[must_use]
pub fn generate(module: &Module) -> String {
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"));
}
let mut module_metadata_str_no_hashes = String::new();
for (key, value) in &module.metadata {
module_metadata_str_no_hashes.push_str(&format!("{key}: {value}\n"));
}
let no_description_provided = "No description provided".to_string();
let module_description =
module.metadata.get("description").unwrap_or(&no_description_provided);
let dependent_modules = module
.dependencies
.iter()
.filter_map(|dep| {
if let Dependency::Depends(name) = dep {
Some(format!("depends-on {}\n", name))
} else {
None
}
})
.fold(String::new(), |mut acc, dep| {
acc.push_str(&dep);
acc
});
let mut class_definitions = String::new();
for class in module.dependencies.iter().filter_map(|dep| {
if let Dependency::Class(name) = dep {
Some(name)
} else {
None
}
}) {
class_definitions
.push_str(&format!("::flavours::prereq -class {class}\n"));
}
let root_dir = &module.install_path;
let mut environment_variables = String::new();
for (key, value) in &module.environment {
environment_variables.push_str(&match value {
Environment::Set(val) => format!("::flavours::modify-path setenv \"{key}\" \"{val}\"\n"),
Environment::SetExact(val) => format!(" 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")
}
});
}
format!(
r#"#%Module
# MODULEFILE GENERATED BY SCCMOD
# https://github.com/Pencilcaseman/sccmod
package require flavours
# Flavours is a bit of a pain, so we have to redefine it sometimes.
# Don't ask me why.
if {{![info exists flavours] || [info procs flavours] eq ""}} {{
proc flavours {{comm args}} {{
# "whatis" is fragile: don't do anything!
if {{ [module-info mode whatis] }} {{ return }}
if {{ [module-info mode help] }} {{ return }}
# Switchboard
switch $comm {{
append-path -
prepend-path -
remove-path {{ eval ::flavours::modify-path $comm $args }}
get {{ eval ::flavours::get_$args }}
default {{ eval ::flavours::$comm $args }}
}}
}}
# Uncomment this for debug information.
# puts stderr "Redefined flavours procedure"
}}
flavours init
# Metadata
{module_metadata_str}
# Module help
proc ModulesHelp {{ }} {{
puts stderr "
{module_metadata_str_no_hashes}
"
}}
module-whatis "{module_description}"
# Load submodules
{dependent_modules}
# Module prerequisites
{class_definitions}
# Conflict with other modules of the same class
# ::flavours::conflict -class {module_class}
{module_conflict}
# Evaluate the flavour
::flavours::root {root_dir}
::flavours::revision 1
::flavours::commit
# Set environment variables
{environment_variables}
# Cleanup and reload conflicting modules
::flavours::cleanup
"#
)
}