aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordiogo464 <[email protected]>2023-06-28 08:58:22 +0100
committerdiogo464 <[email protected]>2023-06-28 08:58:22 +0100
commit66294e53ce2a9eb72af27bf595c64da4c7a1c0e2 (patch)
treee2af7e73e0781de9d633e5798d0e50abf90683ea /src
parentc01d9d0445b5efa6ac0488667919fa51384d852e (diff)
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.
Diffstat (limited to 'src')
-rw-r--r--src/dotup/mod.rs24
1 files 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<()>
181 let metadata = fs_symlink_metadata(&target)?; 181 let metadata = fs_symlink_metadata(&target)?;
182 182
183 // Early return if the symlink already points to the correct source 183 // Early return if the symlink already points to the correct source
184 if metadata.is_symlink() && fs_symlink_points_to(&target, &source)? { 184 if metadata.is_symlink() {
185 continue; 185 log::debug!(
186 "target is a symlink pointing to {}",
187 fs_read_symlink(&target)?.display()
188 );
189 if fs_symlink_points_to(&target, &source)? {
190 log::debug!("target already points to the correct source, skipping");
191 continue;
192 }
186 } 193 }
187 194
188 if !prompt_overwrite(params, &target)? { 195 if !prompt_overwrite(params, &target)? {
@@ -518,10 +525,14 @@ impl KeyValueParser {
518// -------------------- Filesystem -------------------- // 525// -------------------- Filesystem -------------------- //
519 526
520fn fs_exists(path: impl AsRef<Path>) -> Result<bool> { 527fn fs_exists(path: impl AsRef<Path>) -> Result<bool> {
521 path.as_ref().try_exists().map_err(|err| { 528 let path = path.as_ref();
529 if path.is_symlink() {
530 return Ok(true);
531 }
532 path.try_exists().map_err(|err| {
522 Error::Custom(format!( 533 Error::Custom(format!(
523 "failed to check existence of target '{}': {}", 534 "failed to check existence of target '{}': {}",
524 path.as_ref().display(), 535 path.display(),
525 err 536 err
526 )) 537 ))
527 }) 538 })
@@ -576,7 +587,10 @@ fn fs_symlink_points_to(path: impl AsRef<Path>, target: impl AsRef<Path>) -> Res
576 let path = path.as_ref(); 587 let path = path.as_ref();
577 let target = target.as_ref(); 588 let target = target.as_ref();
578 let link_target = fs_read_symlink(path)?; 589 let link_target = fs_read_symlink(path)?;
579 let target_canonical = fs_canonicalize(target)?; 590 let target_canonical = match fs_canonicalize(target) {
591 Ok(canonical) => canonical,
592 Err(_) => return Ok(false),
593 };
580 let link_target_canonical = fs_canonicalize(link_target)?; 594 let link_target_canonical = fs_canonicalize(link_target)?;
581 Ok(target_canonical == link_target_canonical) 595 Ok(target_canonical == link_target_canonical)
582} 596}