Use binary name when searching for artifacts (#1747)

* Use binary name when searching for artifacts

When there is a single binary declared in the manifest and
it differs from the package name, add it to the list of handles
used for pre-built artifact fetching.

* Simplify `binary_name` assignment with a `match`

* Add e2e test

* Only attempt to use the binary name with `GhCrateMeta` fetcher

* Avoid too much over-allocating.

Technically it should also check if gh-crate-meta resolver is enabled, but it is unlikely for it to be disabled and overallocating for extra n-target should be fine, it is an improvement over doubling the space allocated if the binary_name is Some.

* Fix fmt in crates/binstalk/src/ops/resolve.rs

---------

Co-authored-by: Jiahao XU <Jiahao_XU@outlook.com>
This commit is contained in:
Tomas Olvecky 2024-06-14 06:52:37 +02:00 committed by GitHub
parent a220952fd6
commit dfa230f039
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 82 additions and 39 deletions

View file

@ -7,6 +7,7 @@ use std::{
sync::Arc,
};
use binstalk_fetchers::FETCHER_GH_CRATE_META;
use compact_str::{CompactString, ToCompactString};
use itertools::Itertools;
use leon::Template;
@ -91,45 +92,77 @@ async fn resolve_inner(
.collect::<Result<Vec<_>, _>>()?;
let resolvers = &opts.resolvers;
let mut handles: Vec<(Arc<dyn Fetcher>, _)> =
Vec::with_capacity(desired_targets.len() * resolvers.len());
let binary_name = match package_info.binaries.as_slice() {
[bin] if bin.name != package_info.name => Some(CompactString::from(bin.name.as_str())),
_ => None,
};
let data = Arc::new(Data::new(
package_info.name.clone(),
package_info.version_str.clone(),
package_info.repo.clone(),
));
handles.extend(
resolvers
.iter()
.cartesian_product(desired_targets.into_iter().map(|(triple, target)| {
debug!("Building metadata for target: {target}");
let target_meta = package_info.meta.merge_overrides(
iter::once(&opts.cli_overrides).chain(package_info.overrides.get(target)),
);
debug!("Found metadata: {target_meta:?}");
Arc::new(TargetData {
target: target.clone(),
meta: target_meta,
target_related_info: triple,
})
}))
.map(|(f, target_data)| {
let fetcher = f(
opts.client.clone(),
opts.gh_api_client.clone(),
data.clone(),
target_data,
opts.signature_policy,
);
(fetcher.clone(), AutoAbortJoinHandle::new(fetcher.find()))
}),
let mut handles: Vec<(Arc<dyn Fetcher>, _)> = Vec::with_capacity(
desired_targets.len() * resolvers.len()
+ if binary_name.is_some() {
desired_targets.len()
} else {
0
},
);
let mut handles_fn =
|data: Arc<Data>, filter_fetcher_by_name_predicate: fn(&'static str) -> bool| {
handles.extend(
resolvers
.iter()
.cartesian_product(desired_targets.clone().into_iter().map(
|(triple, target)| {
debug!("Building metadata for target: {target}");
let target_meta = package_info.meta.merge_overrides(
iter::once(&opts.cli_overrides)
.chain(package_info.overrides.get(target)),
);
debug!("Found metadata: {target_meta:?}");
Arc::new(TargetData {
target: target.clone(),
meta: target_meta,
target_related_info: triple,
})
},
))
.filter_map(|(f, target_data)| {
let fetcher = f(
opts.client.clone(),
opts.gh_api_client.clone(),
data.clone(),
target_data,
opts.signature_policy,
);
filter_fetcher_by_name_predicate(fetcher.fetcher_name())
.then_some((fetcher.clone(), AutoAbortJoinHandle::new(fetcher.find())))
}),
)
};
handles_fn(
Arc::new(Data::new(
package_info.name.clone(),
package_info.version_str.clone(),
package_info.repo.clone(),
)),
|_| true,
);
if let Some(binary_name) = binary_name {
handles_fn(
Arc::new(Data::new(
binary_name,
package_info.version_str.clone(),
package_info.repo.clone(),
)),
|name| name == FETCHER_GH_CRATE_META,
);
}
for (fetcher, handle) in handles {
fetcher.clone().report_to_upstream();
match handle.flattened_join().await {