Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 46 additions & 43 deletions crates/spk-schema/src/v0/indexed_package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ use crate::foundation::name::PkgName;
use crate::foundation::spec_ops::prelude::*;
use crate::foundation::version::{Compat, Compatibility, Version};
use crate::ident::{Satisfy, VarRequest};
use crate::option::VarOpt;
use crate::package::OptionValues;
use crate::spec::SpecTest;
use crate::v0::EmbeddedPackageSpec;
Expand Down Expand Up @@ -156,6 +157,47 @@ impl IndexedPackage {
<spk_proto::BuildIndex as flatbuffers::Follow>::follow(&self.buf[..], self.offset)
}
}

// Helper function for gathering and filtering downstream
// requirements trait implementation.
fn downstream_requirements<F>(&self, filter: F) -> Cow<'_, RequirementsList<RequestWithOptions>>
where
F: FnMut(&VarOpt) -> bool,
{
// This is a version of downstream_requirements() from
// v0/package_spec.rs modified for this kind of flatbuffer
// backed package.
let build_options = self.build_options();
let embedded = self.embedded();

let requests = build_options
.iter()
.filter_map(|opt| match opt {
Opt::Var(v) => Some(v.with_default_namespace(self.name())),
Opt::Pkg(_) => None,
})
.chain(embedded.iter().flat_map(|embed| {
embed.build().options.iter().filter_map(|opt| match opt {
Opt::Var(v) => Some(v.with_default_namespace(embed.name())),
Opt::Pkg(_) => None,
})
}))
.filter(filter)
.map(|o| {
VarRequest {
// we are assuming that the var here will have a value because
// this is a built binary package
value: o.get_value(None).unwrap_or_default().into(),
var: o.var,
// Index doesn't store the an option's description
description: None,
}
})
.map(RequestWithOptions::Var);
RequirementsList::<RequestWithOptions>::try_from_iter(requests)
.map(Cow::Owned)
.expect("build opts (from a RepoIndex) do not contain duplicates")
}
}

impl BuildOptions for IndexedPackage {
Expand Down Expand Up @@ -489,15 +531,9 @@ impl DownstreamRequirements for IndexedPackage {
&self,
_components: impl IntoIterator<Item = &'a Component>,
) -> Cow<'_, RequirementsList<RequestWithOptions>> {
// This is for build var requirements and inheritance used in
// building. This kinds of package has no build data stored.
let err = Error::SpkIndexedPackageDoesNotImplement(
"DownstreamRequirements".to_string(),
"downstream_build_requirements".to_string(),
);
// TODO: should this change the return value, update all the
// caller's handling, and return an error for this implementation?
unreachable!("{err}");
// This is used when doing a binary build to get additional
// information about the build environment.
self.downstream_requirements(|o| o.inheritance() != Inheritance::Weak)
}

fn downstream_runtime_requirements<'a>(
Expand All @@ -506,40 +542,7 @@ impl DownstreamRequirements for IndexedPackage {
) -> Cow<'_, RequirementsList<RequestWithOptions>> {
// This is used when deprecating an embedded stub/package
// and this is exercised during the automated repository tests.

// This is a version of downstream_runtime_requirements() and
// downstream_requirements() from v0/package_spec.rs modified
// for this kind of flatbuffer backed package.
let build_options = self.build_options();
let embedded = self.embedded();

let requests = build_options
.iter()
.filter_map(|opt| match opt {
Opt::Var(v) => Some(v.with_default_namespace(self.name())),
Opt::Pkg(_) => None,
})
.chain(embedded.iter().flat_map(|embed| {
embed.build().options.iter().filter_map(|opt| match opt {
Opt::Var(v) => Some(v.with_default_namespace(embed.name())),
Opt::Pkg(_) => None,
})
}))
.filter(|o| o.inheritance() == Inheritance::Strong || o.required)
.map(|o| {
VarRequest {
// we are assuming that the var here will have a value because
// this is a built binary package
value: o.get_value(None).unwrap_or_default().into(),
var: o.var,
// Index doesn't store the an option's description
description: None,
}
})
.map(RequestWithOptions::Var);
RequirementsList::<RequestWithOptions>::try_from_iter(requests)
.map(Cow::Owned)
.expect("build opts (from a RepoIndex) do not contain duplicates")
self.downstream_requirements(|o| o.inheritance() == Inheritance::Strong || o.required)
}
}

Expand Down
13 changes: 12 additions & 1 deletion crates/spk-storage/src/storage/flatbuffer_index_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use spk_schema::{
ComponentSpec,
Components,
Deprecate,
DownstreamRequirements,
OptionMap,
OptionValues,
Package,
Expand Down Expand Up @@ -262,7 +263,17 @@ fn assert_packages_are_equivalent(build_from_repo: Arc<Spec>, build_from_index:

// fn get_all_tests(&self) -> Vec<SpecTest> - not implemented by SolverPackageSpec

// DownstreamRequirements - not implemented by SolverPackageSpec
// DownstreamRequirements
assert_eq!(
build_from_repo.downstream_build_requirements([]),
build_from_index.downstream_build_requirements([]),
"downstream_build_requirements() don't match [{pkg}]",
);
assert_eq!(
build_from_repo.downstream_runtime_requirements([]),
build_from_index.downstream_runtime_requirements([]),
"downstream_runtime_requirements() don't match [{pkg}]",
);

// OptionValues
assert_eq!(
Expand Down
Loading