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

lib: add shutil module with rmtree method #1

Closed
wants to merge 6 commits into from
Closed

Conversation

iansu
Copy link
Owner

@iansu iansu commented Apr 28, 2019

Port rimraf to new shutil module.

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

@iansu iansu force-pushed the shutil-rmtree branch 2 times, most recently from a6a312a to 6c2eb84 Compare April 28, 2019 21:15
Copy link

@bcoe bcoe left a comment

Choose a reason for hiding this comment

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

This is looking really good; ends up actually being a fairly small amount of code.

}

// Two possible strategies.
// 1. Assume it's a file. unlink it, then do the dir stuff on EPERM or EISDIR
Copy link

Choose a reason for hiding this comment

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

Curious why we're calling this shutil and not rmraf?

Copy link
Owner Author

Choose a reason for hiding this comment

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

I think that suggestion originally came from @refack. Python puts rmtree and number of other shell type functions like copytree under a lib called shutil. He suggested we do the same as eventually we may want to add more functionality to this lib.

Choose a reason for hiding this comment

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

chiming in: yes, eventually some major portion of python's shutil should be implemented. we want to start with this one

Copy link

Choose a reason for hiding this comment

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

Even if the majority of shutil ends up being ported, this belongs in fs. Most of shutil's functionality is already implemented in the fs module. (Copyfile, readfile, mkdir, mkdir -p, etc.) It adds unnecessary friction for Node.js users to have their fs utils split across two modules.

Copy link

Choose a reason for hiding this comment

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

In other words, from node's point of view, "shell utilities" are not a thing. There are file system utilities in fs, and process utilities in child_process.

Choose a reason for hiding this comment

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

hoping @refack can chime in on the reasoning

Choose a reason for hiding this comment

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

I followed the original idea of having a shutil package inspired on what python provides and I get the rationale but Isaacs comments left me with the impression that node has a way more centralized file system namespace than what python has: https://docs.python.org/3.7/library/filesys.html

so in my understanding it seems to be more friendly to node developers to implement (all the shutil family of functions) in fs as suggested, is that impression something any of you share?

// be made configurable somehow. But until then, YAGNI.
function rmtree_(path, options, callback) {
validatePath(path);
validateOptions(options);
Copy link

Choose a reason for hiding this comment

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

This looks pretty close to the original rimraf logic, we should keep the original license header if we're bringing over @isaacs' code.

Copy link
Owner Author

Choose a reason for hiding this comment

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

Agreed. We discussed that in our last meeting.


shutil.rmtree(path, () => assertGone(path));
}

Copy link

Choose a reason for hiding this comment

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

these tests are structured a bit differently than how we structure tests elsewhere in the codebase; which we usually put in blocks:

// description of test.
{
  test.
}

not functions -- I don't hate this structure .. but might be good to make it consistent just to have one less thing to talk about.

Copy link
Owner Author

Choose a reason for hiding this comment

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

I was trying to model this after some of the existing fs tests and didn't notice that pattern. I'll take a look at some more existing tests. Any particularly good examples you can share?

Copy link

Choose a reason for hiding this comment

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

ignore me if you’re cribbing existing texts 👍

Copy link
Owner Author

Choose a reason for hiding this comment

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

Well, I'm trying. But I'd say I'm familiar with about 2% of the existing codebase. 😀

@isaacs
Copy link

isaacs commented May 5, 2019

I think this is awesome. rimraf is one of my most popular modules, but it's a huge pita to manage all the edge cases, windows performance sucks, etc. Having it in core feels 100% right, and it means that rimraf can be a one-liner for node versions that support it.

If there's any issue with the rimraf license, let me know. It's ISC for a reason, so you of course already have permission to take the code, as long as the copyright and permission stick around. If it's easier for Node.js to relicense it as MIT, that's probably doable.

I'm not sure why a new shutil module is needed, though. Node's fs module already has all the fs stuff, and this is 100% file system functionality. It would make sense to me as fs.rmtree or even fs.rm(path, { recursive: true }). Though that last one would imply fs.rm(path, { recursive: false }) which would call fs.unlink for files and fs.rmdir for dirs, but not recurse through the tree.

@iansu
Copy link
Owner Author

iansu commented May 5, 2019

I'm glad you're onboard with this. Thanks for being willing to contribute rimraf to Node. I'll be sure to mention the license when I submit my PR. I don't know what the process is around that but I'm sure someone will.

I agree that something like fs.rmtree might be more appropriate. I don't really have strong feelings about this one way or the other. Maybe the Tooling Working Group can make a decision on this or I could just submit the PR to Node and see what the larger team and community think.

} while (true);
}

module.exports = {

Choose a reason for hiding this comment

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

I think one thing we mentioned was that we should have a Promise-based implementation. Since this is JS, maybe we can get away with consuming util.promisify()?

What I don't recall is whether or not this PR should block on the Promise implementation. But it doesn't seem (?) so difficult to get it in.

Copy link

@boneskull boneskull left a comment

Choose a reason for hiding this comment

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

LGTM if lint/tests pass. 👍

@iansu iansu closed this Jun 11, 2019
@iansu iansu reopened this Jun 11, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants