add support for parsing Maven project information (using effective pom)

This commit is contained in:
Adrian Malacoda 2019-02-19 00:41:27 -06:00
parent dee9a61d87
commit c399677ab7
4 changed files with 140 additions and 3 deletions

41
scouter/Cargo.lock generated
View File

@ -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"

View File

@ -6,3 +6,5 @@ edition = "2018"
[dependencies]
cargo_metadata = "0.7.1"
sxd-xpath = "0.4.2"
sxd-document = "0.3.0"

View File

@ -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("<?xml").expect("failed to find start of xml")
..
full_output.find("</project>").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<cargo_metadata::Metadata> 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);
}
}

42
scouter/testdata/maven/pom.xml vendored Normal file
View File

@ -0,0 +1,42 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>net.monarchpass</groupId>
<artifactId>shenlong-maven-test</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Shenlong Maven Test Project</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>7</source>
<target>7</target>
</configuration>
</plugin>
</plugins>
</build>
</project>