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
50 changes: 50 additions & 0 deletions crates/spk-cli/cmd-build/src/cmd_build_test/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -798,6 +798,56 @@ build:
}
}

#[rstest]
#[case::cli("cli")]
#[case::checks("checks")]
#[case::resolvo("resolvo")]
#[tokio::test]
async fn test_build_package_with_required_var_dependency(
tmpdir: tempfile::TempDir,
#[case] solver_to_run: &str,
) {
let _rt = spfs_runtime().await;

build_package!(
tmpdir,
"mylib.spk.yaml",
br#"
api: v0/package
pkg: mylib/1.0.0

build:
options:
- var: namespace_style/major_minor
required: true
description: "The namespace style to use"
script:
- "true"
"#,
solver_to_run
);

try_build_package!(
tmpdir,
"mypkg.spk.yaml",
br#"
api: v0/package
pkg: mypkg/1.0.0

build:
options:
- pkg: mylib
- var: mylib.namespace_style/major_minor
description: "The namespace style to use"
script:
- "true"
"#,
solver_to_run
)
.1
.expect("Expected build of mypkg to succeed");
}

#[rstest]
#[case::cli("cli")]
#[case::checks("checks")]
Expand Down
24 changes: 23 additions & 1 deletion crates/spk-schema/src/v0/recipe_spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use spk_schema_foundation::IsDefault;
use spk_schema_foundation::ident::{
AsVersionIdent,
PinnedRequest,
PkgRequestOptionValue,
PkgRequestOptions,
RangeIdent,
VersionIdent,
Expand Down Expand Up @@ -208,6 +209,26 @@ impl Recipe for RecipeSpec {
let options = self.resolve_options(variant)?;
let build_digest = Build::BuildId(self.build_digest(variant)?);
let mut requests = RequirementsList::<RequestWithOptions>::default();

// Collect namespaced var options keyed by their package namespace so
// they can be attached to the corresponding package request.
let mut pkg_var_options: HashMap<String, PkgRequestOptions> = HashMap::new();
for opt in opts.iter() {
if let Opt::Var(var_opt) = opt
&& let Some(ns) = var_opt.var.namespace()
&& let Some(value) = options.get(&var_opt.var)
&& !value.is_empty()
{
pkg_var_options
.entry(ns.as_str().to_owned())
.or_default()
.insert(
var_opt.var.clone(),
PkgRequestOptionValue::Complete(value.to_string()),
);
}
}

for opt in opts {
match opt {
Opt::Pkg(opt) => {
Expand All @@ -220,10 +241,11 @@ impl Recipe for RecipeSpec {
// inject the default component for this context if needed
req.pkg.components.insert(Component::default_for_build());
}
let pkg_options = pkg_var_options.remove(opt.pkg.as_str()).unwrap_or_default();
requests.insert_or_merge_with_options(RequestWithOptions::Pkg(
PkgRequestWithOptions {
pkg_request: req,
options: PkgRequestOptions::default(),
options: pkg_options,
},
))?;
}
Expand Down
19 changes: 18 additions & 1 deletion crates/spk-solve/src/solvers/step/solver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -996,10 +996,27 @@ impl Solver {
// The count is used as a fake version number to
// distinguish which initial request is being checked in
// each dummy package.

// Translate any options on the request into build options
// for the dummy recipe so that the var values are carried
// through to the install requirements and the impossible
// request checker can see them.
let build_options: Vec<serde_json::Value> = req
.options
.iter()
.map(|(name, value)| {
serde_json::json!({
"var": format!("{}/{}", name, value.value()),
})
})
.collect();

let recipe = try_recipe!({"pkg": format!("initialrequest/{}", count + 1),
"build": {
"options": build_options,
},
"install": {
"requirements": [
// TODO: include options here
req.pkg_request,
]
}
Expand Down
Loading