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

Prevent optional subdependencies from being installed with --ignore-optional #3976

Merged
merged 3 commits into from
Jul 26, 2017

Conversation

arcanis
Copy link
Member

@arcanis arcanis commented Jul 20, 2017

Fix #2666

@blexrob Would you mind reviewing this PR? You worked a bit on the hoister in #3465, so you might have some additional insight :)

@arcanis arcanis requested a review from BYK July 20, 2017 17:17
@arcanis arcanis self-assigned this Jul 21, 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 overall.

Need a comment about the isNeeded change and we should extract the isPackageRequired to its own function.

{hint: 'optional', optional: true},
!this.flags.ignoreOptional,
);
pushDeps('optionalDependencies', projectManifestJson, {hint: 'optional', optional: true}, true);
Copy link
Member

Choose a reason for hiding this comment

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

Why always set isUsed to true?

Copy link
Member Author

Choose a reason for hiding this comment

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

Because the ignore flag isn't managed anymore by this portion of the code - we do it directly in the hoister instead, so that we can operate recursively.

Copy link
Member

Choose a reason for hiding this comment

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

Gotcha. May be we should remove that flag in a follow-up since it is only used by devDependencies and is confusing a bit.

Copy link
Contributor

@blexrob blexrob Jul 26, 2017

Choose a reason for hiding this comment

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

isUsed is also used to remove the package from consideration in flat mode, so I wouldn't remove it (if another package requires an incompatible version, this would create a conflict). (never mind, the changes to getFlatHoistedTree fix that :-) )

@@ -142,15 +146,15 @@ export default class PackageHoister {
//
let parentParts: Parts = [];
const isIncompatible = ref.incompatible;
let isRequired = isDirectRequire && !ref.ignore && !isIncompatible;
let isRequired = isDirectRequire && !ref.ignore && !isIncompatible && (!ref.optional || !this.ignoreOptional);
Copy link
Member

Choose a reason for hiding this comment

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

Better to write as !(ref.optional && this.ignoreOptional) since makes the intent clearer. Also possibly fewer instructions :P

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's purely stylistic ;)

Copy link
Member

Choose a reason for hiding this comment

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

Not really stylistic. One reads "if ref is not optional or we should not ignore optionals" and the other one reads "if NOT (ref is optional and we should ignore optionals)". Human brains are bad at double negations ;)


if (parent) {
if (!this.tree.get(parent.key)) {
return null;
}
// non ignored dependencies inherit parent's ignored status
// parent may transition from ignored to non ignored when hoisted if it is used in another non ignored branch
if (!isDirectRequire && !isIncompatible && parent.isRequired) {
if (!isDirectRequire && !isIncompatible && parent.isRequired && (!ref.optional || !this.ignoreOptional)) {
Copy link
Member

Choose a reason for hiding this comment

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

Same as above. Also, may convert this to a function instead of repeating the same logic in multiple places?

depinfo &&
!depinfo.isRequired &&
!depinfo.isIncompatible &&
(!depinfo.pkg._reference || !depinfo.pkg._reference.optional || !this.ignoreOptional)
Copy link
Member

Choose a reason for hiding this comment

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

Yeah, we definitely need to extract this logic out.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah I agree, but there was some subtle changes in the conditions so I aimed to make the minimal change required and revisit if needed. I'll give it a second look.

Copy link
Member

Choose a reason for hiding this comment

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

We can defer this to a follow-up since it's not the main goal of the PR anyways.

@BYK BYK merged commit 9dd9599 into yarnpkg:master Jul 26, 2017
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.

3 participants