Add fs.path.ComponentIterator
and use it in Dir.makePath
#16570
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Before this commit, there were three issues with the
makePath
implementation:a/b//c
asa/b//c
,a/b/
,a/b
, anda
.makeDir
calls, e.g. with the patha/b/
(ifa
doesn't exist), it would try to createa/b/
, then trya/b
, then trya
, then trya/b
, and finally trya/b/
again.X:
for something likeX:\a\b\c
if theX:\
drive doesn't exist. This didn't lead to any problems that I could find, but there's no reason to try to make a drive letter as a directory (or any other root path).This commit fixes all three issues by introducing a ComponentIterator that is root-aware and handles both sequential path separators and trailing path separators and uses it in
Dir.makePath
. This reduces the number ofmakeDir
calls for paths where (1) the root of the path doesn't exist, (2) there are consecutive path separators, or (3) there are trailing path separatorsAs an example, here are the makeDir calls that would have been made before this commit when calling
makePath
for a relative path likea/b//c//
(where the full path needs to be created):a/b//c//
a/b//c/
a/b//c
a/b/
a/b
a
a/b
a/b/
a/b//c
a/b//c/
a/b//c//
And after this commit:
a/b//c
a/b
a
a/b
a/b//c
Tangentially related to #14833, but only in the sense that
ComponentIterator
could be used there as well.