Skip to content

Commit

Permalink
feat: allow self renamer to work if tempdir is on a different device
Browse files Browse the repository at this point in the history
  • Loading branch information
davidkna committed Jul 27, 2024
1 parent 5af0c6a commit d1e5373
Showing 1 changed file with 32 additions and 4 deletions.
36 changes: 32 additions & 4 deletions src/self_renamer.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use color_eyre::eyre::Result;
use std::{env::current_exe, fs, path::PathBuf};
use tracing::{debug, error};
use tracing::{debug, error, warn};

pub struct SelfRenamer {
exe_path: PathBuf,
Expand All @@ -10,12 +10,40 @@ pub struct SelfRenamer {
impl SelfRenamer {
pub fn create() -> Result<Self> {
let tempdir = tempfile::tempdir()?;
let temp_path = tempdir.path().join("topgrade.exe");
let mut temp_path = tempdir.path().join("topgrade.exe");
let exe_path = current_exe()?;

debug!("Current exe in {:?}. Moving it to {:?}", exe_path, temp_path);
debug!(
"Current exe in {:?}. Attempting to move it to {:?}",
exe_path, temp_path
);

fs::rename(&exe_path, &temp_path)?;
match fs::rename(&exe_path, &temp_path) {
// cross-device error
Err(e) if e.raw_os_error() == Some(17) => {
debug!("Temporary directory is on a different device. Using the binary parent directory instead");

let Some(parent_dir) = exe_path.parent() else {
return Err(color_eyre::eyre::Report::msg(
"Could not get parent directory of the current binary",
));
};

let mut builder = tempfile::Builder::new();
builder.prefix("topgrade").suffix(".exe");
let temp_file = builder.tempfile_in(parent_dir)?;
temp_path = temp_file.path().to_path_buf();

// Delete the temporary file immediately to free up the name
if let Err(e) = temp_file.close() {
warn!("Could not close temporary file: {}", e);
}

debug!("Moving current exe in {:?} to {:?}", exe_path, temp_path);
fs::rename(&exe_path, &temp_path)
}
other => other,
}?;

Ok(SelfRenamer { exe_path, temp_path })
}
Expand Down

0 comments on commit d1e5373

Please sign in to comment.