Have you ever wondered what licenses the dependencies of your .NET project are? In the ever-expanding world of open source software usage ensuring that your being compliant with the licenses of your dependencies is becoming harder. Do you have copyleft dependencies? Are you abiding by their licensing terms? Maybe there's some legally grey licenses like WTFPL that you need to watch out for.
This can become even trickier when you look into transient dependencies. You know what dependencies you directly consume, but what about the ones that you indirectly consume as they are a dependency of a dependency?
dotnet-delice, or delice for short, is a tool that will look at the dependencies you have in your project and attempt to determine what license they use and display the results for you. This is a port of the Node.js utility delice, created by Tierney Cyren.
Project dotnet-delice
License Expression: MIT
├── There are 10 occurances of MIT
└─┬ Packages:
├── FSharp.Core
├── Microsoft.NETCore.App
├── Microsoft.NETCore.DotNetAppHost
├── Microsoft.NETCore.DotNetHostPolicy
├── Microsoft.NETCore.DotNetHostResolver
├── Microsoft.NETCore.Platforms
├── Microsoft.NETCore.Targets
├── NETStandard.Library
├── Newtonsoft.Json
└── System.ComponentModel.Annotations
delice will scan the dependency graph of the project and output the license information in a human-readable format (above) or generate JSON (to stdout or a file). The JSON could be used in a build pipeline to fail a build if there are unexpected licenses detected.
You'll find the source code on GitHub if you want to have a dig around in it yourself.
📑 A CLI to help you get insight into your projects' licenses
dotnet-delice
delice is a tool for determining the license information of the packages that are referenced in a project/solution. This is a port of the Node.js utility delice, created by Tierney Cyren.
Note: dotnet-delice only supports SDK project files for C#, F# and VB.NET (although I'm not sure on VB.NET, never tried it!), not the legacy "MSBuild style" project files (which only support .NET full framework). If you are still using the legacy project file the tool will fail. I'd encourage you to try and upgrade (using a tool such as CsprojToVs2017).
Right now, every package can link to a license by providing the licenseUrl property in the metadata. This is awesome, but also not-so-awesome. Allow me to explain my line of thinking.
Every package owner can attach a license to every version of their package. So far, so good, as it allows switching license between versions. So far, so good.
Now imagine utilizing a NuGet package. For impact, let's take Newtonsoft.Json, a very popular OSS package with a permissive license. One day, the author decides to update the HTML contents at the referred license URL. That's... problematic!
Which license applies? The one I read (and agreed with) at package install time? Or the current one that is now displayed on the license URL?
There is no way to figure out the license changed between install and consuming the package, no way to prove it was permissive at time of first install.
Please consider enforcing embedding license info into the package, as the package itself is considered immutable.
</div>
<div class="gh-btn-container"><a class="gh-btn" href="https://github.com/NuGet/Home/issues/4628">View on GitHub</a></div>
This issue raised a concern about the license information in the nuspec file being just the licenseUrl. Since the license is external to the package the URL could conceivably change without changing the package, thus changing the license you agreed to originally without your knowledge.
For reference, here are the planned milestones for this feature:
Milestone 1 (Today):
NuGet.exe v4.9.2 and dotnet.exe (that ships with .NET SDK – 2.1.502 and 2.2.101) supports creating packages using the new “license” property
Providing “LicenseURL” during pack time is deprecated and a warning is shown if used.
NuGet.org accepts packages that contain the “license” property, including license files.
License information (expression or file) is exposed through Package Manager UI in Visual Studio.
Visual Studio 2017 15.9.4 and above supports surfacing the new “license” property.
Milestone 2:
We will monitor the adoption of clients that can understand the “license” property and NuGet.org will disable the use of licenseUrl when that adoption has reached a threshold.
Now the solution is to store the license expression (ideally in spdx format) or embed the license file within the package. Here is how it's set in my project.
By taking this approach the license is now tied to the release of the package and thus you're unlikely to have it changed without you knowing, since a change requires an updated package.
As this is quite a large change to the NuGet ecosystem many packages are still using the legacy licensing format. This makes it a little more challenging for delice to work out what license a package uses. Currently, the tool has a "cache" of known license URLs and which license it maps to (and the packages that use it), but when a license is found that isn't known it'll be marked as "Unable to determine" and show the URL in the output. Feel free to submit a PR to add the URL to the cache!
Hopefully, the increased visibility will help encourage package authors to update their license information or encourage people to submit PR’s to update.
Conclusion
delice aims to empower you with information so that you understand what's in use by your projects and make the appropriate decisions about the dependencies you use.
There's a bit of a roadmap on the projects GitHub repo but I’d like to hear what you would want from this tool.