downloading from Maven central

This commit is contained in:
Shautvast 2025-08-01 18:25:34 +02:00
parent 25a5bde49c
commit e7dee59605
6 changed files with 1339 additions and 18 deletions

1256
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -9,3 +9,4 @@ env_logger = "0.11"
regex="1.11" regex="1.11"
maud = "*" maud = "*"
zip = "4.3" zip = "4.3"
reqwest = { version = "0.12", features = ["json", "blocking", "native-tls"] }

View file

@ -1,12 +1,9 @@
use std::hash::Hash;
use std::path::PathBuf; use std::path::PathBuf;
use std::{env, fs}; use std::env;
use undeepend::maven::project::parse_project; use undeepend::maven::project::parse_project;
use undeepend::maven::reporter::report; use undeepend::maven::reporter::report;
fn main() { fn main() {
let home_dir = env::var("HOME").unwrap();
let args = std::env::args().collect::<Vec<String>>(); let args = std::env::args().collect::<Vec<String>>();
let dir = if args.len() == 1 { let dir = if args.len() == 1 {
env::current_dir().expect("Could not access current directory") env::current_dir().expect("Could not access current directory")
@ -14,12 +11,12 @@ fn main() {
PathBuf::from(&args[1]) PathBuf::from(&args[1])
}; };
let project = parse_project(&dir).unwrap(); let project = parse_project(&dir).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);
} }

View file

@ -1,5 +1,6 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::env; use std::env;
use std::fmt::Display;
use std::path::PathBuf; use std::path::PathBuf;
use std::sync::LazyLock; use std::sync::LazyLock;
@ -56,7 +57,7 @@ pub struct Dependency {
impl Dependency { impl Dependency {
/// returns a relative path to the dependency location /// returns a relative path to the dependency location
pub fn to_path(&self) -> PathBuf { pub fn to_jar_path(&self) -> PathBuf {
let mut path = PathBuf::new(); let mut path = PathBuf::new();
path.push(self.group_id.replace(".", "/")); path.push(self.group_id.replace(".", "/"));
path.push(&self.artifact_id); path.push(&self.artifact_id);
@ -69,10 +70,23 @@ impl Dependency {
/// returns an absolute path based on the default maven localRepository location /// returns an absolute path based on the default maven localRepository location
// useful? // useful?
pub fn to_absolute_path(&self) -> PathBuf { pub fn to_absolute_jar_path(&self) -> PathBuf {
let mut absolute_path = PathBuf::from(HOME.as_str()); let mut absolute_path = PathBuf::from(HOME.as_str());
absolute_path.push(".m2/repository"); absolute_path.push(".m2/repository");
absolute_path.push(self.to_path()); absolute_path.push(self.to_jar_path());
absolute_path absolute_path
} }
} }
use std::fmt;
impl Display for Dependency {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let version = self.version.clone().unwrap_or_else(|| "latest".to_string());
write!(
f,
"{}/{}/{}/{}-{}",
self.group_id.replace(".","/"), self.artifact_id, version, self.artifact_id, version
)
}
}

View file

@ -196,3 +196,31 @@ impl Project {
get_project_pom(&self.root, group_id, artifact_id) get_project_pom(&self.root, group_id, artifact_id)
} }
} }
pub struct PomIterator<'a> {
project: &'a Project,
idx: usize,
}
impl<'a> PomIterator<'a> {
pub fn new(project: &'a Project) -> Self {
PomIterator {
project,
idx: 0,
}
}
}
impl<'a> Iterator for PomIterator<'a> {
type Item = &'a Pom;
fn next(&mut self) -> Option<Self::Item> {
if self.idx < self.project.root.modules.len() {
let module = &self.project.root.modules[self.idx];
self.idx += 1;
Some(module)
} else {
None
}
}
}

View file

@ -1,19 +1,24 @@
use crate::maven::pom::Dependency;
use crate::maven::project::Project; 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::path::Path; use std::io::{BufWriter, Read, Write};
use std::path::{Path, PathBuf};
use std::sync::LazyLock; use std::sync::LazyLock;
use zip::ZipArchive; 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/";
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) {
println!("{:?}", dep); let path = PathBuf::from(dep.to_absolute_jar_path());
//TODO all modules if !path.exists() {
let jar_file = File::open(dep.to_absolute_path()).expect("Can't open jar file"); download(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"); let mut archive = ZipArchive::new(jar_file).expect("Can't read jar file");
let mut packages = HashSet::new(); let mut packages = HashSet::new();
@ -39,6 +44,36 @@ pub fn report(project: &Project) {
} }
} }
use reqwest::blocking::Client;
fn download(dep: &Dependency) -> Result<(), String> {
//TODO inspect settings.xml
let url = format!("{}{}.jar", MAVEN_CENTRAL, dep);
let client = Client::builder()
.timeout(std::time::Duration::from_secs(30)) // Ruime timeout instellen
.build()
.map_err(|e| e.to_string())?;
println!("Downloading {}", &url);
let response = client
.get(&url)
.header("User-Agent", "Maven/1.0") // Goede practice om een User-Agent te sturen
.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 traverse(packages: &HashSet<String>, dir: &Path) { fn traverse(packages: &HashSet<String>, dir: &Path) {
if dir.exists() { if dir.exists() {
for entry in dir.read_dir().unwrap() { for entry in dir.read_dir().unwrap() {