Skip to content

Commit

Permalink
feat(psa): parse maven dependencies from pom.xml.
Browse files Browse the repository at this point in the history
  • Loading branch information
ynfeng committed Mar 6, 2021
1 parent 92e6308 commit c366114
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 29 deletions.
42 changes: 35 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions psa/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,6 @@ regex = "1"

pathdiff = "0.2.0"

xml-rs = "0.8"

sxd-xpath= "0.4.2"

sxd-document= "0.3.2"
4 changes: 2 additions & 2 deletions psa/src/dependency_analyzer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pub trait DependencyAnalyzer {
fn analysis(&self, module_path: &str) -> Vec<Dependency> {
let build_file = self.get_build_file(module_path);
match build_file {
Some(build_file) => self.analysis_dependencies(build_file.as_str()),
Some(build_file) => self.analysis_dependencies(module_path, build_file.as_str()),
_ => vec![],
}
}
Expand All @@ -21,5 +21,5 @@ pub trait DependencyAnalyzer {

fn is_build_file(&self, file: &str) -> bool;

fn analysis_dependencies(&self, build_file: &str) -> Vec<Dependency>;
fn analysis_dependencies(&self, module_path: &str, build_file: &str) -> Vec<Dependency>;
}
105 changes: 88 additions & 17 deletions psa/src/jvm/maven_dependency.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
extern crate xml;

use crate::{Dependency, DependencyAnalyzer, DependencyScope};
use std::fs::read_to_string;
use std::path::PathBuf;
use sxd_document::parser;
use sxd_xpath::{Context, Factory, Value};

pub struct MavenDependencyAnalyzer {}

Expand All @@ -12,20 +14,89 @@ impl DependencyAnalyzer for MavenDependencyAnalyzer {
}
}

fn analysis_dependencies(&self, _build_file: &str) -> Vec<Dependency> {
let mut dependencies = Vec::new();
dependencies.push(Dependency {
group: "org.springframework.boot".to_string(),
name: "spring-boot-starter-web".to_string(),
version: "2.0.0.RELEASE".to_string(),
scope: DependencyScope::Test,
});
dependencies.push(Dependency {
group: "org.springframework.boot".to_string(),
name: "spring-boot-starter-logging".to_string(),
version: "1.0.0.RELEASE".to_string(),
scope: DependencyScope::Compile,
});
dependencies
fn analysis_dependencies(&self, module_path: &str, _build_file: &str) -> Vec<Dependency> {
let build_file_path = PathBuf::from(module_path)
.join(_build_file)
.display()
.to_string();
let build_file_content =
read_to_string(build_file_path.as_str()).expect("can not open build file");
match !build_file_content.is_empty() {
true => parse_deps(build_file_content.as_str()),
_ => vec![],
}
}
}

fn parse_deps(xml_content: &str) -> Vec<Dependency> {
let mut deps = vec![];
let project = parser::parse(xml_content).unwrap();
let document = project.as_document();
let factory = Factory::new();
let mut context = Context::new();
context.set_namespace("ns", "http://maven.apache.org/POM/4.0.0");

let xpath = factory
.build("count(/ns:project/ns:dependencies/ns:dependency)")
.unwrap()
.unwrap();
let num_of_deps = xpath.evaluate(&context, document.root()).unwrap();
if let Value::Number(ref count) = num_of_deps {
for i in 0..(count.round() as i64) {
let group_id_expression = format!(
"/ns:project/ns:dependencies/ns:dependency[{}]/ns:groupId",
i + 1
);
let group_id_xpath = factory
.build(group_id_expression.as_str())
.unwrap()
.unwrap();
let group = group_id_xpath
.evaluate(&context, document.root())
.unwrap()
.string();

let artifact_id_expression = format!(
"/ns:project/ns:dependencies/ns:dependency[{}]/ns:artifactId",
i + 1
);
let artifact_id_xpath = factory
.build(artifact_id_expression.as_str())
.unwrap()
.unwrap();
let name = artifact_id_xpath
.evaluate(&context, document.root())
.unwrap()
.string();

let version_expression = format!(
"/ns:project/ns:dependencies/ns:dependency[{}]/ns:version",
i + 1
);
let version_xpath = factory.build(version_expression.as_str()).unwrap().unwrap();
let version = version_xpath
.evaluate(&context, document.root())
.unwrap()
.string();

let scope_expression = format!(
"/ns:project/ns:dependencies/ns:dependency[{}]/ns:scope",
i + 1
);
let scope_xpath = factory.build(scope_expression.as_str()).unwrap().unwrap();
let scope_content = scope_xpath.evaluate(&context, document.root()).unwrap();
let scope = match scope_content.string().as_str() {
"test" => DependencyScope::Test,
_ => DependencyScope::Compile,
};

deps.push(Dependency {
group,
name,
version,
scope,
});
}
};
deps
}
2 changes: 1 addition & 1 deletion psa/src/jvm/psa_jvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ mod tests {
let dep2 = project_dependencies.get(1).unwrap();
assert_eq!(dep2.name, "spring-boot-starter-logging");
assert_eq!(dep2.group, "org.springframework.boot");
assert_eq!(dep2.version, "1.0.0.RELEASE");
assert_eq!(dep2.version, "${spring-boot-starter.version}");
assert_eq!(dep2.scope, DependencyScope::Compile);
}

Expand Down
2 changes: 2 additions & 0 deletions psa/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ pub use psa_project::Project;
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate sxd_document;
extern crate sxd_xpath;

pub mod dependency_analyzer;
pub mod files;
Expand Down

0 comments on commit c366114

Please sign in to comment.