cah1r
cah1r

Reputation: 1979

Get license information for all used NuGet packages in .NET Core outside of Visual Studio

We have a requirement in our project to list all of the licensed nuget packages. It would be ideal to generate them to some kind of csv, json, xml file. It would have to be done by build or by CI/CD tool. The problem is the only way I found to get that listing is by calling:

Get-Package | Select-Object Id,LicenseUrl

inside Visual studios package manager. I found also some sample powershell scripts but they are all based on versions of .net prior to .net core and are based on reading packages folder which in .net core version no longr exists.

Is there any way to achieve what we need in .NET Core ?

Regards.

Upvotes: 17

Views: 27043

Answers (3)

Kees C. Bakker
Kees C. Bakker

Reputation: 33421

I'm now using sensslen/nuget-license. The code in my Docker is:

dotnet tool install --global nuget-license

PATH=$PATH:/root/.dotnet/tools

lic_file="$nuget-licenses.json"
sln="$(find *.sln | head -1)"

nuget-license --input "$sln" --allowed-license-types "$lic_file" --error-only

Looks like tomchavakis/nuget-license is abandoned:

Abandoned message

Upvotes: 1

mark.monteiro
mark.monteiro

Reputation: 2941

The dotnet-project-licenses CLI tool works well with the current versions of .NET Core and is very easy/quick to set up.

If you wanted to run the tool to report on the solution or project in the current directory you can follow these steps:

  1. Install the tool
dotnet tool install --global dotnet-project-licenses
  1. Run the tool against the current directory (uses the -i flag to specify the input directory)
dotnet-project-licenses -i .

This will produce output similar to this:

Project Reference(s) Analysis...

References:
 | Reference                                               | Version         | License Type        | License                                                                    |
 |------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
 | Bogus                                                   | 34.0.2          |                     | https://raw.githubusercontent.com/bchavez/Bogus/master/LICENSE             |
 | coverlet.collector                                      | 3.2.0           | MIT                 | https://licenses.nuget.org/MIT                                             |
 | CsvHelper                                               | 30.0.1          | MS-PL OR Apache-2.0 | https://licenses.nuget.org/MS-PL%20OR%20Apache-2.0                         |

There are many options that can be used to customize the output, but since the question specifically asked about a machine-readable format here is an example excerpt of using the -j or --json flag:

[
    {
        "PackageName": "coverlet.collector",
        "PackageVersion": "3.2.0",
        "PackageUrl": "https://github.com/coverlet-coverage/coverlet",
        "Copyright": "",
        "Authors": [
            "tonerdo"
        ],
        "Description": "Coverlet is a cross platform code coverage library for .NET, with support for line, branch and method coverage.",
        "LicenseUrl": "https://licenses.nuget.org/MIT",
        "LicenseType": "MIT"
    },
    {
        "PackageName": "CsvHelper",
        "PackageVersion": "30.0.1",
        "PackageUrl": "https://joshclose.github.io/CsvHelper/",
        "Copyright": "Copyright © 2009-2022 Josh Close",
        "Authors": [
            "Josh Close"
        ],
        "Description": "A library for reading and writing CSV files. Extremely fast, flexible, and easy to use. Supports reading and writing of custom class objects.",
        "LicenseUrl": "https://licenses.nuget.org/MS-PL%20OR%20Apache-2.0",
        "LicenseType": "MS-PL OR Apache-2.0"
    },
    ...
]

Upvotes: 8

zivkan
zivkan

Reputation: 15081

According to Nate McMaster's list of .NET global tools, there's a tool called dotnet-project-licenses. I've never used it, but you could try it out.

However, if you want to do things yourself, it's not terribly difficult, but will require some code.

First use dotnet list package --include-transitive to list all the packages used by a project, and parse its output. The NuGet team has a request to make the output easier to parse, but honestly I think you only need 2 regexes to easily parse its current output, only 1 if you don't care about TFMs. If your project targets multiple TFMs, you'll want to deduplicate the lists.

Once you have the list of package ids and version numbers (versions are important, as a package could change licenses between versions), you can find the location of your global packages folder (gpf) dotnet nuget locals -l global-packages, then use the {gpf}\{lowercase package id}\{lowercase package version}\{lowercase package id}.{lowercase package version}.nuspec pattern to load the nuspec as XML and find the licence.

Keep in mind that recently NuGet deprecated LicenseUrl and encourage package authors to use license expressions, or embed their licence file in the nupkg. I imagine that embedded licenses pose the largest challenge to any license tool, because unless you want to parse the license text and guess which license it's most likely to be, you'll need to do something else. If all of your packages come from nuget.org, you can have your tool generate urls to nuget.org/packages/{package id}/{package version}/license. But if you use multiple sources, you have no way of knowing which source a package came from, and other feeds might not have an easy way to see the license text for embedded licenses. To do things "properly" you'll need to search your package sources to see if that specific package id and version exist. NuGet's V3 protocol is documented, but the v2 protocol is intentionally not documented, and some 3rd party nuget servers only implement the v2 protocol. You could also look into using the nuget client libraries.

Upvotes: 26

Related Questions