From b8a745ea23a451f2e64bdb68f0222dcc328b9878 Mon Sep 17 00:00:00 2001 From: Ceyhun Ozugur Date: Fri, 17 Apr 2020 11:57:52 +0200 Subject: [PATCH 1/4] Update script to parse JSON dependency tree recursively --- packages/scripts/CHANGELOG.md | 1 + packages/scripts/scripts/check-licenses.js | 83 ++++++++++++++-------- 2 files changed, 53 insertions(+), 31 deletions(-) diff --git a/packages/scripts/CHANGELOG.md b/packages/scripts/CHANGELOG.md index ccccbf7cf4698c..99f4866b79dee0 100644 --- a/packages/scripts/CHANGELOG.md +++ b/packages/scripts/CHANGELOG.md @@ -3,6 +3,7 @@ ### Bug fix - The bundled `npm-package-json-lint` dependency has been updated from requiring `^4.0.3` to requiring `^5.0.0` ([#21597](https://github.com/WordPress/gutenberg/pull/21597)). [Breaking changes](https://npmpackagejsonlint.org/docs/en/v4-to-v5) don't break anything in this package. It fixes the abrupt shutdown when `"description"` field in `package.json` is empty. +- Update `check-licenses` script to parse JSON dependency tree recursively so sub-dependencies of packages passed in `--ignore` flag are ignored as well. ## 8.0.0 (2020-04-15) diff --git a/packages/scripts/scripts/check-licenses.js b/packages/scripts/scripts/check-licenses.js index acf098cffe63d5..c0a013a8eb619d 100644 --- a/packages/scripts/scripts/check-licenses.js +++ b/packages/scripts/scripts/check-licenses.js @@ -3,7 +3,6 @@ */ const spawn = require( 'cross-spawn' ); const { existsSync, readFileSync } = require( 'fs' ); -const { sep } = require( 'path' ); const chalk = require( 'chalk' ); /** @@ -21,6 +20,7 @@ const { getArgFromCLI, hasArgInCLI } = require( '../utils' ); */ const ERROR = chalk.reset.inverse.bold.red( ' ERROR ' ); +const WARNING = chalk.reset.inverse.bold.yellow( ' WARNING ' ); const prod = hasArgInCLI( '--prod' ) || hasArgInCLI( '--production' ); const dev = hasArgInCLI( '--dev' ) || hasArgInCLI( '--development' ); @@ -170,36 +170,55 @@ const checkLicense = ( allowedLicense, licenseType ) => { ); }; -/** - * Returns true if the given module path is not to be ignored for consideration - * in license validation, or false otherwise. - * - * @param {string} moduleName Module path. - * - * @return {boolean} Whether module path is not to be ignored. - */ -const isNotIgnoredModule = ( moduleName ) => - ! ignored.some( ( ignoredItem ) => - // `moduleName` is a file path to the module directory. Assume CLI arg - // is passed as basename of package (directory(s) after node_modules). - // Prefix with sep to avoid false-positives on prefixing variations. - moduleName.endsWith( sep + ignoredItem ) - ); - // Use `npm ls` to grab a list of all the packages. -const child = spawn.sync( 'npm', [ - 'ls', - '--parseable', - ...( prod ? [ '--prod' ] : [] ), - ...( dev ? [ '--dev' ] : [] ), -] ); - -const modules = child.stdout - .toString() - .split( '\n' ) - .filter( isNotIgnoredModule ); - -modules.forEach( ( path ) => { +const child = spawn.sync( + 'npm', + [ + 'ls', + '--json', + '--long', + ...( prod ? [ '--prod' ] : [] ), + ...( dev ? [ '--dev' ] : [] ), + ], + { maxBuffer: 1024 * 1024 * 100 } // output size for prod is ~21 MB and dev is ~76 MB +); + +const result = JSON.parse( child.stdout.toString() ); + +const topLevelDeps = result.dependencies; + +function traverseDepTree( deps ) { + for ( const key in deps ) { + const dep = deps[ key ]; + + if ( ignored.includes( dep.name ) ) { + return; + } + + if ( ! dep.hasOwnProperty( 'path' ) ) { + if ( dep.hasOwnProperty( 'peerMissing' ) ) { + process.stdout.write( + `${ WARNING } Unable to locate path for missing peer dep ${ dep.name }@${ dep.version }. ` + ); + } else { + process.exitCode = 1; + process.stdout.write( + `${ ERROR } Unable to locate path for ${ dep.name }@${ dep.version }. ` + ); + } + } else { + checkDepLicense( dep.path ); + } + + if ( dep.hasOwnProperty( 'dependencies' ) ) { + traverseDepTree( dep.dependencies ); + } else { + return; + } + } +} + +function checkDepLicense( path ) { if ( ! path ) { return; } @@ -287,4 +306,6 @@ modules.forEach( ( path ) => { `${ ERROR } Module ${ packageInfo.name } has an incompatible license '${ licenseType }'.\n` ); } -} ); +} + +traverseDepTree( topLevelDeps ); From fe2aa19c902295bd2f389c03dc37ef070f51dba7 Mon Sep 17 00:00:00 2001 From: Ceyhun Ozugur Date: Fri, 17 Apr 2020 12:43:48 +0200 Subject: [PATCH 2/4] Debug CI --- package.json | 2 +- packages/scripts/scripts/check-licenses.js | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 86291e9d777f89..9ad6acb6fcd981 100644 --- a/package.json +++ b/package.json @@ -191,7 +191,7 @@ "build:package-types": "node ./bin/packages/validate-typescript-version.js && tsc --build", "build": "npm run build:packages && wp-scripts build", "check-engines": "wp-scripts check-engines", - "check-licenses": "concurrently \"wp-scripts check-licenses --prod --gpl2\" \"wp-scripts check-licenses --dev\"", + "check-licenses": "wp-scripts check-licenses --dev", "precheck-local-changes": "npm run docs:build", "check-local-changes": "( git diff -U0 | xargs -0 node bin/process-git-diff ) || ( echo \"There are local uncommitted changes after one or both of 'npm install' or 'npm run docs:build'!\" && exit 1 );", "predev": "npm run check-engines", diff --git a/packages/scripts/scripts/check-licenses.js b/packages/scripts/scripts/check-licenses.js index c0a013a8eb619d..9ade7ac2d90f1e 100644 --- a/packages/scripts/scripts/check-licenses.js +++ b/packages/scripts/scripts/check-licenses.js @@ -200,6 +200,10 @@ function traverseDepTree( deps ) { process.stdout.write( `${ WARNING } Unable to locate path for missing peer dep ${ dep.name }@${ dep.version }. ` ); + console.log( + '::: traverseDepTree -> process.exitCode', + process.exitCode + ); } else { process.exitCode = 1; process.stdout.write( From 4cef2f9ab2a84a8ccf3774ae2d06187d774eccd8 Mon Sep 17 00:00:00 2001 From: Ceyhun Ozugur Date: Fri, 17 Apr 2020 16:39:19 +0200 Subject: [PATCH 3/4] Revert "Debug CI" This reverts commit fe2aa19c902295bd2f389c03dc37ef070f51dba7. --- package.json | 2 +- packages/scripts/scripts/check-licenses.js | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/package.json b/package.json index 9ad6acb6fcd981..86291e9d777f89 100644 --- a/package.json +++ b/package.json @@ -191,7 +191,7 @@ "build:package-types": "node ./bin/packages/validate-typescript-version.js && tsc --build", "build": "npm run build:packages && wp-scripts build", "check-engines": "wp-scripts check-engines", - "check-licenses": "wp-scripts check-licenses --dev", + "check-licenses": "concurrently \"wp-scripts check-licenses --prod --gpl2\" \"wp-scripts check-licenses --dev\"", "precheck-local-changes": "npm run docs:build", "check-local-changes": "( git diff -U0 | xargs -0 node bin/process-git-diff ) || ( echo \"There are local uncommitted changes after one or both of 'npm install' or 'npm run docs:build'!\" && exit 1 );", "predev": "npm run check-engines", diff --git a/packages/scripts/scripts/check-licenses.js b/packages/scripts/scripts/check-licenses.js index 9ade7ac2d90f1e..c0a013a8eb619d 100644 --- a/packages/scripts/scripts/check-licenses.js +++ b/packages/scripts/scripts/check-licenses.js @@ -200,10 +200,6 @@ function traverseDepTree( deps ) { process.stdout.write( `${ WARNING } Unable to locate path for missing peer dep ${ dep.name }@${ dep.version }. ` ); - console.log( - '::: traverseDepTree -> process.exitCode', - process.exitCode - ); } else { process.exitCode = 1; process.stdout.write( From 63760586dcdc5b7dbc1c6f9f852389fcc263d1b0 Mon Sep 17 00:00:00 2001 From: Ceyhun Ozugur Date: Fri, 17 Apr 2020 16:45:42 +0200 Subject: [PATCH 4/4] Add exception and warning for missing dependencies --- packages/scripts/scripts/check-licenses.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/scripts/scripts/check-licenses.js b/packages/scripts/scripts/check-licenses.js index c0a013a8eb619d..2c554c45699ce4 100644 --- a/packages/scripts/scripts/check-licenses.js +++ b/packages/scripts/scripts/check-licenses.js @@ -206,6 +206,10 @@ function traverseDepTree( deps ) { `${ ERROR } Unable to locate path for ${ dep.name }@${ dep.version }. ` ); } + } else if ( dep.missing ) { + process.stdout.write( + `${ WARNING } missing dep ${ dep.name }@${ dep.version }. ` + ); } else { checkDepLicense( dep.path ); }