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

path: deprecate internal _makeLong, replace #14956

Closed
wants to merge 1 commit into from

Conversation

jasnell
Copy link
Member

@jasnell jasnell commented Aug 21, 2017

Replace the internal path._makeLong() with a public path.toNamespacedPath() method. Add documentation.

Refs: standard-things/esm#66

Ping: @ljharb @jdalton

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)

path

@jasnell jasnell added notable-change PRs with changes that should be highlighted in changelogs. path Issues and PRs related to the path subsystem. semver-major PRs that contain breaking changes and should be released in the next major version. labels Aug 21, 2017
@nodejs-github-bot nodejs-github-bot added fs Issues and PRs related to the fs subsystem / file system. module Issues and PRs related to the module subsystem. path Issues and PRs related to the path subsystem. labels Aug 21, 2017
@jasnell jasnell requested review from MylesBorins, addaleax and a team August 21, 2017 05:50
Copy link
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

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

LGTM

@bnoordhuis
Copy link
Member

You knew this question was coming: is making it public the right thing to do or should it be spun off into a npm package? _makeLong() is not a privileged function and doesn't do anything special, it just munges strings.

Copy link
Contributor

@refack refack left a comment

Choose a reason for hiding this comment

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

See my comments on jasnell@0222709

lib/path.js Outdated
@@ -1342,11 +1342,10 @@ const posix = {
},


