Open loop-evgeny opened 3 years ago
I've been investigating this, and found some interesting tidbits:
license-checker
uses read-installed
to traverse the tree of installed packages. read-installed
returns a data structure that has a few properties, one of which is readme
, another is license
.readme
, license-checker
will read the README.md
file of the package and put that string in the readme
property of the data returned from read-installed
.license
or licenses
property in the data returned from read-installed
, license-checker
will use the readme
property and look for licenses in there instead, using a bunch of regexes, one of which is an URL regex.README.md
file for highcharts@6.2.0
contains a link to https://www.npmjs.com/package/highcharts-server early on.read-installed
does not properly return the license
property of this package, causing license-checker
to grab the incorrect URL from the README.md
instead.read-installed
does not return the license
property of highcharts@6.2.0
, even though it clearly has such a property in its package.json
Not sure if anyone will ever look into this discussion again, but I just stumbled across this issue in combination with a custom license that was used in one of my packages.
I think I was able to track it down to this portion of code from index.js of license-checker (Lines 151 to 172 in Version: 25.0.1)
if (json.path && fs.existsSync(json.path)) {
dirFiles = fs.readdirSync(json.path);
files = licenseFiles(dirFiles);
noticeFiles = dirFiles.filter(function(filename) {
filename = filename.toUpperCase();
var name = path.basename(filename).replace(path.extname(filename), '');
return name === 'NOTICE';
});
}
files.forEach(function(filename, index) {
licenseFile = path.join(json.path, filename);
// Checking that the file is in fact a normal file and not a directory for example.
/*istanbul ignore else*/
if (fs.lstatSync(licenseFile).isFile()) {
var content;
if (!moduleInfo.licenses || moduleInfo.licenses.indexOf(UNKNOWN) > -1 || moduleInfo.licenses.indexOf('Custom:') === 0) {
//Only re-check the license if we didn't get it from elsewhere
content = fs.readFileSync(licenseFile, { encoding: 'utf8' });
moduleInfo.licenses = license(content);
}
The "files" array is populated with all the files that are assumed to be related to a license by the licenseFiles
function - basically checking if the file is named LICENSE, LICENSE.MD, LICENCE, LICENCE.MD or ... README[.MD]
Now if the currently found moduleInfo.licenses starts with "Custom:", which is the case if the the license-field of the package.json does not carry a valid spdx-Expression, it will replace that moduleInfo.licenses with something found in one of the files above.
If the package happens to contain a readme.md file and that readme.md file happens to contains a URL, the license
function would actually match that URL with the IS_URL
-Regex and return "Custom:
match = IS_URL.exec(str) || IS_FILE_REFERENCE.exec(str);
if(match) {
return 'Custom: ' + match[1];
} else {
return null;
}
package.json file:
Run
Output:
However, node_modules/highcharts/package.json has this:
The difference is significant, because highcharts-server is MIT-licensed, while highcharts has a commercial license.