diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b58d103..4598789 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,6 +32,12 @@ jobs: sudo apt-get install -y pkg-config libssl-dev libgpg-error-dev libgpgme-dev - name: Build run: cargo build + env: + RUST_FLAGS: -Dwarnings + - name: Lint + run: cargo clippy --all-targets --all-features + env: + RUST_FLAGS: -Dwarnings - name: Install runtime system dependencies run: | sudo apt-get update diff --git a/src/deb/mod.rs b/src/deb/mod.rs index aed63d5..968c74d 100644 --- a/src/deb/mod.rs +++ b/src/deb/mod.rs @@ -125,8 +125,11 @@ mod tests { let cwd = temp_dir.path(); log::debug!("Created temporary directory: {}", cwd.display()); - log::info!("Pulling package {} from Ubuntu {}...", package, series); - crate::pull::pull(package, "", Some(series), "", "", dist, Some(cwd), None) + log::info!("Pulling package {} from {}...", package, series); + let package_info = crate::package_info::lookup(package, None, Some(series), "", dist, None) + .await + .expect("Cannot lookup package information"); + crate::pull::pull(&package_info, Some(series), Some(cwd), None) .await .expect("Cannot pull package"); log::info!("Successfully pulled package {}", package); diff --git a/src/main.rs b/src/main.rs index e7a16ed..c588545 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,8 +7,6 @@ use pkh::context::ContextConfig; extern crate flate2; -use pkh::pull::pull; - use pkh::changelog::generate_entry; use indicatif_log_bridge::LogWrapper; @@ -94,11 +92,8 @@ fn main() { let package = sub_matches.get_one::("package").expect("required"); let series = sub_matches.get_one::("series").map(|s| s.as_str()); let dist = sub_matches.get_one::("dist").map(|s| s.as_str()); - let version = sub_matches - .get_one::("version") - .map(|s| s.as_str()) - .unwrap_or(""); - let ppa = sub_matches + let version = sub_matches.get_one::("version").map(|s| s.as_str()); + let _ppa = sub_matches .get_one::("ppa") .map(|s| s.as_str()) .unwrap_or(""); @@ -106,16 +101,18 @@ fn main() { let (pb, progress_callback) = ui::create_progress_bar(&multi); // Since pull is async, we need to block on it - if let Err(e) = rt.block_on(pull( - package, - version, - series, - "", - ppa, - dist, - None, - Some(&progress_callback), - )) { + if let Err(e) = rt.block_on(async { + let package_info = pkh::package_info::lookup( + package, + version, + series, + "", + dist, + Some(&progress_callback), + ) + .await?; + pkh::pull::pull(&package_info, series, None, Some(&progress_callback)).await + }) { pb.finish_and_clear(); error!("{}", e); std::process::exit(1); diff --git a/src/package_info.rs b/src/package_info.rs index 12c6880..774f69b 100644 --- a/src/package_info.rs +++ b/src/package_info.rs @@ -332,7 +332,7 @@ fn parse_sources( } /// Get package information from a package, distribution series, and pocket -pub async fn get( +async fn get( package_name: &str, series: &str, pocket: &str, @@ -406,7 +406,7 @@ pub async fn get( } /// Try to find package information in a distribution, trying all series and pockets -pub async fn find_package( +async fn find_package( package_name: &str, dist: &str, pocket: &str, @@ -452,6 +452,58 @@ pub async fn find_package( Err(format!("Package '{}' not found.", package_name).into()) } +/// Lookup package information for a source package +/// +/// This function obtains package information either directly from a specific series +/// or by searching across all series in a distribution. +pub async fn lookup( + package: &str, + version: Option<&str>, + series: Option<&str>, + pocket: &str, + dist: Option<&str>, + progress: ProgressCallback<'_>, +) -> Result> { + // Obtain the package information, either directly in a series or with a search in all series + let package_info = if let Some(s) = series { + if let Some(cb) = progress { + cb( + &format!("Resolving package info for {}...", package), + "", + 0, + 0, + ); + } + + // Get the package information from that series and pocket + get(package, s, pocket, version).await? + } else { + let dist = dist.unwrap_or_else(|| + // Use auto-detection to see if current distro is ubuntu, or fallback to debian by default + if std::process::Command::new("lsb_release").arg("-i").arg("-s").output() + .map(|o| String::from_utf8_lossy(&o.stdout).trim().to_lowercase()).unwrap_or_default() == "ubuntu" { + "ubuntu" + } else { + "debian" + } + ); + + if let Some(cb) = progress { + cb( + &format!("Searching for package {} in {}...", package, dist), + "", + 0, + 0, + ); + } + + // Try to find the package in all series from that dist + find_package(package, dist, pocket, version, progress).await? + }; + + Ok(package_info) +} + #[cfg(test)] mod tests { use super::*; diff --git a/src/pull.rs b/src/pull.rs index 9816b7e..184a7e8 100644 --- a/src/pull.rs +++ b/src/pull.rs @@ -2,7 +2,6 @@ use std::cmp::min; use std::error::Error; use std::path::Path; -use crate::package_info; use crate::package_info::PackageInfo; use std::process::Command; @@ -333,64 +332,18 @@ async fn fetch_archive_sources( Ok(()) } -/// Pull a source package locally +/// Pull a source package locally using pre-retrieved package information /// -/// Will try to find the package information, and use it to download it over prefered way -/// (either git or direct archive download), as well as orig tarball, inside 'package' directory -/// The source will be extracted under 'package/package' +/// This function takes a PackageInfo struct and downloads the package using the preferred method +/// (either git or direct archive download), as well as orig tarball, inside 'package' directory. +/// The source will be extracted under 'package/package'. pub async fn pull( - package: &str, - _version: &str, + package_info: &PackageInfo, series: Option<&str>, - pocket: &str, - _ppa: &str, - dist: Option<&str>, cwd: Option<&Path>, progress: ProgressCallback<'_>, -) -> Result> { - let version_opt = if _version.is_empty() { - None - } else { - Some(_version) - }; - - /* Obtain the package information, either directly in a series or with a search in all series */ - let package_info = if let Some(s) = series { - if let Some(cb) = progress { - cb( - &format!("Resolving package info for {}...", package), - "", - 0, - 0, - ); - } - - // Get the package information from that series and pocket - package_info::get(package, s, pocket, version_opt).await? - } else { - let dist = dist.unwrap_or_else(|| - // Use auto-detection to see if current distro is ubuntu, or fallback to debian by default - if std::process::Command::new("lsb_release").arg("-i").arg("-s").output() - .map(|o| String::from_utf8_lossy(&o.stdout).trim().to_lowercase()).unwrap_or_default() == "ubuntu" { - "ubuntu" - } else { - "debian" - } - ); - - if let Some(cb) = progress { - cb( - &format!("Searching for package {} in {}...", package, dist), - "", - 0, - 0, - ); - } - - // Try to find the package in all series from that dist - package_info::find_package(package, dist, pocket, version_opt, progress).await? - }; - +) -> Result<(), Box> { + let package = &package_info.stanza.package; let package_dir = if let Some(path) = cwd { path.join(package) } else { @@ -446,7 +399,7 @@ pub async fn pull( if let Some(cb) = progress { cb("Fetching orig tarball...", "", 0, 0); } - fetch_orig_tarball(&package_info, Some(&package_dir), progress).await?; + fetch_orig_tarball(package_info, Some(&package_dir), progress).await?; } else { debug!("Native package, skipping orig tarball fetch."); } @@ -454,16 +407,16 @@ pub async fn pull( if let Some(cb) = progress { cb("Fetching dsc file...", "", 0, 0); } - fetch_dsc_file(&package_info, Some(&package_dir), progress).await?; + fetch_dsc_file(package_info, Some(&package_dir), progress).await?; } else { // Fallback to archive fetching if let Some(cb) = progress { cb("Downloading from archive...", "", 0, 0); } - fetch_archive_sources(&package_info, Some(&package_dir), progress).await?; + fetch_archive_sources(package_info, Some(&package_dir), progress).await?; } - Ok(package_info) + Ok(()) } #[cfg(test)] @@ -482,9 +435,10 @@ mod tests { let cwd = temp_dir.path(); // Main 'pull' command: the one we want to test - let info = pull(package, "", series, "", "", dist, Some(cwd), None) + let info = crate::package_info::lookup(package, None, series, "", dist, None) .await .unwrap(); + pull(&info, series, Some(cwd), None).await.unwrap(); let package_dir = cwd.join(package); assert!(package_dir.exists());