diff --git a/.eslintignore b/.eslintignore index 26b39197a..9584af704 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1966,6 +1966,9 @@ packages/tools/generate-images.js.map packages/tools/git-changelog.d.ts packages/tools/git-changelog.js packages/tools/git-changelog.js.map +packages/tools/licenseChecker.d.ts +packages/tools/licenseChecker.js +packages/tools/licenseChecker.js.map packages/tools/release-android.d.ts packages/tools/release-android.js packages/tools/release-android.js.map diff --git a/.gitignore b/.gitignore index 7a000a87c..02be4abce 100644 --- a/.gitignore +++ b/.gitignore @@ -1956,6 +1956,9 @@ packages/tools/generate-images.js.map packages/tools/git-changelog.d.ts packages/tools/git-changelog.js packages/tools/git-changelog.js.map +packages/tools/licenseChecker.d.ts +packages/tools/licenseChecker.js +packages/tools/licenseChecker.js.map packages/tools/release-android.d.ts packages/tools/release-android.js packages/tools/release-android.js.map diff --git a/packages/tools/licenseChecker.ts b/packages/tools/licenseChecker.ts new file mode 100644 index 000000000..66fc14f37 --- /dev/null +++ b/packages/tools/licenseChecker.ts @@ -0,0 +1,78 @@ +import { readdir, stat, writeFile } from 'fs-extra'; +import { chdir, cwd } from 'process'; +import { execCommand2, rootDir } from './tool-utils'; + +interface LicenseInfo { + licenses: string; + repository: string; + path: string; +} + +const getLicenses = async (directory: string): Promise> => { + const previousDir = cwd(); + await chdir(directory); + const result = await execCommand2(['license-checker-rseidelsohn', '--production', '--json'], { quiet: true }); + const info: Record = JSON.parse(result); + if (!info) throw new Error(`Could not parse JSON: ${directory}`); + await chdir(previousDir); + return info; +}; + +const createCsvLine = (items: string[]) => { + try { + return `"${items.map(i => i.replace(/"/g, '""')).join('", "')}"`; + } catch (error) { + error.message = `Could not process line: ${JSON.stringify(items)}: ${error.message}`; + throw error; + } +}; + +const enforceString = (line: any): string => { + if (Array.isArray(line)) return line.join(', '); + return line ? (`${line}`) : ''; +}; + +async function main() { + const directories: string[] = []; + const packageItems = await readdir(`${rootDir}/packages`); + for (const item of packageItems) { + const fullPath = `${rootDir}/packages/${item}`; + const info = await stat(fullPath); + if (info.isDirectory()) directories.push(fullPath); + } + directories.push(rootDir); + + let licenses: Record = {}; + + for (const dir of directories) { + console.info(`Processing ${dir}...`); + const dirLicenses = await getLicenses(dir); + for (const [, v] of Object.entries(dirLicenses)) { + v.path = dir.substr(rootDir.length); + } + licenses = { ...licenses, ...dirLicenses }; + } + + const csv: string[][] = []; + csv.push(['Package', 'Licenses', 'Repository', 'Path']); + + for (const [packageName, info] of Object.entries(licenses)) { + csv.push([ + enforceString(packageName), + enforceString(info.licenses), + enforceString(info.repository), + enforceString(info.path), + ]); + } + + const outputFile = `${rootDir}/licenses.csv`; + await writeFile(outputFile, csv.map(line => createCsvLine(line)).join('\n')); + + console.info(`Created summary in ${outputFile}`); +} + +main().catch((error) => { + console.error('Fatal error'); + console.error(error); + process.exit(1); +}); diff --git a/packages/tools/tool-utils.ts b/packages/tools/tool-utils.ts index 91bf57f86..60fd6ff35 100644 --- a/packages/tools/tool-utils.ts +++ b/packages/tools/tool-utils.ts @@ -127,7 +127,7 @@ async function saveGitHubUsernameCache(cache: any) { } // Returns the project root dir -export const rootDir = require('path').dirname(require('path').dirname(__dirname)); +export const rootDir: string = require('path').dirname(require('path').dirname(__dirname)); export function execCommand(command: string, options: any = null): Promise { options = options || {};