-
Notifications
You must be signed in to change notification settings - Fork 29.8k
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: refactor "options" processing as a function #7165
Conversation
@@ -41,6 +41,25 @@ const isWindows = process.platform === 'win32'; | |||
const DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG); | |||
const errnoException = util._errnoException; | |||
|
|||
function getOptions(options, defaultOptions) { | |||
let actualType = typeof options; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW v8 still does not (IIRC) optimize storing typeof foo
in a variable. It's faster to just inline the typeof
without using a variable (e.g. typeof actualType === 'function'
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's how I understand it too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
Generally +1 and LGTM, left a nit. I think this can safely be a minor - this should only break code that parses error messages - right? |
AFAIK changing error message(s) still makes it a semver-major change. |
While we're at it, either the error should say "object that isn't a function", or functions should be accepted as option bags too. |
@seishun The default options is used because, the functions which call |
typeof options + ' instead.'); | ||
} | ||
|
||
options.encoding === 'buffer' || assertEncoding(options.encoding); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we please place this in an if ()
. no sense abusing JS's logical operators to run code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ya sure... I changed it to an if
block.
211453d
to
8de37d0
Compare
assert.throws(function() { | ||
fs.createReadStream(example, 0); | ||
}, /"options" argument must be a string or an object/); | ||
}, /"options" must be a string or an object/); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not keep the other tests and adapt the string?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@silverwind Now, I just changed the strings and allowed only null
.
LGTM with question. |
ffd1fb8
to
706316c
Compare
Bump! |
@@ -41,6 +41,24 @@ const isWindows = process.platform === 'win32'; | |||
const DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG); | |||
const errnoException = util._errnoException; | |||
|
|||
function getOptions(options, defaultOptions) { | |||
if (options == null || typeof options === 'function') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just want to double check that using == null
is intentional?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, @trevnorris. It is intentional.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sometimes people pass null
and sometimes undefined
. That is why I wrote it like this. Eg: https://github.com/isaacs/node-graceful-fs/blob/master/graceful-fs.js#L89
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(a bit late, sorry)
My only beef with this is that next time a developer sees this, they may become eager to "fix" this, causing either a bug or a new discussion about this pattern. My preference is to just be explicit and check for null
and undefined
explicitly with ===
. Just my 2 cents.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ronkorving Fair Enough. Changed it.
One question, otherwise LGTM |
706316c
to
59ceb95
Compare
Okay, added a commit to fix #7655 as well. PTAL. |
if (options.encoding !== 'buffer') | ||
assertEncoding(options.encoding); | ||
|
||
return Object.assign(defaultOptions, options); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably only do this where we need to modify it, otherwise there will be a hit to each call
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Fishrock123 You mean if we don't actually modify options
, we don't want to create this copy?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm, that's what I am afraid of. Then the actual logic of options
processing will not at the same place. Perhaps we can have a second parameter in the function which can be used to flag if a copy has to be made. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Fishrock123 I changed it to util._extend
from Object.assign
. Hope the hit will not be that much now, at least as per #7655 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does util._extend solve this problem? By the way, Object.assign should've become quite a bit faster since V8 5.1 (see http://v8project.blogspot.jp/2016/04/v8-release-51.html). Now I do believe someone was adding a benchmark to compare the two, so I'm not making the assertion that util._extends should be avoided (yet). But a copy is a copy, and is probably more than we need in quite a few cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To think of it, it just copies things to defaultOptions
. That object is constructed already in memory. Would this still be a problem?
LGTM |
@micnic how do you think it could be done in a non semver major way? |
@thealphanerd something like |
8608551
to
2c279ed
Compare
Rebased. CI Run: https://ci.nodejs.org/job/node-test-pull-request/3380/ |
5c0feb3
to
845eeaf
Compare
@thealphanerd started a comparison CITGM run with v6.3.1 yesterday with the same vinyl-fs failures: https://ci.nodejs.org/view/Node.js-citgm/job/citgm-smoker/371/ (from #8253 (comment)). That shows the same failures, so the failures here are likely unrelated… |
/cc @phated On Sat, Aug 27, 2016, 11:02 AM Anna Henningsen [email protected]
|
f502293
to
1b13514
Compare
Squashed and Rebased. |
CI looks good other than a known flaky failure. @thefourtheye, do you want to go ahead and get this landed? |
As it is, the "options" processing is repeated in all the functions which need it. That introduces checks which are inconsistent with other functions and produces slightly different error messages. This patch moves the basic "options" validation and processing to a seperate function.
1b13514
to
4693ee5
Compare
As it is, the "options" processing is repeated in all the functions which need it. That introduces checks which are inconsistent with other functions and produces slightly different error messages. This patch moves the basic "options" validation and processing to a seperate function. PR-URL: #7165 Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: Roman Reiss <[email protected]> Reviewed-By: Trevor Norris <[email protected]> Reviewed-By: Nicu Micleușanu <[email protected]> Reviewed-By: Yorkie Liu <[email protected]> Reviewed-By: James M Snell <[email protected]>
Is this only |
@addaleax The |
Okay then, that’s a bit more than just changed messages. I’m not sure, but maybe it’s still worth to ping @nodejs/ctc and see if anybody feels strongly about it? |
yeah, prefer major. If you want it in v7 we should discuss this now |
I'm ok with pulling this into v7. @nodejs/ctc ... thoughts? |
Seems okay to me, yes. 👍 |
If there are no objections from @nodejs/ctc by Monday, I'll pull this in to v7.x-staging |
As it is, the "options" processing is repeated in all the functions which need it. That introduces checks which are inconsistent with other functions and produces slightly different error messages. This patch moves the basic "options" validation and processing to a seperate function. PR-URL: #7165 Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: Roman Reiss <[email protected]> Reviewed-By: Trevor Norris <[email protected]> Reviewed-By: Nicu Micleușanu <[email protected]> Reviewed-By: Yorkie Liu <[email protected]> Reviewed-By: James M Snell <[email protected]>
As it is, the "options" processing is repeated in all the functions which need it. That introduces checks which are inconsistent with other functions and produces slightly different error messages. This patch moves the basic "options" validation and processing to a seperate function. PR-URL: nodejs/node#7165 Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: Roman Reiss <[email protected]> Reviewed-By: Trevor Norris <[email protected]> Reviewed-By: Nicu Micleușanu <[email protected]> Reviewed-By: Yorkie Liu <[email protected]> Reviewed-By: James M Snell <[email protected]>
As it is, the "options" processing is repeated in all the functions which need it. That introduces checks which are inconsistent with other functions and produces slightly different error messages. This patch moves the basic "options" validation and processing to a seperate function. PR-URL: nodejs/node#7165 Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: Roman Reiss <[email protected]> Reviewed-By: Trevor Norris <[email protected]> Reviewed-By: Nicu Micleușanu <[email protected]> Reviewed-By: Yorkie Liu <[email protected]> Reviewed-By: James M Snell <[email protected]>
Checklist
Affected core subsystem(s)
fs
Description of change
As it is the "options" processing is repeated in all the functions
which need it. That introduces checks which are inconsistent with
similar functions and produces slightly different error messages.
This patch moves the basic "options" validation and processing to a
separate function.
cc @nodejs/fs @nodejs/collaborators
Marking this as major, as this might break some code in the wild.