Skip to content

Commit

Permalink
Change spk ls/search filters to use host var compatibility rules (#1169)
Browse files Browse the repository at this point in the history
Signed-off-by: David Gilligan-Cook <[email protected]>
  • Loading branch information
dcookspi authored Jan 22, 2025
1 parent 9c856ab commit 8bcd163
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 14 deletions.
75 changes: 74 additions & 1 deletion crates/spk-cli/group2/src/cmd_ls_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ async fn test_ls_shows_remote_packages_with_host_default_filter() {
remote_repo.publish_recipe(&recipe).await.unwrap();
let host_options = HOST_OPTIONS.get().unwrap();
let os_id = host_options.get(OptName::distro()).unwrap();

// Build with all matching host options
let spec = spec!({"pkg": "my-pkg/1.0.0/BGSHW3CN",
"build": {
"options":
Expand All @@ -140,7 +142,78 @@ async fn test_ls_shows_remote_packages_with_host_default_filter() {

let mut opt = Opt::try_parse_from(["ls", "--host"]).unwrap();
opt.ls.run().await.unwrap();
assert_ne!(opt.ls.output.vec.len(), 0);
assert_eq!(opt.ls.output.vec.len(), 1);
}

/// `spk ls` is expected to list packages in the configured remote
/// repositories that match the default filter for the current host
#[tokio::test]
async fn test_ls_shows_remote_packages_with_host_default_filter_multiple_builds() {
let mut rt = spfs_runtime().await;
let remote_repo = spfsrepo().await;

// Populate the "origin" repo with one package.
// The "local" repo is empty.

rt.add_remote_repo(
"origin",
Remote::Address(RemoteAddress {
address: remote_repo.address().clone(),
}),
)
.unwrap();

let recipe = recipe!({"pkg": "my-pkg/1.0.0"});
remote_repo.publish_recipe(&recipe).await.unwrap();
let host_options = HOST_OPTIONS.get().unwrap();
let os_id = host_options.get(OptName::distro()).unwrap();

// Build with all matching host options
let spec = spec!({"pkg": "my-pkg/1.0.0/BGSHW3CN",
"build": {
"options":
[
{"var": format!("{}/{}", OptName::distro(), host_options.get(OptName::distro()).unwrap()) },
{"var": format!("{}/{}", OptName::os(), host_options.get(OptName::os()).unwrap()) },
{"var": format!("{}/{}", OptName::arch(), host_options.get(OptName::arch()).unwrap()) },
{"var": format!("{}/{}", os_id, host_options.get(os_id).unwrap()) }
]
}});
remote_repo
.publish_package(
&spec,
&vec![(Component::Run, empty_layer_digest())]
.into_iter()
.collect(),
)
.await
.unwrap();

// Build with for another distro in its host options
let spec = spec!({"pkg": "my-pkg/1.0.0/2RGMWL2B",
"build": {
"options":
[
{"var": format!("{}/{}", OptName::distro(), "test_distro") },
{"var": format!("{}/{}", OptName::os(), host_options.get(OptName::os()).unwrap()) },
{"var": format!("{}/{}", OptName::arch(), host_options.get(OptName::arch()).unwrap()) },
{"var": format!("{}/{}", os_id, host_options.get(os_id).unwrap()) }
]
}});
remote_repo
.publish_package(
&spec,
&vec![(Component::Run, empty_layer_digest())]
.into_iter()
.collect(),
)
.await
.unwrap();

let mut opt = Opt::try_parse_from(["ls", "--host"]).unwrap();
opt.ls.run().await.unwrap();
println!("Output: {:?}", opt.ls.output.vec);
assert_eq!(opt.ls.output.vec.len(), 1);
}

/// `spk ls` is expected to list packages in both the local and the configured
Expand Down
12 changes: 0 additions & 12 deletions crates/spk-schema/crates/foundation/src/option_map/filters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,6 @@ pub struct OptFilter {
pub value: String,
}

impl OptFilter {
pub fn matches(&self, options: &OptionMap) -> bool {
if let Some(v) = options.get(&self.name) {
self.value == *v
} else {
// Not having an option with the filter's name is
// considered a match.
true
}
}
}

/// Constructs a list of filters from the current host's host options,
/// if any.
pub fn get_host_options_filters() -> Option<Vec<OptFilter>> {
Expand Down
13 changes: 12 additions & 1 deletion crates/spk-schema/src/v0/spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,8 +257,19 @@ impl Package for Spec<BuildIdent> {
fn matches_all_filters(&self, filter_by: &Option<Vec<OptFilter>>) -> bool {
if let Some(filters) = filter_by {
let settings = self.option_values();

for filter in filters {
if !filter.matches(&settings) {
if !settings.contains_key(&filter.name) {
// Not having an option with the filter's name is
// considered a match.
continue;
}

let var_request =
VarRequest::new_with_value(filter.name.clone(), filter.value.clone());

let compat = self.check_satisfies_request(&var_request);
if !compat.is_ok() {
return false;
}
}
Expand Down
1 change: 1 addition & 0 deletions cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,7 @@
"respecifying",
"retpoline",
"retryable",
"RGMWL",
"rhelversion",
"robinmap",
"rootdata",
Expand Down

0 comments on commit 8bcd163

Please sign in to comment.