This commit is contained in:
11
src/get.rs
11
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Vec<String>, Box<dyn Error>> {
|
||||
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<Optio
|
||||
|
||||
let base_url = get_base_url(&dist);
|
||||
|
||||
let component = "main"; // TODO: Make configurable or detect
|
||||
let url = get_sources_url(base_url, series, pocket, component);
|
||||
let components = get_components(base_url, series, pocket).await?;
|
||||
debug!("Found components: {:?}", components);
|
||||
|
||||
debug!("Fetching sources from: {}", url);
|
||||
|
||||
let response = reqwest::get(&url).await?;
|
||||
let compressed_data = response.bytes().await?;
|
||||
|
||||
debug!("Downloaded Sources.gz for {}/{}", dist, series);
|
||||
for component in components {
|
||||
let url = get_sources_url(base_url, series, pocket, &component);
|
||||
|
||||
debug!("Fetching sources from: {}", url);
|
||||
|
||||
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 response = match reqwest::get(&url).await {
|
||||
Ok(resp) => 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)]
|
||||
|
||||
Reference in New Issue
Block a user