fs icon indicating copy to clipboard operation
fs copied to clipboard

dir_exists sometimes returns FALSE for a relative symlink to a directory

Open heavywatal opened this issue 3 years ago • 4 comments

It is not always, but under some unknown conditions:

x = fs::dir_create(tempfile())
parent = fs::path_dir(x)

abs_ln = fs::link_create(x, fs::path(parent, "abs_ln"))
fs::link_exists(abs_ln)
#> /var/folders/vc/yv3lbg614jv_f7r5046k8yxm0000gn/T/RtmpLxUH0e/abs_ln 
#>                                                               TRUE
fs::dir_exists(abs_ln)
#> /var/folders/vc/yv3lbg614jv_f7r5046k8yxm0000gn/T/RtmpLxUH0e/abs_ln 
#>                                                               TRUE

rel_ln = fs::link_create(fs::path_file(x), fs::path(parent, "rel_ln"))
fs::link_exists(rel_ln)
#> /var/folders/vc/yv3lbg614jv_f7r5046k8yxm0000gn/T/RtmpLxUH0e/rel_ln 
#>                                                               TRUE
fs::dir_exists(rel_ln)
#> /var/folders/vc/yv3lbg614jv_f7r5046k8yxm0000gn/T/RtmpLxUH0e/rel_ln 
#>                                                              FALSE

setwd(parent)
fs::dir_create("path")
rel_ln2 = fs::link_create("path", "new_path")
fs::link_exists("new_path")
#> new_path 
#>     TRUE
fs::dir_exists("new_path")
#> new_path 
#>     TRUE

cat(system2("lsd", c("--tree", parent), stdout = TRUE), sep = "\n")
#> RtmpLxUH0e/
#> ├── abs_ln@ ⇒ /var/folders/vc/yv3lbg614jv_f7r5046k8yxm0000gn/T/RtmpLxUH0e/file772215100b6f
#> ├── file772215100b6f/
#> ├── new_path@ ⇒ path
#> ├── path/
#> └── rel_ln@ ⇒ file772215100b6f

Created on 2022-09-18 with reprex v2.0.2

  • fs 1.5.2
  • R version 4.2.1 (2022-06-23)
  • Platform: x86_64-apple-darwin17.0 (64-bit); macOS 12.5.1
  • Platform: x86_64-pc-linux-gnu (64-bit): Ubuntu 20.04.5

heavywatal avatar Sep 18 '22 07:09 heavywatal

I guess the following part needs a fix similar to #280: https://github.com/r-lib/fs/blob/238032fd0454fa54816c5af7cff6385b1cf81d17/R/access.R#L47

heavywatal avatar Sep 20 '22 13:09 heavywatal

I guess the following part needs a fix similar to https://github.com/r-lib/fs/pull/280:

I am not sure what you mean. is_dir() calls file_info() already, and it follows symlinks. THe problem is that if follows them forever.

I am actually not sure why we are not using realpath(3). There is also uv_fs_realpath() which discusses some limitations.

gaborcsardi avatar Sep 20 '22 13:09 gaborcsardi

For fs::dir_exists(rel_ln), link_path(path[links]) returns just fs::path_file(x) ("file772215100b6f" in this case), which can be followed from the directory where rel_ln is, not from the current directory. Calling is_dir("file772215100b6f") in the current directory returns FALSE.

heavywatal avatar Sep 20 '22 13:09 heavywatal

Never mind, wrong issue...

gaborcsardi avatar Sep 20 '22 13:09 gaborcsardi