use std::process::Command;
use crate::build::{OutputCallback, run_command_streaming};
use crate::cli::{CliError, Result};
use crate::pack::{PackError, print_cargo_line};
use crate::reporter::Step;
use super::plan::PythonPackagingPlan;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BuiltPythonSharedLibrary {
pub source_path: std::path::PathBuf,
}
pub struct PythonSharedLibraryBuilder<'a> {
plan: &'a PythonPackagingPlan,
}
impl<'a> PythonSharedLibraryBuilder<'a> {
pub fn new(plan: &'a PythonPackagingPlan) -> Self {
Self { plan }
}
pub fn existing(&self) -> Result<BuiltPythonSharedLibrary> {
let source_path = self.plan.built_shared_library_path();
source_path
.exists()
.then_some(BuiltPythonSharedLibrary { source_path })
.ok_or(CliError::FileNotFound(
self.plan.built_shared_library_path(),
))
}
pub fn build(&self, step: &Step) -> Result<BuiltPythonSharedLibrary> {
let verbose = step.is_verbose();
let on_output: Option<OutputCallback> =
verbose.then(|| Box::new(|line: &str| print_cargo_line(line)) as OutputCallback);
let mut command = Command::new("cargo");
if let Some(toolchain_selector) = self.plan.cargo_context.toolchain_selector.as_deref() {
command.arg(toolchain_selector);
}
command.arg("build");
command
.arg("--manifest-path")
.arg(&self.plan.cargo_context.cargo_manifest_path);
if let Some(package_selector) = self.plan.cargo_context.package_selector.as_deref() {
command.arg("-p").arg(package_selector);
}
if self.plan.cargo_context.release {
command.arg("--release");
}
command.args(&self.plan.cargo_context.cargo_command_args);
if !run_command_streaming(&mut command, on_output.as_ref()) {
return Err(PackError::BuildFailed {
targets: vec![self.plan.host_platform.canonical_name().to_string()],
}
.into());
}
self.existing()
}
}