mod admit;
mod artifact;
mod context_summary;
mod expectations;
mod paths;
mod reasons;
mod run;
pub use admit::{admit, AdmittedFacts};
pub use artifact::{
Coverage, IncompleteUnit, Profile, COMPILER_FACTS_ARTIFACT_SCHEMA_VERSION,
COMPILER_FACTS_CONTRACT_VERSION, COMPILER_FACTS_FORMAT,
};
#[cfg(test)]
pub(crate) use artifact::CompilationRef;
#[cfg(test)]
pub(crate) use context_summary::recompute as recompute_context_summary;
pub use expectations::{
expectations_for, AdmissionExpectations, EXPECTED_CONTEXT_SCHEMA_VERSION,
EXPECTED_DEPENDENCY_FINGERPRINT, EXPECTED_ENGINE_REVISION, EXPECTED_PRODUCER_NAME,
};
pub use paths::compiler_facts_json_path;
pub use reasons::RefusalReason;
pub use run::{run_engine, DEFAULT_OUTPUT_CAP, DEFAULT_TIMEOUT};
use std::fs;
use std::io;
use std::path::{Path, PathBuf};
use super::paths::atomic_write_bytes;
pub const SCOUT_COMPILER_ENGINE: &str = "SCOUT_COMPILER_ENGINE";
pub fn locate_engine() -> Option<PathBuf> {
let raw = std::env::var(SCOUT_COMPILER_ENGINE).ok()?;
if raw.is_empty() {
return None;
}
Some(PathBuf::from(raw))
}
#[derive(Debug)]
pub enum PublishError {
Refused(RefusalReason),
Io(io::Error),
}
impl From<RefusalReason> for PublishError {
fn from(reason: RefusalReason) -> Self {
PublishError::Refused(reason)
}
}
pub fn admit_and_publish(
root: &Path,
candidate_bytes: &[u8],
expected: &AdmissionExpectations,
) -> Result<AdmittedFacts, PublishError> {
let facts = admit::admit(candidate_bytes, expected)?;
atomic_write_bytes(&paths::compiler_facts_json_path(root), &facts.bytes)
.map_err(PublishError::Io)?;
paths::remove_superseded_compiler_facts(root);
Ok(facts)
}
pub fn read_compiler_facts(root: &Path) -> Option<AdmittedFacts> {
let bytes = fs::read(paths::compiler_facts_json_path(root)).ok()?;
let header = artifact::parse_header(&bytes).ok()?;
Some(AdmittedFacts { header, bytes })
}