added settings.xml
This commit is contained in:
parent
2deae73132
commit
f6e39067c8
11 changed files with 634 additions and 61 deletions
24
index.html
Normal file
24
index.html
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
<!DOCTYPE html><html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Project Dependencies</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: sans-serif;
|
||||||
|
}
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
th, td {
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
padding: 8px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
th {
|
||||||
|
background-color: #f2f2f2;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body><h1>Project Dependencies</h1><table><thead><tr><th>Group ID</th><th>Artifact ID</th><th>Version</th></tr></thead><tbody></tbody></table></body></html>
|
||||||
22
src/main.rs
22
src/main.rs
|
|
@ -1,7 +1,8 @@
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::env;
|
use std::{env, fs};
|
||||||
use undeepend::maven::project::parse_project;
|
use undeepend::maven::project::parse_project;
|
||||||
use undeepend::maven::reporter::report;
|
use undeepend::maven::reporter::report;
|
||||||
|
use undeepend::maven::settings::get_settings;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let args = std::env::args().collect::<Vec<String>>();
|
let args = std::env::args().collect::<Vec<String>>();
|
||||||
|
|
@ -11,15 +12,12 @@ fn main() {
|
||||||
PathBuf::from(&args[1])
|
PathBuf::from(&args[1])
|
||||||
};
|
};
|
||||||
let project = parse_project(&dir).unwrap();
|
let project = parse_project(&dir).unwrap();
|
||||||
// //
|
get_settings().unwrap();
|
||||||
// // fs::write(
|
fs::write(
|
||||||
// // PathBuf::from("index.html"),
|
PathBuf::from("index.html"),
|
||||||
// // project.generate_dependency_html(),
|
project.generate_dependency_html(),
|
||||||
// // )
|
)
|
||||||
// // .unwrap();
|
.unwrap();
|
||||||
//
|
|
||||||
// report(&project);
|
report(&project);
|
||||||
for pom in project.iter(){
|
|
||||||
println!("{:?}", pom);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,14 @@
|
||||||
|
use std::{env, sync::LazyLock};
|
||||||
|
|
||||||
pub mod metadata;
|
pub mod metadata;
|
||||||
pub mod pom;
|
pub mod pom;
|
||||||
pub mod pom_parser;
|
pub mod pom_parser;
|
||||||
pub mod project;
|
pub mod project;
|
||||||
pub mod reporter;
|
pub mod reporter;
|
||||||
|
pub mod settings;
|
||||||
|
|
||||||
|
pub const HOME: LazyLock<String> = LazyLock::new(|| env::var("HOME").unwrap());
|
||||||
|
pub const MAVEN_HOME: LazyLock<String> =
|
||||||
|
LazyLock::new(|| env::var("MAVEN_HOME").unwrap_or("".to_string()));
|
||||||
|
pub const CUSTOM_SETTINGS_LOCATION: LazyLock<String> =
|
||||||
|
LazyLock::new(|| env::var("SETTINGS_PATH").unwrap_or("".to_string()));
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,9 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::env;
|
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::sync::LazyLock;
|
|
||||||
|
|
||||||
/// the maven object model
|
/// the maven object model
|
||||||
|
|
||||||
const HOME: LazyLock<String> = LazyLock::new(|| env::var("HOME").unwrap());
|
|
||||||
|
|
||||||
#[derive(PartialEq, Debug)]
|
#[derive(PartialEq, Debug)]
|
||||||
pub struct Pom {
|
pub struct Pom {
|
||||||
pub parent: Option<Parent>,
|
pub parent: Option<Parent>,
|
||||||
|
|
@ -80,13 +76,19 @@ impl Dependency {
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
|
use crate::maven::HOME;
|
||||||
|
|
||||||
impl Display for Dependency {
|
impl Display for Dependency {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
let version = self.version.clone().unwrap_or_else(|| "latest".to_string());
|
let version = self.version.clone().unwrap_or_else(|| "latest".to_string());
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"{}/{}/{}/{}-{}",
|
"{}/{}/{}/{}-{}",
|
||||||
self.group_id.replace(".","/"), self.artifact_id, version, self.artifact_id, version
|
self.group_id.replace(".", "/"),
|
||||||
|
self.artifact_id,
|
||||||
|
version,
|
||||||
|
self.artifact_id,
|
||||||
|
version
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ use std::path::PathBuf;
|
||||||
/// parse the pom.xml into a Pom object (struct)
|
/// parse the pom.xml into a Pom object (struct)
|
||||||
pub fn get_pom(home_dir: PathBuf, xml: impl Into<String>) -> Result<Pom, SaxError> {
|
pub fn get_pom(home_dir: PathBuf, xml: impl Into<String>) -> Result<Pom, SaxError> {
|
||||||
let mut group_id = None;
|
let mut group_id = None;
|
||||||
let mut artefact_id = None;
|
let mut artifact_id = None;
|
||||||
let mut parent = None;
|
let mut parent = None;
|
||||||
let mut version = None;
|
let mut version = None;
|
||||||
let mut name = None;
|
let mut name = None;
|
||||||
|
|
@ -21,7 +21,7 @@ pub fn get_pom(home_dir: PathBuf, xml: impl Into<String>) -> Result<Pom, SaxErro
|
||||||
for child in get_document(xml.into().as_str())?.root.children {
|
for child in get_document(xml.into().as_str())?.root.children {
|
||||||
match child.name.as_str() {
|
match child.name.as_str() {
|
||||||
"groupId" => group_id = child.text,
|
"groupId" => group_id = child.text,
|
||||||
"artifactId" => artefact_id = child.text,
|
"artifactId" => artifact_id = child.text,
|
||||||
"parent" => parent = Some(get_parent(&child)),
|
"parent" => parent = Some(get_parent(&child)),
|
||||||
"version" => version = child.text,
|
"version" => version = child.text,
|
||||||
"name" => name = child.text,
|
"name" => name = child.text,
|
||||||
|
|
@ -37,7 +37,7 @@ pub fn get_pom(home_dir: PathBuf, xml: impl Into<String>) -> Result<Pom, SaxErro
|
||||||
Ok(Pom {
|
Ok(Pom {
|
||||||
parent,
|
parent,
|
||||||
group_id,
|
group_id,
|
||||||
artifact_id: artefact_id.unwrap(),
|
artifact_id: artifact_id.unwrap(),
|
||||||
version,
|
version,
|
||||||
name,
|
name,
|
||||||
packaging,
|
packaging,
|
||||||
|
|
@ -91,19 +91,19 @@ fn get_dependencies(element: Node) -> Vec<Dependency> {
|
||||||
|
|
||||||
fn get_dependency(element: Node) -> Dependency {
|
fn get_dependency(element: Node) -> Dependency {
|
||||||
let mut grouo_id = None;
|
let mut grouo_id = None;
|
||||||
let mut artefact_id = None;
|
let mut artifact_id = None;
|
||||||
let mut version = None;
|
let mut version = None;
|
||||||
for node in element.children {
|
for node in element.children {
|
||||||
match node.name.as_str() {
|
match node.name.as_str() {
|
||||||
"groupId" => grouo_id = node.text,
|
"groupId" => grouo_id = node.text,
|
||||||
"artifactId" => artefact_id = node.text,
|
"artifactId" => artifact_id = node.text,
|
||||||
"version" => version = node.text,
|
"version" => version = node.text,
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Dependency {
|
Dependency {
|
||||||
group_id: grouo_id.unwrap(),
|
group_id: grouo_id.unwrap(),
|
||||||
artifact_id: artefact_id.unwrap(),
|
artifact_id: artifact_id.unwrap(),
|
||||||
version,
|
version,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -136,19 +136,19 @@ fn get_developer(element: Node) -> Developer {
|
||||||
|
|
||||||
fn get_parent(element: &Node) -> Parent {
|
fn get_parent(element: &Node) -> Parent {
|
||||||
let mut group_id = None;
|
let mut group_id = None;
|
||||||
let mut artefact_id = None;
|
let mut artifact_id = None;
|
||||||
let mut version = None;
|
let mut version = None;
|
||||||
for child in &element.children {
|
for child in &element.children {
|
||||||
match child.name.as_str() {
|
match child.name.as_str() {
|
||||||
"groupId" => group_id = child.text.clone(),
|
"groupId" => group_id = child.text.clone(),
|
||||||
"artefactId" => artefact_id = child.text.clone(),
|
"artifactId" => artifact_id = child.text.clone(),
|
||||||
"version" => version = child.text.clone(),
|
"version" => version = child.text.clone(),
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Parent {
|
Parent {
|
||||||
group_id: group_id.unwrap(),
|
group_id: group_id.unwrap(),
|
||||||
artifact_id: artefact_id.unwrap(),
|
artifact_id: artifact_id.unwrap(),
|
||||||
version: version.unwrap(),
|
version: version.unwrap(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -196,15 +196,14 @@ impl Project {
|
||||||
get_project_pom(&self.root, group_id, artifact_id)
|
get_project_pom(&self.root, group_id, artifact_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter(&self) -> PomIterator{
|
pub fn iter<'a>(&'a self) -> PomIterator<'a> {
|
||||||
PomIterator{
|
PomIterator {
|
||||||
project: self,
|
project: self,
|
||||||
idx: 0,
|
idx: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub struct PomIterator<'a> {
|
pub struct PomIterator<'a> {
|
||||||
project: &'a Project,
|
project: &'a Project,
|
||||||
idx: usize,
|
idx: usize,
|
||||||
|
|
@ -212,10 +211,7 @@ pub struct PomIterator<'a> {
|
||||||
|
|
||||||
impl<'a> PomIterator<'a> {
|
impl<'a> PomIterator<'a> {
|
||||||
pub fn new(project: &'a Project) -> Self {
|
pub fn new(project: &'a Project) -> Self {
|
||||||
PomIterator {
|
PomIterator { project, idx: 0 }
|
||||||
project,
|
|
||||||
idx: 0,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -231,4 +227,4 @@ impl<'a> Iterator for PomIterator<'a> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ use crate::maven::project::Project;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{BufWriter, Read, Write};
|
use std::io::{BufWriter, Write};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::sync::LazyLock;
|
use std::sync::LazyLock;
|
||||||
use zip::ZipArchive;
|
use zip::ZipArchive;
|
||||||
|
|
@ -11,6 +11,7 @@ use zip::ZipArchive;
|
||||||
static CLASS_EXPR: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"(.+)/.+\.class").unwrap());
|
static CLASS_EXPR: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"(.+)/.+\.class").unwrap());
|
||||||
const MAVEN_CENTRAL: &str = "https://repo1.maven.org/maven2/";
|
const MAVEN_CENTRAL: &str = "https://repo1.maven.org/maven2/";
|
||||||
|
|
||||||
|
// TODO should not be downloading dependencies
|
||||||
pub fn report(project: &Project) {
|
pub fn report(project: &Project) {
|
||||||
let pom = &project.root;
|
let pom = &project.root;
|
||||||
for dep in &project.get_dependencies(pom) {
|
for dep in &project.get_dependencies(pom) {
|
||||||
|
|
@ -52,14 +53,14 @@ fn download(dep: &Dependency) -> Result<(), String> {
|
||||||
let url = format!("{}{}.jar", MAVEN_CENTRAL, dep);
|
let url = format!("{}{}.jar", MAVEN_CENTRAL, dep);
|
||||||
|
|
||||||
let client = Client::builder()
|
let client = Client::builder()
|
||||||
.timeout(std::time::Duration::from_secs(30)) // Ruime timeout instellen
|
.timeout(std::time::Duration::from_secs(30))
|
||||||
.build()
|
.build()
|
||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
println!("Downloading {}", &url);
|
println!("Downloading {}", &url);
|
||||||
let response = client
|
let response = client
|
||||||
.get(&url)
|
.get(&url)
|
||||||
.header("User-Agent", "Maven/1.0") // Goede practice om een User-Agent te sturen
|
.header("User-Agent", "Maven/1.0")
|
||||||
.send()
|
.send()
|
||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| e.to_string())?;
|
||||||
if response.status().is_success() {
|
if response.status().is_success() {
|
||||||
|
|
|
||||||
523
src/maven/settings.rs
Normal file
523
src/maven/settings.rs
Normal file
|
|
@ -0,0 +1,523 @@
|
||||||
|
use std::{fs, path::PathBuf, str::FromStr};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
maven::{CUSTOM_SETTINGS_LOCATION, HOME, MAVEN_HOME},
|
||||||
|
xml::dom_parser::{Node, get_document},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn get_settings() -> Result<Settings, String> {
|
||||||
|
let mut local_repository = None;
|
||||||
|
let mut interactive_mode = true;
|
||||||
|
let mut use_plugin_registry = false;
|
||||||
|
let mut offline = false;
|
||||||
|
let mut proxies = vec![];
|
||||||
|
let mut servers = vec![];
|
||||||
|
let mut mirrors = vec![];
|
||||||
|
let mut profiles = vec![];
|
||||||
|
let mut active_profiles = vec![];
|
||||||
|
let mut plugin_groups = vec![];
|
||||||
|
|
||||||
|
let settings_path = get_settings_path();
|
||||||
|
let settings_file = fs::read_to_string(settings_path?).map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
|
for child in get_document(settings_file)
|
||||||
|
.map_err(|err| err.to_string())?
|
||||||
|
.root
|
||||||
|
.children
|
||||||
|
{
|
||||||
|
match child.name.as_str() {
|
||||||
|
"localRepository" => local_repository = child.text,
|
||||||
|
"interactiveMode" => interactive_mode = child.text.map(|b| b == "true").unwrap_or(true),
|
||||||
|
"usePluginRegistry" => {
|
||||||
|
use_plugin_registry = child.text.map(|b| b == "true").unwrap_or(false)
|
||||||
|
}
|
||||||
|
"offline" => offline = child.text.map(|b| b == "true").unwrap_or(false),
|
||||||
|
"proxies" => proxies = get_proxies(child),
|
||||||
|
"servers" => servers = get_servers(child),
|
||||||
|
"mirrors" => mirrors = get_mirrors(child),
|
||||||
|
"profiles" => profiles = get_profiles(child),
|
||||||
|
"activeProfiles" => active_profiles = get_active_profiles(child),
|
||||||
|
"pluginGroups" => plugin_groups = get_plugin_groups(child),
|
||||||
|
_ => {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Settings {
|
||||||
|
local_repository,
|
||||||
|
interactive_mode,
|
||||||
|
use_plugin_registry,
|
||||||
|
offline,
|
||||||
|
proxies,
|
||||||
|
servers,
|
||||||
|
mirrors,
|
||||||
|
profiles,
|
||||||
|
active_profiles,
|
||||||
|
plugin_groups,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_proxies(element: Node) -> Vec<Proxy> {
|
||||||
|
let mut proxies = vec![];
|
||||||
|
for child in element.children {
|
||||||
|
proxies.push(get_proxy(child));
|
||||||
|
}
|
||||||
|
proxies
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_active_profiles(element: Node) -> Vec<String> {
|
||||||
|
let mut active_profiles = vec![];
|
||||||
|
for child in element.children {
|
||||||
|
if let Some(active_profile) = child.text {
|
||||||
|
active_profiles.push(active_profile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
active_profiles
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_plugin_groups(element: Node) -> Vec<String> {
|
||||||
|
let mut plugin_groups = vec![];
|
||||||
|
for child in element.children {
|
||||||
|
if let Some(plugin_group) = child.text {
|
||||||
|
plugin_groups.push(plugin_group);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
plugin_groups
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_servers(servers_element: Node) -> Vec<Server> {
|
||||||
|
let mut servers = vec![];
|
||||||
|
for server_element in servers_element.children {
|
||||||
|
servers.push(get_server(server_element));
|
||||||
|
}
|
||||||
|
servers
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_mirrors(mirrors_element: Node) -> Vec<Mirror> {
|
||||||
|
let mut mirrors = vec![];
|
||||||
|
for mirror_element in mirrors_element.children {
|
||||||
|
mirrors.push(get_mirror(mirror_element));
|
||||||
|
}
|
||||||
|
mirrors
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_profiles(profiles_element: Node) -> Vec<Profile> {
|
||||||
|
let mut profiles = vec![];
|
||||||
|
for mirror_element in profiles_element.children {
|
||||||
|
profiles.push(get_profile(mirror_element));
|
||||||
|
}
|
||||||
|
profiles
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_server(server_element: Node) -> Server {
|
||||||
|
let mut id = None;
|
||||||
|
let mut username = None;
|
||||||
|
let mut password = None;
|
||||||
|
let mut private_key = None;
|
||||||
|
let mut passphrase = None;
|
||||||
|
let mut file_permissions = None;
|
||||||
|
let mut directory_permissions = None;
|
||||||
|
let mut configuration = None;
|
||||||
|
for child in server_element.children {
|
||||||
|
match child.name.as_str() {
|
||||||
|
"id" => id = child.text,
|
||||||
|
"username" => username = child.text,
|
||||||
|
"password" => password = child.text,
|
||||||
|
"private_key" => private_key = child.text,
|
||||||
|
"passphrase" => passphrase = child.text,
|
||||||
|
"filePermissions" => file_permissions = child.text,
|
||||||
|
"directoryPermissions" => directory_permissions = child.text,
|
||||||
|
"configuration" => configuration = Some(child),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Server {
|
||||||
|
id,
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
private_key,
|
||||||
|
passphrase,
|
||||||
|
file_permissions,
|
||||||
|
directory_permissions,
|
||||||
|
configuration,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_proxy(element: Node) -> Proxy {
|
||||||
|
let mut active = false;
|
||||||
|
let mut protocol = "http".to_owned();
|
||||||
|
let mut username = None;
|
||||||
|
let mut password = None;
|
||||||
|
let mut port: usize = 8080;
|
||||||
|
let mut host = None;
|
||||||
|
let mut non_proxy_hosts = None;
|
||||||
|
let mut id = None;
|
||||||
|
|
||||||
|
for child in element.children {
|
||||||
|
match child.name.as_str() {
|
||||||
|
"active" => active = child.text.map(|b| b == "true").unwrap_or(false),
|
||||||
|
"protocol" => protocol = child.text.unwrap_or("http".to_owned()),
|
||||||
|
"username" => username = child.text,
|
||||||
|
"password" => password = child.text,
|
||||||
|
"port" => {
|
||||||
|
port = child
|
||||||
|
.text
|
||||||
|
.map(|i| {
|
||||||
|
usize::from_str(&i).expect(&format!("Illegal value for port: '{}'", i))
|
||||||
|
})
|
||||||
|
.unwrap_or(8080)
|
||||||
|
}
|
||||||
|
"host" => host = child.text,
|
||||||
|
"non_proxy_hosts" => non_proxy_hosts = child.text,
|
||||||
|
"id" => id = child.text,
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Proxy {
|
||||||
|
active,
|
||||||
|
protocol,
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
port,
|
||||||
|
host,
|
||||||
|
non_proxy_hosts,
|
||||||
|
id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_mirror(mirror_element: Node) -> Mirror {
|
||||||
|
let mut id = None;
|
||||||
|
let mut mirror_of = None;
|
||||||
|
let mut url = None;
|
||||||
|
let mut name = None;
|
||||||
|
for child in mirror_element.children {
|
||||||
|
match child.name.as_str() {
|
||||||
|
"id" => id = child.text,
|
||||||
|
"mirror_of" => mirror_of = child.text,
|
||||||
|
"url" => url = child.text,
|
||||||
|
"name" => name = child.text,
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Mirror {
|
||||||
|
id,
|
||||||
|
mirror_of,
|
||||||
|
url,
|
||||||
|
name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_profile(profile_element: Node) -> Profile {
|
||||||
|
let mut id = None;
|
||||||
|
let mut activation = None;
|
||||||
|
let mut properties = vec![];
|
||||||
|
let mut repositories = vec![];
|
||||||
|
let mut plugin_repositories = vec![];
|
||||||
|
|
||||||
|
for child in profile_element.children {
|
||||||
|
match child.name.as_str() {
|
||||||
|
"id" => id = child.text,
|
||||||
|
"activation" => activation = Some(get_activation(child)),
|
||||||
|
"properties" => properties.append(&mut get_properties(child)),
|
||||||
|
"repositories" => repositories = get_repositories(child),
|
||||||
|
"pluginRepositories" => plugin_repositories = get_repositories(child),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Profile {
|
||||||
|
id,
|
||||||
|
activation,
|
||||||
|
properties,
|
||||||
|
repositories,
|
||||||
|
plugin_repositories,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_activation(activation_element: Node) -> Activation {
|
||||||
|
let mut active_by_default = false;
|
||||||
|
let mut jdk = None;
|
||||||
|
let mut os = None;
|
||||||
|
let mut property = None;
|
||||||
|
let mut file = None;
|
||||||
|
for child in activation_element.children {
|
||||||
|
match child.name.as_str() {
|
||||||
|
"activeByDefault" => {
|
||||||
|
active_by_default = child.text.map(|b| b == "true").unwrap_or(false)
|
||||||
|
}
|
||||||
|
"jdk" => jdk = child.text,
|
||||||
|
"os" => os = Some(get_activation_os(child)),
|
||||||
|
"property" => property = Some(get_activation_property(child)),
|
||||||
|
"file" => file = Some(get_activation_file(child)),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Activation {
|
||||||
|
active_by_default,
|
||||||
|
jdk,
|
||||||
|
os,
|
||||||
|
property,
|
||||||
|
file,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_properties(element: Node) -> Vec<Property> {
|
||||||
|
let mut properties = vec![];
|
||||||
|
for child in element.children {
|
||||||
|
properties.push(Property {
|
||||||
|
name: child.name,
|
||||||
|
value: child.text,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
properties
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_repositories(element: Node) -> Vec<Repository> {
|
||||||
|
let mut repositories = vec![];
|
||||||
|
|
||||||
|
for child in element.children {
|
||||||
|
match child.name.as_str() {
|
||||||
|
"repository" => repositories.push(get_repository(child)),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
repositories
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_repository(element: Node) -> Repository {
|
||||||
|
let mut releases = None;
|
||||||
|
let mut snapshots = None;
|
||||||
|
let mut id = None;
|
||||||
|
let mut name = None;
|
||||||
|
let mut url = None;
|
||||||
|
let mut layout = "default".to_owned();
|
||||||
|
|
||||||
|
for child in element.children {
|
||||||
|
match child.name.as_str() {
|
||||||
|
"releases" => releases = Some(get_update_policy(child)),
|
||||||
|
"snapshots" => snapshots = Some(get_update_policy(child)),
|
||||||
|
"id" => id = child.text,
|
||||||
|
"name" => name = child.text,
|
||||||
|
"url" => url = child.text,
|
||||||
|
"layout" => layout = child.text.unwrap_or("default".to_owned()),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Repository {
|
||||||
|
releases,
|
||||||
|
snapshots,
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
url,
|
||||||
|
layout,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_update_policy(element: Node) -> RepositoryPolicy {
|
||||||
|
let mut enabled = true;
|
||||||
|
let mut update_policy = None;
|
||||||
|
let mut checksum_policy = None;
|
||||||
|
|
||||||
|
for child in element.children {
|
||||||
|
match child.name.as_str() {
|
||||||
|
"enabled" => enabled = child.text.map(|b| b == "true").unwrap_or(true),
|
||||||
|
"update_policy" => update_policy = child.text,
|
||||||
|
"checksum_policy" => checksum_policy = child.text,
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RepositoryPolicy {
|
||||||
|
enabled,
|
||||||
|
update_policy,
|
||||||
|
checksum_policy,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_activation_os(element: Node) -> ActivationOs {
|
||||||
|
let mut name = None;
|
||||||
|
let mut family = None;
|
||||||
|
let mut arch = None;
|
||||||
|
let mut version = None;
|
||||||
|
for child in element.children {
|
||||||
|
match child.name.as_str() {
|
||||||
|
"name" => name = child.text,
|
||||||
|
"family" => family = child.text,
|
||||||
|
"arch" => arch = child.text,
|
||||||
|
"version" => version = child.text,
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ActivationOs {
|
||||||
|
name,
|
||||||
|
family,
|
||||||
|
arch,
|
||||||
|
version,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_activation_property(element: Node) -> ActivationProperty {
|
||||||
|
let mut name = None;
|
||||||
|
let mut value = None;
|
||||||
|
for child in element.children {
|
||||||
|
match child.name.as_str() {
|
||||||
|
"name" => name = child.text,
|
||||||
|
"value" => value = child.text,
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ActivationProperty { name, value }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_activation_file(element: Node) -> ActivationFile {
|
||||||
|
let mut missing = None;
|
||||||
|
let mut exists = None;
|
||||||
|
for child in element.children {
|
||||||
|
match child.name.as_str() {
|
||||||
|
"missing" => missing = child.text,
|
||||||
|
"exists" => exists = child.text,
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ActivationFile { missing, exists }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_settings_path() -> Result<PathBuf, String> {
|
||||||
|
let mut settings = PathBuf::from_str(HOME.as_str()).map_err(|e| e.to_string())?;
|
||||||
|
settings.push(".m2/settings.xml");
|
||||||
|
if !settings.exists() {
|
||||||
|
settings = PathBuf::from_str(MAVEN_HOME.as_str()).map_err(|e| e.to_string())?;
|
||||||
|
settings.push("conf/settings.xml");
|
||||||
|
}
|
||||||
|
if !settings.exists() {
|
||||||
|
settings =
|
||||||
|
PathBuf::from_str(CUSTOM_SETTINGS_LOCATION.as_str()).map_err(|e| e.to_string())?;
|
||||||
|
if settings.is_dir() {
|
||||||
|
settings.push("settings.xml");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(settings)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Settings {
|
||||||
|
local_repository: Option<String>,
|
||||||
|
interactive_mode: bool,
|
||||||
|
use_plugin_registry: bool,
|
||||||
|
offline: bool,
|
||||||
|
proxies: Vec<Proxy>,
|
||||||
|
servers: Vec<Server>,
|
||||||
|
mirrors: Vec<Mirror>,
|
||||||
|
profiles: Vec<Profile>,
|
||||||
|
active_profiles: Vec<String>,
|
||||||
|
plugin_groups: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Server {
|
||||||
|
id: Option<String>,
|
||||||
|
username: Option<String>,
|
||||||
|
password: Option<String>,
|
||||||
|
private_key: Option<String>,
|
||||||
|
passphrase: Option<String>,
|
||||||
|
file_permissions: Option<String>,
|
||||||
|
directory_permissions: Option<String>,
|
||||||
|
configuration: Option<Node>, //xsd:any
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Mirror {
|
||||||
|
id: Option<String>,
|
||||||
|
mirror_of: Option<String>,
|
||||||
|
name: Option<String>,
|
||||||
|
url: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Proxy {
|
||||||
|
active: bool,
|
||||||
|
protocol: String,
|
||||||
|
username: Option<String>,
|
||||||
|
password: Option<String>,
|
||||||
|
port: usize,
|
||||||
|
host: Option<String>,
|
||||||
|
non_proxy_hosts: Option<String>,
|
||||||
|
id: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Profile {
|
||||||
|
id: Option<String>,
|
||||||
|
activation: Option<Activation>,
|
||||||
|
properties: Vec<Property>,
|
||||||
|
repositories: Vec<Repository>,
|
||||||
|
plugin_repositories: Vec<Repository>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Activation {
|
||||||
|
active_by_default: bool,
|
||||||
|
jdk: Option<String>,
|
||||||
|
os: Option<ActivationOs>,
|
||||||
|
property: Option<ActivationProperty>,
|
||||||
|
file: Option<ActivationFile>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct ActivationOs {
|
||||||
|
name: Option<String>,
|
||||||
|
family: Option<String>,
|
||||||
|
arch: Option<String>,
|
||||||
|
version: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct ActivationProperty {
|
||||||
|
name: Option<String>,
|
||||||
|
value: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct ActivationFile {
|
||||||
|
missing: Option<String>,
|
||||||
|
exists: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Property {
|
||||||
|
name: String,
|
||||||
|
value: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Repository {
|
||||||
|
releases: Option<RepositoryPolicy>,
|
||||||
|
snapshots: Option<RepositoryPolicy>,
|
||||||
|
id: Option<String>,
|
||||||
|
name: Option<String>,
|
||||||
|
url: Option<String>,
|
||||||
|
layout: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct RepositoryPolicy {
|
||||||
|
enabled: bool,
|
||||||
|
update_policy: Option<String>,
|
||||||
|
checksum_policy: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test() {
|
||||||
|
let settings = get_settings().expect("no fail");
|
||||||
|
println!("{:?}", settings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
use crate::maven::project::Project;
|
use crate::maven::project::Project;
|
||||||
use maud::{PreEscaped, html};
|
use maud::{DOCTYPE, PreEscaped, html};
|
||||||
|
|
||||||
impl Project {
|
impl Project {
|
||||||
pub fn generate_dependency_html(&self) -> String {
|
pub fn generate_dependency_html(&self) -> String {
|
||||||
let html = html! {
|
let html = html! {
|
||||||
|
(DOCTYPE)
|
||||||
|
html {
|
||||||
(PreEscaped(r#"
|
(PreEscaped(r#"
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
|
|
@ -27,26 +29,29 @@ impl Project {
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
"#))
|
"#))
|
||||||
h1{"Project Dependencies"}
|
body{
|
||||||
table{
|
h1{"Project Dependencies"}
|
||||||
thead{
|
table{
|
||||||
tr {
|
thead{
|
||||||
th{"Group ID"}
|
tr {
|
||||||
th{"Artifact ID"}
|
th{"Group ID"}
|
||||||
th{"Version"}
|
th{"Artifact ID"}
|
||||||
}
|
th{"Version"}
|
||||||
}
|
}
|
||||||
tbody{
|
|
||||||
@for dependency in &self.get_dependencies(&self.root) {
|
|
||||||
tr {
|
|
||||||
td { (dependency.group_id) }
|
|
||||||
td { (dependency.artifact_id) }
|
|
||||||
td { (dependency.version.clone().unwrap()) }
|
|
||||||
}
|
}
|
||||||
|
tbody{
|
||||||
|
@for dependency in &self.get_dependencies(&self.root) {
|
||||||
|
tr {
|
||||||
|
td { (dependency.group_id) }
|
||||||
|
td { (dependency.artifact_id) }
|
||||||
|
td { (dependency.version.clone().unwrap()) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
html.into_string()
|
html.into_string()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,9 @@ use crate::xml::sax_parser::parse_string;
|
||||||
use crate::xml::{Attribute, SaxError, SaxHandler};
|
use crate::xml::{Attribute, SaxError, SaxHandler};
|
||||||
|
|
||||||
/// get a generic XML object (Document) from the xml contents. This is called DOM parsing
|
/// get a generic XML object (Document) from the xml contents. This is called DOM parsing
|
||||||
pub fn get_document(xml: &str) -> Result<Document, SaxError> {
|
pub fn get_document(xml: impl Into<String>) -> Result<Document, SaxError> {
|
||||||
let mut dom_hax_handler = DomSaxHandler::new();
|
let mut dom_hax_handler = DomSaxHandler::new();
|
||||||
parse_string(xml, Box::new(&mut dom_hax_handler))?;
|
parse_string(&xml.into(), Box::new(&mut dom_hax_handler))?;
|
||||||
|
|
||||||
Ok(dom_hax_handler.into_doc())
|
Ok(dom_hax_handler.into_doc())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ struct SAXParser<'a> {
|
||||||
xml: Vec<char>,
|
xml: Vec<char>,
|
||||||
handler: Box<&'a mut dyn SaxHandler>,
|
handler: Box<&'a mut dyn SaxHandler>,
|
||||||
position: usize,
|
position: usize,
|
||||||
|
current_line: usize,
|
||||||
current: char,
|
current: char,
|
||||||
char_buffer: Vec<char>,
|
char_buffer: Vec<char>,
|
||||||
namespace_stack: Vec<(String, isize)>,
|
namespace_stack: Vec<(String, isize)>,
|
||||||
|
|
@ -35,6 +36,7 @@ impl<'a> SAXParser<'a> {
|
||||||
xml: xml.chars().collect(),
|
xml: xml.chars().collect(),
|
||||||
handler,
|
handler,
|
||||||
position: 0,
|
position: 0,
|
||||||
|
current_line: 0,
|
||||||
current: '\0',
|
current: '\0',
|
||||||
char_buffer: Vec::new(),
|
char_buffer: Vec::new(),
|
||||||
namespace_stack: Vec::new(),
|
namespace_stack: Vec::new(),
|
||||||
|
|
@ -111,6 +113,9 @@ impl<'a> SAXParser<'a> {
|
||||||
|
|
||||||
while c.is_whitespace() {
|
while c.is_whitespace() {
|
||||||
self.skip_whitespace()?;
|
self.skip_whitespace()?;
|
||||||
|
if self.current == '/' {
|
||||||
|
break;
|
||||||
|
}
|
||||||
atts.push(self.parse_attribute()?);
|
atts.push(self.parse_attribute()?);
|
||||||
c = self.advance()?;
|
c = self.advance()?;
|
||||||
}
|
}
|
||||||
|
|
@ -158,15 +163,21 @@ impl<'a> SAXParser<'a> {
|
||||||
let att_name = self.read_until("=")?;
|
let att_name = self.read_until("=")?;
|
||||||
self.skip_whitespace()?;
|
self.skip_whitespace()?;
|
||||||
self.expect("=", "Expected =")?;
|
self.expect("=", "Expected =")?;
|
||||||
self.expect("\"", "Expected start of attribute value")?;
|
self.skip_whitespace()?;
|
||||||
|
self.expect(
|
||||||
|
r#"""#,
|
||||||
|
&format!(
|
||||||
|
"Expected start of attribute value at line {}. Instead found [{}]",
|
||||||
|
self.current_line, self.current
|
||||||
|
),
|
||||||
|
)?;
|
||||||
let att_value = self.read_until("\"")?;
|
let att_value = self.read_until("\"")?;
|
||||||
|
|
||||||
if att_name.starts_with("xmlns:") {
|
if att_name.starts_with("xmlns:") {
|
||||||
let prefix = att_name[6..].to_string();
|
let prefix = att_name[6..].to_string();
|
||||||
self.prefix_mapping
|
self.prefix_mapping
|
||||||
.insert(prefix.clone(), att_value.to_string());
|
.insert(prefix.clone(), att_value.to_string());
|
||||||
self.handler
|
self.handler.start_prefix_mapping(&prefix, &att_value);
|
||||||
.start_prefix_mapping(&prefix, &att_value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let namespace = if att_name == "xmlns" {
|
let namespace = if att_name == "xmlns" {
|
||||||
|
|
@ -245,6 +256,10 @@ impl<'a> SAXParser<'a> {
|
||||||
} else {
|
} else {
|
||||||
'\0'
|
'\0'
|
||||||
};
|
};
|
||||||
|
// print!("{}", self.current);
|
||||||
|
if self.current == '\n' {
|
||||||
|
self.current_line += 1;
|
||||||
|
}
|
||||||
Ok(self.current)
|
Ok(self.current)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue