exp: cross #6
This commit is contained in:
@@ -19,7 +19,6 @@ pub fn build_source_package(cwd: Option<&Path>) -> Result<(), Box<dyn Error>> {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
|
||||||
|
|
||||||
// We are not testing the build part, as for now this is just a wrapper
|
// We are not testing the build part, as for now this is just a wrapper
|
||||||
// around dpkg-buildpackage.
|
// around dpkg-buildpackage.
|
||||||
|
|||||||
@@ -8,8 +8,15 @@ use std::process::Command;
|
|||||||
pub struct LocalDriver;
|
pub struct LocalDriver;
|
||||||
|
|
||||||
impl ContextDriver for LocalDriver {
|
impl ContextDriver for LocalDriver {
|
||||||
fn ensure_available(&self, src: &Path, _dest_root: &str) -> io::Result<PathBuf> {
|
fn ensure_available(&self, src: &Path, dest_root: &str) -> io::Result<PathBuf> {
|
||||||
src.canonicalize()
|
let dest_root_path = Path::new(dest_root);
|
||||||
|
let dest = dest_root_path.join(src.file_name().unwrap_or(src.as_os_str()));
|
||||||
|
|
||||||
|
if src != dest {
|
||||||
|
// Copy src inside dest_root
|
||||||
|
self.copy_path(src, &dest)?;
|
||||||
|
}
|
||||||
|
dest.canonicalize()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_temp_dir(&self) -> io::Result<String> {
|
fn create_temp_dir(&self) -> io::Result<String> {
|
||||||
@@ -17,8 +24,8 @@ impl ContextDriver for LocalDriver {
|
|||||||
Ok(temp_dir.keep().to_string_lossy().to_string())
|
Ok(temp_dir.keep().to_string_lossy().to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn retrieve_path(&self, _src: &Path, _dest: &Path) -> io::Result<()> {
|
fn retrieve_path(&self, src: &Path, dest: &Path) -> io::Result<()> {
|
||||||
Ok(())
|
self.copy_path(src, dest)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn list_files(&self, path: &Path) -> io::Result<Vec<PathBuf>> {
|
fn list_files(&self, path: &Path) -> io::Result<Vec<PathBuf>> {
|
||||||
|
|||||||
@@ -103,3 +103,45 @@ fn find_dsc_file(
|
|||||||
}
|
}
|
||||||
Ok(dsc_path)
|
Ok(dsc_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
async fn test_build_end_to_end(package: &str, series: &str, arch: Option<&str>, cross: bool) {
|
||||||
|
let temp_dir = tempfile::tempdir().unwrap();
|
||||||
|
let cwd = temp_dir.path();
|
||||||
|
|
||||||
|
crate::pull::pull(
|
||||||
|
package,
|
||||||
|
"",
|
||||||
|
Some(series),
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
Some("ubuntu"),
|
||||||
|
Some(cwd),
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.expect("Cannot pull package");
|
||||||
|
|
||||||
|
// Change directory to the package directory
|
||||||
|
let cwd = cwd.join(package).join(package);
|
||||||
|
|
||||||
|
crate::deb::build_binary_package(arch, Some(series), Some(&cwd), cross, None)
|
||||||
|
.expect("Cannot build binary package (deb)");
|
||||||
|
|
||||||
|
// Check that the .deb files are present
|
||||||
|
let parent_dir = cwd.parent().expect("Cannot find parent directory");
|
||||||
|
let deb_files = std::fs::read_dir(parent_dir)
|
||||||
|
.expect("Cannot read build directory")
|
||||||
|
.filter_map(|entry| entry.ok())
|
||||||
|
.filter(|entry| entry.path().extension().is_some_and(|ext| ext == "deb"))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
assert!(!deb_files.is_empty(), "No .deb files found after build");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_deb_hello_ubuntu_end_to_end() {
|
||||||
|
test_build_end_to_end("hello", "noble", None, false).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,21 +1,19 @@
|
|||||||
/// Sbuild binary package building
|
/// Sbuild binary package building
|
||||||
/// Call 'sbuild' with the dsc file to build the package with unshare
|
/// Call 'sbuild' with the dsc file to build the package with unshare
|
||||||
use crate::context;
|
use crate::context;
|
||||||
use crate::deb::find_dsc_file;
|
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
|
||||||
pub fn build(
|
pub fn build(
|
||||||
package: &str,
|
package: &str,
|
||||||
version: &str,
|
_version: &str,
|
||||||
arch: &str,
|
arch: &str,
|
||||||
series: &str,
|
series: &str,
|
||||||
build_root: &str,
|
build_root: &str,
|
||||||
cross: bool,
|
cross: bool,
|
||||||
) -> Result<(), Box<dyn Error>> {
|
) -> Result<(), Box<dyn Error>> {
|
||||||
let dsc_path = find_dsc_file(build_root, package, version)?;
|
|
||||||
|
|
||||||
let ctx = context::current();
|
let ctx = context::current();
|
||||||
let mut cmd = ctx.command("sbuild");
|
let mut cmd = ctx.command("sbuild");
|
||||||
|
cmd.current_dir(format!("{}/{}", build_root, package));
|
||||||
cmd.arg("--chroot-mode=unshare");
|
cmd.arg("--chroot-mode=unshare");
|
||||||
|
|
||||||
if cross {
|
if cross {
|
||||||
@@ -28,8 +26,7 @@ pub fn build(
|
|||||||
// Add output directory argument
|
// Add output directory argument
|
||||||
cmd.arg(format!("--build-dir={}", build_root));
|
cmd.arg(format!("--build-dir={}", build_root));
|
||||||
|
|
||||||
let status = cmd.arg(dsc_path).status()?;
|
let status = cmd.status()?;
|
||||||
|
|
||||||
if !status.success() {
|
if !status.success() {
|
||||||
return Err(format!("sbuild failed with status: {}", status).into());
|
return Err(format!("sbuild failed with status: {}", status).into());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ fn main() {
|
|||||||
.arg(arg!(-a --arch <arch> "Target architecture").required(false))
|
.arg(arg!(-a --arch <arch> "Target architecture").required(false))
|
||||||
.arg(arg!(--cross "Cross-compile for target architecture (instead of qemu-binfmt)")
|
.arg(arg!(--cross "Cross-compile for target architecture (instead of qemu-binfmt)")
|
||||||
.long_help("Cross-compile for target architecture (instead of using qemu-binfmt)\nNote that most packages cannot be cross-compiled").required(false))
|
.long_help("Cross-compile for target architecture (instead of using qemu-binfmt)\nNote that most packages cannot be cross-compiled").required(false))
|
||||||
.arg(arg!(--mode "Change build mode [sbuild, local]").required(false)
|
.arg(arg!(--mode <mode> "Change build mode [sbuild, local]").required(false)
|
||||||
.long_help("Change build mode [sbuild, local]\nDefault will chose depending on other parameters, don't provide if unsure")),
|
.long_help("Change build mode [sbuild, local]\nDefault will chose depending on other parameters, don't provide if unsure")),
|
||||||
)
|
)
|
||||||
.subcommand(
|
.subcommand(
|
||||||
@@ -151,8 +151,8 @@ fn main() {
|
|||||||
let series = sub_matches.get_one::<String>("series").map(|s| s.as_str());
|
let series = sub_matches.get_one::<String>("series").map(|s| s.as_str());
|
||||||
let arch = sub_matches.get_one::<String>("arch").map(|s| s.as_str());
|
let arch = sub_matches.get_one::<String>("arch").map(|s| s.as_str());
|
||||||
let cross = sub_matches.get_one::<bool>("cross").unwrap_or(&false);
|
let cross = sub_matches.get_one::<bool>("cross").unwrap_or(&false);
|
||||||
let mode = sub_matches.get_one::<String>("mode").map(|s| s.as_str());
|
let mode: Option<&str> = sub_matches.get_one::<String>("mode").map(|s| s.as_str());
|
||||||
let mode = match mode {
|
let mode: Option<pkh::deb::BuildMode> = match mode {
|
||||||
Some("sbuild") => Some(pkh::deb::BuildMode::Sbuild),
|
Some("sbuild") => Some(pkh::deb::BuildMode::Sbuild),
|
||||||
Some("local") => Some(pkh::deb::BuildMode::Local),
|
Some("local") => Some(pkh::deb::BuildMode::Local),
|
||||||
_ => None,
|
_ => None,
|
||||||
|
|||||||
44
src/pull.rs
44
src/pull.rs
@@ -262,6 +262,35 @@ async fn fetch_orig_tarball(
|
|||||||
Ok(())
|
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(
|
async fn fetch_archive_sources(
|
||||||
info: &PackageInfo,
|
info: &PackageInfo,
|
||||||
cwd: Option<&Path>,
|
cwd: Option<&Path>,
|
||||||
@@ -399,6 +428,7 @@ pub async fn pull(
|
|||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
clone_repo(
|
clone_repo(
|
||||||
url.as_str(),
|
url.as_str(),
|
||||||
package,
|
package,
|
||||||
@@ -406,6 +436,7 @@ pub async fn pull(
|
|||||||
Some(&package_dir),
|
Some(&package_dir),
|
||||||
progress,
|
progress,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
if !package_info.is_native() {
|
if !package_info.is_native() {
|
||||||
if let Some(cb) = progress {
|
if let Some(cb) = progress {
|
||||||
cb("Fetching orig tarball...", "", 0, 0);
|
cb("Fetching orig tarball...", "", 0, 0);
|
||||||
@@ -414,12 +445,17 @@ pub async fn pull(
|
|||||||
} else {
|
} else {
|
||||||
debug!("Native package, skipping orig tarball fetch.");
|
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 {
|
} else {
|
||||||
// Fallback to archive fetching
|
// Fallback to archive fetching
|
||||||
if let Some(cb) = progress {
|
if let Some(cb) = progress {
|
||||||
cb("Downloading from archive...", "", 0, 0);
|
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)
|
Ok(package_info)
|
||||||
@@ -482,16 +518,20 @@ mod tests {
|
|||||||
|
|
||||||
// Check for orig tarball in package dir
|
// Check for orig tarball in package dir
|
||||||
let mut found_tarball = false;
|
let mut found_tarball = false;
|
||||||
|
let mut found_dsc = false;
|
||||||
for entry in std::fs::read_dir(package_dir).unwrap() {
|
for entry in std::fs::read_dir(package_dir).unwrap() {
|
||||||
let entry = entry.unwrap();
|
let entry = entry.unwrap();
|
||||||
let name = entry.file_name().to_string_lossy().to_string();
|
let name = entry.file_name().to_string_lossy().to_string();
|
||||||
if name.contains(".orig.tar.") {
|
if name.contains(".orig.tar.") {
|
||||||
found_tarball = true;
|
found_tarball = true;
|
||||||
break;
|
}
|
||||||
|
if name.ends_with(".dsc") {
|
||||||
|
found_dsc = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert!(found_tarball, "Orig tarball not found in package dir");
|
assert!(found_tarball, "Orig tarball not found in package dir");
|
||||||
|
assert!(found_dsc, "DSC file not found in package dir");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
|
|||||||
Reference in New Issue
Block a user