43

To keep our house in order, I want to automatically assemble licenses for project dependencies in our documentation, rather than having to add them manually.

Does anybody know a simple way to traverse programmatically a set of CSPROJ files and extract the license information for the referenced packages as a link or string?

mguassa
  • 707
Byron Ross
  • 627
  • 1
  • 5
  • 8

4 Answers4

47

One way I know to get such information is by using PowerShell in the Package Manager Console, from within Visual Studio.

The Package Manager Console is a PowerShell console within Visual Studio used to interact with NuGet and automate Visual Studio.

Basically you can use the Get-Package cmdlet to get a list of packages referenced in a specific project (or in an entire Solution). Regarding the license information for each package, for what I've seen you can only get the license URL and not just a short string representing the license type.

Here's an example for a Solution of mine returning a list of entries, each one consisting of the package identifier and the link to the license:

Get-Package | Select-Object Id,LicenseUrl

The output is something like this:

get-package output

Other elements that can be returned are documented in the Nuspec reference, in the metadata section (e.g. the version of the package, a short description, etc.).

mguassa
  • 707
10

Based on multiple sources, I've made a PowerShell script that reads all NuGet packages and fetches the license files and put that in a folder called "licenses". The script should be run on the root of the project (where the "packages" folder is located).

# Run in Package Manager Console with `./download-packages-license.ps1`.
# If access denied, execute `Set-ExecutionPolicy -Scope Process -ExecutionPolicy RemoteSigned`.

Split-Path -parent $dte.Solution.FileName | cd; New-Item -ItemType Directory -Force -Path ".\licenses"; @( Get-Project -All | ? { $.ProjectName } | % { Get-Package -ProjectName $.ProjectName | ? { $.LicenseUrl } } ) | Sort-Object Id -Unique | % { $pkg = $; Try { if ($pkg.Id -notlike 'microsoft*' -and $pkg.LicenseUrl.StartsWith('http')) { Write-Host ("Download license for package " + $pkg.Id + " from " + $pkg.LicenseUrl); #Write-Host (ConvertTo-Json ($pkg));

        $licenseUrl = $pkg.LicenseUrl
        if ($licenseUrl.contains('github.com')) {
            $licenseUrl = $licenseUrl.replace("/blob/", "/raw/")
        }

        $extension = ".txt"
        if ($licenseUrl.EndsWith(".md")) {
            $extension = ".md"
        }

        (New-Object System.Net.WebClient).DownloadFile($licenseUrl, (Join-Path (pwd) 'licenses\') + $pkg.Id + $extension);
    }
}
Catch [system.exception] {
    Write-Host ("Could not download license for " + $pkg.Id)
}

}

Disclaimer: I'm no PowerShell expert. Run at your own risk :)

I couldn't find any simple code that detects which license the NuGet package has, based on it's license file. The only project that comes close to a solution is Licensee, but this is build in Ruby.

jerone
  • 211
1

I managed to get the licence information using the following command:

@( @(Get-Project -All | ForEach-Object { Get-Package -ProjectName $_.ProjectName }) | Select Id -Unique ) | ForEach-Object { $pkg = $_ ;$pkgId = $_.Id ; if ($pkgId -notlike  'microsoft*'){ $url = Open-PackagePage $pkgId -License -WhatIf -PassThru; Write-Host "$pkgId $url"}}
1

There is now a project called "Nuget License Utility" for .NET:

A .net core tool to print the licenses of a project. This tool support .NET Core and .NET Standard Projects.

jerone
  • 211