Skip to content

Instantly share code, notes, and snippets.

@nfreear
Last active February 25, 2021 11:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nfreear/a6a981ac8237d8dd2b8453f223d63bd2 to your computer and use it in GitHub Desktop.
Save nfreear/a6a981ac8237d8dd2b8453f223d63bd2 to your computer and use it in GitHub Desktop.
Parse PHP composer.json and composer.lock files to extract license information.
/**
* Work-in-progress!
*
* Parse PHP composer.json and composer.lock files to extract license information.
*
* OUTPUT: CSV output to standard error.
*
* @author Nick Freear, 24-Feb-2021.
*/
const fs = require('fs');
const path = require('path');
const DIR = process.cwd();
const CSV_HEADERS = 'name,installed version,license type,author,link';
phpLicenseReport();
async function phpLicenseReport() {
const REQUIRE_RUN = await readJsonObj('composer.json', 'require');
const REQUIRE_DEV = await readJsonObj('composer.json', 'require-dev');
const PACKAGES_RUN = await readJsonObj('composer.lock', 'packages');
const PACKAGES_DEV = await readJsonObj('composer.lock', 'packages-dev')
// console.debug(PACKAGES_RUN.length, PACKAGES_DEV.length);
const LICENSES_RUN = parseComposerJson(REQUIRE_RUN, PACKAGES_RUN);
const LICENSES_DEV = parseComposerJson(REQUIRE_DEV, PACKAGES_DEV, PACKAGES_RUN);
console.debug('\n# Runtime dependencies (CSV):\n');
console.debug(LICENSES_RUN.join('\n'));
console.debug('\n# DEV. dependencies (CSV):\n');
console.debug(LICENSES_DEV.join('\n'));
}
// --------------------------------------------------------
function pwdPath(fileName) {
return path.resolve(DIR, fileName);
}
async function readJsonObj(jsonFileName, key = null) {
const jsonFilePath = pwdPath(jsonFileName);
const json = await fs.promises.readFile(jsonFilePath, 'utf8');
const data = JSON.parse(json);
return key ? data[key] : data;
}
function parseComposerJson(requireSource = {}, packagesRun, packagesDev = []) {
const licenseResult = [ CSV_HEADERS ];
Object.keys(requireSource).forEach(name => {
if (/^(php$|ext-\w+)/.test(name)) {
console.debug('Skipping:', name);
return;
}
const PKG = findLockPackage(name, packagesRun, packagesDev);
const version = PKG.version || '(none)';
const license = PKG.license || '(none)';
const author = PKG.authors[0].name || '(none)';
const url = PKG.source.url || '(none)';
licenseResult.push(`${name},${version},${license},${author},${url}`);
});
return licenseResult;
}
function findLockPackage(name, packagesRun, packagesDev) {
let PKG = packagesRun.find(pkg => name === pkg.name);
if (!PKG) {
PKG = packagesDev.find(pkg => name === pkg.name);
}
if (!PKG) throw new Error('Missing package? ' + name);
return PKG;
}
// End.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment