get: clone the right branch for series, better testing
All checks were successful
CI / build (push) Successful in 1m50s
All checks were successful
CI / build (push) Successful in 1m50s
This commit is contained in:
82
src/get.rs
82
src/get.rs
@@ -13,7 +13,7 @@ use regex::Regex;
|
||||
|
||||
use pkh::ProgressCallback;
|
||||
|
||||
fn clone_repo(url: &str, package: &str, cwd: Option<&Path>, progress: ProgressCallback<'_>) -> Result<(), Box<dyn Error>> {
|
||||
fn clone_repo(url: &str, package: &str, branch: Option<&str>, cwd: Option<&Path>, progress: ProgressCallback<'_>) -> Result<(), Box<dyn Error>> {
|
||||
let target_path = if let Some(path) = cwd {
|
||||
path.join(package)
|
||||
} else {
|
||||
@@ -46,6 +46,10 @@ fn clone_repo(url: &str, package: &str, cwd: Option<&Path>, progress: ProgressCa
|
||||
|
||||
let mut builder = git2::build::RepoBuilder::new();
|
||||
builder.fetch_options(fetch_options);
|
||||
|
||||
if let Some(b) = branch {
|
||||
builder.branch(b);
|
||||
}
|
||||
|
||||
return match builder.clone(url, &target_path) {
|
||||
Ok(_repo) => {
|
||||
@@ -239,7 +243,7 @@ async fn fetch_archive_sources(info: &PackageInfo, cwd: Option<&Path>, progress:
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn get(package: &str, _version: &str, series: Option<&str>, pocket: &str, _ppa: &str, dist: Option<&str>, cwd: Option<&Path>, progress: ProgressCallback<'_>) -> Result<(), Box<dyn Error>> {
|
||||
pub async fn get(package: &str, _version: &str, series: Option<&str>, pocket: &str, _ppa: &str, dist: Option<&str>, cwd: Option<&Path>, progress: ProgressCallback<'_>) -> Result<PackageInfo, Box<dyn Error>> {
|
||||
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 */
|
||||
@@ -279,11 +283,26 @@ pub async fn get(package: &str, _version: &str, series: Option<&str>, pocket: &s
|
||||
if let Some(ref url) = package_info.preferred_vcs {
|
||||
// We have found a preferred VCS (git repository) for the package, so
|
||||
// we fetch the package from that repo.
|
||||
if let Some(cb) = progress {
|
||||
cb(&format!("Cloning {}...", url), "", 0, 0);
|
||||
}
|
||||
clone_repo(url.as_str(), package, Some(&package_dir), progress)?;
|
||||
|
||||
// Depending on target series, we pick target branch; if no series is specified,
|
||||
// we target the development branch, i.e. the default branch
|
||||
let branch_name = if let Some(s) = series {
|
||||
if package_info.dist == "ubuntu" {
|
||||
Some(format!("{}/{}", package_info.dist, s))
|
||||
} else {
|
||||
// Debian does not have reliable branch naming...
|
||||
// For now, we skip that part and clone default
|
||||
// TODO: Inspect remote branches and tags for matches
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
if let Some(cb) = progress {
|
||||
cb(&format!("Cloning {}{}...", url, if let Some(b) = &branch_name { format!(" (branch {})", b) } else { String::new() }), "", 0, 0);
|
||||
}
|
||||
clone_repo(url.as_str(), package, branch_name.as_deref(), Some(&package_dir), progress)?;
|
||||
if let Some(cb) = progress {
|
||||
cb("Fetching orig tarball...", "", 0, 0);
|
||||
}
|
||||
@@ -296,28 +315,55 @@ pub async fn get(package: &str, _version: &str, series: Option<&str>, pocket: &s
|
||||
fetch_archive_sources(&package_info, Some(cwd.unwrap_or(Path::new("."))), progress).await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
Ok(package_info)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
async fn test_get_package_end_to_end(package: &str, series: Option<&str>) {
|
||||
async fn test_get_package_end_to_end(package: &str, series: Option<&str>, dist: Option<&str>) {
|
||||
// This test verifies that 'pkh get' clones the repo and fetches the tarball.
|
||||
|
||||
// For determinism, we require for tests that either a distro or series is specified,
|
||||
// as no distribution would mean fallback to system distro
|
||||
assert!(dist != None || series != None);
|
||||
|
||||
// Use a temp directory as working directory
|
||||
let temp_dir = tempfile::tempdir().unwrap();
|
||||
let cwd = temp_dir.path();
|
||||
|
||||
// Main 'get' command: the one we want to test
|
||||
get(package, "", series, "", "", None, Some(cwd), None).await.unwrap();
|
||||
let info = get(package, "", series, "", "", dist, Some(cwd), None).await.unwrap();
|
||||
|
||||
let package_dir = cwd.join(package);
|
||||
assert!(package_dir.exists());
|
||||
let package_source_dir = package_dir.join(package);
|
||||
assert!(package_source_dir.exists(), "Package git repo directory not created");
|
||||
assert!(package_source_dir.join("debian").exists(), "debian directory not present");
|
||||
|
||||
if package_source_dir.join(".git").exists() {
|
||||
// Verify we are on the correct branch
|
||||
let repo = git2::Repository::open(&package_source_dir).unwrap();
|
||||
let head = repo.head().unwrap();
|
||||
let name = head.name().unwrap();
|
||||
|
||||
if let Some(s) = series {
|
||||
// The local branch should be named dist/series
|
||||
// We skip debian for now as it does not have a reliable naming scheme
|
||||
if info.dist == "ubuntu" {
|
||||
assert_eq!(name, format!("refs/heads/{0}/{s}", info.dist));
|
||||
}
|
||||
} else {
|
||||
// The local branch should be named ubuntu/devel for Ubuntu
|
||||
// Debian unfortunately does not have a reliable naming scheme
|
||||
// Given that there was no series specified, and this is a test,
|
||||
// we require to have a distribution specified
|
||||
if dist.unwrap() == "ubuntu" {
|
||||
assert_eq!(name, "refs/heads/ubuntu/devel");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check for orig tarball in package dir
|
||||
let mut found_tarball = false;
|
||||
@@ -335,29 +381,33 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_get_hello_ubuntu_end_to_end() {
|
||||
test_get_package_end_to_end("hello", Some("noble")).await;
|
||||
test_get_package_end_to_end("hello", Some("noble"), None).await;
|
||||
}
|
||||
#[tokio::test]
|
||||
async fn test_get_hello_debian_end_to_end() {
|
||||
test_get_package_end_to_end("hello", Some("bookworm")).await;
|
||||
test_get_package_end_to_end("hello", Some("bookworm"), None).await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_get_2048_universe_ubuntu_end_to_end() {
|
||||
test_get_package_end_to_end("2048", Some("noble")).await;
|
||||
test_get_package_end_to_end("2048", Some("noble"), None).await;
|
||||
}
|
||||
#[tokio::test]
|
||||
async fn test_get_1oom_contrib_debian_end_to_end() {
|
||||
test_get_package_end_to_end("1oom", Some("trixie")).await;
|
||||
test_get_package_end_to_end("1oom", Some("trixie"), None).await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_get_agg_svn_fallback_ok() {
|
||||
test_get_package_end_to_end("agg", Some("trixie")).await;
|
||||
test_get_package_end_to_end("agg", Some("trixie"), None).await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_get_hello_latest_end_to_end() {
|
||||
test_get_package_end_to_end("hello", None).await;
|
||||
async fn test_get_hello_debian_latest_end_to_end() {
|
||||
test_get_package_end_to_end("hello", None, Some("debian")).await;
|
||||
}
|
||||
#[tokio::test]
|
||||
async fn test_get_hello_ubuntu_latest_end_to_end() {
|
||||
test_get_package_end_to_end("hello", None, Some("ubuntu")).await;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user