in src/resolver.rs [956:1048]
fn resolve_audits(
graph: &DepGraph<'_>,
store: &Store,
criteria_mapper: &CriteriaMapper,
requirements: &[CriteriaSet],
) -> (Vec<Option<ResolveResult>>, Conclusion) {
let _resolve_audits = trace_span!("resolve_audits").entered();
let mut violations = Vec::new();
let mut failures = Vec::new();
let mut vetted_with_exemptions = Vec::new();
let mut vetted_partially = Vec::new();
let mut vetted_fully = Vec::new();
let results: Vec<_> = requirements
.iter()
.enumerate()
.map(|(pkgidx, required_criteria)| {
let package = &graph.nodes[pkgidx];
if !package.is_third_party {
return None; // first-party crates don't need audits
}
let audit_graph = AuditGraph::build(store, criteria_mapper, package.name, None)
.map_err(|v| violations.push((pkgidx, v)))
.ok()?;
// NOTE: We currently always compute all search results even if we
// only need those in `req_criteria` because some later passes using
// the resolver results might need that information. We might want
// to look into simplifying this in the future.
let search_results: Vec<_> = (0..criteria_mapper.len())
.map(|criteria_idx| {
audit_graph.search(criteria_idx, &package.version, SearchMode::PreferExemptions)
})
.collect();
let mut needed_exemptions = false;
let mut directly_exempted = false;
let mut criteria_failures = criteria_mapper.no_criteria();
for criteria_idx in required_criteria.indices() {
match &search_results[criteria_idx] {
Ok(path) => {
needed_exemptions |= path
.iter()
.any(|o| matches!(o, DeltaEdgeOrigin::Exemption { .. }));
// Ignore `Unpublished` entries when deciding if a crate
// is directly exempted.
directly_exempted |= path.iter().all(|o| {
matches!(
o,
DeltaEdgeOrigin::Exemption { .. }
| DeltaEdgeOrigin::Unpublished { .. }
)
});
}
Err(_) => criteria_failures.set_criteria(criteria_idx),
}
}
if !criteria_failures.is_empty() {
failures.push((pkgidx, AuditFailure { criteria_failures }));
}
// XXX: Callers using these fields in success should perhaps be
// changed to instead walk the results?
if !needed_exemptions {
vetted_fully.push(pkgidx);
} else if directly_exempted {
vetted_with_exemptions.push(pkgidx);
} else {
vetted_partially.push(pkgidx);
}
Some(ResolveResult { search_results })
})
.collect();
let conclusion = if !violations.is_empty() {
Conclusion::FailForViolationConflict(FailForViolationConflict { violations })
} else if !failures.is_empty() {
Conclusion::FailForVet(FailForVet {
failures,
suggest: None,
})
} else {
Conclusion::Success(Success {
vetted_with_exemptions,
vetted_partially,
vetted_fully,
})
};
(results, conclusion)
}