Make binaries with required-features optional (#438)

* Make binaries with `required-features` optional so that crates like `sccache` would work as expected.
* Fix `infer_bin_dir_template`: concat with `data.bin_path` introduced in #417 
* Always `chmod +x $bin` on unix in case the archive (e.g. `sccache`) did not set the executable bit of fmt == Bin.
* CI: Install `sccache` but do not run it since it requires cargo env to be ready

Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
This commit is contained in:
Jiahao XU 2022-09-28 13:46:55 +10:00 committed by GitHub
parent 4ba1e221ea
commit f482e362ba
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 43 additions and 18 deletions

View file

@ -52,7 +52,7 @@ pub fn infer_bin_dir_template(data: &Data) -> Cow<'static, str> {
possible_dirs
.into_iter()
.find(|dirname| Path::new(dirname).is_dir())
.find(|dirname| data.bin_path.join(dirname).is_dir())
.map(|mut dir| {
dir.reserve_exact(1 + default_bin_dir_template.len());
dir += "/";
@ -68,7 +68,6 @@ pub struct BinFile {
pub source: PathBuf,
pub dest: PathBuf,
pub link: Option<PathBuf>,
pub pkg_fmt: Option<PkgFmt>,
}
impl BinFile {
@ -96,9 +95,7 @@ impl BinFile {
binary_ext,
};
let pkg_fmt = data.meta.pkg_fmt;
let source = if pkg_fmt == Some(PkgFmt::Bin) {
let source = if data.meta.pkg_fmt == Some(PkgFmt::Bin) {
data.bin_path.clone()
} else {
// Generate install paths
@ -140,7 +137,6 @@ impl BinFile {
source,
dest,
link,
pkg_fmt,
})
}
@ -184,13 +180,11 @@ impl BinFile {
self.dest.display()
);
if self.pkg_fmt == Some(PkgFmt::Bin) {
#[cfg(unix)]
fs::set_permissions(
&self.source,
std::os::unix::fs::PermissionsExt::from_mode(0o755),
)?;
}
#[cfg(unix)]
fs::set_permissions(
&self.source,
std::os::unix::fs::PermissionsExt::from_mode(0o755),
)?;
atomic_install(&self.source, &self.dest)?;

View file

@ -327,11 +327,36 @@ async fn download_extract_and_verify(
no_symlinks,
)?;
for bin_file in bin_files.iter() {
bin_file.check_source_exists()?;
}
let name = &package.name;
Ok(bin_files)
binaries
.iter()
.zip(bin_files)
.filter_map(|(bin, bin_file)| {
match bin_file.check_source_exists() {
Ok(()) => Some(Ok(bin_file)),
// This binary is optional
Err(err) => {
let required_features = &bin.required_features;
if required_features.is_empty() {
// This bin is not optional, error
Some(Err(err))
} else {
// Optional, print a warning and continue.
let bin_name = bin.name.as_deref().unwrap();
let features = required_features.join(",");
warn!(
"When resolving {name} bin {bin_name} is not found. \
But since it requies features {features}, this bin is ignored."
);
None
}
}
}
})
.collect::<Result<Vec<bins::BinFile>, BinstallError>>()
})
}