diff --git a/src/get.rs b/src/get.rs index 74318e4..98d7167 100644 --- a/src/get.rs +++ b/src/get.rs @@ -315,8 +315,17 @@ mod tests { test_get_package_end_to_end("hello", "bookworm").await; } + #[tokio::test] + async fn test_get_2048_universe_ubuntu_end_to_end() { + test_get_package_end_to_end("2048", "noble").await; + } + #[tokio::test] + async fn test_get_1oom_contrib_debian_end_to_end() { + test_get_package_end_to_end("1oom", "trixie").await; + } + #[tokio::test] async fn test_get_agg_svn_fallback_ok() { - test_get_package_end_to_end("agg", "sid").await; + test_get_package_end_to_end("agg", "trixie").await; } } diff --git a/src/package_info.rs b/src/package_info.rs index b394615..3c49954 100644 --- a/src/package_info.rs +++ b/src/package_info.rs @@ -119,6 +119,34 @@ fn get_base_url(dist: &str) -> &str { } } +/* +* Obtain the URL for the 'Release' file of a distribution series +*/ +fn get_release_url(base_url: &str, series: &str, pocket: &str) -> String { + let pocket_full = if pocket.is_empty() { String::new() } else { format!("-{}", pocket) }; + format!("{base_url}/dists/{series}{pocket_full}/Release") +} + +/* +* Obtain the components of a distribution series by parsing the 'Release' file +*/ +async fn get_components(base_url: &str, series: &str, pocket: &str) -> Result, Box> { + let url = get_release_url(base_url, series, pocket); + debug!("Fetching Release file from: {}", url); + + let content = reqwest::get(&url).await?.text().await?; + + for line in content.lines() { + if line.starts_with("Components:") { + if let Some((_, components)) = line.split_once(':') { + return Ok(components.split_whitespace().map(|s| s.to_string()).collect()); + } + } + } + + Err("Components not found.".into()) +} + /* * Parse a 'Sources.gz' debian package file data, to look for a target package and * return the data for that package stanza @@ -193,33 +221,49 @@ pub async fn get(package_name: &str, series: &str, pocket: &str) -> Result resp, + Err(e) => { + debug!("Failed to fetch {}: {}", url, e); + continue; } + }; + + if !response.status().is_success() { + debug!("Failed to fetch {}: status {}", url, response.status()); + continue; } - let archive_url = format!("{base_url}/{0}", stanza.directory); - return Ok(Some(PackageInfo { - dist: dist, - stanza: stanza, - preferred_vcs: preferred_vcs, - archive_url: archive_url, - })); - } else { - Err(format!("Package '{}' not found in {}/{}", package_name, dist, series).into()) + let compressed_data = response.bytes().await?; + + debug!("Downloaded Sources.gz for {}/{}/{}", dist, series, component); + + if let Some(stanza) = parse_sources(&compressed_data, package_name)? { + if let Some(vcs) = &stanza.vcs_git { + if preferred_vcs.is_none() { + preferred_vcs = Some(vcs.clone()); + } + } + + let archive_url = format!("{base_url}/{0}", stanza.directory); + return Ok(Some(PackageInfo { + dist: dist, + stanza: stanza, + preferred_vcs: preferred_vcs, + archive_url: archive_url, + })); + } } + + Err(format!("Package '{}' not found in {}/{}", package_name, dist, series).into()) } #[cfg(test)]