Skip to content

Commit

Permalink
feat: add a "full" template for package in order to get every thing f…
Browse files Browse the repository at this point in the history
…rom a single a file
  • Loading branch information
tmorin committed Aug 13, 2022
1 parent 0b3328f commit 63ae6ec
Show file tree
Hide file tree
Showing 6 changed files with 175 additions and 1 deletion.
3 changes: 3 additions & 0 deletions src/cmd/library/generate/tasks/package/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ use crate::cmd::library::generate::task::Task;
use crate::cmd::library::generate::tasks::package::package_bootstrap::PackageBootstrapTask;
use crate::cmd::library::generate::tasks::package::package_documentation::PackageDocumentationTask;
use crate::cmd::library::generate::tasks::package::package_example::PackageExampleTask;
use crate::cmd::library::generate::tasks::package::package_full::PackageFullTask;
use crate::manifest::library::Library;
use crate::manifest::package::Package;
use crate::result::Result;

mod package_bootstrap;
mod package_documentation;
mod package_example;
mod package_full;

pub fn parse_package(
_config: &Config,
Expand All @@ -26,6 +28,7 @@ pub fn parse_package(
}

tasks.push(Box::from(PackageBootstrapTask::create(_config, _package)?));
tasks.push(Box::from(PackageFullTask::create(_config, _package)?));
tasks.push(Box::from(PackageDocumentationTask::create(
_config, _library, _package,
)?));
Expand Down
145 changes: 145 additions & 0 deletions src/cmd/library/generate/tasks/package/package_full.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
use std::fs::File;
use std::path::Path;

use serde::{Deserialize, Serialize};
use tera::{Context, Tera};

use crate::cmd::library::generate::config::Config;
use crate::cmd::library::generate::task::{CleanupScope, Task};
use crate::error::Error;
use crate::manifest::package::Package;
use crate::result::Result;
use crate::utils::{create_parent_directory, delete_file};

#[derive(Debug, Deserialize, Serialize)]
pub struct Item {
/// The URN of the package.
item_urn: String,
}

#[derive(Debug, Deserialize, Serialize)]
pub struct PackageFullTask {
/// The URN of the package.
package_urn: String,
/// The items of the library.
items: Vec<Item>,
/// The path to the output directory.
output_directory: String,
/// The name of the Tera template
template: String,
}

impl PackageFullTask {
pub fn create(config: &Config, package: &Package) -> Result<PackageFullTask> {
let items = package
.modules
.iter()
.fold(vec![], |mut module_urns, module| {
module
.items
.iter()
.map(|item| item.urn.clone())
.for_each(|urn| module_urns.push(urn));
module_urns
})
.into_iter()
.map(|item_urn| Item {
item_urn: item_urn.value,
})
.collect();
Ok(PackageFullTask {
package_urn: package.urn.value.clone(),
items,
output_directory: config.output_directory.clone(),
template: package.templates.full.clone(),
})
}
fn get_relative_destination_path(&self) -> Box<Path> {
Box::from(Path::new(
format!("{}/full.puml", self.package_urn).as_str(),
))
}
fn get_full_destination_path(&self) -> Box<Path> {
Path::new(&self.output_directory)
.join(self.get_relative_destination_path())
.into_boxed_path()
}
}

impl Task for PackageFullTask {
fn cleanup(&self, _scopes: &[CleanupScope]) -> Result<()> {
log::debug!("{} - PackageFullTask - cleanup", self.package_urn);
delete_file(self.get_full_destination_path().as_ref())?;
Ok(())
}

fn render_templates(&self, _tera: &Tera) -> Result<()> {
log::debug!("{} - PackageFullTask - render templates", self.package_urn);

let destination_path = self.get_full_destination_path();

// skip early when generation not required
if destination_path.exists() {
return Ok(());
}

// create the destination directory
create_parent_directory(&destination_path)?;

// create the destination file
let destination_file = File::create(&destination_path).map_err(|e| {
Error::Cause(
"unable to create the destination file".to_string(),
Box::from(e),
)
})?;

let mut context = Context::new();
context.insert("data", &self);
_tera
.render_to(&self.template, &context, destination_file)
.map_err(|e| Error::Cause(format!("unable to render {}", &self.template), Box::from(e)))
}
}

#[cfg(test)]
mod test {
use std::fs::read_to_string;

use crate::cmd::library::generate::templates::TEMPLATES;
use crate::constants::get_default_template_package_full;
use crate::tera::create_tera;

use super::*;

#[test]
fn test_template() {
let tera = &create_tera(TEMPLATES.to_vec(), Some("test/tera/*".to_string())).unwrap();
let generator = PackageFullTask {
package_urn: "Package".to_string(),
items: vec![
Item {
item_urn: "urn_a".to_string(),
},
Item {
item_urn: "urn_b".to_string(),
},
Item {
item_urn: "urn_c".to_string(),
},
],
output_directory: "target/tests/package_full_generator".to_string(),
template: get_default_template_package_full(),
};
generator.cleanup(&vec![CleanupScope::All]).unwrap();
generator.render_templates(tera).unwrap();
let content =
read_to_string(format!("{}/Package/full.puml", generator.output_directory)).unwrap();
assert!(content.trim().contains("@startuml"));
assert!(content.trim().contains("include('Package/bootstrap')"));
assert!(content.trim().contains("include('urn_a')"));
assert!(content.trim().contains("include('urn_b')"));
assert!(content.trim().contains("include('urn_c')"));
assert!(content.trim().contains("@enduml"));
}
}
5 changes: 4 additions & 1 deletion src/cmd/library/generate/templates/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::constants::{
TEMPLATE_ITEM_DOCUMENTATION, TEMPLATE_ITEM_SNIPPET, TEMPLATE_ITEM_SOURCE,
TEMPLATE_LIBRARY_BOOTSTRAP, TEMPLATE_LIBRARY_DOCUMENTATION, TEMPLATE_MODULE_DOCUMENTATION,
TEMPLATE_PACKAGE_BOOTSTRAP, TEMPLATE_PACKAGE_DOCUMENTATION, TEMPLATE_PACKAGE_EXAMPLE,
TEMPLATE_PACKAGE_FULL,
};

mod item_documentation;
Expand All @@ -13,8 +14,9 @@ mod module_documentation;
mod package_bootstrap;
mod package_documentation;
mod package_example;
mod package_full;

pub const TEMPLATES: &[(&str, &str); 9] = &[
pub const TEMPLATES: &[(&str, &str); 10] = &[
(TEMPLATE_ITEM_DOCUMENTATION, item_documentation::TEMPLATE),
(TEMPLATE_ITEM_SNIPPET, item_snippet::TEMPLATE),
(TEMPLATE_ITEM_SOURCE, item_source::TEMPLATE),
Expand All @@ -28,6 +30,7 @@ pub const TEMPLATES: &[(&str, &str); 9] = &[
module_documentation::TEMPLATE,
),
(TEMPLATE_PACKAGE_BOOTSTRAP, package_bootstrap::TEMPLATE),
(TEMPLATE_PACKAGE_FULL, package_full::TEMPLATE),
(
TEMPLATE_PACKAGE_DOCUMENTATION,
package_documentation::TEMPLATE,
Expand Down
10 changes: 10 additions & 0 deletions src/cmd/library/generate/templates/package_full.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
pub const TEMPLATE: &str = r##"@startuml
{% block header %}{% endblock header %}
{% block content %}
include('{{ data.package_urn }}/bootstrap')
{% for item in data.items -%}
include('{{ item.item_urn }}')
{% endfor %}
{% endblock content %}
{% block footer %}{% endblock footer %}
@enduml"##;
6 changes: 6 additions & 0 deletions src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,12 @@ pub fn get_default_template_package_bootstrap() -> String {
TEMPLATE_PACKAGE_BOOTSTRAP.to_string()
}

pub const TEMPLATE_PACKAGE_FULL: &str = "package_full.tera";

pub fn get_default_template_package_full() -> String {
TEMPLATE_PACKAGE_FULL.to_string()
}

pub const TEMPLATE_PACKAGE_DOCUMENTATION: &str = "package_documentation.tera";

pub fn get_default_template_package_documentation() -> String {
Expand Down
7 changes: 7 additions & 0 deletions src/manifest/package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,17 @@ mod templates {

use crate::constants::{
get_default_template_package_bootstrap, get_default_template_package_documentation,
get_default_template_package_full,
};

#[derive(Serialize, Deserialize, Debug)]
pub struct PackageTemplates {
/// The template used to generate `<library>/<package>/bootstrap.puml`.
#[serde(default = "get_default_template_package_bootstrap")]
pub bootstrap: String,
/// The template name used to generate `<library>/<package>/full.puml`. */
#[serde(default = "get_default_template_package_full")]
pub full: String,
/// The template used to generate `<library>/<package>/README.md`.
#[serde(default = "get_default_template_package_documentation")]
pub documentation: String,
Expand All @@ -26,6 +30,7 @@ mod templates {
fn default() -> Self {
PackageTemplates {
bootstrap: get_default_template_package_bootstrap(),
full: get_default_template_package_full(),
documentation: get_default_template_package_documentation(),
}
}
Expand Down Expand Up @@ -57,12 +62,14 @@ mod tests {
urn: package/urn
templates:
bootstrap: templates_bootstrap_path
full: templates_full_path
"#;
let package: Package = serde_yaml::from_str(&yaml).unwrap();
assert_eq!(package.urn.value, "package/urn");
assert!(package.modules.is_empty());
assert!(package.examples.is_empty());
assert_eq!(package.templates.bootstrap, "templates_bootstrap_path");
assert_eq!(package.templates.full, "templates_full_path");
assert!(!package.templates.documentation.is_empty());
}
}

0 comments on commit 63ae6ec

Please sign in to comment.