-
Notifications
You must be signed in to change notification settings - Fork 3.2k
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: relativize file links when inflating shrinkwrap #758
Conversation
There are two things that are not addressed yet:
|
I realized that this is concern only for https://github.com/npm/cli/blob/latest/lib/shrinkwrap.js#L180 |
The a-1.0.0.tar.gz: package/package.json
The Then, in a project/package.json
The generated lockfile includes I'll need to spend some more time to make this right. |
Hey @jsnajdr thanks so much for contributing a fix for this! Seems like you've identified some tests that need to be cleaned up. I might suggest, if this gets a little too hairy because of the legacy changes and domino effect that could happen, we're in the process of working on Let us know if you need any help! |
If the shrinkwrap code calls `getRequested` on an optional dependency, the `spec` passed to `npa.resolve` is null. `npa.resolve` then thinks it's a request `fromRegistry`, with spec defaulting to `latest`. And in case the real spec is a tarball, returns nonsensical result where `isRegistry` is true, `fetchSpec` is `1.0.0` instead of `file:...` and the record written to the shrinkwrap is wrong. It contains a `resolved` field, which should be used only for packages downloaded from the registry.
I think it's more like I discovered another bug when optional dependencies are involved. Look at the lockfile that the
All three dependencies are tarballs, but That's because Now the tests are still failing because a repeated @mikemimik @isaacs let me know if it's likely that this patch will be eventually merged into the 6.x line and if it's worth spending more time on. |
The path in `sw.requires` is always relative to the requesting package location, and the default from `packageRelativePath(tree)` is always correct. For `type=file` dependencies, `tree.package._where` contains the `realpath` of the requesting tarball, which is the location where it was unpacked in `node_modules`. That's completely useless for resolving dependency paths. We're interested in the source location of the packed tarball. That's the path against which the dependency spec should be resolved.
When comparing specs like `file:../b-1.0.0.tgz`, the `rawSpec` and `saveSpec` contain paths that are relative against different roots. We need to compare the `fetchSpec`, too, which is absolute.
`realpath` contains the location of the unpacked tarball, and that's useless when resolving relative dependency paths in `package.json`. For that resolution, the location of the packed tarball is important.
After a few more fixes for dependencies of type When calling Another bug that needed fixing is the fact that I think this also uncovers a preexisting bug in
and on-disk directory structure like this:
Then |
Fixes #750.
When reading a package tree from disk and
package.json
files,file:*
dependencies have paths relative to the current package directory. But when reading from shrinkwap file, the shrinkwrap file stores paths relative to the top package's path.Both data are used to populate a
tree.package.dependencies
field. For the shrinkwrap, it happens here. But suchdependencies
have wrong path. They need to be relativized after reading from the shrinkwrap.The bug manifests when
computeMetadata
goes throughtree.package.dependencies
and tries to find a matching package in the tree that satisfies each dependency. But because thefile:
paths are wrong, the matching package is not found, although it is present in the tree. The package'srequiredBy
array remains empty and it's removed bypruneIdealTree
. The result is a brokennode_modules
tree with missing links.