DEV Community

Aaron Powell for .NET

Posted on • Originally published at aaron-powell.com on

What Licenses Are in Use?

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

Enter fullscreen mode Exit fullscreen mode

And then run it by pointing to a folder, a solution file or a csproj/fsproj file:

> dotnet delice ~/github/DotNetDelice/DotNetDelice.sln

Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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.

GitHub logo aaronpowell / dotnet-delice

📑 A CLI to help you get insight into your projects' licenses

CI build Release build NuGet Badge The MIT License

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:


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>
Enter fullscreen mode Exit fullscreen mode


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:

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)

Collapse
 
turnerj profile image
James Turner

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 the life of me, I didn't actually know why the change to the license files being referenced happened but that makes complete sense.