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

Yarn 1.1.0 optimizeResolutions fails if package pattern has || in the range #4547

Closed
rekotiira opened this issue Sep 26, 2017 · 2 comments
Closed

Comments

@rekotiira
Copy link

Commit 4020ccd introduced a feature that still exists in the current version:

As a final step of package resolution, for each dependency we check whether any version satisfies all resolved version ranges.

There is a bug with this feature. If a dependency has a || in its semver range, the code incorrectly resolves to a version that in reality really doesn't satisfy all version ranges.

For example I had the following lodash versions:

lodash@^4.11.1
lodash@~3.5.0
[email protected]
lodash@^3.0.1 || ^2.0.0

And the available versions were '4.17.4', '3.5.0', '2.4.2', '3.10.1'

The code generates a combinedRange: ^4.11.1 ~3.5.0 2.4.2 ^3.0.1 || ^2.0.0

And this combined range incorrectly resolves to a single version: 2.4.2.

The root of the issue is that semver apparently evaluates that expression as: ( ^4.11.1 ~3.5.0 2.4.2 ^3.0.1 ) || ^2.0.0 although the intention of the code is to evaluate it as ^4.11.1 ~3.5.0 2.4.2 ( ^3.0.1 || ^2.0.0 )

It seems that there is no way to group the OR in the latter manner, hence as a fix the patterns with OR could simply be excluded from the optimization. Here's a patch that fixes the issue:

diff --git a/src/package-resolver.js b/src/package-resolver.js
index 8079989..3468ad1 100644
--- a/src/package-resolver.js
+++ b/src/package-resolver.js
@@ -560,10 +560,12 @@ export default class PackageResolver {

     // don't optimize things that already have a lockfile entry:
     // https://github.com/yarnpkg/yarn/issues/79
-    const collapsablePatterns = patterns.filter(pattern => {
-      const remote = this.patterns[pattern]._remote;
-      return !this.lockfile.getLocked(pattern) && (!remote || remote.type !== 'workspace');
-    });
+    const collapsablePatterns = patterns
+      .filter(pattern => {
+        const remote = this.patterns[pattern]._remote;
+        return !this.lockfile.getLocked(pattern) && (!remote || remote.type !== 'workspace');
+      })
+      .filter(pattern => pattern.indexOf('||') === -1);
     if (collapsablePatterns.length < 2) {
       return;
     }

Tested on latest LTS version of node (v6.11.3).

@BYK
Copy link
Member

BYK commented Sep 26, 2017

Actually, looks like we can manually craft a range that satisfies our needs: https://github.com/npm/node-semver/blob/master/semver.js#L768

@BYK
Copy link
Member

BYK commented Sep 27, 2017

I have a PR cooking for this.

BYK added a commit that referenced this issue Sep 27, 2017
… with top level dependency (#4488)"

**Summary**

Fixes #4547, unfixes #3780 by reverting #4488 (commit 4020ccd).

**Test plan**

Existing unit tests.
@BYK BYK closed this as completed in #4562 Sep 27, 2017
BYK pushed a commit that referenced this issue Sep 27, 2017
…ns (#4562)

**Summary**

Fixes #4547 by testing each version against all ranges individually, rather than munging the patterns together to get a single range.

**Test plan**

Existing tests, plus a regression test to repro #4547: "manifest optimization respects versions with alternation"
joaolucasl pushed a commit to joaolucasl/yarn that referenced this issue Oct 27, 2017
…ns (yarnpkg#4562)

**Summary**

Fixes yarnpkg#4547 by testing each version against all ranges individually, rather than munging the patterns together to get a single range.

**Test plan**

Existing tests, plus a regression test to repro yarnpkg#4547: "manifest optimization respects versions with alternation"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants