From bb5517470e3bee7865708ed76ca00673429da643 Mon Sep 17 00:00:00 2001 From: "Hautvast, S. (Sander)" Date: Thu, 18 Sep 2025 21:39:14 +0200 Subject: [PATCH] wip lookup in configured repositories --- src/maven/common_model.rs | 4 +- src/maven/project.rs | 78 +++++++++++++++++++++++++++++++++++++-- src/maven/reporter.rs | 39 +------------------- src/maven/settings.rs | 35 ++++++++++++++++++ 4 files changed, 113 insertions(+), 43 deletions(-) diff --git a/src/maven/common_model.rs b/src/maven/common_model.rs index 36867fa..ade1750 100644 --- a/src/maven/common_model.rs +++ b/src/maven/common_model.rs @@ -1,6 +1,6 @@ use crate::xml::dom_parser::Node; -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct Repository { pub releases: Option, pub snapshots: Option, @@ -10,7 +10,7 @@ pub struct Repository { pub layout: String, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct RepositoryPolicy { pub enabled: bool, pub update_policy: Option, diff --git a/src/maven/project.rs b/src/maven/project.rs index 6197345..ccd73f2 100644 --- a/src/maven/project.rs +++ b/src/maven/project.rs @@ -1,11 +1,17 @@ +use crate::maven::common_model::Repository; use crate::maven::pom::{Dependency, Pom}; use crate::maven::pom_parser::get_pom; use crate::maven::settings::{Settings, get_settings}; use regex::Regex; +use reqwest::blocking::Client; use std::fs; -use std::path::Path; +use std::fs::File; +use std::io::{BufWriter, Write}; +use std::path::{Path, PathBuf}; use std::sync::LazyLock; +const MAVEN_CENTRAL: &str = "https://repo1.maven.org/maven2/"; + static PROPERTY_EXPR: LazyLock = LazyLock::new(|| Regex::new(r"\$\{(.+)}").unwrap()); /// Loads all poms from a given project directory. @@ -33,11 +39,27 @@ pub fn parse_project(project_dir: &Path) -> Result { let project_home = project_dir.to_str().unwrap_or_else(|| "?").to_string(); let settings = get_settings()?; - Ok(Project { + let mut project = Project { settings, project_home, root, - }) + repositories: vec![], + }; + + let repositories = project.get_repositories(); + project.repositories = repositories; // well this is convoluted + + for pom in &project.root.modules { + for dep in &project.get_dependencies(pom) { + let path = PathBuf::from(dep.to_absolute_jar_path()); + if !path.exists() { + project + .download(dep) + .expect(&format!("Can't download jar file {}", dep)); + } + } + } + Ok(project) } // examines modules in pom and loads them @@ -72,6 +94,7 @@ pub struct Project { pub settings: Settings, pub project_home: String, pub root: Pom, + pub repositories: Vec, } impl Project { @@ -122,6 +145,55 @@ impl Project { }) } + fn download(&self, dep: &Dependency) -> Result<(), String> { + // self.repositories has all repos, + // but mirrors are not yet taken into account + + let url = format!("{}{}.jar", MAVEN_CENTRAL, dep); + + let client = Client::builder() + .timeout(std::time::Duration::from_secs(30)) + .build() + .map_err(|e| e.to_string())?; + + println!("Downloading {}", &url); + let response = client + .get(&url) + .header("User-Agent", "Maven/1.0") + .send() + .map_err(|e| e.to_string())?; + if response.status().is_success() { + let bytes = response.bytes().map_err(|e| e.to_string())?; + let mut buf_writer = BufWriter::new( + File::create(dep.to_absolute_jar_path()).map_err(|e| e.to_string())?, + ); + + buf_writer.write_all(&bytes).map_err(|e| e.to_string())?; + buf_writer.flush().map_err(|e| e.to_string())?; + println!("Downloaded {}", &url); + } + Ok(()) + } + + pub fn get_repositories(&self) -> Vec { + let mut repositories = vec![]; + for pom in &self.root.modules { + repositories.append(&mut pom.repositories.to_vec()); + } + self.add_repositories(&self.root, &mut repositories); + repositories.append(&mut self.settings.get_repositories().to_vec()); + repositories + } + + fn add_repositories(&self, pom: &Pom, repositories: &mut Vec) { + repositories.append(&mut pom.repositories.to_vec()); + if let Some(parent) = &pom.parent { + if let Some(parent_pom) = self.get_pom(&parent.group_id, &parent.artifact_id) { + self.add_repositories(parent_pom, repositories); + } + } + } + // searches in managed_dependencies for dependencies fn collect_managed_dependencies<'a>( &self, diff --git a/src/maven/reporter.rs b/src/maven/reporter.rs index 92352cd..2df3c02 100644 --- a/src/maven/reporter.rs +++ b/src/maven/reporter.rs @@ -3,22 +3,17 @@ use crate::maven::project::Project; use regex::Regex; use std::collections::HashSet; use std::fs::File; -use std::io::{BufWriter, Write}; + use std::path::{Path, PathBuf}; use std::sync::LazyLock; use zip::ZipArchive; static CLASS_EXPR: LazyLock = LazyLock::new(|| Regex::new(r"(.+)/.+\.class").unwrap()); -const MAVEN_CENTRAL: &str = "https://repo1.maven.org/maven2/"; // TODO should not be downloading dependencies pub fn report(project: &Project) { let pom = &project.root; // TODO other modules for dep in &project.get_dependencies(pom) { - let path = PathBuf::from(dep.to_absolute_jar_path()); - if !path.exists() { - download(&pom, dep).expect(&format!("Can't download jar file {}", dep)); - } let jar_file = File::open(dep.to_absolute_jar_path()).expect("Can't open jar file"); let mut archive = ZipArchive::new(jar_file).expect("Can't read jar file"); @@ -44,38 +39,6 @@ fn new_path(dir: &PathBuf, child: &str) -> PathBuf { new_dir } -use reqwest::blocking::Client; - -fn download(pom: &Pom, dep: &Dependency) -> Result<(), String> { - //TODO inspect settings.xml - // gather repositories - // pom.repositories - - let url = format!("{}{}.jar", MAVEN_CENTRAL, dep); - - let client = Client::builder() - .timeout(std::time::Duration::from_secs(30)) - .build() - .map_err(|e| e.to_string())?; - - println!("Downloading {}", &url); - let response = client - .get(&url) - .header("User-Agent", "Maven/1.0") - .send() - .map_err(|e| e.to_string())?; - if response.status().is_success() { - let bytes = response.bytes().map_err(|e| e.to_string())?; - let mut buf_writer = - BufWriter::new(File::create(dep.to_absolute_jar_path()).map_err(|e| e.to_string())?); - - buf_writer.write_all(&bytes).map_err(|e| e.to_string())?; - buf_writer.flush().map_err(|e| e.to_string())?; - println!("Downloaded {}", &url); - } - Ok(()) -} - fn analyse_source(packages: &HashSet, dir: &Path) { if dir.exists() { for entry in dir.read_dir().unwrap() { diff --git a/src/maven/settings.rs b/src/maven/settings.rs index 57ff539..c61b8f9 100644 --- a/src/maven/settings.rs +++ b/src/maven/settings.rs @@ -349,6 +349,41 @@ fn get_settings_path() -> Result { Ok(settings) } +impl Settings { + pub fn get_active_profiles(&self) -> Vec<&Profile> { + self.profiles + .iter() + .filter(|p| { + if let Some(activation) = &p.activation { + activation.active_by_default //TODO other activation types are possible + } else if let Some(id) = &p.id { + self.active_profiles.contains(id) + } else { + false + } + }) + .collect() + } + + pub fn get_repositories(&self) -> Vec { + self.get_active_profiles() + .iter() + .map(|p| &p.repositories) + .flatten() + .cloned() + .collect() + } + + pub fn get_plugin_repositories(&self) -> Vec { + self.get_active_profiles() + .iter() + .map(|p| &p.plugin_repositories) + .flatten() + .cloned() + .collect() + } +} + #[derive(Debug)] pub struct Settings { pub local_repository: Option,