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
Add licenses command to pnpm #5567
Conversation
If you run the command {
"MIT": [
{
"name": "next",
"path": "/Users/User/temporary/license-proto/pnpm-licenses/node_modules/next",
"license": "MIT",
"vendorUrl": "https://nextjs.org"
}
],
"Apache-2.0": [
{
"name": "typescript",
"path": "/Users/User/temporary/license-proto/pnpm-licenses/node_modules/typescript",
"license": "Apache-2.0",
"vendorName": "Microsoft Corp.",
"vendorUrl": "https://www.typescriptlang.org/"
}
]
} If you leave out the ┌──────────────────┬────────────┬─────────────────────────────────┐
│ Package │ License │ Details │
├──────────────────┼────────────┼─────────────────────────────────┤
│ typescript (dev) │ Apache-2.0 │ Microsoft Corp. │
│ │ │ https://www.typescriptlang.org/ │
├──────────────────┼────────────┼─────────────────────────────────┤
│ next │ MIT │ https://nextjs.org │
└──────────────────┴────────────┴─────────────────────────────────┘ If you exclude the
|
It's currently a draft because of two issues:
Would appreciate some helper on the second issue how I could make that work |
There is a package for walking the lockfile: https://github.com/pnpm/pnpm/tree/main/packages/lockfile-walker |
Thank you, I will have a look and see how I can use it :) |
I have reimplemented to use the lockfile-walker package and added tests to the new packages this PR is introducing |
Only question I am having whether peerDependencies of a package that user hasn't installed should be included? |
The manifests should be updated with |
When I try to run this I am getting this error:
|
version, | ||
prefix: modules, | ||
}); | ||
} catch (err: unknown) {} |
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.
why should this error be ignored?
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.
I have the problem that sometimes an optional dependency is listed in the lock file but not stored in modules directory and then the fetching fails. In that case I am skipping/ignoring this package so it won't get listed.
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.
No, it is not OK to skip such issues. It would mean that your license checker doesn't check all the dependencies, so a package with a bad license might pass under your radar. Besides, now that you read from the CAFS, the optional deps will always be found. So this try/catch is not needed.
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.
I think this problem is resolved now. I have removed it, while making this change I did struggle to make it work with PNPM repo and the pkg
-package as it's a tarball
and the workspace projects but I think I cracked it. Only definitely not 100% sure it's the right approach
@zkochan Thank you for taking the time to review my PR. I have tried to apply your suggestions to my branch. I can totally imagine that are better ways to do some things :) |
Hey @weyert ! Nice to see such a command finding a place in PNPM and thank you for your work! 😀 Does this PR also include disclaimer-file generation, like |
Not yet as I didn't have a need for it yet . I am happy to work on it in a follow-up pull request |
The approach that is used here has some disadvantages.
A better solution would be to read the package.json file and the license files from the content-addressable store. It would solve issues the 1st and 2nd issues. The 3rd issue will still exist unless we will dynamically fetch missing packages to the store (which may be done in a separate PR). You can see examples how to read info from the store here: https://github.com/pnpm/pnpm/blob/main/packages/package-requester/src/packageRequester.ts For instance, see how the readManifestFromStore function is used to read the manifest. To find the license file in the content-addressable store, you should read the index file of the package. It contains the list of files. The path to the index file is calculated from the package's integrity checksum: pnpm/packages/package-requester/src/packageRequester.ts Lines 331 to 333 in e19356c
|
I have tried to accommodate your change requests. I hope what I changed is what you intended. Hopefully I didn't misunderstood you |
version, | ||
prefix: modules, | ||
}); | ||
} catch (err: unknown) {} |
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.
No, it is not OK to skip such issues. It would mean that your license checker doesn't check all the dependencies, so a package with a bad license might pass under your radar. Besides, now that you read from the CAFS, the optional deps will always be found. So this try/catch is not needed.
I have updated the PR to resolve issues and accommodated the request changes I have attached an example of the command when running against this repo: |
} | ||
} | ||
|
||
const licenseNodeTree: LicenseNodeTree = { |
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.
Why do you create a tree of license nodes if in the output you just list all the packages in a flat list?
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.
I will have a look at changing this
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.
Would this be a blocker for the PR to be merged?
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.
Isn't that simpler code?
packages/licenses/src/getPkgInfo.ts
Outdated
const isLocalPkg = packageResolution.type === 'directory' | ||
if (isLocalPkg) { | ||
const localInfo = await fetchFromDir( | ||
path.join(opts.lockfileDir, packageResolution.directory), | ||
{} | ||
) | ||
return { | ||
local: true, | ||
files: localInfo.filesIndex, | ||
} |
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 will scan the whole package with all subdirectories even though the license files are only searched for in the root directory of the package.
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.
I couldn't find a way to get the package file index of a pnpm workspace project, so generating one. Is there a way to get it? It's not available in the CAFS
|
||
return { | ||
name: 'Unknown', | ||
licenseFile: licenseContents?.toString('utf-8'), | ||
} |
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.
What if the package has multiple license files?
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.
Hah good question, I haven't discovered any of such package yet. Are you aware of one?
I don't think other licenses commands of other packages handle this use case, though
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.
I have seen such packages in the past.
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.
Packages that don't use license
-property but have multiple license files? Happy to improve the code after this PR has been merged sounds like a pretty edge case to me
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.
I work in a company that archives npm data and I can tell you without question that there are more packages that do that than you'd think. Roughly 10% of packages in the registry. People do nutty stuff in package.json and npm has no validation.
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.
If you happen to archive npm data via work, could younbe so kind and suggest some npm packages that does this so I can make it part of a test case?
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.
give me a bit of time to get to that, but I'll take a look for you. if I don't get to this in a week, please ping me
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.
Sure, of course, I am already happy you want to take the time help me :)
I see that in yarn v1 there is a In yarn v2 they don't have this command but there is a plugin that may be used. With this plugin, the command is: I wonder if we need to make this command cc @pnpm/collaborators |
Updated the code so that the `getPkgInfo` function attempts to fetch the `package.json` and potential license files from the cafs directory by integrity id
Improved handling of reading package manifest for packages resolving to workspace projects,and tarballs Improved the handlign of parsing the license from the `package.json`-file
Renamed the `@pnpm/licenses`-package to `@pnpm/license-scanner` Updated the keywords for the packages Renamed the main function of `@pnpm/license-scanner` to be `findDependencyLicenses` Renamed to the fields `vendorName`, `vendorUrl` to the original fields used in the packages: `author` and `homepage`
99f6499
to
2176e74
Compare
Congrats on merging your first pull request! 🎉🎉🎉 |
Introduces a new command named licenses which generates a license compliance report
refs #2825