deb: cross-compilation, ephemeral contexts, local builds
All checks were successful
CI / build (push) Successful in 7m18s

Multiple changes:
- New contexts (schroot, unshare)
- Cross-building quirks, with ephemeral contexts and repositories management
- Contexts with parents, global context manager, better lifetime handling
- Local building of binary packages
- Pull: pulling dsc files by default
- Many small bugfixes and changes

Co-authored-by: Valentin Haudiquet <valentin.haudiquet@canonical.com>
Co-committed-by: Valentin Haudiquet <valentin.haudiquet@canonical.com>
This commit was merged in pull request #1.
This commit is contained in:
2025-12-25 17:10:44 +00:00
committed by Valentin Haudiquet
parent 88313b0c51
commit 1538e9ee19
19 changed files with 1784 additions and 301 deletions

View File

@@ -262,22 +262,51 @@ async fn fetch_orig_tarball(
Ok(())
}
async fn fetch_dsc_file(
info: &PackageInfo,
cwd: Option<&Path>,
progress: ProgressCallback<'_>,
) -> Result<(), Box<dyn Error>> {
let target_dir = cwd.unwrap_or_else(|| Path::new("."));
// Find the dsc file in the file list
let dsc_file = info
.stanza
.files
.iter()
.find(|f| f.name.ends_with(".dsc"))
.ok_or("Could not find .dsc file in package info")?;
let filename = &dsc_file.name;
debug!("Fetching dsc file: {}", filename);
download_file_checksum(
format!("{}/{}", &info.archive_url, filename).as_str(),
&dsc_file.sha256,
target_dir,
progress,
)
.await?;
Ok(())
}
async fn fetch_archive_sources(
info: &PackageInfo,
cwd: Option<&Path>,
progress: ProgressCallback<'_>,
) -> Result<(), Box<dyn Error>> {
let package_dir = if let Some(path) = cwd {
path.join(&info.stanza.package)
path
} else {
Path::new(&info.stanza.package).to_path_buf()
&Path::new(".").to_path_buf()
};
std::fs::create_dir_all(&package_dir)?;
std::fs::create_dir_all(package_dir)?;
for file in &info.stanza.files {
let url = format!("{}/{}", info.archive_url, file.name);
download_file_checksum(&url, &file.sha256, &package_dir, progress).await?;
download_file_checksum(&url, &file.sha256, package_dir, progress).await?;
}
// Extract the debian tarball or diff
@@ -399,6 +428,7 @@ pub async fn pull(
0,
);
}
clone_repo(
url.as_str(),
package,
@@ -406,6 +436,7 @@ pub async fn pull(
Some(&package_dir),
progress,
)?;
if !package_info.is_native() {
if let Some(cb) = progress {
cb("Fetching orig tarball...", "", 0, 0);
@@ -414,12 +445,17 @@ pub async fn pull(
} else {
debug!("Native package, skipping orig tarball fetch.");
}
if let Some(cb) = progress {
cb("Fetching dsc file...", "", 0, 0);
}
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(cwd.unwrap_or(Path::new("."))), progress).await?;
fetch_archive_sources(&package_info, Some(&package_dir), progress).await?;
}
Ok(package_info)
@@ -480,18 +516,25 @@ mod tests {
}
}
// Check for orig tarball in package dir
// Check for orig tarball in package dir (only for non-native packages)
let mut found_tarball = false;
let mut found_dsc = false;
for entry in std::fs::read_dir(package_dir).unwrap() {
let entry = entry.unwrap();
let name = entry.file_name().to_string_lossy().to_string();
if name.contains(".orig.tar.") {
found_tarball = true;
break;
}
if name.ends_with(".dsc") {
found_dsc = true;
}
}
assert!(found_tarball, "Orig tarball not found in package dir");
// Only check for orig tarball if the package is not native
if !info.is_native() {
assert!(found_tarball, "Orig tarball not found in package dir");
}
assert!(found_dsc, "DSC file not found in package dir");
}
#[tokio::test]