uv-sbom 2.3.0

SBOM generation tool for uv projects - Generate CycloneDX SBOMs from uv.lock files
Documentation
use super::super::schema::{Affect, Rating, Vulnerability, VulnerabilitySource};
use super::property;
use crate::application::read_models::{
    ResolutionGuideView, UpgradeRecommendationView, VulnerabilityReportView, VulnerabilityView,
};

/// Build a list of CycloneDX [`Vulnerability`] entries from a [`VulnerabilityReportView`].
///
/// Actionable vulnerabilities are listed first, followed by informational ones.
pub(in super::super) fn build_all(
    report: &VulnerabilityReportView,
    resolution_guide: Option<&ResolutionGuideView>,
    upgrade_recommendations: Option<&UpgradeRecommendationView>,
) -> Vec<Vulnerability> {
    let mut vulnerabilities = Vec::new();

    for vuln in &report.actionable {
        vulnerabilities.push(build(vuln, resolution_guide, upgrade_recommendations));
    }

    for vuln in &report.informational {
        vulnerabilities.push(build(vuln, resolution_guide, upgrade_recommendations));
    }

    vulnerabilities
}

/// Build a single CycloneDX [`Vulnerability`] entry from a [`VulnerabilityView`].
fn build(
    vuln: &VulnerabilityView,
    resolution_guide: Option<&ResolutionGuideView>,
    upgrade_recommendations: Option<&UpgradeRecommendationView>,
) -> Vulnerability {
    let source = vuln
        .source_url
        .as_ref()
        .map(|url| VulnerabilitySource { url: url.clone() });

    let ratings = Some(vec![Rating {
        score: vuln.cvss_score,
        severity: vuln.severity.as_str().to_string(),
        vector: vuln.cvss_vector.clone(),
    }]);

    let properties =
        property::from_resolution_guide(vuln, resolution_guide, upgrade_recommendations);

    Vulnerability {
        bom_ref: vuln.bom_ref.clone(),
        id: vuln.id.clone(),
        description: vuln.description.clone(),
        source,
        ratings,
        affects: vec![Affect {
            bom_ref: vuln.affected_component.clone(),
        }],
        properties,
    }
}