Pragmatism in the real 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.