diff --git a/src/cargo/ops/cargo_package/mod.rs b/src/cargo/ops/cargo_package/mod.rs index fdc80399fad..bbd94bb8b4a 100644 --- a/src/cargo/ops/cargo_package/mod.rs +++ b/src/cargo/ops/cargo_package/mod.rs @@ -1,7 +1,7 @@ use std::collections::BTreeMap; use std::collections::BTreeSet; use std::collections::HashMap; -use std::fs::{self, File}; +use std::fs::File; use std::io::SeekFrom; use std::io::prelude::*; use std::path::{Path, PathBuf}; @@ -177,10 +177,8 @@ fn create_package( .context("failed to prepare local package for uploading")?; dst.seek(SeekFrom::Start(0))?; - let src_path = dst.path(); let dst_path = dst.parent().join(&filename); - fs::rename(&src_path, &dst_path) - .context("failed to move temporary tarball into final location")?; + dst.rename(&dst_path)?; let dst_metadata = dst .file() diff --git a/src/cargo/util/flock.rs b/src/cargo/util/flock.rs index e82465e89a1..89613f04a97 100644 --- a/src/cargo/util/flock.rs +++ b/src/cargo/util/flock.rs @@ -76,6 +76,29 @@ impl FileLock { } Ok(()) } + + /// Renames the file and updates the internal path. + /// + /// This method performs a filesystem rename operation using [`std::fs::rename`] + /// while keeping the FileLock's internal path synchronized with the actual + /// file location. + /// + /// ## Difference from `std::fs::rename` + /// + /// - `std::fs::rename(old, new)` only moves the file on the filesystem + /// - `FileLock::rename(new)` moves the file AND updates `self.path` to point to the new location + pub fn rename>(&mut self, new_path: P) -> CargoResult<()> { + let new_path = new_path.as_ref(); + std::fs::rename(&self.path, new_path).with_context(|| { + format!( + "failed to rename {} to {}", + self.path.display(), + new_path.display() + ) + })?; + self.path = new_path.to_path_buf(); + Ok(()) + } } impl Read for FileLock {