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

fs: restore javascript realpath implementation #7899

Closed
wants to merge 7 commits into from

Conversation

bzoz
Copy link
Contributor

@bzoz bzoz commented Jul 27, 2016

Checklist
  • make -j4 test (UNIX), or vcbuild test nosign (Windows) passes
  • commit message follows commit guidelines
Affected core subsystem(s)

fs

Description of change

Libuv realpath implementation brought a lot of problems described here #7726. This restores old JS implementation of realpath and realpathSync, adding new API, with options in place of cache.

This requires #7846 to land, as it reverts changes to fs on which old JS implementation depended. This PR is about 3rd and 4th commit which bring back old realpath implementation with support for the new API.

First two commits are from #7846, reverting some changes to fs that landed after JS realpath implementation was dropped.

Third commit reverts b488b19 bringing back JS implementation of realpath and realpathSync.

Fourth commit updates old implementation. It removes the cache and implements new realpath API (support for encoding parameter).

This cannot land before #7846. In case #7846 does not make it, this can be easily updated.

@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. fs Issues and PRs related to the fs subsystem / file system. labels Jul 27, 2016
@addaleax
Copy link
Member

addaleax commented Jul 27, 2016

A couple of suggestions:

  • I don’t think the native binding to the libuv realpath needs to be removed. It can be, but it might be nice to retain it for comparing results with the JS implementation later.
  • You could add the benchmark/test commit from @trevnorrisfs: fix long symlinks in realpath #7548 here.
  • I’ll try to benchmark it, but removing the cache altogether sounds like something that won’t work out. I realize that it conflicts with the encoding: option, but that seems to be easily worked around by never adding an encoding: key to the cache? It also won’t be a likely problem in practice, because only path.resolve()d keys are added to the cache. People in the CTC meeting made some good points and removing the cache sounds okay.
  • The encoding option should probably be used for all fs.* calls that are made from inside the realpath implementations?

@orangemocha orangemocha mentioned this pull request Jul 27, 2016
7 tasks
@orangemocha
Copy link
Contributor

@orangemocha
Copy link
Contributor

At the last meeting, the CTC has expressed consensus with the approach in this PR: reverting, leaving the cache out, but keeping the encoding option.

@ChALkeR
Copy link
Member

ChALkeR commented Jul 27, 2016

To me it looks like this reverts too many tests. Could we keep the ones that still pass?

@bzoz
Copy link
Contributor Author

bzoz commented Jul 28, 2016

@addaleax :

  • I think that since we are not using native realpath anymore there is no need to keep bindings around.
  • Adding benchmarks from fs: fix long symlinks in realpath #7548 is a good idea, I'll do that.
  • Inside we are using path.resolve, which expects utf-8 strings. So we stick to them when calling other fs functions, and only apply encoding option when returning result.

@ChALkeR: Those test are reverted by #7846 on which this PR depends.

@addaleax
Copy link
Member

I think that since we are not using native realpath anymore there is no need to keep bindings around.

@bzoz Your call.There seems to be agreement that the long-term plan is to use a fixed libuv implementation, though, and I think keeping the binding around might be useful for e.g. comparative benchmarks.

we are using path.resolve, which expects utf-8 strings

path.resolve expects strings, which means that it it isn’t concerned with encodings at all. But you’re right, this is not as easy as I though it would be, and it’s probably best to just stick with UTF-8 for all intermediate results (and accepting that that means that symlinks encountered along the way must be valid UTF-8).

@bzoz bzoz force-pushed the bartek-restore-js-realpath branch from bddaab2 to 0329b6a Compare July 28, 2016 16:27
@jasnell
Copy link
Member

jasnell commented Jul 28, 2016

In general this LGTM with a green CI. I definitely want to make sure this gets additional eyes on it to review, however. @nodejs/ctc

@StefanScherer
Copy link

StefanScherer commented Jul 28, 2016

@bzoz I've just compiled your PR on Windows and tried the node.exe inside a Windows Container. Installed Node.js 6.3.1 from MSI inside the container and just replaced node.exe.

Running npm init, npm install express ... works fine again. 🐳
So this PR would fix #7044

@saghul
Copy link
Member

saghul commented Jul 29, 2016

Why does this PR also revert "fs: validate args of truncate functions in js" and "fs: make callback mandatory to all async functions" ? How are those related to the realpath problems? It makes is a lot harder to review this PR.

@saghul
Copy link
Member

saghul commented Jul 29, 2016

Those seem to be handled by #7846, btw.

@addaleax
Copy link
Member

@saghul This PR would otherwise create merge conflicts, that’s all; the intent here is to wait until #7846 is landed, if I understood @bzoz correctly.

assert(!err);
assert.equal(typeof result, 'string');
assert.equal(result, filename);
});
Copy link
Member

Choose a reason for hiding this comment

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

You don’t need the asyncCompleted checks; wrapping the callback as common.mustCall(function(err, result) { … }) handles that automatically for you.

@addaleax
Copy link
Member

@bzoz Many, many thanks for starting to add regression tests! Overall LGTM, too.

@bzoz
Copy link
Contributor Author

bzoz commented Jul 29, 2016

@addaleax addaleax mentioned this pull request Aug 2, 2016
2 tasks
@addaleax
Copy link
Member

addaleax commented Aug 2, 2016

LGTM, thanks for doing the work behind this PR!

CI: https://ci.nodejs.org/job/node-test-commit/4374/

@addaleax
Copy link
Member

addaleax commented Aug 2, 2016

One Windows build bot failure, running CI again to be safe: https://ci.nodejs.org/job/node-test-commit/4376/

@bzoz
Copy link
Contributor Author

