diff --git a/scouter/Cargo.lock b/scouter/Cargo.lock index 24acf05..5c250de 100644 --- a/scouter/Cargo.lock +++ b/scouter/Cargo.lock @@ -65,6 +65,11 @@ name = "libc" version = "0.2.48" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "peresil" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "proc-macro2" version = "0.4.27" @@ -73,6 +78,11 @@ dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "quick-error" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "quote" version = "0.6.11" @@ -96,6 +106,8 @@ name = "scouter" version = "0.0.1" dependencies = [ "cargo_metadata 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "sxd-document 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sxd-xpath 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -137,6 +149,25 @@ dependencies = [ "serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "sxd-document" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "peresil 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "typed-arena 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "sxd-xpath" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "peresil 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "sxd-document 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "syn" version = "0.15.26" @@ -147,6 +178,11 @@ dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "typed-arena" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "unicode-xid" version = "0.1.0" @@ -181,7 +217,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07e791d3be96241c77c43846b665ef1384606da2cd2a48730abe606a12906e02" "checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b" "checksum libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)" = "e962c7641008ac010fa60a7dfdc1712449f29c44ef2d4702394aea943ee75047" +"checksum peresil 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f658886ed52e196e850cfbbfddab9eaa7f6d90dd0929e264c31e5cec07e09e57" "checksum proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)" = "4d317f9caece796be1980837fd5cb3dfec5613ebdb04ad0956deea83ce168915" +"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" "checksum quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "cdd8e04bd9c52e0342b406469d494fcb033be4bdbe5c606016defbb1681411e1" "checksum rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "adacaae16d02b6ec37fdc7acfcddf365978de76d1983d3ee22afc260e1ca9619" "checksum ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7" @@ -190,7 +228,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)" = "9f301d728f2b94c9a7691c90f07b0b4e8a4517181d9461be94c04bddeb4bd850" "checksum serde_derive 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)" = "beed18e6f5175aef3ba670e57c60ef3b1b74d250d962a26604bff4c80e970dd4" "checksum serde_json 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)" = "27dce848e7467aa0e2fcaf0a413641499c0b745452aaca1194d24dedde9e13c9" +"checksum sxd-document 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7f9daa5f04135690dcb001fd5d4f1d536d62e988262954e68abb3ab7db36a4f9" +"checksum sxd-xpath 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "36e39da5d30887b5690e29de4c5ebb8ddff64ebd9933f98a01daaa4fd11b36ea" "checksum syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)" = "f92e629aa1d9c827b2bb8297046c1ccffc57c99b947a680d3ccff1f136a3bee9" +"checksum typed-arena 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c6c06a92aef38bb4dc5b0df00d68496fc31307c5344c867bb61678c6e1671ec5" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" diff --git a/scouter/Cargo.toml b/scouter/Cargo.toml index 24cb402..99f4631 100644 --- a/scouter/Cargo.toml +++ b/scouter/Cargo.toml @@ -6,3 +6,5 @@ edition = "2018" [dependencies] cargo_metadata = "0.7.1" +sxd-xpath = "0.4.2" +sxd-document = "0.3.0" diff --git a/scouter/src/lib.rs b/scouter/src/lib.rs index 64da62b..77f4f76 100644 --- a/scouter/src/lib.rs +++ b/scouter/src/lib.rs @@ -1,4 +1,5 @@ use std::path::{Path, PathBuf}; +use std::process::Command; #[derive(Debug, PartialEq)] pub enum ProjectType { @@ -35,9 +36,9 @@ impl Project { pub fn info(&self) -> ProjectInfo { match self.project_type { - ProjectType::Maven => ProjectInfo { - name: "placeholder".into(), - version: "placeholder".into() + ProjectType::Maven => { + let effective_pom = self.read_effective_pom(); + ProjectInfo::from_pom(&effective_pom) }, ProjectType::Npm => ProjectInfo { name: "placeholder".into(), @@ -53,6 +54,21 @@ impl Project { .exec() .expect("metadata call failed") } + + fn read_effective_pom(&self) -> sxd_document::Package { + let full_output = std::str::from_utf8(&Command::new("mvn") + .arg("help:effective-pom") + .current_dir(&self.path) + .output() + .expect("failed to generate effective pom") + .stdout).expect("failed to generate string from output").to_owned(); + let xml = full_output.get( + full_output.find("").expect("failed to find end of xml") + 10 + ).expect("failed to extract xml body"); + sxd_document::parser::parse(xml).expect("failed to parse effective pom") + } } #[derive(Debug)] @@ -77,6 +93,32 @@ impl From for ProjectInfo { } } +impl ProjectInfo { + fn from_pom(pom: &sxd_document::Package) -> Self { + let document = pom.as_document(); + + let mut context = sxd_xpath::context::Context::new(); + context.set_namespace("mvn", "http://maven.apache.org/POM/4.0.0"); + + let factory = sxd_xpath::Factory::new(); + let name_xpath = factory.build("/mvn:project/mvn:name") + .expect("failed to compile name xpath") + .expect("No XPath was compiled"); + let version_xpath = factory.build("/mvn:project/mvn:version") + .expect("failed to compile name xpath") + .expect("No XPath was compiled"); + + ProjectInfo { + name: name_xpath.evaluate(&context, document.root()) + .expect("failed to evaluate name expression") + .into_string(), + version: version_xpath.evaluate(&context, document.root()) + .expect("failed to evaluate version expression") + .into_string(), + } + } +} + pub struct Scouter { search_path: PathBuf } @@ -129,4 +171,14 @@ mod test { assert_eq!(env!("CARGO_PKG_NAME"), project_info.name); assert_eq!(env!("CARGO_PKG_VERSION"), project_info.version); } + + #[test] + fn test_maven_project() { + let mut scouter = Scouter::new(format!("{}/testdata/maven", env!("CARGO_MANIFEST_DIR"))); + let project = scouter.next().unwrap(); + let project_info = project.info(); + assert_eq!(ProjectType::Maven, project.project_type); + assert_eq!("Shenlong Maven Test Project", project_info.name); + assert_eq!("1.0.0-SNAPSHOT", project_info.version); + } } diff --git a/scouter/testdata/maven/pom.xml b/scouter/testdata/maven/pom.xml new file mode 100644 index 0000000..8d85746 --- /dev/null +++ b/scouter/testdata/maven/pom.xml @@ -0,0 +1,42 @@ + + 4.0.0 + + net.monarchpass + shenlong-maven-test + 1.0.0-SNAPSHOT + jar + + Shenlong Maven Test Project + + + UTF-8 + + + + + junit + junit + 4.11 + test + + + com.googlecode.json-simple + json-simple + 1.1.1 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.0 + + 7 + 7 + + + + +