user494461
user494461

Reputation:

how to extract the licenses of JS libraries used

I want to make a list of JS libraries I have used in my webapp. Can I somehow extract it automatically from the included files? The ones which I include in my head tag? Can I somehow scan particular JS files for licenses?

Upvotes: 4

Views: 4016

Answers (4)

Amitt K Sharma
Amitt K Sharma

Reputation: 1

One can use bower to manage client side dependencies. And someone wants to audit the bower packages installed with meta information and license file one can use "bower-license-tracker" module. The module will generate the JSON file which looks like: enter image description here

Upvotes: -1

Boris Zagoruiko
Boris Zagoruiko

Reputation: 13174

First of all I recommend you to use bower.js for managing your client-side javascript dependencies. It is useful a lot and helps with many things like installing or updating your javascript libraries.

If you do, you can install npm package bower-license. It generates a list of bower dependencies for a project and their licenses. You can install it with

<<sudo>> npm install -g bower-license

Note that you must have node.js with npm and sudo depends on platform your use

Output looks like this:

bower-license

├─ highlight
│  └─ licenses: UNKNOWN
├─ [email protected]
│  └─ licenses: MIT*
├─ [email protected]
│  ├─ licenses: MIT*
│  └─ homepage: http://millermedeiros.github.com/js-signals/
├─ [email protected]
│  └─ licenses: MIT*
├─ [email protected]
│  ├─ licenses: UNKNOWN
│  └─ homepage: https://github.com/highslide-software/highcharts.com
├─ [email protected]
│  ├─ licenses: MIT*
│  └─ homepage: https://github.com/millermedeiros/Hasher

You can use package as library as well:

var license = require('bower-license');
license.init('/path/to/package', function(licenseMap){
    console.log(licenseMap);
});

Upvotes: 2

mailmindlin
mailmindlin

Reputation: 624

Usually, the licences are the first comment in a JS file. For example (from jQuery-1.11.1 uncompressed):

 /*!
 * jQuery JavaScript Library v1.11.1
 * http://jquery.com/
 *
 * Includes Sizzle.js
 * http://sizzlejs.com/
 *
 * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors
 * Released under the MIT license
 * http://jquery.org/license
 *
 * Date: 2014-05-01T17:42Z
 */

(function( global, factory ) {
    if ( typeof module === "object" && typeof module.exports === "object" ) {
....

Though there are not standardized headers, there are some things that you can do to determine it's license, though they won't work for every script. You can see a working jsfiddle 2[here].

var getLicense = function (text) {
    var output = document.querySelector('#output');
    var regex = new RegExp("/\\*[\\S\\s]*?\\*/","m");
    var commentText = rexex.exec(text)[0];
    //check for some common licenses.
    if(commentText.toLowerCase().contains("apache license")||commentText.toLowerCase().contains("apache commons")) {
        output.innerHTML += "License is: Apache";
        return "Apache";
    } else if(commentText.toUpperCase().contains("BSD")) {
        output.innerHTML += "License is: BSD";//you might want to check for different versions
        return "BSD";
    } else if(commentText.toUpperCase().contains("LGPL")) {
        output.innerHTML += "License is: LGPL";
        return "LGPL";
    } else if(commentText.toUpperCase().contains("GPL")) {
        output.innerHTML += "License is: GPL";
        return "GPL";
    } else if(commentText.toLowerCase().contains("mozilla public")) {
        output.innerHTML += "License is: Mozilla Public License";
        return "Mozilla";
    } else if(commentText.toLowerCase().contains("mit license")) {
        output.innerHTML += "License is: MIT";
        return "MIT";
    }
    //remove any dangling newlines or spaces before the beginning
    text = text.trim();
    //check if there is a 'header' comment
    if(text.startsWith('/*')) {
        var commentLines = commentText.split('\n');
        console.log(commentLines);
        //iterate through the comment lines, and pull out the important ones
        for (var k in commentLines) {
            var commentLine = commentLines[k];
            console.log(commentLine);
            if(commentLine.contains('license')) {
                output.innerHTML+=commentLine+"\n";
            }
        }
        return;
    } else {
        output.innerHTML+="No idea...\n";
    }
};

It basically searches for a one of a few common JS licences (I assumed you only meant open source licences). Failing that, it takes the first multiline comment, and prints out the lines with the word 'license', which kinda works. If you know the set of licenses that your scripts are using, you can use a lookup function to get the license text.

This will work in pretty well, but some scripts won't have headers comments. This script will work in node.js, standard javascript, or you could probably port it to other languages pretty easily (especially java, with its JS ScriptEngine).

Upvotes: 4

Niels Keurentjes
Niels Keurentjes

Reputation: 41968

Because there is no fixed file format for Javascript, or its headers, what you want is (practically) impossible in a generic app. You can however of course attempt the same thing by hand.

On a *nix machine (including Macs) you have the very powerful find command, which allows you to scan for specific files and performing actions on them. For example:

find -name "*.js" -exec head {} \;

This will find all JS files in a directory tree, and run the head command on them, which dumps by default the first 10 lines of the file. This should in general show more than enough license information.

Now to find out which JS files are actually included you can use wget with the recursive flag. This also circumvents the common CMS problem, because it retrieves the site as the browser sees it, not how it is internally organized. You can mirror a site to a local folder with:

wget -r http://www.mydomain.tld/

Don't do this on Stack Overflow, you'll blow up your machine. But on a reasonably sized site, combining these 2 commands are the closest you're gonna get to your intended result without writing hundreds of lines of code. Using system(...) you can also execute both these commands from within PHP, allowing you to execute them remotely on a *nix server if needed.

Upvotes: 1

Related Questions