fix: gate unix-only permission and symlink calls in the toolchain registry
commit
db5955efix: gate unix-only permission and symlink calls in the toolchain registry
set_mode and unix::fs::symlink do not exist on Windows, breaking Windows CI compilation. Both call sites now go through small unix/windows-gated helpers; marking a file executable is a no-op on Windows, and symlinks use the windows-specific APIs there instead.
Assisted-by: Claude:claude-sonnet-5
Reviews
No reviews of this commit yet — record a verdict below.
Start a review
crates/git-ents/src/registry.rs
@@ -8,7 +8,6 @@
//! a toolchain.
use std::fs;
-use std::os::unix::fs::PermissionsExt as _;
use std::path::{Path, PathBuf};
use std::process::Command;
@@ -408,12 +407,26 @@
let dest = staging.join("sccache");
fs::copy(&binary, &dest)
.map_err(|error| format!("could not copy {}: {error}", binary.display()))?;
- let mut perms = fs::metadata(&dest)
- .map_err(|error| format!("could not read {}: {error}", dest.display()))?
+ make_executable(&dest)
+}
+
+/// Mark `path` executable. A no-op on platforms without a permission bit for
+/// it (Windows determines executability from the file extension instead).
+#[cfg(unix)]
+fn make_executable(path: &Path) -> Result<(), String> {
+ use std::os::unix::fs::PermissionsExt as _;
+
+ let mut perms = fs::metadata(path)
+ .map_err(|error| format!("could not read {}: {error}", path.display()))?
.permissions();
perms.set_mode(0o755);
- fs::set_permissions(&dest, perms)
- .map_err(|error| format!("could not set permissions on {}: {error}", dest.display()))
+ fs::set_permissions(path, perms)
+ .map_err(|error| format!("could not set permissions on {}: {error}", path.display()))
+}
+
+#[cfg(windows)]
+fn make_executable(_path: &Path) -> Result<(), String> {
+ Ok(())
}
/// The manifest name for a version rustc reported: nightly builds collapse
@@ -501,12 +514,7 @@
let dest = staging.join(entry.file_name());
fs::copy(entry.path(), &dest)
.map_err(|error| format!("could not copy {}: {error}", entry.path().display()))?;
- let mut perms = fs::metadata(&dest)
- .map_err(|error| format!("could not read {}: {error}", dest.display()))?
- .permissions();
- perms.set_mode(0o755);
- fs::set_permissions(&dest, perms)
- .map_err(|error| format!("could not set permissions on {}: {error}", dest.display()))?;
+ make_executable(&dest)?;
relink_rpath(&dest)?;
}
copy_dir_all(lib_src, &staging.join("lib"))
@@ -570,7 +578,7 @@
let target = fs::read_link(entry.path()).map_err(|error| {
format!("could not read symlink {}: {error}", entry.path().display())
})?;
- std::os::unix::fs::symlink(&target, &dest_path)
+ symlink(&target, &dest_path)
.map_err(|error| format!("could not symlink {}: {error}", dest_path.display()))?;
} else {
fs::copy(entry.path(), &dest_path)
@@ -589,6 +597,21 @@
Ok(())
}
+/// Create a symlink at `link` pointing to `original`.
+#[cfg(unix)]
+fn symlink(original: &Path, link: &Path) -> std::io::Result<()> {
+ std::os::unix::fs::symlink(original, link)
+}
+
+#[cfg(windows)]
+fn symlink(original: &Path, link: &Path) -> std::io::Result<()> {
+ if original.is_dir() {
+ std::os::windows::fs::symlink_dir(original, link)
+ } else {
+ std::os::windows::fs::symlink_file(original, link)
+ }
+}
+
/// Run `rustc <toolchain_arg> <args>` and return its stdout, so a missing
/// toolchain or missing `rustc`/`rustup` shim surfaces as a plain error
/// rather than a panic.