Skip to content

Commit

Permalink
Dedicated incompatibility type for missing embedded components
Browse files Browse the repository at this point in the history
Build on the ComponentsMissing type to be able to detect when missing
components are from some package not embedding them (or requests for them
are missing).

    .. TRY victim/1.0.0/3I42H3S6 - fake-pkg embeds real-pkg but does not provide all required components: needed comp2, have comp1

Signed-off-by: J Robert Ray <[email protected]>
  • Loading branch information
jrray committed Jun 5, 2023
1 parent f0baf57 commit 4a78ab7
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 10 deletions.
25 changes: 25 additions & 0 deletions crates/spk-schema/crates/foundation/src/version/compat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ pub struct ComponentsMissing {
pub enum IncompatibleReason {
ComponentsMissing(ComponentsMissing),
ConflictingEmbeddedPackage(PkgNameBuf),
EmbeddedComponentsMissing(PkgNameBuf, ComponentsMissing),
Other(String),
}

Expand Down Expand Up @@ -132,6 +133,30 @@ impl std::fmt::Display for IncompatibleReason {
"embedded package conflicts with existing package in solve: {pkg}"
)
}
IncompatibleReason::EmbeddedComponentsMissing(
pkg,
ComponentsMissing {
package,
provided,
missing,
},
) => {
write!(f, "{pkg} embeds {package} but does not provide all required components: needed {}, have {}",
missing
.iter()
.map(Component::to_string)
.join("\n"),
{
if provided.is_empty() {
"none".to_owned()
} else {
provided
.iter()
.map(Component::to_string)
.join("\n")
}
})
}
IncompatibleReason::Other(msg) => f.write_str(msg),
}
}
Expand Down
34 changes: 24 additions & 10 deletions crates/spk-solve/crates/validation/src/validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -618,10 +618,15 @@ impl PkgRequirementsValidator {
Err(err) => return Err(err.into()),
};

let mut was_embedded = None;

let (resolved, provided_components) = match state.get_current_resolve(&request.pkg.name) {
Ok((spec, source, _)) => match source {
PackageSource::Repository { components, .. } => (spec, components.keys().collect()),
PackageSource::Embedded { components, .. } => (spec, components.iter().collect()),
PackageSource::Embedded { parent, components } => {
was_embedded = Some(parent);
(spec, components.iter().collect())
}
PackageSource::BuildFromSource { .. } | PackageSource::SpkInternalTest => {
(spec, spec.components().names())
}
Expand All @@ -631,15 +636,24 @@ impl PkgRequirementsValidator {
}
};

let compat = Self::validate_request_against_existing_resolve(
&request,
resolved,
provided_components,
)?;
if !&compat {
return Ok(compat);
}
Ok(Compatible)
Ok(
match Self::validate_request_against_existing_resolve(
&request,
resolved,
provided_components,
)? {
Compatible => Compatible,
Compatibility::Incompatible(reason) => match (reason, was_embedded) {
(IncompatibleReason::ComponentsMissing(missing), Some(parent)) => {
Compatibility::Incompatible(IncompatibleReason::EmbeddedComponentsMissing(
parent.name().to_owned(),
missing,
))
}
(reason, _) => Compatibility::Incompatible(reason),
},
},
)
}

fn validate_request_against_existing_resolve(
Expand Down

0 comments on commit 4a78ab7

Please sign in to comment.