return new Promise((resolve, reject) => { licenseChecker.init({ start: directory, development: dev, production: !dev, json: true, customFormat: { realPath: true, licenseText: false, licenseFile: false } }, (err, licenseInfo) => { if (err) reject(err); else { resolve( // Extend original licenseInfo object with a new attribute // stating whether a license was found in a package used // only as a dev dependency or not Object.keys(licenseInfo).reduce(function (result, key) { result[key] = Object.assign(licenseInfo[key], { isDevOnly: dev }); return result; }, {}) ); } }); });
return new Promise((resolve, reject) => { licenseChecker.init({ start: directory, production: !dev, json: true, customFormat: { realPath: true, licenseText: false, licenseFile: false } }, (err, licenseInfo) => { if (err) reject(err); else resolve(licenseInfo); }); });
gulp.task('prepare-licenses', ['clean:licenses'], function(){ checker.init({ start: './', relativeLicensePath: true }, function(output, err){ if(err){ console.log(err); } else { var stream = source('licenses.json'); stream.end(JSON.stringify(output)); return stream.pipe(gulp.dest(paths.webRoot)); } }); });
gulp.task('checkDependencies', function () { var dependencies = buildDependenciesArray(packageJSON.dependencies); dependencies = dependencies.concat( buildDependenciesArray(packageJSON.devDependencies) ); checker.init({ start: './' }, function(json, error) { if (error) { console.log(error); process.exit(1); } var count = 0; var found = []; Object.keys(json).forEach(function (dependency) { if (dependencies.indexOf(dependency) === -1) { return; } count++; found.push(dependency); var licenses = json[dependency].licenses; if (licenses === 'UNKNOWN') { console.warn( 'Dependency has an unknown license', json[dependency] ); } if (licenses.indexOf('LGPL') === -1 && licenses.match(/GPL/gi)) { console.log('Package has invalid license.', json[dependency]); process.exit(1); } }); // Ensure we found them all if (count !== dependencies.length) { console.log('Dependency length doesn\'t match.'); var missing = dependencies.filter(function (dependency) { return found.indexOf(dependency) === -1; }); console.log(missing); process.exit(1); } }); });
grunt.registerTask('license', 'List all packages (and their sub-packages) that this project depends on with license information', function() { function convertToCsv(data) { var ret = "", module, licenses, repository; for (module in data) { if (data.hasOwnProperty(module)) { licenses = data[module].licenses || ""; repository = data[module].repository || ""; ret = ret + module + ";" + licenses + ";" + repository + "\r\n"; } } return ret; } var checker = require('license-checker'), fs = require('fs'), done = this.async(), defaults = { start: '.', unknown: false, depth: 1, include: 'all', output: 'console', //console or file filename: 'LICENSES', format: 'json' //json or csv }, options = grunt.util._.extend(defaults, this.options()); checker.init(options, function(data){ if (options.format === 'csv') { data = convertToCsv(data); } else { data = JSON.stringify(data, null, 4); } if (options.output === 'file') { fs.writeFile(options.filename, data, function() { console.log('Successfully written '.green + options.filename.grey); done(); }); } else if (options.output === 'console') { grunt.log.writeln(data); } else { grunt.log.writeln("Unknown output channel: " + options.output); } }); });
exports.init = function(fileName) { if (fileName === undefined) { fileName = 'TERMS.md'; } checker.init( { start: './', exclude: 'CC0-1.0, Public domain, public domain, Public Domain', // @todo fix path to be relative to node modules folder not project folder, write test!!! customPath: 'customFormatExample.json' // for this module // has to point to node_modules path for anything installing this // customPath: './node_modules/license-exceptions/customFormatExample.json' // customPath: customFormatJSON }, function( json, err ) { if ( err ) { // Handle error console.log( err ); } else { exports.getTermsFile( json, fileName ); } } ); };
gulp.task('dist:licenses', function() { var defaults = extend( true, { licenseChecker: { start: './', production: true, licenseFinalDestDir: '/META-INF/LICENSES' } }, config ); checker.init(defaults.licenseChecker, function(err, json) { if (err) { throw err; } else { // ... copy existing license files to the desired target directoy checker.asFiles(json, config.buildTargetDir + '/classes/' + defaults.licenseChecker.licenseFinalDestDir); // ... consolidate json e.g. remove all entries from K15t and update license file info to the new location Object.keys(json).forEach(function(moduleName) { if (json[moduleName].publisher && json[moduleName].publisher.toLowerCase() === 'k15t') { delete json[moduleName]; } else { if (json[moduleName].licenseFile) { json[moduleName].licenseFile = defaults.licenseChecker.licenseFinalDestDir + '/' + moduleName + "-LICENSE.txt"; } } }); // ... write summary file to the root directory of the final artifact fs.writeFileSync(config.buildTargetDir + '/classes/' + config.moduleName + '-THIRD-PARTY.txt', JSON.stringify(json, null, 2)); } }); });
grunt.registerTask('grunt-license-report', [], function createLicenseReport() { // Tell grunt, that we want to do asynchronous tasks var done = this.async(); // Start the license-checker, which gives back a .json file, with all found licenses checker.init({ start: './' }, function processLicenseJson(json) { var fileOutputData; if(grunt.config.data['grunt-license-report'].output.format === 'html') { fileOutputData = output.createHTML(json, grunt); } else { fileOutputData = output.createHTML(json, grunt); } var fileOutputPath; if(!grunt.config.data['grunt-license-report'].output.path || !grunt.config.data['grunt-license-report'].output.format) { fileOutputPath = './report/licenses.html'; } else { fileOutputPath = grunt.config.data['grunt-license-report'].output.path + '.' + grunt.config.data['grunt-license-report'].output.format; } grunt.file.write(fileOutputPath, fileOutputData); grunt.log.writeln('File ' + fileOutputPath + ' created.'); // Tell grunt, that we are done with our asynchronous tasks done(); }); });
grunt.registerTask('_build:notice', 'Adds a notice', function () { const done = this.async(); const buildPath = path.join(grunt.config.get('buildDir'), 'kibana'); function getPackagePaths() { const packagePaths = {}; const installedPackages = execSync(`npm ls --parseable --long`, { cwd: buildPath }); installedPackages.toString().trim().split('\n').forEach(pkg => { let modulePath; let dirPath; let packageName; let drive; const packageDetails = pkg.split(':'); if (/^win/.test(process.platform)) { [drive, dirPath, packageName] = packageDetails; modulePath = `${drive}:${dirPath}`; } else { [modulePath, packageName] = packageDetails; } const licenses = glob.sync(path.join(modulePath, '*LICENSE*')); const notices = glob.sync(path.join(modulePath, '*NOTICE*')); packagePaths[packageName] = { relative: modulePath.replace(/.*(\/|\\)kibana(\/|\\)/, ''), licenses, notices }; }); return packagePaths; } function combineFiles(filePaths) { let content = ''; filePaths.forEach(filePath => { content += fs.readFileSync(filePath) + '\n'; }); return content; } function getNodeInfo() { const nodeVersion = grunt.config.get('nodeVersion'); const nodeDir = path.join(grunt.config.get('root'), '.node_binaries', nodeVersion); const licensePath = path.join(nodeDir, 'linux-x64', 'LICENSE'); const license = fs.readFileSync(licensePath); return `This product bundles Node.js.\n\n${license}`; } function getPackageInfo(packages) { const packagePaths = getPackagePaths(); const overrides = grunt.config.get('licenses.options.overrides'); let content = ''; _.forOwn(packages, (value, key) => { const licenses = [].concat(overrides.hasOwnProperty(key) ? overrides[key] : value.licenses); if (!licenses.length || licenses.includes('UNKNOWN')) return grunt.fail.fatal(`Unknown license for ${key}`); const packagePath = packagePaths[key]; const readLicenseAndNotice = combineFiles([].concat(packagePath.licenses, packagePath.notices)); const licenseOverview = licenses.length > 1 ? `the\n"${licenses.join('", ')} licenses` : `a\n"${licenses[0]}" license`; const licenseAndNotice = readLicenseAndNotice ? `\n${readLicenseAndNotice}` : ` For details, see ${packagePath.relative}/.`; const combinedText = `This product bundles ${key} which is available under ${licenseOverview}.${licenseAndNotice}\n---\n`; content += combinedText; }); return content; } function getBaseNotice() { return fs.readFileSync(path.join(__dirname, 'notice', 'base_notice.txt')); } npmLicense.init({ start: buildPath, production: true, json: true }, (result, error) => { if (error) return grunt.fail.fatal(error); const noticePath = path.join(buildPath, 'NOTICE.txt'); const fd = fs.openSync(noticePath, 'w'); fs.appendFileSync(fd, getBaseNotice()); fs.appendFileSync(fd, getPackageInfo(result)); fs.appendFileSync(fd, getNodeInfo()); fs.closeSync(fd); done(); }); });
checker.init({ start: path.join(__dirname, '..') }, (err, json) => { if (err) { logger.fatal(`Something happened:\n${err.message}`); } else { logger.info(`Testing ${Object.keys(json).length} packages.\n`); // Packages with bad licenses are those that neither pass SPDX nor are ignored. const badLicensePackages = Object.keys(json) .map(key => { return { id: key, licenses: [] .concat(json[key].licenses) .map(x => x.replace(/\*$/, '')) // `*` is used when the license is guessed. .map(x => x in licenseReplacements ? licenseReplacements[x] : x), }; }) .filter(pkg => !passesSpdx(pkg.licenses, licensesWhitelist)) .filter(pkg => !ignoredPackages.find(ignored => ignored === pkg.id)); // Report packages with bad licenses if (badLicensePackages.length > 0) { logger.error('Invalid package licences found:'); badLicensePackages.forEach(pkg => logger.error(`${pkg.id}: ${JSON.stringify(pkg.licenses)}`)); logger.fatal(`\n${badLicensePackages.length} total packages with invalid licenses.`); } else { logger.info('All package licenses are valid.'); } } });
this.apply = function (compiler) { licenseChecker.init({json: true, production: false, start: process.cwd()}, (err, licenseData) => { if (err) { console.error('Found error'); //eslint-disable-line no-console console.error(err); //eslint-disable-line no-console process.exit(1); } const filenames = []; compiler.plugin("emit", (compilation, callback) => { compilation.chunks.forEach((chunk) => { chunk.modulesIterable.forEach((chunkModule) => { filenames.push(chunkModule.resource || (chunkModule.rootModule && chunkModule.rootModule.resource)); if (Array.isArray(chunkModule.fileDependencies)) { chunkModule.fileDependencies.forEach((e) => { filenames.push(e); }); } }); }); callback(); const licenseReport = _.chain(filenames) .uniq() .filter((fileName) => fileName && fileName.indexOf('node_modules') >= 0) .map((fileName) => { const file = upath.normalize(fileName).replace(upath.join(process.cwd(), '/node_modules/'), ''); return file.startsWith("@") ? file.split("/").slice(0, 2).join("/") : file.split("/")[0]; }) .uniq() .sort() .reduce((accumulator, moduleName) => { const moduleNameWithVersion = _(licenseData).findKey((_moduleLicenseInfo, moduleNameWithVersion) => { return moduleNameWithVersion.startsWith(`${moduleName}@`); }); const licenseDataForModule = licenseData[moduleNameWithVersion]; if (licenseDataForModule) { const moduleVersion = moduleNameWithVersion.split('@')[1]; if (licenseDataForModule.licenseFile) { const licenseReportDirForModule = path.join(path.dirname(options.licenseReportFile), `${moduleName}-${moduleVersion}`); fsExtra.removeSync(licenseReportDirForModule); fsExtra.mkdirsSync(licenseReportDirForModule); fsExtra.copySync(licenseDataForModule.licenseFile, path.join(licenseReportDirForModule, path.basename(licenseDataForModule.licenseFile))); } accumulator[moduleName] = { moduleName, moduleVersion, moduleUrls: [licenseDataForModule.repository], moduleLicenses: [ { moduleLicense: licenseDataForModule.licenses, moduleLicenseUrl: `https://spdx.org/licenses/${licenseDataForModule.licenses}.html` } ] }; } else { console.error(`Unable to find license data for ${moduleName}`); //eslint-disable-line no-console process.exit(1); } return accumulator; }, {}).value(); fs.writeFileSync(options.licenseReportFile, `${JSON.stringify(licenseReport, null, 2)}\n`); }); }); };
const checker = require('license-checker'); const INCOMPATIBLE_LICENCE_REGEX = /GPL/; checker.init({ start: '.' }, function(json, err) { if (err) { console.error(err.message); process.exit(1); } else { const incompatibleDependencies = Object.keys(json).filter((packageName) => { let licenses = json[packageName].licenses; if (!Array.isArray(licenses)) licenses = [licenses]; if (licenses.find((license) => license.match(INCOMPATIBLE_LICENCE_REGEX))) return packageName; }); if (incompatibleDependencies.length > 0) { console.error('Found packages with incompatible license: ' + JSON.stringify(incompatibleDependencies)); process.exit(1); } else { console.log('All is well! No packages with an incompatible license found.'); } } });
return new Promise(function (resolve, reject) { checker.init(opts, function (err, json) { err ? reject(err) : resolve(json) }) })
checker.init( { start: '.' }, function(err, json) { if (err) { console.error(err.message); process.exit(1); } else { const incompatibleDependencies = Object.keys(json).filter(packageName => { let licenses = json[packageName].licenses; if (!Array.isArray(licenses)) licenses = [licenses]; if ( licenses .filter( license => !( license.match(/LGPL/) || license.match(/MIT/) || license.match(/BSD/) ) ) .find(license => license.match(/GPL/)) ) return packageName; }); if (incompatibleDependencies.length > 0) { console.error( 'Found packages with incompatible license: ' + JSON.stringify(incompatibleDependencies) ); process.exit(1); } else { console.log( 'All is well! No packages with an incompatible license found.' ); } } } );
checker.init( { start: '.' }, function(err, license_json) { if (err) { //Handle error console.log(err); return err; } for_every_prod_package = function(fn) { var pkg_name, pkg_title, pkg_info; for (pkg_name in license_json) { pkg_title = pkg_name.replace(/\@\d+\.\d+\.\d+$/, ""); if (_.has(pkg.dependencies, pkg_title)) { pkg_info = license_json[pkg_name]; fn(pkg_name, pkg_info, pkg_title); } } } console.log("The leaflet.extras package as a whole is distributed under GPL-3 (GNU GENERAL PUBLIC LICENSE version 3).\n\nThe leaflet.extras package includes other open source software components. The following\nis a list of these components (full copies of the license agreements used by\nthese components are included below):"); console.log(""); //The sorted json data // console.log(json); for_every_prod_package(function(pkg_name, pkg_info, pkg_title) { console.log(" -", pkg_name, "-", pkg_info.licenses, "-", pkg_info.repository); }); console.log("\n\n\n"); for_every_prod_package(function(pkg_name, pkg_info, pkg_title) { console.log(pkg_name, "-", pkg_info.licenses, "-", pkg_info.repository); console.log("----------------------------------------------------"); file_info = fs.readFileSync(pkg_info.licenseFile, 'utf8'); console.log(file_info); console.log("\n\n\n\n"); }); } );