Description
Describe the user story
I'm a project manager and I want to prevent my employees from adding to our codebase new code distributed under untested licenses (ex WTFPL).
Describe the solution you'd like
I'd like to set a list of accepted (or rejected) SPDX license strings in my .yarnrc
that would cause a validation error at install time. For example:
valid-licenses:
- MIT
- BSD
Note that this would require to also validate transitive dependencies.
Describe the drawbacks of your solution
While it might be important for various entities, I don't think it would belong to the "core". In that sense I'm pretty sure it should be distributed as a separate plugin (either developed on this repository or by an interested third-party).
It would also require a better plugin workflow than what we currently have (we would definitely need this yarn plugin add
command!).
Describe alternatives you've considered
The exact validation mechanism is TBD as while there are multiple ways to achieve a similar result, all have their own drawbacks. In particular:
-
We could pass a
validate
named parameter to the resolvers that they would have the responsibility to call themselves before returning, passing the manifest of the package they're currently handling. Thisvalidate
function wouldn't be set in most cases except foryarn add
which would implement it by calling the project validation hook (I think I like this option the most). -
We could simply make it an extra command whose sole purpose would be to check the versions. I think it makes sense to do that regardless of the case (it might be especially important when changing the set of accepted dependencies, since in those cases the "validateNewPackage" hook wouldn't trigger), but the overall experience isn't great since it requires an extra command to be run after each install.
Click here to see a bunch of other possible solutions
-
We could implement it as a validation hook that would be called from
Project
with thePackage
value returned by the resolvers, but that would require us to add the license field to thePackage
type - and thus serialize it withinyarn.lock
. It's not clear how scalable this is - if we need to add all the fields from the manifests to theyarn.lock
it kinda defeats the purpose (this might be alleviated if the plugins were able to specify a list of fields that need to be persisted, but even then it's dubious). -
We could store the
Manifest
instance within the returnedPackage
(at least for every resolver where it makes sense) and instruct the lockfile serializer to not save this field (then we would still have this validation hook I mentioned inProject
that would be able to access all values from the manifest). But while it would solve the lockfile format scalability issue that would make the behavior different from one execution to the next (sometimes the manifest for a package would be there and sometimes it wouldn't), and I don't like that very much. -
We could add a validation hook to the cache ("if a file should be added, first validate it"), but that wouldn't work well with the global cache approach. At the same time, we don't want to validate the packages every time as that would be a waste of resources.
-
We could make the
resolveEverything
function accept a list argument that would be populated with the list of locators that couldn't be resolved from the lockfile (this is a bit tricky because the resolvers don't return this information at the moment). Then after callingfetchEverything
we would iterate over those new locators and trigger a validation hook. The downside is that rejected packages (+ dependencies + dependents) will still have reached the cache, unless we somehow manage to remove them. -
There's a reasonable case that this could be implemented through the constraints engine by exposing all the packages in the dependency tree (rather than just the workspaces). In practice I have some concerns it might grow the fact list exponentially, although I don't have numbers. It would also be an after-the-fact validation, which I'd like to avoid (it wouldn't be a good experience to use a package then at PR-time you figure out you can't use it).
Additional context
I received the stats from the npm survey and interestingly enough licenses were proeminently featured: