-
Notifications
You must be signed in to change notification settings - Fork 30.1k
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: implement recursive (mkdirp) functionality #21875
Conversation
doc/api/fs.md
Outdated
@@ -2066,16 +2066,22 @@ changes: | |||
--> | |||
|
|||
* `path` {string|Buffer|URL} | |||
* `mode` {integer} Not supported on Windows. **Default:** `0o777`. | |||
* `options` {Object|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.
{Object|integer}
applies also to fs.mkdirSync
and fsPromises.mkdir
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.
It's not clear that the integer
value is still supported. It should.
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.
updating to rubys' suggestion of {Object|integer}
, this was copy pasta on my part.
The design phase may be over, so I may have missed the boat. But I do find it surprising this implemented as a flag to This may just be familiarity with the existing patterns. But an explicit method, does have some value:
Ultimately, If I have to choose between it not existing, and being implemented as a flag. I would absolutely choose it existing as a flag. But I do believe my preference, if given the option, would be as a separate method. |
I would be curious, how this implementation compares performance wise to |
Also, I am super excited to see this be baked in! |
I agree with @stefanpenner in that I find If you continue down the road of |
Setting whether this should be in core aside (I am neural on this given how many times I need this in the user land), a few notes on the current design/implementation:
|
Sorry, missed the bits about C++ implementation in the OP
If I understand correctly this just DRYs the validation (but only if this is implemented as an option of EDIT: as for |
I'm the author of I don't think it should be a new method. The difference between I would be happy to donate |
src/node_file.cc
Outdated
@@ -479,7 +483,6 @@ bool FSReqAfterScope::Proceed() { | |||
void AfterNoArgs(uv_fs_t* req) { | |||
FSReqBase* req_wrap = static_cast<FSReqBase*>(req->data); | |||
FSReqAfterScope after(req_wrap, req); | |||
|
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.
This has become an unrelated whitespace change :)
src/node_file.cc
Outdated
@@ -1150,28 +1153,133 @@ static void RMDir(const FunctionCallbackInfo<Value>& args) { | |||
} | |||
} | |||
|
|||
int MKDirpSync(uv_loop_t* loop, uv_fs_t* req, const std::string& path, int mode, | |||
uv_fs_cb cb = nullptr) { | |||
FSContinuationData continuation_data = FSContinuationData(req, mode, cb); |
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.
I think the compiler could optimize the copy operation away here, but either way, it’s a bit more idiomatic to initialize this as FSContinuationData continuation_data(req, mode, cb);
(i.e. without the assignment) 🙂
src/node_file.cc
Outdated
case UV_EPERM: { | ||
return err; | ||
break; | ||
}default: |
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.
style nit: new line for default
(and/or just omit the break;
and the braces here)
src/node_file.cc
Outdated
case 0: | ||
break; | ||
case UV_ENOENT: { | ||
std::string dirname = next_path.substr(0, path.find_last_of("\\/")); |
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.
I think this will lead to an infinite loop if there is no / or \ character?
This can happen if the current working directory does not exist anymore:
const fs = require('fs');
fs.mkdirSync('/tmp/foo');
process.chdir('/tmp/foo');
fs.rmdirSync('/tmp/foo');
fs.mkdirSync('X', { parent: true });
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.
added a test case for this.
src/node_file.cc
Outdated
const char* path, | ||
int mode, | ||
uv_fs_cb cb) { | ||
FSReqBase* req_wrap = static_cast<FSReqBase*>(req->data); |
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.
I just landed #21839 – can you use FSReqBase::from_req(req)
here and below? :)
src/node_file.cc
Outdated
// on each iteration of algorithm, mkdir directory on top of stack. | ||
std::string next_path = req_wrap->continuation_data->PopPath(); | ||
ssize_t err = uv_fs_mkdir(loop, req, next_path.c_str(), mode, | ||
uv_fs_callback_t{[](uv_fs_t* req) { |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
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 discussed out of band the problem with using req_wrap->Dispatch()
and @addaleax and I came the the decision that using uv_fs_mkdir
directly was sufficient.
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.
I think we need to call uv_fs_req_cleanup()
after a uv_fs_mkdir
call is done, but before we start the next one?
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.
I'm now calling uv_fs_req_cleanup()
for all but the last fs
operation, since it's called in the codebase already at the top level of the request wrap.
src/node_file.h
Outdated
req->result = result; | ||
done_cb(req); | ||
} | ||
void MemoryInfo(MemoryTracker* tracker) const override { |
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.
tiny style nit: We usually leave blank lines between methods
src/node_file.h
Outdated
|
||
void PushPath(const std::string& path) { | ||
paths.push_back(path); | ||
} |
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.
I think everywhere where this is called, the path
parameter is not used afterwards in the caller. Currently, this creates a copy of path
and then disposes the original – it might make sense to use std::string&&
as the parameter and move the string rather than copying it? (i.e. use paths.emplace_back(std::move(path));
here and continuation_data->PushPath(std::move(str));
elsewhere)
src/node_file.h
Outdated
} | ||
std::string PopPath() { | ||
CHECK_GE(paths.size(), 0); | ||
std::string path = paths[paths.size() - 1]; |
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.
Similarly, this also creates a copy but doesn’t really need to – I think path = std::move(paths.back())
works?
doc/api/fs.md
Outdated
* `callback` {Function} | ||
* `err` {Error} | ||
|
||
Asynchronously creates a directory. No arguments other than a possible exception | ||
are given to the completion callback. | ||
|
||
The optional options argument can be an integer specifying mode (permission and |
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.
nit: there should be backticks around options
here.
doc/api/fs.md
Outdated
The optional options argument can be an integer specifying mode (permission and | ||
sticky bits), or an object with a mode property and a parent property | ||
indicating whether parent folders should be created. | ||
|
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.
An example showing each variant would be nice.
doc/api/fs.md
Outdated
* Returns: {Promise} | ||
|
||
Asynchronously creates a directory then resolves the `Promise` with no | ||
arguments upon success. | ||
|
||
The optional options argument can be an integer specifying mode (permission and |
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.
Backticks around options
here also.
lib/fs.js
Outdated
options = _extend(defaults, options); | ||
options.mode = validateMode(options.mode, 'mode', 0o777); | ||
if (typeof options.parent !== 'boolean') | ||
throw new ERR_INVALID_ARG_TYPE('parent', 'boolean', options.parent); |
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.
likely should be 'options.parent'
for the first argument here
src/node_file.cc
Outdated
uv_fs_callback_t{[](uv_fs_t* req) { | ||
FSReqBase* req_wrap = static_cast<FSReqBase*>(req->data); | ||
ssize_t err = req->result; | ||
if (err == 0 && !S_ISDIR(req->statbuf.st_mode)) err = UV_EEXIST; |
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.
extreme nit: We generally put the body of if statements on a new line or within brackets.
Great to see this. Would like @addaleax's nits addressed then will sign off :-) |
If the current design is preserved. When we change a heading in the docs, we need to check if there are links to this outdated heading (to do so, copy the old hash from the old HTML doc and grep this hash in Currently, this fragment needs to be updated: |
doc/api/fs.md
Outdated
@@ -2066,16 +2066,22 @@ changes: | |||
--> | |||
|
|||
* `path` {string|Buffer|URL} | |||
* `mode` {integer} Not supported on Windows. **Default:** `0o777`. | |||
* `options` {Object|string} | |||
* `parent` {boolean} **Default:** `false`. |
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 tiny nit: we usually add periods after the **Default:** ...
parts only if they followed full sentences (the same for changes below).
test/parallel/test-fs-mkdir.js
Outdated
|
||
// mkdirpSync ../ | ||
{ | ||
const pathname = `${tmpdir.path}/../`; |
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.
Should this be something like ${tmpdir.path}/testX/testY/../
or even
${tmpdir.path}/testX/../testX/testY/
to make sure the directory created is under the temporary directory that gets cleaned up?
so that we know its creating
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.
I've updated both the ../
and ./
test accordingly, found a couple bugs in the process.
test/parallel/test-fs-promises.js
Outdated
} catch (err) { | ||
assert.notStrictEqual(err.message, 'unreachable'); | ||
assert.strictEqual(err.code, 'EEXIST'); | ||
assert.strictEqual(err.syscall, 'mkdir'); |
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.
Should we have the ../ variant here as well.
Overall happy to see this, will sign off once comments from everybody so far have been addressed. |
@nodejs/fs |
@bcoe I'm all in favor of making this happen. Was there a public design phase by the way? I don't mind at all PRs coming in without it having been publicly discussed first, but now that it's here, the merits of one API over another should be discussed (if it hasn't happened yet). Could you link to some existing conversation if it exists? I'm with @joyeecheung that a pure JavaScript implementation would make sense, although performance may be reason to make an exception. A demonstration of performance would be nice; how does this implementation perform vs. a pure JS implementation that does the same operations? |
Based on nodejs/TSC#604, I'm removing the |
Implements mkdirp functionality in node_file.cc. The Benefit of implementing in C++ layer is that the logic is more easily shared between the Promise and callback implementation and there are notable performance improvements. This commit is part of the Tooling Group Initiative. Refs: nodejs/user-feedback#70 PR-URL: #21875 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Jon Moss <me@jonathanmoss.me> Reviewed-By: Ron Korving <ron@ronkorving.nl> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com> Reviewed-By: Anatoli Papirovski <apapirovski@mac.com> Reviewed-By: Sam Ruby <rubys@intertwingly.net> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Landed this and all others from #21875 (comment). |
Notable changes: * assert * The diff output is now a tiny bit improved by sorting object properties when inspecting the values that are compared with each other. #22788 * cli * The options parser now normalizes `_` to `-` in all multi-word command-line flags, e.g. `--no_warnings` has the same effect as `--no-warnings`. #23020 * Added bash completion for the `node` binary. To generate a bash completion script, run `node --completion-bash`. The output can be saved to a file which can be sourced to enable completion. #20713 * crypto * Added support for PEM-level encryption. #23151 * Added an API asymmetric key pair generation. The new methods `crypto.generateKeyPair` and `crypto.generateKeyPairSync` can be used to generate public and private key pairs. The API supports RSA, DSA and EC and a variety of key encodings (both PEM and DER). #22660 * fs * Added a `recursive` option to `fs.mkdir` and `fs.mkdirSync`. If this option is set to true, non-existing parent folders will be automatically created. #21875 * http2 * Added a `'ping'` event to `Http2Session` that is emitted whenever a non-ack `PING` is received. #23009 * Added support for the `ORIGIN` frame. #22956 * module * Added `module.createRequireFromPath(filename)`. This new method can be used to create a custom require function that will resolve modules relative to the filename path. #19360 * process * Added a `'multipleResolves'` process event that is emitted whenever a `Promise` is attempted to be resolved multiple times, e.g. if the `resolve` and `reject` functions are both called in a `Promise` executor. #22218 * **url** * Added `url.fileURLToPath(url)` and `url.pathToFileURL(path)`. These methods can be used to correctly convert between file: URLs and absolute paths. #22506 * **util** * Added the `sorted` option to `util.inspect()`. If set to `true`, all properties of an object and Set and Map entries will be sorted in the returned string. If set to a function, it is used as a compare function. #22788 * The `util.instpect.custom` symbol is now defined in the global symbol registry as `Symbol.for('nodejs.util.inspect.custom')`. #20857 * **Windows** * The Windows msi installer now provides an option to automatically install the tools required to build native modules. #22645 * **Added new collaborators**: * digitalinfinity - Hitesh Kanwathirtha PR-URL: #23313
Notable changes: * assert * The diff output is now a tiny bit improved by sorting object properties when inspecting the values that are compared with each other. #22788 * cli * The options parser now normalizes `_` to `-` in all multi-word command-line flags, e.g. `--no_warnings` has the same effect as `--no-warnings`. #23020 * Added bash completion for the `node` binary. To generate a bash completion script, run `node --completion-bash`. The output can be saved to a file which can be sourced to enable completion. #20713 * crypto * Added support for PEM-level encryption. #23151 * Added an API asymmetric key pair generation. The new methods `crypto.generateKeyPair` and `crypto.generateKeyPairSync` can be used to generate public and private key pairs. The API supports RSA, DSA and EC and a variety of key encodings (both PEM and DER). #22660 * fs * Added a `recursive` option to `fs.mkdir` and `fs.mkdirSync`. If this option is set to true, non-existing parent folders will be automatically created. #21875 * http2 * Added a `'ping'` event to `Http2Session` that is emitted whenever a non-ack `PING` is received. #23009 * Added support for the `ORIGIN` frame. #22956 * Updated nghttp2 to 1.34.0. This adds RFC 8441 extended connect protocol support to allow use of WebSockets over HTTP/2. #23284 * module * Added `module.createRequireFromPath(filename)`. This new method can be used to create a custom require function that will resolve modules relative to the filename path. #19360 * process * Added a `'multipleResolves'` process event that is emitted whenever a `Promise` is attempted to be resolved multiple times, e.g. if the `resolve` and `reject` functions are both called in a `Promise` executor. #22218 * url * Added `url.fileURLToPath(url)` and `url.pathToFileURL(path)`. These methods can be used to correctly convert between file: URLs and absolute paths. #22506 * util * Added the `sorted` option to `util.inspect()`. If set to `true`, all properties of an object and Set and Map entries will be sorted in the returned string. If set to a function, it is used as a compare function. #22788 * The `util.instpect.custom` symbol is now defined in the global symbol registry as `Symbol.for('nodejs.util.inspect.custom')`. #20857 * Added support for `BigInt` numbers in `util.format()`. #22097 * V8 API * A number of V8 C++ APIs have been marked as deprecated since they have been removed in the upstream repository. Replacement APIs are added where necessary. #23159 * Windows * The Windows msi installer now provides an option to automatically install the tools required to build native modules. #22645 * Workers * Debugging support for Workers using the DevTools protocol has been implemented. #21364 * The public `inspector` module is now enabled in Workers. #22769 * Added new collaborators: * digitalinfinity - Hitesh Kanwathirtha PR-URL: #23313
Notable changes: * assert * The diff output is now a tiny bit improved by sorting object properties when inspecting the values that are compared with each other. #22788 * cli * The options parser now normalizes `_` to `-` in all multi-word command-line flags, e.g. `--no_warnings` has the same effect as `--no-warnings`. #23020 * Added bash completion for the `node` binary. To generate a bash completion script, run `node --completion-bash`. The output can be saved to a file which can be sourced to enable completion. #20713 * crypto * Added support for PEM-level encryption. #23151 * Added an API asymmetric key pair generation. The new methods `crypto.generateKeyPair` and `crypto.generateKeyPairSync` can be used to generate public and private key pairs. The API supports RSA, DSA and EC and a variety of key encodings (both PEM and DER). #22660 * fs * Added a `recursive` option to `fs.mkdir` and `fs.mkdirSync`. If this option is set to true, non-existing parent folders will be automatically created. #21875 * http2 * Added a `'ping'` event to `Http2Session` that is emitted whenever a non-ack `PING` is received. #23009 * Added support for the `ORIGIN` frame. #22956 * Updated nghttp2 to 1.34.0. This adds RFC 8441 extended connect protocol support to allow use of WebSockets over HTTP/2. #23284 * module * Added `module.createRequireFromPath(filename)`. This new method can be used to create a custom require function that will resolve modules relative to the filename path. #19360 * process * Added a `'multipleResolves'` process event that is emitted whenever a `Promise` is attempted to be resolved multiple times, e.g. if the `resolve` and `reject` functions are both called in a `Promise` executor. #22218 * url * Added `url.fileURLToPath(url)` and `url.pathToFileURL(path)`. These methods can be used to correctly convert between file: URLs and absolute paths. #22506 * util * Added the `sorted` option to `util.inspect()`. If set to `true`, all properties of an object and Set and Map entries will be sorted in the returned string. If set to a function, it is used as a compare function. #22788 * The `util.instpect.custom` symbol is now defined in the global symbol registry as `Symbol.for('nodejs.util.inspect.custom')`. #20857 * Added support for `BigInt` numbers in `util.format()`. #22097 * V8 API * A number of V8 C++ APIs have been marked as deprecated since they have been removed in the upstream repository. Replacement APIs are added where necessary. #23159 * Windows * The Windows msi installer now provides an option to automatically install the tools required to build native modules. #22645 * Workers * Debugging support for Workers using the DevTools protocol has been implemented. #21364 * The public `inspector` module is now enabled in Workers. #22769 * Added new collaborators: * digitalinfinity - Hitesh Kanwathirtha PR-URL: #23313
Notable changes: * assert * The diff output is now a tiny bit improved by sorting object properties when inspecting the values that are compared with each other. #22788 * cli * The options parser now normalizes `_` to `-` in all multi-word command-line flags, e.g. `--no_warnings` has the same effect as `--no-warnings`. #23020 * Added bash completion for the `node` binary. To generate a bash completion script, run `node --completion-bash`. The output can be saved to a file which can be sourced to enable completion. #20713 * crypto * Added support for PEM-level encryption. #23151 * Added an API asymmetric key pair generation. The new methods `crypto.generateKeyPair` and `crypto.generateKeyPairSync` can be used to generate public and private key pairs. The API supports RSA, DSA and EC and a variety of key encodings (both PEM and DER). #22660 * fs * Added a `recursive` option to `fs.mkdir` and `fs.mkdirSync`. If this option is set to true, non-existing parent folders will be automatically created. #21875 * http2 * Added a `'ping'` event to `Http2Session` that is emitted whenever a non-ack `PING` is received. #23009 * Added support for the `ORIGIN` frame. #22956 * Updated nghttp2 to 1.34.0. This adds RFC 8441 extended connect protocol support to allow use of WebSockets over HTTP/2. #23284 * module * Added `module.createRequireFromPath(filename)`. This new method can be used to create a custom require function that will resolve modules relative to the filename path. #19360 * process * Added a `'multipleResolves'` process event that is emitted whenever a `Promise` is attempted to be resolved multiple times, e.g. if the `resolve` and `reject` functions are both called in a `Promise` executor. #22218 * url * Added `url.fileURLToPath(url)` and `url.pathToFileURL(path)`. These methods can be used to correctly convert between file: URLs and absolute paths. #22506 * util * Added the `sorted` option to `util.inspect()`. If set to `true`, all properties of an object and Set and Map entries will be sorted in the returned string. If set to a function, it is used as a compare function. #22788 * The `util.instpect.custom` symbol is now defined in the global symbol registry as `Symbol.for('nodejs.util.inspect.custom')`. #20857 * Added support for `BigInt` numbers in `util.format()`. #22097 * V8 API * A number of V8 C++ APIs have been marked as deprecated since they have been removed in the upstream repository. Replacement APIs are added where necessary. #23159 * Windows * The Windows msi installer now provides an option to automatically install the tools required to build native modules. #22645 * Workers * Debugging support for Workers using the DevTools protocol has been implemented. #21364 * The public `inspector` module is now enabled in Workers. #22769 * Added new collaborators: * digitalinfinity - Hitesh Kanwathirtha PR-URL: #23313
Notable changes: * assert * The diff output is now a tiny bit improved by sorting object properties when inspecting the values that are compared with each other. #22788 * cli * The options parser now normalizes `_` to `-` in all multi-word command-line flags, e.g. `--no_warnings` has the same effect as `--no-warnings`. #23020 * Added bash completion for the `node` binary. To generate a bash completion script, run `node --completion-bash`. The output can be saved to a file which can be sourced to enable completion. #20713 * crypto * Added support for PEM-level encryption. #23151 * Added an API asymmetric key pair generation. The new methods `crypto.generateKeyPair` and `crypto.generateKeyPairSync` can be used to generate public and private key pairs. The API supports RSA, DSA and EC and a variety of key encodings (both PEM and DER). #22660 * fs * Added a `recursive` option to `fs.mkdir` and `fs.mkdirSync`. If this option is set to true, non-existing parent folders will be automatically created. #21875 * http2 * Added a `'ping'` event to `Http2Session` that is emitted whenever a non-ack `PING` is received. #23009 * Added support for the `ORIGIN` frame. #22956 * Updated nghttp2 to 1.34.0. This adds RFC 8441 extended connect protocol support to allow use of WebSockets over HTTP/2. #23284 * module * Added `module.createRequireFromPath(filename)`. This new method can be used to create a custom require function that will resolve modules relative to the filename path. #19360 * process * Added a `'multipleResolves'` process event that is emitted whenever a `Promise` is attempted to be resolved multiple times, e.g. if the `resolve` and `reject` functions are both called in a `Promise` executor. #22218 * url * Added `url.fileURLToPath(url)` and `url.pathToFileURL(path)`. These methods can be used to correctly convert between file: URLs and absolute paths. #22506 * util * Added the `sorted` option to `util.inspect()`. If set to `true`, all properties of an object and Set and Map entries will be sorted in the returned string. If set to a function, it is used as a compare function. #22788 * The `util.instpect.custom` symbol is now defined in the global symbol registry as `Symbol.for('nodejs.util.inspect.custom')`. #20857 * Added support for `BigInt` numbers in `util.format()`. #22097 * V8 API * A number of V8 C++ APIs have been marked as deprecated since they have been removed in the upstream repository. Replacement APIs are added where necessary. #23159 * Windows * The Windows msi installer now provides an option to automatically install the tools required to build native modules. #22645 * Workers * Debugging support for Workers using the DevTools protocol has been implemented. #21364 * The public `inspector` module is now enabled in Workers. #22769 * Added new collaborators: * digitalinfinity - Hitesh Kanwathirtha PR-URL: #23313
I'm an advocate of a small core library (and this is a big part of why such an amazing ecosystem of modules has grown up around Node.js and JavaScript).
Having said this, I love the Tooling Group initiative being advocated by @boneskull; some modules are so prolific, and the behavior at this point in Node's history so standardized, that the functionality should probably simply be part of the core API.
Two great examples of this are
mkdirp
andrimraf
.mkdirp
andrimraf
get downloaded over8,000,000
times a day, and are dependencies of some 250,000 applications on GitHub -- wow!.This pull request implements
mkdirp
by adding aparent
(make the parents) boolean option tomkdir
,mkdirSync
, andpromises.mkdir
methods.I've opted to implement the feature in C++ mainly because the codepath wasn't shared for
mkdir
andpromises.mkdir
and this felt like a good way to DRY things up a bit.Interested to hear what people think, and excited for future discussions around Node tooling.
CC: @stefanpenner, @cb1kenobi.
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passes