wip lookup in configured repositories

This commit is contained in:
Hautvast, S. (Sander) 2025-09-18 21:39:14 +02:00
parent 3f30afa689
commit bb5517470e
4 changed files with 113 additions and 43 deletions

View file

@ -1,6 +1,6 @@
use crate::xml::dom_parser::Node;
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct Repository {
pub releases: Option<RepositoryPolicy>,
pub snapshots: Option<RepositoryPolicy>,
@ -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<String>,

View file

@ -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<Regex> = 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<Project, String> {
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<Repository>,
}
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<Repository> {
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<Repository>) {
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,

View file

@ -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<Regex> = 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<String>, dir: &Path) {
if dir.exists() {
for entry in dir.read_dir().unwrap() {

View file

@ -349,6 +349,41 @@ fn get_settings_path() -> Result<PathBuf, String> {
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<Repository> {
self.get_active_profiles()
.iter()
.map(|p| &p.repositories)
.flatten()
.cloned()
.collect()
}
pub fn get_plugin_repositories(&self) -> Vec<Repository> {
self.get_active_profiles()
.iter()
.map(|p| &p.plugin_repositories)
.flatten()
.cloned()
.collect()
}
}
#[derive(Debug)]
pub struct Settings {
pub local_repository: Option<String>,