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

Fix: Deprecate implicit file: protocol and only allow package dirs #4257

Merged
merged 2 commits into from
Aug 25, 2017

Conversation

BYK
Copy link
Member

@BYK BYK commented Aug 25, 2017

Summary

Fixes #4251. Follow up to #4088. Instead of just checking whether the
target is a valid directory, we now check if it contains a
package.json file too. This is still different from npm's behavior.
Apparently, npm fetches the package info upfront to favor dist-tags
over directories but this comes at a distinct performance penalty and
makes static, deterministic resolution impossible so we are now
deprecating the implicit file: protocol in patterns. After a certain
point, we'll remove this code and will require everyone to use file:
or at least one of the following path identifiers: ./, ../. /.

Test plan

Updated the existing test for warning check and added a new test for
invalid directories.

**Summary**

Fixes #4251. Follow up to #4088. Instead of just checking whether the
target is a valid directory, we now check if it contains a
`package.json` file too. This is still different from `npm`'s behavior.
Apparently, `npm` fetches the package info upfront to favor dist-tags
over directories but this comes at a distinct performance penalty and
makes static, deterministic resolution impossible so we are now
deprecating the implicit `file:` protocol in patterns. After a certain
point, we'll remove this code and will require everyone to use `file:`
or at least one of the following path identifiers: `./`, `../`. `/`.

**Test plan**

Updated the existing test for warning check and added a new test for
invalid directories.
@BYK BYK requested a review from arcanis August 25, 2017 11:22
import path from 'path';

import invariant from 'invariant';
import semver from 'semver';
Copy link
Member

Choose a reason for hiding this comment

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

Be careful with this, I think some of our third-party modules (or their dependencies) are sometimes mocked in our tests, so using import will break them. Case in mind: request.

static prefixMatcher = /^.{,2}\//;

static isVersion(pattern: string): boolean {
return super.isVersion.call(this, pattern) || this.prefixMatcher.test(pattern);
Copy link
Member

Choose a reason for hiding this comment

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

Maybe update the regex to also match C:\... ?

Copy link
Member Author

Choose a reason for hiding this comment

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

Hmm, good catch. I'll go with path.isAbsolute which takes care of it for me.

@BYK BYK merged commit d47a2bf into master Aug 25, 2017
@BYK BYK deleted the deprecate-implicit-file branch August 25, 2017 14:47
@@ -23,6 +24,11 @@ export default class FileResolver extends ExoticResolver {
loc: string;

static protocol = 'file';
static prefixMatcher = /^.{1,2}\//;
Copy link
Contributor

Choose a reason for hiding this comment

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

Oops, looks like the . isn't escaped, so it's matching any two characters, including single-character scopes like @m.

I have a fix here: #4338

BYK pushed a commit that referenced this pull request Sep 8, 2017
**Summary**

The exotic `file-resolver` checks for `.` and `..`, but the regex is missing the escape on the `.`, so *any* two characters count as a file. This includes single-character scope names, like `@s/packagename`.

This issue was introduced in #4257.

**Test plan**

I wasn't sure how packages should be named in `__tests__/fixtures/install/resolutions/exotic-version`, so I have not added add a single-character scoped package reference to test.

I don't know of any single-character scopes in the public registry to use as reference, the way `left-pad-1.1.1.tgz` is mirrored in there. Could I just copy `leftpad-1.1.1.tgz` as `@s/leftpad-1.1.1.tgz` and use that?
@sheerun
Copy link
Contributor

sheerun commented Sep 13, 2017

Unfortunately this breaks possibility to install local packages without package.json #3855 :(

@BYK
Copy link
Member Author

BYK commented Sep 13, 2017

@sheerun - yeah that was kind of intentional since this caused lots of headaches and I think this is safer. Is it too much trouble to require people to have a simple package.json for local packages?

@sheerun
Copy link
Contributor

sheerun commented Sep 13, 2017

For non-npm packages (like bower's or assets) there isn't package.json available. Also checking for package.json won't solve #4251 if test directory contains package.json (likely to happen).

The real fix would be to require local dependencies to have ../, ./, /, or file: prepended, just like you noticed. I'd agree that package.json requirement could be enforced when they aren't present.

@BYK
Copy link
Member Author

BYK commented Sep 13, 2017

So, we are doing both right now if I'm not wrong. Are you suggesting making it an either / or check?

@sheerun
Copy link
Contributor

sheerun commented Sep 13, 2017

Yes, either correct path format, or package.json :) But also deprecate incorrect path next major

@BYK
Copy link
Member Author

BYK commented Sep 13, 2017

@sheerun you have angered the open source gods and now they want a PR. Are you up to the challenge?

sheerun added a commit to sheerun/yarn that referenced this pull request Sep 14, 2017
sheerun added a commit to sheerun/yarn that referenced this pull request Sep 14, 2017
BYK pushed a commit that referenced this pull request Sep 14, 2017
#4456)

**Summary**

Refs #4257. Adds the missing regression test.

**Test plan**

The new test should pass.
joaolucasl pushed a commit to joaolucasl/yarn that referenced this pull request Oct 27, 2017
…arnpkg#4257)

**Summary**

Fixes yarnpkg#4251. Follow up to yarnpkg#4088. Instead of just checking whether the
target is a valid directory, we now check if it contains a
`package.json` file too. This is still different from `npm`'s behavior.
Apparently, `npm` fetches the package info upfront to favor dist-tags
over directories but this comes at a distinct performance penalty and
makes static, deterministic resolution impossible so we are now
deprecating the implicit `file:` protocol in patterns. After a certain
point, we'll remove this code and will require everyone to use `file:`
or at least one of the following path identifiers: `./`, `../`. `/`.

**Test plan**

Updated the existing test for warning check and added a new test for
invalid directories.
joaolucasl pushed a commit to joaolucasl/yarn that referenced this pull request Oct 27, 2017
**Summary**

The exotic `file-resolver` checks for `.` and `..`, but the regex is missing the escape on the `.`, so *any* two characters count as a file. This includes single-character scope names, like `@s/packagename`.

This issue was introduced in yarnpkg#4257.

**Test plan**

I wasn't sure how packages should be named in `__tests__/fixtures/install/resolutions/exotic-version`, so I have not added add a single-character scoped package reference to test.

I don't know of any single-character scopes in the public registry to use as reference, the way `left-pad-1.1.1.tgz` is mirrored in there. Could I just copy `leftpad-1.1.1.tgz` as `@s/leftpad-1.1.1.tgz` and use that?
joaolucasl pushed a commit to joaolucasl/yarn that referenced this pull request Oct 27, 2017
yarnpkg#4456)

**Summary**

Refs yarnpkg#4257. Adds the missing regression test.

**Test plan**

The new test should pass.
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.

4 participants