bzoz commented Aug 2, 2016

I had one running here https://ci.nodejs.org/job/node-test-commit/4373/, it is green.

@addaleax
Copy link
Member

addaleax commented Aug 2, 2016

Oh, sorry (but good to hear)! I’d say this is good to go once #7846 is resolved.

@misterdjules
Copy link

@bzoz What do you think of squashing all commits but the ones from #7846 to make reviewing changes easier? Currently one has to go through all these commits separately in order to focus on reviewing the changes that are actually related to this PR, which is a bit tedious.

@bzoz bzoz force-pushed the bartek-restore-js-realpath branch from 28efdae to 0c0a6b4 Compare August 3, 2016 09:08
@bzoz
Copy link
Contributor Author

bzoz commented Aug 3, 2016

@misterdjules OK, squashed

Commits:

  1. Restore old js realpath implementation
  2. Implement new API (i.e. options.encoding) and add a test
  3. Add tests and benchmarks from fs: fix long symlinks in realpath #7548
  4. Remove one test from fs: fix long symlinks in realpath #7548 which was failing

@saghul
Copy link
Member

saghul commented Aug 3, 2016

What was the result of the discussion about the substed realpath behavior thing? This PR adds a test thus making certain behavior "correct" which might not necessarily be the case. It depends on how substed drives are interpreted, IMHO.

On the maze of issues and notes I recall reading that some people where using substed drives to get shorter paths. Was that the case? What breaks if we would give them the long path?

@bzoz
Copy link
Contributor Author

bzoz commented Aug 10, 2016

I've added a note to the fs documentation.

@jasnell
Copy link
Member

jasnell commented Aug 10, 2016

LGTM, thank you.

@jasnell
Copy link
Member

jasnell commented Aug 10, 2016

CI is green. Let's give it another day before landing. @nodejs/ctc @nodejs/collaborators ... please take one final look.

@@ -1563,38 +1563,239 @@ fs.unwatchFile = function(filename, listener) {
};


fs.realpathSync = function realpathSync(path, options) {
// Regexp that finds the next partion of a (partial) path
Copy link
Member

Choose a reason for hiding this comment

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

typo: partion

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed

bzoz added a commit that referenced this pull request Aug 12, 2016
This reverts parts of b488b19
restoring javascript implementation of realpath and realpathSync.

Fixes: #7175
Fixes: #6861
Fixes: #7294
Fixes: #7192
Fixes: #7044
Fixes: #6624
Fixes: #6978
PR-URL: #7899
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
bzoz pushed a commit that referenced this pull request Aug 12, 2016
The benchmarks included also work for the previous JS
implementation of fs.realpath(). In case the new implementation of
realpath() needs to be reverted, we want these changes to stick around.

PR-URL: #7899
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
@bzoz
Copy link
Contributor Author

bzoz commented Aug 12, 2016

Landed in 08996fd and b9832eb

@bzoz bzoz closed this Aug 12, 2016
cjihrig pushed a commit that referenced this pull request Aug 15, 2016
This reverts parts of b488b19
restoring javascript implementation of realpath and realpathSync.

Fixes: #7175
Fixes: #6861
Fixes: #7294
Fixes: #7192
Fixes: #7044
Fixes: #6624
Fixes: #6978
PR-URL: #7899
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
cjihrig pushed a commit that referenced this pull request Aug 15, 2016
The benchmarks included also work for the previous JS
implementation of fs.realpath(). In case the new implementation of
realpath() needs to be reverted, we want these changes to stick around.

PR-URL: #7899
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
@cjihrig cjihrig mentioned this pull request Aug 15, 2016
@bpasero
Copy link
Contributor

bpasero commented Sep 22, 2016

@bzoz @addaleax one thing I really liked from the behaviour of native fs.realpath is that it would return the actual casing of a path as it exists on disk. E.g. if there is an actual path /foo/bar/some.txt, running fs.realpath("/foo/BAR/some.txt") would return /foo/bar/some.txt. Are there any plans to support this behaviour after going back to the old JS implementation? Or any plans to provide this functionality in a separate method?

@addaleax
Copy link
Member

@bpasero I guess you can open a separate issue for this? It sounds like something that would be okay to have.

@bpasero
Copy link
Contributor

bpasero commented Sep 22, 2016

@addaleax makes sense, opened #8715

bnoordhuis added a commit to bnoordhuis/io.js that referenced this pull request Nov 9, 2017
Make the `uv_fs_realpath()` binding (which calls the libc `realpath()`
on UNIX and `GetFinalPathNameByHandle()` on Windows) available as the
`fs.realpath.native()` and `fs.realpathSync.native()` functions.

The binding was already available as `process.binding('fs').realpath`
but was not exposed or tested - and partly broken as a result.

Fixes: nodejs#8715
PR-URL: nodejs#15776
Refs: nodejs#7899
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
Reviewed-By: Minwoo Jung <minwoo@nodesource.com>
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
evanlucas pushed a commit that referenced this pull request Nov 13, 2017
Make the `uv_fs_realpath()` binding (which calls the libc `realpath()`
on UNIX and `GetFinalPathNameByHandle()` on Windows) available as the
`fs.realpath.native()` and `fs.realpathSync.native()` functions.

The binding was already available as `process.binding('fs').realpath`
but was not exposed or tested - and partly broken as a result.

Fixes: #8715
PR-URL: #15776
Refs: #7899
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
Reviewed-By: Minwoo Jung <minwoo@nodesource.com>
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c++ Issues and PRs that require attention from people who are familiar with C++. fs Issues and PRs related to the fs subsystem / file system.
Projects
None yet
Development

Successfully merging this pull request may close these issues.