diff --git a/.github/workflows/Continuous-Integration.yml b/.github/workflows/Continuous-Integration.yml index a946919..dbd70e0 100644 --- a/.github/workflows/Continuous-Integration.yml +++ b/.github/workflows/Continuous-Integration.yml @@ -1,6 +1,10 @@ name: Continuous-Integration -on: [ push, pull_request ] +on: + push: + branches: + - main + pull_request: { } jobs: diff --git a/src/cli.rs b/src/cli.rs index d83a7c4..1f989a1 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,3 +1,4 @@ +use crate::constants::SOURCE_PATTERNS; use clap::builder::{PossibleValuesParser, ValueParser}; use clap::{ crate_authors, crate_description, crate_version, value_parser, Arg, ArgAction, Command, @@ -14,6 +15,15 @@ pub fn build_cli() -> Command { .env("PLANTUML_GENERATOR_SOURCE_DIRECTORY") .help("The directory where the .puml will be discovered."); + let arg_source_patterns: Arg = Arg::new("source_patterns") + .short('p') + .long("patterns") + .default_value(SOURCE_PATTERNS) + .action(ArgAction::Set) + .num_args(1) + .env("PLANTUML_GENERATOR_SOURCE_DIRECTORY") + .help("The directory where the .puml will be discovered."); + let arg_cache_directory: Arg = Arg::new("cache_directory") .short('C') .long("cache") @@ -173,6 +183,7 @@ pub fn build_cli() -> Command { Command::new("generate") .about("Generate discovered .puml files which has been mutated since the last generation.") .arg(&arg_source_directory) + .arg(&arg_source_patterns) .arg(Arg::new("do_force_generation") .short('f') .long("force") diff --git a/src/cmd/diagram/generate/config.rs b/src/cmd/diagram/generate/config.rs index 0ac8c75..74a1ad3 100644 --- a/src/cmd/diagram/generate/config.rs +++ b/src/cmd/diagram/generate/config.rs @@ -3,17 +3,20 @@ use std::path::Path; use clap::ArgMatches; use serde::{Deserialize, Serialize}; -use crate::constants::get_default_cache_directory; use crate::constants::get_default_java_binary; use crate::constants::get_default_plantuml_jar; use crate::constants::get_default_plantuml_version; use crate::constants::get_default_source_directory; +use crate::constants::{get_default_cache_directory, get_default_source_patterns}; #[derive(Clone, Debug, Serialize, Deserialize)] pub struct Config { /// The path to the output directory. #[serde(default = "get_default_source_directory")] pub source_directory: String, + /// The patterns to discover the source files separated by comas. + #[serde(default = "get_default_source_patterns")] + pub source_patterns: String, /// The path to the cache directory. #[serde(default = "get_default_cache_directory")] pub cache_directory: String, @@ -35,6 +38,11 @@ impl Config { .map(|v| v.to_string()) .unwrap_or_else(|| self.source_directory.clone()); + let source_patterns = args + .get_one::("source_patterns") + .map(|v| v.to_string()) + .unwrap_or_else(|| self.source_patterns.clone()); + let cache_directory = args .get_one::("cache_directory") .map(|v| v.to_string()) @@ -62,6 +70,7 @@ impl Config { Config { source_directory, + source_patterns, cache_directory, plantuml_version, plantuml_jar, @@ -78,19 +87,20 @@ impl Default for Config { Config { source_directory: std::env::var("PLANTUML_GENERATOR_SOURCE_DIRECTORY") .unwrap_or_else(|_| get_default_source_directory()), + source_patterns: std::env::var("PLANTUML_GENERATOR_SOURCE_PATTERNS") + .unwrap_or_else(|_| get_default_source_patterns()), cache_directory: std::env::var("PLANTUML_GENERATOR_CACHE_DIRECTORY") .unwrap_or_else(|_| get_default_cache_directory()), plantuml_version: std::env::var("PLANTUML_GENERATOR_PLANTUML_VERSION") .unwrap_or_else(|_| get_default_plantuml_version()), plantuml_jar: std::env::var("PLANTUML_GENERATOR_PLANTUML_JAR") .unwrap_or_else(|_| get_default_plantuml_jar()), - java_binary: match std::env::var("PLANTUML_GENERATOR_JAVA_BINARY") { - Ok(v) => v, - Err(_) => match std::env::var("JAVA_HOME") { + java_binary: std::env::var("PLANTUML_GENERATOR_JAVA_BINARY").unwrap_or_else(|_| { + match std::env::var("JAVA_HOME") { Ok(v) => format!("{}/bin/java", v), Err(_) => get_default_java_binary(), - }, - }, + } + }), } } } diff --git a/src/cmd/diagram/generate/mod.rs b/src/cmd/diagram/generate/mod.rs index f020d4a..4598e85 100644 --- a/src/cmd/diagram/generate/mod.rs +++ b/src/cmd/diagram/generate/mod.rs @@ -1,12 +1,12 @@ use std::fs::{read_to_string, OpenOptions}; use std::io::Write; -use std::path::Path; +use std::path::{Path, PathBuf}; use std::time::SystemTime; use anyhow::Result; use chrono::prelude::*; use clap::ArgMatches; -use glob::{glob, Paths}; +use glob::glob; use crate::cmd::diagram::generate::config::Config; use crate::plantuml::create_plantuml; @@ -73,14 +73,25 @@ fn save_last_generation_timestamp(last_gen_path: &Path) -> Result<()> { Ok(()) } -fn get_puml_paths(config: &Config) -> Result { - let glob_pattern = format!("{}/**/*.puml", config.source_directory); - glob(&glob_pattern).map_err(|e| { - anyhow::Error::new(e).context(format!( - "unable to parse the glob pattern ({})", - &glob_pattern - )) - }) +fn get_puml_paths(config: &Config) -> Vec { + config + .source_patterns + .split(",") + .map(str::trim) + .map(|pattern| format!("{}/{}", config.source_directory, pattern)) + .flat_map(|glob_pattern| { + glob(&glob_pattern) + .map(|paths| paths.flatten()) + .map_err(|e| { + anyhow::Error::new(e).context(format!( + "unable to parse the glob pattern ({})", + &glob_pattern + )) + }) + .map(|paths| paths.collect::>()) + .unwrap() + }) + .collect::>() } pub fn execute_diagram_generate(arg_matches: &ArgMatches) -> Result<()> { @@ -107,9 +118,9 @@ pub fn execute_diagram_generate(arg_matches: &ArgMatches) -> Result<()> { plantuml.download()?; // get latest generation let last_generation_timestamp = get_last_generation_timestamp(last_gen_path)?; - // discover .puml files - let puml_paths = get_puml_paths(config)?.flatten(); - // generate .puml file + // discover source files + let puml_paths = get_puml_paths(config); + // generate source files for source_path in puml_paths { let last_modification_timestamp = get_last_modified(&source_path)?; log::debug!( @@ -142,7 +153,11 @@ mod test { #[test] fn test_diagram_generation() { delete_file_or_directory("target/tests/cmd/diagram/generate".as_ref()).unwrap(); - for source_file in &["diagrams_a.puml", "folder_a/diagrams_b.puml"] { + for source_file in &[ + "diagrams_a.puml", + "diagrams_c.plantuml", + "folder_a/diagrams_b.puml", + ] { let from_prefix = "test/source"; let from_path = Path::new(from_prefix).join(source_file); let to_prefix = "target/tests/cmd/diagram/generate/source"; @@ -180,6 +195,12 @@ mod test { let path_diagram_b_1_png = Path::new("target/tests/cmd/diagram/generate/source/folder_a/diagram_b_1.png"); assert!(path_diagram_b_1_png.exists()); + let path_diagram_b_0_png = + Path::new("target/tests/cmd/diagram/generate/source/diagram_c_0.png"); + assert!(path_diagram_b_0_png.exists()); + let path_diagram_b_1_png = + Path::new("target/tests/cmd/diagram/generate/source/diagram_c_1.png"); + assert!(path_diagram_b_1_png.exists()); // get path_diagram_a_0_src modified let path_diagram_a_0_png_modified_before = path_diagram_a_0_png.metadata().unwrap().modified().unwrap(); @@ -187,7 +208,6 @@ mod test { let path_diagram_a_0_src = Path::new("target/tests/cmd/diagram/generate/source/diagrams_a.puml"); let mut file_diagram_a_0_src = OpenOptions::new() - .write(true) .append(true) .open(path_diagram_a_0_src) .unwrap(); diff --git a/src/cmd/workspace/init/mod.rs b/src/cmd/workspace/init/mod.rs index 21101a3..5c07c56 100644 --- a/src/cmd/workspace/init/mod.rs +++ b/src/cmd/workspace/init/mod.rs @@ -52,6 +52,7 @@ mod test { use crate::cli::build_cli; use crate::constants::WORKSPACE_MANIFEST; use crate::utils::delete_file_or_directory; + use std::fs::OpenOptions; use super::*; @@ -89,9 +90,7 @@ mod test { delete_file_or_directory(source_path).unwrap(); create_parent_directory(&manifest_path).unwrap(); - std::fs::OpenOptions::new() - .write(true) - .create(true) + OpenOptions::create(OpenOptions::new().write(true), true) .open(manifest_path) .expect("Couldn't open file"); diff --git a/src/cmd/workspace/install/mod.rs b/src/cmd/workspace/install/mod.rs index aaa5c49..8cca422 100644 --- a/src/cmd/workspace/install/mod.rs +++ b/src/cmd/workspace/install/mod.rs @@ -128,7 +128,7 @@ pub fn execute_workspace_install(arg_matches: &ArgMatches) -> anyhow::Result<()> #[cfg(test)] mod test { - use std::fs::copy; + use std::fs::{copy, OpenOptions}; use crate::cli::build_cli; use crate::constants::WORKSPACE_MANIFEST; @@ -145,9 +145,7 @@ mod test { create_parent_directory(manifest_path).unwrap(); copy(Path::new("test/workspace-simple.yaml"), manifest_path).unwrap(); - std::fs::OpenOptions::new() - .write(true) - .create(true) + OpenOptions::create(OpenOptions::new().write(true), true) .open(manifest_path) .expect("Couldn't open file"); diff --git a/src/constants.rs b/src/constants.rs index 11d9787..8f1bafb 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -88,6 +88,12 @@ pub fn get_default_source_directory() -> String { SOURCE_DIRECTORY.to_string() } +pub const SOURCE_PATTERNS: &str = "**/*.puml,**/*.pu,**/*.pml,**/*.plantuml"; + +pub fn get_default_source_patterns() -> String { + SOURCE_PATTERNS.to_string() +} + pub const OUTPUT_DIRECTORY: &str = "distribution"; pub fn get_default_output_directory() -> String { diff --git a/test/source/diagrams_c.plantuml b/test/source/diagrams_c.plantuml new file mode 100644 index 0000000..224fa38 --- /dev/null +++ b/test/source/diagrams_c.plantuml @@ -0,0 +1,11 @@ +@startuml diagram_c_0 +object ObjectA +object ObjectB +ObjectA -> ObjectB +@enduml + +@startuml diagram_c_1 +object ObjectC +object ObjectD +ObjectC -> ObjectD +@enduml