Motivation

Often a requirement in software projects is to list all your open-source dependencies of your code with licenses being used including the source code url, version number and name of the library. The reasons can be different — one reason could be that your customer wants to have this list to make a approval for your software or you want a documentation of libraries being used.

The task to create such lists is time-consuming and error-prone if you do it manually. Additionally, you always have to update the list for a new version of your software. So let us see if this task can be automated.

Licence Report Generators

When you look around there are many license report generators available, mostly depending on the buildsystem you use. In our case we have an application which uses npm as dependency management for frontend and gradle as build tool for the backend.

Example — npm based projects

Our project based on npm defines the dependencies via the file package.json. These entries in the json path dependencies are of our interest. So let us start with a simple licence checker, the nlf project. nlf is a project which helps you to list all licenses in your project.
Install it with npm like this:

npm install -g nlf

 

You can now run nlf via commandline in your project folder:

nlf -d

 

This command will generate a list of dependencies with the license found in the package.json file (-d will exclude the developer dependencies).

The output (shortened) looks like this:

ajv@5.2.2 [license(s): MIT]
├── package.json: MIT
└── license files: MIT

angular@1.6.5 [license(s): MIT]
├── package.json: MIT
├── license files: MIT
└── readme files: MIT

angular-animate@1.6.5 [license(s): MIT]
├── package.json: MIT
├── license files: MIT
└── readme files: MIT

angular-aria@1.6.5 [license(s): MIT]
├── package.json: MIT
├── license files: MIT
└── readme files: MIT

angular-cookies@1.6.5 [license(s): MIT]
├── package.json: MIT
├── license files: MIT
└── readme files: MIT

angular-file-saver@1.1.3 [license(s): MIT]
├── package.json: MIT
└── readme files: MIT

angular-material@1.1.4 [license(s): MIT]
├── package.json: MIT
└── license files: MIT

angular-sanitize@1.6.5 [license(s): MIT]
├── package.json: MIT
├── license files: MIT
└── readme files: MIT

angular-toastr@2.1.1 [license(s): MIT]
├── package.json: MIT
└── license files: MIT

angular-touch@1.6.5 [license(s): MIT]
├── package.json: MIT
├── license files: MIT
└── readme files: MIT

angular-translate@2.15.2 [license(s): MIT]
├── package.json: MIT
└── license files: MIT

angular-translate-handler-log@2.15.2 [license(s): MIT]
└── package.json: MIT

angular-translate-loader-static-files@2.15.2 [license(s): MIT]
└── package.json: MIT

angular-truncate@0.1.2 [license(s): MIT]
├── package.json: MIT
└── license files: MIT

angular-ui-router@0.3.2 [license(s): MIT]
├── package.json: MIT
└── license files: MIT

angular-ui-router-title@0.1.1 [license(s): MIT]
├── package.json: MIT
└── readme files: MIT

angular-ui-tree@2.22.5 [license(s): MIT]
├── package.json: MIT
└── license files: MIT

angular-xeditable@0.8.0 [license(s): MIT]
├── package.json: MIT
└── license files: MIT

animate.css@3.5.2 [license(s): MIT]
├── package.json: MIT
├── license files: MIT
└── readme files: MIT

good-listener@1.2.2 [license(s): MIT]
└── package.json: MIT

groupdms-admin-frontend@1.0.0 [license(s): Unknown]

jquery@3.2.1 [license(s): MIT]
└── package.json: MIT

jsnlog@2.24.0 [license(s): MIT]
├── package.json: MIT
└── license files: MIT

json-schema-traverse@0.3.1 [license(s): MIT]
├── package.json: MIT
└── license files: MIT

json-stable-stringify@1.0.1 [license(s): MIT]
├── package.json: MIT
├── license files: MIT
└── readme files: MIT

LICENSES: Apache-2.0, MIT, Public Domain, Unknown

Hint: Unknown comes from the project itself.

As you can see, we only use “easy to use”-licenses like Apache-2.0, MIT and Public Domain in our project which will make approvals very easy.
If this is not enough, we can use the licence-checker project to generate a richer output with more metadata.

license-checker — production — csv — customPath licenceCheckerFormat.json

 

license-checker will generate of all production dependencies (no dev-dependencies) in csv format.
The fields are being used can be configured with the licenceCheckerFormat.json file which looks like this:

{
"name": "",
"version": "",
"repository":"",
"licenses": ""
}

The output of the license-checker tool looks like:

Goldhammer_1_97U5HcnQkN3DMbII9Sn3UA

Example — gradle based project

Gradle is a popular build tool currently. It allows to configure your dependencies in a declarative way (like maven). The dependencies look like:

Goldhammer_2_97U5HcnQkN3DMbII9Sn3UA

 

Currently there are not many options to generate a list of licenses.
One option is the Gradle License Plugin

To use it, you have to configure it in your main gradle buildfile like this:

apply plugin: 'java'
apply plugin: "com.jaredsburrows.license"

licenseReport {
generateHtmlReport = false
generateJsonReport = true
// These options are ignored for Java projects
copyHtmlReportToAssets = false
copyJsonReportToAssets = false
}

Afterwards you can generate a json report it by using following command:

gradle licenseReport

 

The task generates also a json file besides the html — the output looks like:

Goldhammer_3_97U5HcnQkN3DMbII9Sn3UA

This json file can be further processed to generate a csv file by using json2csv, a npm based tool.
The following command can transform the json output from the gradle plugin to a csv-file

json2csv -i licenseReport.json -p -u licenses -f

project,version,url,licenses.license_url,licenses.license -d “|” -o

licenseReport.csv

 

The csv which is generated looks like this in Excel (after seperating data via | symbol):Goldhammer_4_Excel_97U5HcnQkN3DMbII9Sn3UA_neu

Summary

Two examples for npm and gradle based projects have shown that this boring task can be scripted and could be part of a continuous delivery pipeline, so that these reports are automatically created with each version of your software and so kept up to date automatically.

Nevertheless the quality of these reports are depending on the libraries being used because libraries have to maintain the metadata in their own projects. If your customer or you need a complete list, you have to manually edit the generated list. But the output is a good start and maybe sometimes enough as documentation.

 

Tags: Software Development