_makeLong: function _makeLong(path) {
toLongUNCPath: function toLongUNCPath(path) {
Copy link
Contributor

Choose a reason for hiding this comment

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

AFAICT to make this a consistent API this needs to be

     return  posix.resolve(path);

Copy link
Member Author

Choose a reason for hiding this comment

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

That would change the implementation. That's not what this intends to do.

Copy link
Contributor

Choose a reason for hiding this comment

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

This is a new API, it need to be consistent.
Since the windows implementation uses resolve either the posix one does too, or remove it from the Windows one.

Copy link
Member Author

Choose a reason for hiding this comment

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

No, it's not a new API. It literally just renames the existing function and makes the old name a deprecated alias. This api is and has been used by core for a long time and changing its behavior is not something I want to do in this pr.

@refack
Copy link
Contributor

refack commented Aug 21, 2017

You knew this question was coming: is making it public the right thing to do or should it be spun off into a npm package? _makeLong() is not a privileged function and doesn't do anything special, it just munges strings.

IMHO it has value as another endpoint on path, which is anyway just a string munger. Using paths with the \\?\ prefix has "special powers" on Windows e.g. it can include . and .. as directory names, and has a much longer size limitation.
Refs: https://msdn.microsoft.com/library/windows/desktop/aa365247(v=vs.85).aspx

The name is incorrect tough, it should be resolveExtended, since the output in not a UNC path.

@jasnell
Copy link
Member Author

jasnell commented Aug 21, 2017

@bnoordhuis: simple answer is: node.js needs the function, it's already in the code, it's already accessible, it costs us extremely little to do this. So yes, I think it's the right thing to do.

<a id="DEP00XX"></a>
### DEP00XX: path._makeLong()

Type: Runtime
Copy link
Member

Choose a reason for hiding this comment

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

-1 on runtime-deprecating without a reason, especially if we’re exposing an alias

Copy link
Member Author

Choose a reason for hiding this comment

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

The reason is to strongly discourage userland from making continued use of _-prefixed methods. This is an api they already should not be using, without the deprecation notice, there's no strong motivation for those who are to change.

Copy link
Member

Choose a reason for hiding this comment

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

I don't know if this should be runtime- or docs- deprecated, but I think the deprecation should be in an other commit so we can cherry-pick the addition to v8.x

Copy link
Member

Choose a reason for hiding this comment

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

@jasnell I think I have two issues with that approach:

  • There should to be a time frame for migration, in which using either name just works, and a run-time deprecation is functional breakage
  • This PR is committing to supporting this API anyway (which is a good thing in my eyes!). Imho, we should focus runtime-deprecation of APIs, internal or not, on code that can actually be expected to be broken/removed in the future.

Copy link
Member Author

Choose a reason for hiding this comment

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

A compromise approach, then, would be docs-only in 9.x, runtime deprecation in 10.x.

Copy link
Member Author

Choose a reason for hiding this comment

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

@targos ... re: cherry-picking, If this goes through, I would open a separate PR against 8.x that can be cherry-picked.

Copy link
Member

Choose a reason for hiding this comment

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

@jasnell I’m okay with that, I guess (not a fan, but eh).

Also, if this is just a docs-deprecation, I’d be in favour of just landing it as a minor in v8.x.

lib/path.js Outdated
@@ -673,7 +674,7 @@ const win32 = {
},


_makeLong: function _makeLong(path) {
toLongUNCPath: function toLongUNCPath(path) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This name is incorrect, the result is not UNC but a specially prefixed "extended lengh" path name.
IMHO best option is resolveExtended (although to keep with dirname and extname is could be all lowercase resolveextended)
Ref: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx
image

doc/api/path.md Outdated
* `path` {string}
* Returns: {string}

On Windows systems only, returns the equivalent UNC path for the given `path`.
Copy link
Contributor

Choose a reason for hiding this comment

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

The description is imprecise. Also if we decide to go with a resolveExtended interpretation the description needs to change to include a reference to resolve:

Resolves the `path` with [`path.resolve()`][].
On Windows systems only, returns an "extended-length" path, which includes the "\\?\" prefix.
For more information see [this MSDN][aa365247]
...
[`path.resolve()`]: #path_path_resolve_paths
[aa365247]: https://msdn.microsoft.com/library/windows/desktop/aa365247(v=vs.85).aspx

@refack
Copy link
Contributor

refack commented Aug 21, 2017

No, it's not a new API. It literally just renames the existing function and makes the old name a deprecated alias. This api is and has been used by core for a long time and changing its behavior is not something I want to do in this pr.

I get that you want to make it a minimal change, but you can't avoid the fact that documenting it is de facto declaring a new API. New users will become aware of it and will try to figure out how to use it, and for them we need it to make sense and have least amount of surprise.

IMHO simply documenting an internal ad-hoc-ish API has sub-optimal benefit. If we can't find a way to make sense of it, I'd rather it stayed undocumented, or be documented as deprecated.

As I see it the crux of the design issue is that besides prepending \\?\ (which doesn't have a counterpart on POSIX), it also does resolve on Windows (which does have a POSIX counterpart)
https://github.com/nodejs/node/blob/0222709088f03e0d936d4fbf609e81fffd735888/lib/path.js#L686
while on POSIX it's the whole method is a noop, that asymmetry was a surprise to me, so I'm assuming it will surprise others.

@jasnell
Copy link
Member Author

jasnell commented Aug 21, 2017

while on POSIX it's a noop, that was a surprise to me, so I'm assuming it will surprise others.

which is why it is clearly indicated as a no-op in the added documentation.

@refack
Copy link
Contributor

refack commented Aug 21, 2017

while on POSIX it's a noop, that was a surprise to me, so I'm assuming it will surprise others.

which is why it is clearly indicated as a no-op in the added documentation.

That doesn't answer why it is that way... Or what this API is good for.

Anyway, I am now tending to see this from your POV, but I want to convince myself. Please let me think some more about what you are saying, and about the big picture.

@jasnell
Copy link
Member Author

jasnell commented Aug 21, 2017

@addaleax ... moved to a docs-only deprecation
@refack ... renamed the public method

Copy link
Member

@ljharb ljharb left a comment

Choose a reason for hiding this comment

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

Would love to see this as semver-minor in 8, and the original name runtime-deprecated in v9 :-)

@jasnell
Copy link
Member Author

jasnell commented Aug 21, 2017

I will be opening a backport PR to land it as a minor in 8.x, 6.x and 4.x

@jasnell
Copy link
Member Author

jasnell commented Aug 21, 2017

@refack ... if there are specific implementation changes to the posix version that you'd like to see, please open a separate PR for that.

@jasnell
Copy link
Member Author

jasnell commented Aug 21, 2017

@bnoordhuis
Copy link
Member

simple answer is: node.js needs the function, it's already in the code, it's already accessible, it costs us extremely little to do this. So yes, I think it's the right thing to do.

That's not a great answer. Node has a lot of functions it needs that we don't expose. Why is this function special?

"Costs us extremely little" was the same argument for net.Server#maxConnections, process.on('uncaughtException') and a host of other things we've come to regret later. I'd like to hear a better motivation.

@jasnell
Copy link
Member Author

jasnell commented Aug 21, 2017

@nodejs/ctc ... please review and weigh in.

@ljharb
Copy link
Member

ljharb commented Aug 21, 2017

It's already exposed. This change just documents it and gives it a better name. If not this, is your suggestion to remove it entirely?

@ChALkeR
Copy link
Member

ChALkeR commented Sep 27, 2017

@jasnell, doing it right now. Sorry for the long delay on all this…
Btw, I think we need to move the whole gzemnid thing into the org, I got stuck on that, too…

@@ -660,6 +660,15 @@ Type: Runtime

`REPLServer.parseREPLKeyword()` was removed from userland visibility.

<a id="DEP00XX"></a>
### DEP00XX: path._makeLong()
Copy link
Contributor

Choose a reason for hiding this comment

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

Please escape the underscore.

@ChALkeR
Copy link
Member

ChALkeR commented Sep 27, 2017

Full grep: https://gist.github.com/ChALkeR/d740faa02146b6d726fedb328c08a043
That is mostly fs copies. Without those, the list is pretty short. I will post a prettier (filtered and weighted) list later today.

+1 to this PR.

@Fishrock123
Copy link
Contributor

I am updating the OP to use the current new API name of path.toNamespacedPath(), rather than path.toLongUNCPath().

@ChALkeR ChALkeR self-requested a review September 27, 2017 17:12
Copy link
Contributor

@Fishrock123 Fishrock123 left a comment

Choose a reason for hiding this comment

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

I'm not super keen on exposing more easy-to-implement API but it does also seem reasonable. +-0 with comments addressed.

@@ -673,7 +673,7 @@ const win32 = {
},


_makeLong: function _makeLong(path) {
toNamespacedPath: function toNamespacedPath(path) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems to have rather poor type-checking, can we fix that before exposing it publicly?

Copy link
Member Author

Choose a reason for hiding this comment

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

Fix in what way? If the value is not a string it simply returns the value. Given how extensively this method is used by other fs methods that perform their own type checking, adding additional type checking to this would be redundant and largely unnecessary.

@mhdawson
Copy link
Member

Based on discussion in the TSC meeting consensus is that we can move forward. We can land once comments are addressed unless there are objections in next 48 hours.

@jasnell
Copy link
Member Author

jasnell commented Sep 27, 2017

Ok. Glad to finally see progress on this. I'll get the pr updated

@BridgeAR BridgeAR removed the tsc-agenda Issues and PRs to discuss during the meetings of the TSC. label Sep 27, 2017
Replace the internal `path._makeLong()` with a public
`path.toLongUNCPath()` method. Add documentation.

Refs: standard-things/esm#66
@jasnell jasnell force-pushed the deprecate-internal-makelong branch from 656f162 to 9277e4a Compare October 2, 2017 17:46
@jasnell
Copy link
Member Author

jasnell commented Oct 2, 2017

PR rebased and updated to address the feedback. Opted not to apply additional type checking to the method. If we want to pursue adding additional type checking, then that can be done as a separate semver-major PR

@jasnell
Copy link
Member Author

jasnell commented Oct 2, 2017

@jasnell jasnell dismissed Fishrock123’s stale review October 2, 2017 17:53

TSC decided to move forward with the change. We can add additional type checking later in a separate semver-major PR

@refack
Copy link
Contributor

refack commented Oct 2, 2017

@bnoordhuis
Copy link
Member

Based on discussion in the TSC meeting consensus is that we can move forward.

@mhdawson The meeting notes in nodejs/TSC#367 don't mention the rationale, only that discussion happened.

jasnell added a commit that referenced this pull request Oct 2, 2017
Replace the internal `path._makeLong()` with a public
`path.toLongUNCPath()` method. Add documentation.

PR-URL: #14956
Ref: standard-things/esm#66
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Refael Ackermann <refack@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
@jasnell
Copy link
Member Author

jasnell commented Oct 2, 2017

Landed in 1f8d527

@jasnell jasnell closed this Oct 2, 2017
@jasnell
Copy link
Member Author

jasnell commented Oct 2, 2017

@bnoordhuis ... just saw your comment here right after pushing to master. If we need to revisit this, we can, but I was proceeding based on the goahead from TSC and the green CI

@bnoordhuis
Copy link
Member

@jasnell No, it's fine, I'm just interested to know what the TSC's motivation for moving forward was.

The questions I posted are mentioned in the meeting notes but not if they were actually discussed.

@refack
Copy link
Contributor

refack commented Oct 2, 2017

DEP code left unassigned.
I'm thinking of a way to lint for this 🤔

@jasnell
Copy link
Member Author

jasnell commented Oct 2, 2017

Pr to fix the dep code is already open.
There is a check made already during the release process. A tool such as @evanlucas' commit checker could be modified to check for this.

@refack
Copy link
Contributor

refack commented Oct 2, 2017

A tool such as @evanlucas' commit checker could be modified to check for this.

I was think about something that wraps core-validate-commit:

  1. Find the the changeset since upstream/master
  2. Loop and run core-validate-commit on all commits message
  3. Run lint on all changed files
  4. Special lint rules

I'm open a PR and if anyone has suggestions they should add there.

addaleax pushed a commit to addaleax/ayo that referenced this pull request Oct 4, 2017
Replace the internal `path._makeLong()` with a public
`path.toLongUNCPath()` method. Add documentation.

PR-URL: nodejs/node#14956
Ref: standard-things/esm#66
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Refael Ackermann <refack@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
@tniessen tniessen added the deprecations Issues and PRs related to deprecations. label Sep 7, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
deprecations Issues and PRs related to deprecations. fs Issues and PRs related to the fs subsystem / file system. module Issues and PRs related to the module subsystem. notable-change PRs with changes that should be highlighted in changelogs. path Issues and PRs related to the path subsystem. semver-major PRs that contain breaking changes and should be released in the next major version.
Projects
None yet
Development

Successfully merging this pull request may close these issues.