diff --git a/src/commands/template.rs b/src/commands/template.rs index 8d7aa22..ed36e42 100644 --- a/src/commands/template.rs +++ b/src/commands/template.rs @@ -15,7 +15,7 @@ use serde::{Deserialize, Serialize}; use serde_yaml::Value; use typed_builder::TypedBuilder; -use crate::module_recipe::Recipe; +use crate::module_recipe::{Module, ModuleExt, Recipe}; use super::BlueBuildCommand; @@ -25,10 +25,18 @@ pub struct ContainerFileTemplate<'a> { recipe: &'a Recipe, recipe_path: &'a Path, + module_template: ModuleTemplate<'a>, + #[builder(default)] export_script: ExportsTemplate, } +#[derive(Debug, Clone, Template, TypedBuilder)] +#[template(path = "Containerfile.module", escape = "none")] +pub struct ModuleTemplate<'a> { + module_ext: &'a ModuleExt, +} + #[derive(Debug, Clone, Default, Template)] #[template(path = "export.sh", escape = "none")] pub struct ExportsTemplate; @@ -65,6 +73,11 @@ impl TemplateCommand { let template = ContainerFileTemplate::builder() .recipe(&recipe_de) .recipe_path(&self.recipe) + .module_template( + ModuleTemplate::builder() + .module_ext(&recipe_de.modules_ext) + .build(), + ) .build(); let output_str = template.render()?; @@ -109,3 +122,84 @@ fn running_gitlab_actions() -> bool { env::var("GITHUB_ACTIONS").is_ok_and(|e| e == "true") } + +fn get_containerfile_list(module: &Module) -> Option> { + if module.module_type.as_ref()? == "containerfile" { + Some( + module + .config + .get("containerfiles")? + .as_sequence()? + .iter() + .filter_map(|t| Some(t.as_str()?.to_owned())) + .collect(), + ) + } else { + None + } +} + +fn print_containerfile(containerfile: &str) -> String { + trace!("print_containerfile({containerfile})"); + debug!("Loading containerfile contents for {containerfile}"); + + let path = format!("config/containerfiles/{containerfile}/Containerfile"); + + let file = fs::read_to_string(&path).unwrap_or_else(|e| { + error!("Failed to read file {path}: {e}"); + process::exit(1); + }); + + trace!("Containerfile contents {path}:\n{file}"); + + file +} + +fn get_module_from_file(file_name: &str) -> String { + trace!("get_module_from_file({file_name})"); + + let io_err_fn = |e| { + error!("Failed to read module {file_name}: {e}"); + process::exit(1); + }; + + let file_path = PathBuf::from("config").join(file_name); + + let file = fs::read_to_string(file_path).unwrap_or_else(io_err_fn); + + let serde_err_fn = |e| { + error!("Failed to deserialize module {file_name}: {e}"); + process::exit(1); + }; + + let template_err_fn = |e| { + error!("Failed to render module {file_name}: {e}"); + process::exit(1); + }; + + serde_yaml::from_str::(file.as_str()).map_or_else( + |_| { + let module = serde_yaml::from_str::(file.as_str()).unwrap_or_else(serde_err_fn); + + ModuleTemplate::builder() + .module_ext(&ModuleExt::builder().modules(vec![module]).build()) + .build() + .render() + .unwrap_or_else(template_err_fn) + }, + |module_ext| { + ModuleTemplate::builder() + .module_ext(&module_ext) + .build() + .render() + .unwrap_or_else(template_err_fn) + }, + ) +} + +fn print_module_context(module: &Module) -> String { + serde_json::to_string(module).unwrap_or_else(|e| { + error!("Failed to parse module: {e}"); + process::exit(1); + }) +} diff --git a/src/module_recipe.rs b/src/module_recipe.rs index 818428b..9206f16 100644 --- a/src/module_recipe.rs +++ b/src/module_recipe.rs @@ -112,8 +112,7 @@ impl Recipe { } } -#[derive(Serialize, Clone, Deserialize, Debug, Template, TypedBuilder)] -#[template(path = "Containerfile.module", escape = "none")] +#[derive(Serialize, Clone, Deserialize, Debug, TypedBuilder)] pub struct ModuleExt { #[builder(default, setter(into))] pub modules: Vec, @@ -137,78 +136,3 @@ pub struct Module { // ======================================================== // // ========================= Helpers ====================== // // ======================================================== // - -fn get_containerfile_list(module: &Module) -> Option> { - if module.module_type.as_ref()? == "containerfile" { - Some( - module - .config - .get("containerfiles")? - .as_sequence()? - .iter() - .filter_map(|t| Some(t.as_str()?.to_owned())) - .collect(), - ) - } else { - None - } -} - -fn print_containerfile(containerfile: &str) -> String { - trace!("print_containerfile({containerfile})"); - debug!("Loading containerfile contents for {containerfile}"); - - let path = format!("config/containerfiles/{containerfile}/Containerfile"); - - let file = fs::read_to_string(&path).unwrap_or_else(|e| { - error!("Failed to read file {path}: {e}"); - process::exit(1); - }); - - trace!("Containerfile contents {path}:\n{file}"); - - file -} - -fn get_module_from_file(file_name: &str) -> String { - trace!("get_module_from_file({file_name})"); - - let io_err_fn = |e| { - error!("Failed to read module {file_name}: {e}"); - process::exit(1); - }; - - let file_path = PathBuf::from("config").join(file_name); - - let file = fs::read_to_string(file_path).unwrap_or_else(io_err_fn); - - let serde_err_fn = |e| { - error!("Failed to deserialize module {file_name}: {e}"); - process::exit(1); - }; - - let template_err_fn = |e| { - error!("Failed to render module {file_name}: {e}"); - process::exit(1); - }; - - serde_yaml::from_str::(file.as_str()).map_or_else( - |_| { - let module = serde_yaml::from_str::(file.as_str()).unwrap_or_else(serde_err_fn); - - ModuleExt::builder() - .modules(vec![module]) - .build() - .render() - .unwrap_or_else(template_err_fn) - }, - |module_ext| module_ext.render().unwrap_or_else(template_err_fn), - ) -} - -fn print_module_context(module: &Module) -> String { - serde_json::to_string(module).unwrap_or_else(|e| { - error!("Failed to parse module: {e}"); - process::exit(1); - }) -} diff --git a/templates/Containerfile b/templates/Containerfile index c0c5062..66bba6c 100644 --- a/templates/Containerfile +++ b/templates/Containerfile @@ -42,6 +42,6 @@ ARG CONFIG_DIRECTORY="/tmp/config" ARG IMAGE_NAME="{{ recipe.name }}" ARG BASE_IMAGE="{{ recipe.base_image }}" -{{ recipe.modules_ext }} +{{ module_template }} RUN rm -rf /tmp/* /var/* && ostree container commit diff --git a/templates/Containerfile.module b/templates/Containerfile.module index 6f1c563..c95af17 100644 --- a/templates/Containerfile.module +++ b/templates/Containerfile.module @@ -1,4 +1,4 @@ -{%- for module in modules %} +{%- for module in module_ext.modules %} {%- if let Some(type) = module.module_type %} {%- if type == "containerfile" %} {%- if let Some(containerfiles) = self::get_containerfile_list(module) %}