Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(fs): fix copying of symlink directories on Windows #6278

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

IgorM867
Copy link
Contributor

This PR fixes the handling of symlink directories in the copy function on Windows. Previously, copying a directory that was a symlink resulted in creating a symlink of type "file" instead of "dir".

The test case for copying symlink directories passed because Deno.lstat() (which does not follow symlinks) was used. However, when Deno.stat() (which follows symlinks) was used on this type of symlink, the system would throw a PermissionDenied error.

Copy link

codecov bot commented Dec 18, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 96.34%. Comparing base (8573618) to head (d2e0c60).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #6278   +/-   ##
=======================================
  Coverage   96.34%   96.34%           
=======================================
  Files         543      543           
  Lines       41601    41601           
  Branches     6312     6310    -2     
=======================================
+ Hits        40079    40081    +2     
+ Misses       1478     1477    -1     
+ Partials       44       43    -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@kt3k
Copy link
Member

kt3k commented Dec 19, 2024

Thanks @IgorM867 for working on this!

I merged #6236 and this branch at #6280, but the CI shows some errors. Do you see the reason for those errors?

@IgorM867
Copy link
Contributor Author

@kt3k The reason is that in the copySymLink() function, when copying a symlink, await Deno.readLink(src); returns only a relative path ("dir"), not the full path. I believe this is due to how the symlinks were initially created. When I recreated them on Windows, all the tests passed.

@@ -137,7 +137,7 @@ async function copySymLink(
) {
await ensureValidCopy(src, dest, options);
const originSrcFilePath = await Deno.readLink(src);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using Deno.realPath should return the absolute path of the symlink target. Additional explanation for suggestion in PR #6236:

Suggested change
const originSrcFilePath = await Deno.readLink(src);
const originSrcFilePath = await Deno.realPath(src);

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think changing this to realPath causes another problem. I think we should keep this work for relative symlinks.

@@ -161,7 +161,7 @@ function copySymlinkSync(
) {
ensureValidCopySync(src, dest, options);
const originSrcFilePath = Deno.readLinkSync(src);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using Deno.realPathSync should return the absolute path of the symlink target. Additional explanation for suggestion in PR #6236:

Suggested change
const originSrcFilePath = Deno.readLinkSync(src);
const originSrcFilePath = Deno.realPathSync(src);

@@ -137,7 +137,7 @@ async function copySymLink(
) {
await ensureValidCopy(src, dest, options);
const originSrcFilePath = await Deno.readLink(src);
const type = getFileInfoType(await Deno.lstat(src));
const type = getFileInfoType(await Deno.lstat(originSrcFilePath));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this only works when originSrcFilePath is an absolute path or relative path accidentally points to path accessible from cwd. originSrcFilePath could be relative path from link path to target, which could be inaccessible from cwd, and in that case this lstat call would fail.

I think this should Deno.stat(src) instead with fallback to 'file' type in case Deno.stat(src) throws NotFound. What do you think?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants