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: 'yarn --flat' unbound transitive deps shouldn't conflict with top level deps #4488

Merged
merged 1 commit into from
Sep 22, 2017
Merged

Fix: 'yarn --flat' unbound transitive deps shouldn't conflict with top level deps #4488

merged 1 commit into from
Sep 22, 2017

Conversation

mxmul
Copy link
Contributor

@mxmul mxmul commented Sep 17, 2017

Summary

Fixes #3780, and makes the failing test from #3779 passing.

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

Test plan

Fixes an existing (failing) test: "unbound transitive dependencies should not conflict with top level dependency"

BYK
BYK previously requested changes Sep 18, 2017
Copy link
Member

@BYK BYK left a comment

Choose a reason for hiding this comment

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

Looks good but I have some suggestions.

Also, I'm wondering if we can put this logic into .find() itself, potentially avoiding some more network requests and the extra loop over dependencies at the end.

// https://github.com/yarnpkg/yarn/issues/79
const anyLocked = patterns.some(pattern => this.lockfile.getLocked(pattern));
if (anyLocked) {
return;
Copy link
Member

Choose a reason for hiding this comment

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

Why not exclude only the locked ones and still optimize the rest?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So I've made this change, but it causes some workspace related tests to fail ("install should link workspaces that refer each other", "install should not link workspaces that refer not compatible version of another workspace"). I don't quite understand why these are failing, but I've just disabled the optimization wherever remote.type === "workspace". Open to other suggestions.

return;
}

const manifestByVersion: Map<string, Manifest> = new Map();
Copy link
Member

Choose a reason for hiding this comment

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

Looks like you just need this.getAllInfoForPackageName(name) above instead.

});

// reverse sort, so we'll find the maximum satisfying version
const availableVersions = [...manifestByVersion.keys()];
Copy link
Member

Choose a reason for hiding this comment

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

Why not Array.from(manifestByVersion.keys()). That said spread looks is faster in latest V8 versions so NVM: https://jsperf.com/set-iterator-vs-foreach/4

const availableVersions = [...manifestByVersion.keys()];
availableVersions.sort(semver.rcompare);

const requiredRanges = patterns.map(p => normalizePattern(p).range);
Copy link
Member

Choose a reason for hiding this comment

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

I think you can leverage some semver secrets as follows:

const fullRange = patterns.map(pattern => normalizePattern(p).range).join(' ');
const oneRingToRuleThemAll = semver.maxSatisfying([...manifestByVersion.keys()], fullRange);
if (oneRingToRuleThemAll) {
    this.collapseAllVersionsOfPackage(name, oneRingToRuleThemAll);
}

This should be more efficient than what the code below does. Also, the code below continuously resolves to new versions as it goes on since return in a forEach loop doesn't terminate the loop at all.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep, that's a nice optimization.

@buildsize
Copy link

buildsize bot commented Sep 18, 2017

This change will decrease the build size from 9.7 MB to 9.7 MB, a decrease of 1.79 KB (0%)

File name Previous Size New Size Change
yarn-[version].noarch.rpm 835.38 KB 834.94 KB -445 bytes (0%)
yarn-[version].js 3.7 MB 3.7 MB -137 bytes (0%)
yarn-legacy-[version].js 3.75 MB 3.74 MB -551 bytes (0%)
yarn-v[version].tar.gz 839.47 KB 839.06 KB -423 bytes (0%)
yarn_[version]all.deb 635.3 KB 635.03 KB -272 bytes (0%)

@buildsize
Copy link

buildsize bot commented Sep 18, 2017

This change will increase the build size from 9.69 MB to 9.7 MB, an increase of 870 bytes (0%)

File name Previous Size New Size Change
yarn-[version].noarch.rpm 835.17 KB 835 KB -179 bytes (0%)
yarn-[version].js 3.69 MB 3.7 MB 693 bytes (0%)
yarn-legacy-[version].js 3.74 MB 3.75 MB 554 bytes (0%)
yarn-v[version].tar.gz 839.21 KB 839.11 KB -102 bytes (0%)
yarn_[version]all.deb 635.2 KB 635.1 KB -96 bytes (0%)

Copy link
Member

@BYK BYK 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 a bit worried about impacting performance with this but overall looks good.

Would love to get @arcanis or @kaylieEB's feedback before approving though.

const remote = this.patterns[pattern]._remote;
return !this.lockfile.getLocked(pattern) && (!remote || remote.type !== 'workspace');
});
if (collapsablePatterns.length === 0) {
Copy link
Member

Choose a reason for hiding this comment

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

Actually, maybe this should be < 2 since if you have only one pattern, you still don't need to collapse it, right?

@@ -530,10 +545,37 @@ export default class PackageResolver {
this.resolveToResolution(req);
}

deps.forEach(dep => {
Copy link
Member

Choose a reason for hiding this comment

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

For loops are more efficient so I strongly recommend writing this as a for loop. .forEach becomes as fast only after Node 8.5.

@BYK BYK dismissed their stale review September 19, 2017 13:07

Waiting other's input. The final version LGTM.

Copy link
Member

@arcanis arcanis left a comment

Choose a reason for hiding this comment

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

Makes sense to me. I think the ideal fix would rather be in the hoister (we broke part of it somewhere in 0.26, which is why we noticed some packages stopped being merged together since this release), but it seems like a valid iteration for the time being.

@BYK BYK merged commit 4020ccd into yarnpkg:master Sep 22, 2017
@BYK BYK mentioned this pull request Sep 22, 2017
BYK added a commit that referenced this pull request Sep 27, 2017
… with top level dependency (#4488)"

**Summary**

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

**Test plan**

Existing unit tests.
BYK added a commit that referenced this pull request Oct 3, 2017
**Summary**

Fixes #4550. The optimization introduced in #4488 should only
apply to flat installations since even if a single pattern can
satisfy all resolved versions, it is not guaranteed that it is
strict enough for resolving correctly for all patterns under all
circumstances.

**Test plan**

Manual verification.
arcanis pushed a commit that referenced this pull request Oct 3, 2017
**Summary**

Fixes #4550. The optimization introduced in #4488 should only
apply to flat installations since even if a single pattern can
satisfy all resolved versions, it is not guaranteed that it is
strict enough for resolving correctly for all patterns under all
circumstances.

**Test plan**

Manual verification.
joaolucasl pushed a commit to joaolucasl/yarn that referenced this pull request Oct 27, 2017
…el dependency (yarnpkg#4488)

**Summary**

Fixes yarnpkg#3780, and makes the failing test from yarnpkg#3779 passing.

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

**Test plan**

Fixes an existing (failing) test: "unbound transitive dependencies should not conflict with top level dependency"
joaolucasl pushed a commit to joaolucasl/yarn that referenced this pull request Oct 27, 2017
**Summary**

Fixes yarnpkg#4550. The optimization introduced in yarnpkg#4488 should only
apply to flat installations since even if a single pattern can
satisfy all resolved versions, it is not guaranteed that it is
strict enough for resolving correctly for all patterns under all
circumstances.

**Test plan**

Manual verification.
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.

yarn --flat sees a version conflict where there is none
3 participants