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?
Enter dotnet-delice
TL;DR : I created a dotnet
global tool called dotnet-delice
to help you with this.
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.
You can install it from NuGet:
> dotnet tool install --global dotnet-delice --version 1.0.0
And then run it by pointing to a folder, a solution file or a csproj
/fsproj
file:
> dotnet delice ~/github/DotNetDelice/DotNetDelice.sln
Here's a snapshot of the output it will generate:
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.
aaronpowell / dotnet-delice
📑 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).
Usage
This tool ships as a dotnet
global tool and can be installed like so:
dotnet tool install -g dotnet-delice
You can then use it like so:
dotnet delice [folder, sln, csproj, fsproj]
Commands
-
-?|-h|--help
Boolean. Show help. -
-j|--json
Boolean. Output results as JSON rather than pretty-print. -
--json-output [path]
String. Path to file that…
A Note on Package Licenses
While I was doing my research into how this works I came across this NuGet issue.
Self-Contained NuGet Packages - License #4628
Update (by @anangaur on 1/8/2019) - Useful links:
- Feature announcement: Packaging Icon, License and Documentation within the nupkg
- Deprecation announcement for
licenseUrl
: 'licenseUrl' as package metadata is now deprecated, use 'license' instead - Spec wiki: Packaging License within the nupkg
- Discussion issue: Self-Contained NuGet Packages – License #4628
- Documentation for
license
metadata in nuspec: https://docs.microsoft.com/en-us/nuget/reference/nuspec#license - Documentation for
license
metadata using MSBuild properties in project file: https://docs.microsoft.com/en-us/nuget/reference/msbuild-targets#packing-a-license-expression-or-a-license-file
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.
This resulted in the deprecation of licenseUrl
in favour of a license
property.
'licenseUrl' as package metadata is now deprecated, use 'license' instead #32
As announced earlier about our aim to remove content Urls (license, icons and markdown documentation) from the package and make these metadata part of the package, we have now deprecated the use of licenseUrl
as package metadata. You can now use license
field in the nuspec, instead.
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.
Links:
- Feature announcement: Packaging Icon, License and Documentation within the nupkg
- Spec wiki: Packaging License within the nupkg
- Discussion issue: Self-Contained NuGet Packages – License #4628
- Documentation for
license
metadata in nuspec: https://docs.microsoft.com/en-us/nuget/reference/nuspec#license - Documentation for
license
metadata using MSBuild properties in project file: https://docs.microsoft.com/en-us/nuget/reference/msbuild-targets#packing-a-license-expression-or-a-license-file
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.
Top comments (1)
For the life of me, I didn't actually know why the change to the license files being referenced happened but that makes complete sense.