Pragmatism in today's world

Check licenses of composer dependencies

With some commercial projects, it can be useful to know that all your dependencies have licences that your organisation deems acceptable.

I had this requirement for a few clients now and came up with this script that we ran as part of our CI which would then fail if a dependency used a license that wasn’t allowed.

This proved to be reasonably easy as composer licenses will provide a list of all packages with their license, and more usefully, the -f json switch will output the list as JSON. With a machine-readable format, the script just came together!

At some point, we discovered that we needed to allow exceptions for specifically authorised packages, so I added that and haven’t changed it since.

check-licenses.php

<?php

$allowedLicenses = ['Apache-2.0', 'BSD-2-Clause', 'BSD-3-Clause', 'ISC', 'MIT', 'MPL-2.0', 'OSL-3.0'];
$allowedExceptions = [
    'some-provider/some-provider-php', // Proprietary license used by SMS provider
];

$licences = shell_exec('composer licenses -f json');
if ($licences === null || $licences === false) {
    echo "Failed to retrieve licenses\n";
    exit(1);
}

try {
    $data = json_decode($licences, true, 512, JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
    echo "Failed to decode licenses JSON: " . $e->getMessage() . "\n";
    exit(1);
}

// Filter out all dependencies that have an allowed license or exception
$disallowed = array_filter(
    $data['dependencies'],
    fn(array $info, $name) => ! in_array($name, $allowedExceptions)
        && count(array_diff($info['license'], $allowedLicenses)) === 1,
    ARRAY_FILTER_USE_BOTH
);
if (count($disallowed)) {
    $disallowedList = array_map(
        fn(string $k, array $info) => sprintf("$k (%s)", implode(',', $info['license'])),
        array_keys($disallowed),
        $disallowed
    );

    printf("Disallowed licenses found in PHP dependencies: %s\n", implode(', ', $disallowedList));
    exit(1);
}

exit(0);

Running check-licenses.php

If all dependencies are allowed, then check-licenses will output nothing and exit with status code 0:

$ php bin/check-licenses.php
$ echo $?
0

If at least one dependency is not allowed, then check-licenses will list the packages that have licenses that ar not allowed and exit with status code 1:

$ php bin/check-licenses.php 
Disallowed licenses found in PHP dependencies: foo/bar (GPL-3.0)
$ echo $?
1

Maybe it’s useful to others too. If you use it, put it in your CI system.

3 thoughts on “Check licenses of composer dependencies

Comments are closed.