use std::fs;
use scallop::pool::redirect_output;
use scallop::{Error, ExecStatus, functions};
use tempfile::NamedTempFile;
use crate::pkg::ebuild::{EbuildPkg, EbuildRawPkg};
use crate::pkg::{Build, Package, PkgPretend, Source};
use crate::shell::phase::PhaseKind;
use crate::shell::scope::Scope;
use crate::shell::{BuildData, get_build_mut};
use super::OperationKind;
impl Build for EbuildPkg {
fn build(&self) -> scallop::Result<()> {
get_build_mut().source_ebuild(&self.path()).map_err(|e| {
let err: crate::Error = e.into();
err.into_invalid_pkg_err(self)
})?;
for phase in self.eapi().operation(OperationKind::Build) {
phase.run().map_err(|e| {
let err: crate::Error = e.into();
err.into_pkg_err(self)
})?;
}
Ok(())
}
}
impl PkgPretend for EbuildPkg {
fn pkg_pretend(&self) -> scallop::Result<Option<String>> {
let Some(phase) = self.eapi().phases().get(&PhaseKind::PkgPretend) else {
return Ok(None);
};
if !self.defined_phases().contains(&phase.kind) {
return Ok(None);
}
self.source()?;
let Some(mut func) = functions::find(phase) else {
return Err(Error::Base(format!("{self}: {phase} phase missing")));
};
let build = get_build_mut();
build.scope = Scope::Phase(phase.kind);
build.set_vars()?;
let file = NamedTempFile::new()?;
redirect_output(&file)?;
let result = func.execute(&[]);
let output = fs::read_to_string(file.path()).unwrap_or_default();
let output = output.trim();
if let Err(e) = result {
if output.is_empty() {
Err(Error::Base(format!("{self}: {e}")))
} else {
Err(Error::Base(format!("{self}: {e}\n{output}")))
}
} else if !output.is_empty() {
Ok(Some(format!("{self}\n{output}")))
} else {
Ok(None)
}
}
}
impl Source for EbuildRawPkg {
fn source(&self) -> scallop::Result<ExecStatus> {
BuildData::from_raw_pkg(self);
get_build_mut().source_ebuild(self.data())
}
}
impl Source for EbuildPkg {
fn source(&self) -> scallop::Result<ExecStatus> {
BuildData::from_pkg(self);
get_build_mut().source_ebuild(&self.path())
}
}
#[cfg(test)]
mod tests {
use crate::test::test_data;
#[test]
fn pkg_pretend() {
let data = test_data();
let repo = data.ebuild_repo("phases").unwrap();
let pkg = repo.get_pkg("pkg-pretend/none-1").unwrap();
assert!(pkg.pretend().is_ok());
let pkg = repo.get_pkg("pkg-pretend/success-1").unwrap();
assert!(pkg.pretend().is_ok());
let pkg = repo.get_pkg("pkg-pretend/success-with-output-1").unwrap();
assert!(pkg.pretend().is_ok());
let pkg = repo.get_pkg("pkg-pretend/failure-1").unwrap();
assert!(pkg.pretend().is_err());
let pkg = repo.get_pkg("pkg-pretend/failure-with-output-1").unwrap();
assert!(pkg.pretend().is_err());
}
}