From 66294e53ce2a9eb72af27bf595c64da4c7a1c0e2 Mon Sep 17 00:00:00 2001 From: diogo464 Date: Wed, 28 Jun 2023 08:58:22 +0100 Subject: fix: installing existing broken symlink. When installing a symlink but the target symlink already existed and was broken it would fail since it could not canonicalize the path properly. `fs_exists` also failed to account for broken symlinks and would return false when the symlink existed but was broken. --- src/dotup/mod.rs | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/dotup/mod.rs b/src/dotup/mod.rs index 3b0380b..4002f93 100644 --- a/src/dotup/mod.rs +++ b/src/dotup/mod.rs @@ -181,8 +181,15 @@ pub fn install(dotup: &Dotup, params: &InstallParams, group: &str) -> Result<()> let metadata = fs_symlink_metadata(&target)?; // Early return if the symlink already points to the correct source - if metadata.is_symlink() && fs_symlink_points_to(&target, &source)? { - continue; + if metadata.is_symlink() { + log::debug!( + "target is a symlink pointing to {}", + fs_read_symlink(&target)?.display() + ); + if fs_symlink_points_to(&target, &source)? { + log::debug!("target already points to the correct source, skipping"); + continue; + } } if !prompt_overwrite(params, &target)? { @@ -518,10 +525,14 @@ impl KeyValueParser { // -------------------- Filesystem -------------------- // fn fs_exists(path: impl AsRef) -> Result { - path.as_ref().try_exists().map_err(|err| { + let path = path.as_ref(); + if path.is_symlink() { + return Ok(true); + } + path.try_exists().map_err(|err| { Error::Custom(format!( "failed to check existence of target '{}': {}", - path.as_ref().display(), + path.display(), err )) }) @@ -576,7 +587,10 @@ fn fs_symlink_points_to(path: impl AsRef, target: impl AsRef) -> Res let path = path.as_ref(); let target = target.as_ref(); let link_target = fs_read_symlink(path)?; - let target_canonical = fs_canonicalize(target)?; + let target_canonical = match fs_canonicalize(target) { + Ok(canonical) => canonical, + Err(_) => return Ok(false), + }; let link_target_canonical = fs_canonicalize(link_target)?; Ok(target_canonical == link_target_canonical) } -- cgit