Closed mahyarmirrashed closed 11 months ago
license-report just takes the entry 'licenseType' from the package.json file of the project. It is not guaranteed that a package has a license file. If you need that field, perhaps take a look at the license-downloader that gets all the license files.
Seems fair enough. However, license-downloader
would be slow since it would make API calls and retrieve them on every build. It would be better for me to have something that looks directly into the node_packages
directory to find each packages' LICENSE file after something like npm ci
. That way, license retrieval and processing is done after required work anyway. Plus, there is no guarantee that all packages will be hosted on GitHub to use the GitHub method. Maybe a feature to match the first instance of LICENSE
in each project's root would be a useful feature?
the field 'license' in a package.json file can be a string or an object.
If it is a string: where to look for a file and what would be the name of the file? (or is this the "match the first instance of LICENSE in each project's root" part of our last comment? But then this is IMHO no generic solution).
If it is an object, it may have an 'url' field or not - same problem as before. And in that case it is probably not a local file path.
And in what format the output field should be? We have linux and windows based systems. relative or absolute paths?
What about mono repos?
Perhaps yore requirement can be solved with a small node script (I called it addLicensePath.js
) that gets the output from license-report and adds a field named licensePath
(I assume you are using the json output format):
#!/usr/bin/env node
import fs from 'node:fs';
import path from 'node:path';
import process from 'node:process';
let inputString = '';
process.stdin.resume();
// make stdin return a string
process.stdin.setEncoding('utf-8');
process.stdin.on('data', inputStdin => {
// license-report emits only 1 line
inputString += inputStdin;
});
process.stdin.on('end', () => {
inputString = inputString.trim();
main();
});
function getLicensePath(packageName, projectRootPath) {
let licensePath = '';
const elementPackagePath = path.join(projectRootPath, 'node_modules', packageName);
if (fs.existsSync(elementPackagePath)) {
['LICENSE', 'LICENSE.md'].every(licenseFileName => {
let elementLicensePath = path.join(elementPackagePath, licenseFileName);
if (fs.existsSync(elementLicensePath)) {
licensePath = path.relative(projectRootPath, elementLicensePath);
return false;
}
});
}
return licensePath;
}
function main() {
const projectRootPath = process.cwd();
const licenseReport = JSON.parse(inputString);
licenseReport.forEach(licenseEntry => {
licenseEntry['licensePath'] = getLicensePath(licenseEntry.name, projectRootPath);
});
console.log(JSON.stringify(licenseReport));
}
And calling it with a script in package.json would look like that:
:
"scripts": {
"demo": "npx --yes license-report --fields=name --fields=installedVersion --fields=licenseType | node addLicensePath.js"
},
"type": "module",
:
It would be helpful to have in the output, a relative path to the actual LICENSE file given if the dependency is installed.