-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Refactored integrity generation and check #2818
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
Conversation
src/cli/commands/check.js
Outdated
| const install = new Install(flags, config, reporter, lockfile); | ||
|
|
||
| // get patterns that are installed when running `yarn install` | ||
| // TODO measure slowdown here |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a reminder for myself, I noticed check got slower in the last month.
Probably one of the following 2 commands to blame
src/integrity-checker.js
Outdated
| // if we already have an integrity hash in one of these folders then use it's location otherwise use the | ||
| // first folder | ||
| const possibles = possibleFolders.map((folder): string => path.join(folder, constants.INTEGRITY_FILENAME)); | ||
| let loc = possibles[0]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't it check to see if a directory exists before fallbacking to the first entry? For example, let's say Yarn supports Bower and that there's a bower_modules directory but no node_modules one. Shouldn't Yarn use the bower_directory rather than the non-existing node_modules? (on a similar note but possibly out of scope for this PR, shouldn't the integrity file be different for each registry rather than global to all of them?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check out the next few lines.
possibles[0] is taken by default but then it checks fs.exists(possibleLoc) and picks the first one that exists.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
on a similar note but possibly out of scope for this PR, shouldn't the integrity file be different for each registry rather than global to all of them?
We use one type of registry per project, unlikely there will be a bower_modules and node_modules in one folder, so it should be fine to have only one integrity there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It checks to see if the path(folder, constants.INTEGRITY_FILENAME) file exists, but not the folder itself. So for example, if there's a bower_modules without integrity file, the returned path will still be node_modules/....
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still thinking it through.
I don't think we should choose location for .yarn-integrity based on a folder.
What if a project has checked-in bower_modules folder managed by bower, then Yarn might pick it up as the location but user might want to install node_modules instead.
However, we should pick the location based on what type of registry are there in the project.
Right now we support only node_modules and yarn/npm registry, so it would be a more relevant when we support another one.
src/cli/commands/check.js
Outdated
| } | ||
| const match = await integrityChecker.check(patterns, lockfile, lockSource, flags); | ||
| for (const pattern of match.missingPatterns) { | ||
| reportError('lockfileNotContainPatter', pattern); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems there's a typo in the name of the error (but this typo also affects the lang file so it actually works)
src/cli/commands/check.js
Outdated
| } | ||
| } else { | ||
| if (match.integrityFileMissing) { | ||
| reportError('noIntegirtyHashFile'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, let's fix those here.
In the future it may be problematic when there are translations in the wild
|
@arcanis, I refactored integrity hash location a bit. |
| let registries = registryNames; | ||
| if (usedRegistries && usedRegistries.size > 0) { | ||
| registries = usedRegistries; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even if it's currently the case here, you might want to put a comment to explain that passing falsy values for usedRegistries is only acceptable when one only needs to read the file but not write to it - otherwise multiple integrity files might get generated!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed my previous comment.
Actually it is fine to pass falsy usedRegistries when generating the integrity file, e.g. running yarn install for empty package.json.
Also Yarn won't generate multiple integrity files because this method checks whether one exists already and reuses that location
| return { | ||
| locationPath: loc || possibles[0], | ||
| exists: !!loc, | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not fond of the location getter that also check if a file exists, but it's a private method, so no big deal.
| loc = possibleLoc; | ||
| break; | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's still the behaviour where the first entry will always be returned if there is no integrity file, even if a more "suitable" already directory exists, right? Do you want to keep it that way?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This script will return the first folder that has .yarn-integrity file.
If none found it will pick the first from the list of available.
Right now it is hard to decide whether existence of bower_modules is the right signal for Yarn to save .yarn-integrity there.
Let's get back to this subject when Yarn has more than one folder it can serve, currently it is node_modules only
Summary
I plan to improve integrity check code so that it could also verify node_modules structure.
This PR moves most of the integrity checking and saving code into a separate class, no actual changes to the logic.
Test plan
All tests should pass (integrity checks are covered with integration tests)
Pending things to do: