From b14be4dfb1b67a86c93ef01d6347f80e91ccb1d1 Mon Sep 17 00:00:00 2001 From: Steve Smith Date: Fri, 31 Jul 2020 17:54:03 +1000 Subject: [PATCH] feat(package): Add Maven pom.xml version support (#1511) * Add gitignore for Emacs backup files. * Add package version support for Maven pom.xml. * Update docs with Maven package version support. * Fix for clippy. --- .gitignore | 4 + docs/config/README.md | 2 +- src/modules/package.rs | 178 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 183 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 9b00ab1a0..62b0a1a1e 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,10 @@ Cargo.lock # Vim swap files *.swp +# Emacs +*~ +\#*\# + # Compiled files for documentation docs/node_modules docs/.vuepress/dist/ diff --git a/docs/config/README.md b/docs/config/README.md index 0680ac3c2..f59d3d618 100644 --- a/docs/config/README.md +++ b/docs/config/README.md @@ -1629,7 +1629,7 @@ package, and shows its current version. The module currently supports `npm`, `ca - **julia** - The package version is extracted from the `Project.toml` present - **mix** - The `mix` package version is extracted from the `mix.exs` present - **helm** - The `helm` chart version is extracted from the `Chart.yaml` present - +- **maven** - The `maven` package version is extracted from the `pom.xml` present > ⚠️ The version being shown is that of the package whose source code is in your > current directory, not your package manager. diff --git a/src/modules/package.rs b/src/modules/package.rs index c7ff45508..5c56ac12c 100644 --- a/src/modules/package.rs +++ b/src/modules/package.rs @@ -5,6 +5,8 @@ use crate::configs::package::PackageConfig; use crate::formatter::StringFormatter; use crate::utils; +use quick_xml::events::Event as QXEvent; +use quick_xml::Reader as QXReader; use regex::Regex; use serde_json as json; @@ -122,6 +124,44 @@ fn extract_mix_version(file_contents: &str) -> Option { Some(formatted_version) } +fn extract_maven_version(file_contents: &str) -> Option { + let mut reader = QXReader::from_str(file_contents); + reader.trim_text(true); + + let mut buf = vec![]; + let mut in_ver = false; + let mut depth = 0; + loop { + match reader.read_event(&mut buf) { + Ok(QXEvent::Start(ref e)) => { + in_ver = depth == 1 && e.name() == b"version"; + depth += 1; + } + Ok(QXEvent::End(_)) => { + in_ver = false; + depth -= 1; + } + Ok(QXEvent::Text(t)) if in_ver => { + let ver = t.unescape_and_decode(&reader).ok(); + return match ver { + // Ignore version which is just a property reference + Some(ref v) if !v.starts_with('$') => ver, + _ => None, + }; + } + Ok(QXEvent::Eof) => break, + Ok(_) => (), + + Err(err) => { + log::warn!("Error parsing pom.xml`:\n{}", err); + break; + } + } + } + + None +} + fn get_package_version(base_dir: &PathBuf, config: &PackageConfig) -> Option { if let Ok(cargo_toml) = utils::read_file(base_dir.join("Cargo.toml")) { extract_cargo_version(&cargo_toml) @@ -139,6 +179,8 @@ fn get_package_version(base_dir: &PathBuf, config: &PackageConfig) -> Option io::Result<()> { + // pom.xml with common nested tags and dependencies + let pom = " + + + 4.0.0 + parent + pom + + 0.3.20-SNAPSHOT + + Test POM + Test POM + + + 1.8 + 2.3.3 + 4.13 + 3.3.3 + + + + + + jta + jta + ${jta.version} + + + com.fasterxml.woodstox + woodstox-core + ${woodstox.core.version} + + + com.fasterxml.jackson.dataformat + jackson-dataformat-xml + ${jackson.version} + + + + + + + + maven-enforcer-plugin + ${maven.enforcer.version} + + + enforce-maven + + enforce + + + + + 3.0.5 + + + + + + + + + + "; + + let project_dir = create_project_dir()?; + fill_config(&project_dir, "pom.xml", Some(&pom))?; + expect_output(&project_dir, Some("0.3.20-SNAPSHOT"), None)?; + project_dir.close() + } + + #[test] + fn test_extract_maven_version_no_version() -> io::Result<()> { + // pom.xml with common nested tags and dependencies + let pom = " + + + 4.0.0 + + + + jta + jta + 1.2.3 + + + + "; + + let project_dir = create_project_dir()?; + fill_config(&project_dir, "pom.xml", Some(&pom))?; + expect_output(&project_dir, None, None)?; + project_dir.close() + } + + #[test] + fn test_extract_maven_version_is_prop() -> io::Result<()> { + // pom.xml with common nested tags and dependencies + let pom = " + + + 4.0.0 + ${pom.parent.version} + + "; + + let project_dir = create_project_dir()?; + fill_config(&project_dir, "pom.xml", Some(&pom))?; + expect_output(&project_dir, None, None)?; + project_dir.close() + } + + #[test] + fn test_extract_maven_version_no_version_but_deps() -> io::Result<()> { + // pom.xml with common nested tags and dependencies + let pom = " + + + 4.0.0 + parent + pom + + Test POM + Test POM + + "; + + let project_dir = create_project_dir()?; + fill_config(&project_dir, "pom.xml", Some(&pom))?; + expect_output(&project_dir, None, None)?; + project_dir.close() + } + fn create_project_dir() -> io::Result { Ok(tempfile::tempdir()?) }