fix: extract toolchain archives from a seekable temp file, not a pipe
commit
6f2c6defix: extract toolchain archives from a seekable temp file, not a pipe
GNU tar cannot sniff xz/gzip compression on a non-seekable stdin pipe, so extraction failed on Linux CI while passing locally under bsdtar.
Assisted-by: Claude:claude-sonnet-5
Reviews
No reviews of this commit yet — record a verdict below.
Start a review
crates/git-toolchain/src/lib.rs
@@ -877,20 +877,19 @@
};
fs::create_dir_all(&dest).map_err(|error| Error::Io(dest.clone(), error))?;
let strip = format!("--strip-components={}", component.strip);
- let mut child = Command::new("tar")
+ // A seekable file is required: GNU tar can only sniff the compression
+ // format (gzip, xz, ...) on a regular file, not a pipe.
+ let mut archive_file =
+ tempfile::NamedTempFile::new().map_err(|error| Error::Io(dest.clone(), error))?;
+ archive_file
+ .write_all(archive)
+ .map_err(|error| Error::Io(dest.clone(), error))?;
+ let status = Command::new("tar")
.args(["-x", &strip, "-C"])
.arg(&dest)
- .stdin(Stdio::piped())
- .spawn()
- .map_err(|error| Error::Fetch("tar".to_owned(), error.to_string()))?;
- child
- .stdin
- .take()
- .ok_or_else(|| Error::Fetch("tar".to_owned(), "no stdin".to_owned()))?
- .write_all(archive)
- .map_err(|error| Error::Fetch("tar".to_owned(), error.to_string()))?;
- let status = child
- .wait()
+ .arg("-f")
+ .arg(archive_file.path())
+ .status()
.map_err(|error| Error::Fetch("tar".to_owned(), error.to_string()))?;
if status.success() {
Ok(())