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: move fs.promises API to fs/promises #18777

Closed
wants to merge 3 commits into from
Closed

Conversation

targos
Copy link
Member

@targos targos commented Feb 14, 2018

First commit moves utility functions that both fs and fs.promises make use of to internal/fs. It will make backporting easier if needed.

Second commit moves fs.promises to a separate file: fs/promises. It also changes the async function definitions to regular declarations. This allowed to find a bug thanks to ESLint.

I'm doing this for three reasons:

  • fs was already a large file before the addition of fs.promises. This lightens it a bit.
  • fs.promises code is independent of fs code. It should not have to be loaded at the same time.
  • a separate module will allow to use named imports in ESM for promises functions.

/cc @jasnell @joyeecheung

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message follows commit guidelines
Affected core subsystem(s)

fs

@nodejs-github-bot nodejs-github-bot added build Issues and PRs related to build files or the CI. fs Issues and PRs related to the fs subsystem / file system. labels Feb 14, 2018
lib/fs.js Outdated
if (constants.O_SYMLINK !== undefined) {
const fd = await promises.open(path,
constants.O_WRONLY | constants.O_SYMLINK);
return promises.fschmod(fd, mode).finally(fd.close.bind(fd));
Copy link
Member Author

Choose a reason for hiding this comment

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

this is the bug caught by moving out of an object

Copy link
Member

@benjamingr benjamingr Feb 14, 2018

Choose a reason for hiding this comment

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

@targos mind explaining why catching the bug required moving it out of an object?

I realize that eslint has a much harder time to figure out missing properties on objects than ReferenceErrors - but not catching such typos is kind of embarrassing for us - more so if this wasn't a stage 1 API.

Copy link
Member Author

Choose a reason for hiding this comment

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

AFAIK eslint cannot check properties on objects. It is not something that can be easily done statically.
The best way to catch such errors is to increase code coverage.

lib/fs.js Outdated
if (constants.O_SYMLINK !== undefined) {
const fd = await promises.open(path,
constants.O_WRONLY | constants.O_SYMLINK);
return promises.fschmod(fd, uid, gid).finally(fd.close.bind(fd));
Copy link
Member Author

Choose a reason for hiding this comment

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

ditto

@targos targos added promises Issues and PRs related to ECMAScript promises. and removed build Issues and PRs related to build files or the CI. labels Feb 14, 2018
Copy link
Member

@benjamingr benjamingr left a comment

Choose a reason for hiding this comment

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

Overall bug fix and code movement lgtm.

@@ -3231,11 +3231,11 @@ in that, if the `FileHandle` is not explicitly closed using the
and will emit a process warning, thereby helping to prevent memory leaks.

Instances of the `FileHandle` object are created internally by the
`fs.promises.open()` method.
`fsPromises.open()` method.
Copy link
Member

Choose a reason for hiding this comment

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

I'd prefer it if it was referred to as simply fs in the examples (where it's clear it's the promise version) - that's because that's how people typically use it. Not blocking on it.

Copy link
Member Author

Choose a reason for hiding this comment

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

I also prefer to use just fs. Let's wait and see if someone disagrees.

Copy link
Member

@joyeecheung joyeecheung Feb 16, 2018

Choose a reason for hiding this comment

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

I prefer fsPromises.something because that is clearer...if we use fs.something then it looks confusing for new comers if they don't read through the document and notice that they need to get the promisified version that way.

Copy link
Member

@joyeecheung joyeecheung Feb 16, 2018

Choose a reason for hiding this comment

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

EDIT: s/fs.promise/fsPromises/

Copy link
Member Author

Choose a reason for hiding this comment

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

After checking how the documentation is, I changed my mind and also prefer to use a different name.
Ideally, I think it should be possible to switch from the callback documentation to the Promise one instead of having one giant page with both at the same time.

lib/fs.js Outdated
if (constants.O_SYMLINK !== undefined) {
const fd = await promises.open(path,
constants.O_WRONLY | constants.O_SYMLINK);
return promises.fschmod(fd, mode).finally(fd.close.bind(fd));
Copy link
Member

@benjamingr benjamingr Feb 14, 2018

Choose a reason for hiding this comment

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

@targos mind explaining why catching the bug required moving it out of an object?

I realize that eslint has a much harder time to figure out missing properties on objects than ReferenceErrors - but not catching such typos is kind of embarrassing for us - more so if this wasn't a stage 1 API.

} = process.binding('constants').fs;
const { statValues } = process.binding('fs');

const isWindows = process.platform === 'win32';
Copy link
Member

Choose a reason for hiding this comment

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

Not that it matters, but we repeat this line in quite a few places.


function assertEncoding(encoding) {
if (encoding && !Buffer.isEncoding(encoding)) {
throw new errors.TypeError('ERR_INVALID_OPT_VALUE_ENCODING', encoding);
}
}

function copyObject(source) {
Copy link
Member

Choose a reason for hiding this comment

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

I know this PR just moves this - but do you know the rationale for reimplementing this over?

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't

Copy link
Member

Choose a reason for hiding this comment

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

Then I guess I'll just follow up on it after this lands

@benjamingr
Copy link
Member

benjamingr commented Feb 14, 2018

I'm +0 on require(fs/promises) vs require(fs).promises - but I'm +1 on splitting the file away anyway.

We're still at a point where moving it isn't a big deal. Also ping @jasnell.

Copy link
Member

@joyeecheung joyeecheung left a comment

Choose a reason for hiding this comment

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

Thanks for doing this!

@targos
Copy link
Member Author

targos commented Feb 16, 2018

return fsync(this);
}


Copy link
Member

Choose a reason for hiding this comment

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

extra space?

@targos targos added the author ready PRs that have at least one approval, no pending requests for changes, and a CI started. label Feb 16, 2018
@targos
Copy link
Member Author

targos commented Feb 17, 2018

Landed in 760f86c...513d939

@targos targos closed this Feb 17, 2018
@targos targos deleted the fs-promises branch February 17, 2018 09:23
targos added a commit that referenced this pull request Feb 17, 2018
PR-URL: #18777
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
targos added a commit that referenced this pull request Feb 17, 2018
PR-URL: #18777
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
@ljharb
Copy link
Member

ljharb commented May 2, 2018

imo this should not have been merged unflagged, pending the outcome of nodejs/TSC#389 (comment) (specifically, making fs/promises exposed unflagged)

MayaLekova pushed a commit to MayaLekova/node that referenced this pull request May 8, 2018
PR-URL: nodejs#18777
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
MayaLekova pushed a commit to MayaLekova/node that referenced this pull request May 8, 2018
PR-URL: nodejs#18777
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
author ready PRs that have at least one approval, no pending requests for changes, and a CI started. fs Issues and PRs related to the fs subsystem / file system. promises Issues and PRs related to ECMAScript promises.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants