From 703fb3217a632f27a4c9d7b461e1727d024d28e1 Mon Sep 17 00:00:00 2001 From: Yu Tian Date: Wed, 8 Nov 2017 02:04:51 +1100 Subject: [PATCH 1/3] =?UTF-8?q?-=20Terminate=20the=20build=20if=20entry=20?= =?UTF-8?q?point=20not=20whitelisted=20-=20Terminate=20the=20build=20if=20?= =?UTF-8?q?'files'=20field=20is=20missing=20from=20package.json=20-=20Term?= =?UTF-8?q?inate=20the=20build=20if=20any=20entry=20point=20doesn=E2=80=99?= =?UTF-8?q?t=20have=20equivalent=20in=20./npm=20folder=20-=20Handle=20patt?= =?UTF-8?q?erns=20in=20'files'=20field?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/rollup/packaging.js | 87 ++++++++++++++++++++++++++++++++----- 1 file changed, 77 insertions(+), 10 deletions(-) mode change 100644 => 100755 scripts/rollup/packaging.js diff --git a/scripts/rollup/packaging.js b/scripts/rollup/packaging.js old mode 100644 new mode 100755 index c272d7cddd7..c0b022d2f0f --- a/scripts/rollup/packaging.js +++ b/scripts/rollup/packaging.js @@ -1,11 +1,13 @@ 'use strict'; const basename = require('path').basename; +const dirname = require('path').dirname; const fs = require('fs'); const join = require('path').join; const resolve = require('path').resolve; const Bundles = require('./bundles'); const asyncCopyTo = require('./utils').asyncCopyTo; +const glob = require('glob'); const UMD_DEV = Bundles.bundleTypes.UMD_DEV; const UMD_PROD = Bundles.bundleTypes.UMD_PROD; @@ -156,7 +158,7 @@ function copyBundleIntoNodePackage(packageName, filename, bundleType) { function copyNodePackageTemplate(packageName) { const from = resolve(`./packages/${packageName}`); const to = resolve(`./build/packages/${packageName}`); - const npmFrom = resolve(`${from}/npm`); + const npmFrom = `${from}/npm`; if (!fs.existsSync(npmFrom)) { // The package is not meant for npm consumption. return Promise.resolve(); @@ -165,15 +167,80 @@ function copyNodePackageTemplate(packageName) { // We already created this package (e.g. due to another entry point). return Promise.resolve(); } - // TODO: verify that all copied files are either in the "files" - // whitelist or implicitly published by npm. - return asyncCopyTo(npmFrom, to).then(() => - Promise.all([ - asyncCopyTo(resolve(`${from}/package.json`), `${to}/package.json`), - asyncCopyTo(resolve(`${from}/README.md`), `${to}/README.md`), - asyncCopyTo(resolve('./LICENSE'), `${to}/LICENSE`), - ]) - ); + // Get all entry points in the package root + // Exceptions: *.fb.js + const packageEntries = glob.sync('!(*.fb).js', { + cwd: from, + }); + const npmFiles = fs.readdirSync(npmFrom); + packageEntries.forEach(entry => { + if (!npmFiles.includes(entry)) { + // Terminate the build if any entry point(Exception: *.fb.js) + // does not have an equivalent in ./npm. + console.error( + `Entry point ${entry} in package ${ + packageName + } does not have an equivalent in ./npm` + ); + process.exit(1); + } + }); + const packageJson = `${from}/package.json`; + const whitelist = fs.existsSync(packageJson) && require(packageJson).files; + let promisesForForwardingModules = []; + if (!whitelist) { + // Terminate the build if 'files' field is missing from package.json. + console.error( + `'files' field is missing from package.json in package ${packageName}` + ); + process.exit(1); + } + fs.mkdirSync(to); + let existingDirCache = {}; + // looping through entries(single file / directory / pattern) in `files` + const whitelistedFiles = whitelist.reduce((list, pattern) => { + const matchedFiles = glob.sync(pattern, { + cwd: npmFrom, + }); + // copy matching files/directories from './npm' to build package. + matchedFiles.forEach(file => { + // create all nesting directories ahead to avoid 'No such file or directory' error + const dirnameSegments = dirname(file).split('/'); + dirnameSegments.reduce((prevPath, currentPath) => { + const fullPath = `${prevPath}/${currentPath}`; + if (!existingDirCache[fullPath] && !fs.existsSync(fullPath)) { + existingDirCache[fullPath] = true; + fs.mkdirSync(`${to}/${fullPath}`); + } + return fullPath; + }, ''); + promisesForForwardingModules.push( + asyncCopyTo(`${npmFrom}/${file}`, `${to}/${file}`) + ); + }); + // return an array of whitelisted files + // for entry point check next. + // All patterns have been parsed to file/directory + return list.concat(matchedFiles); + }, []); + // terminate the build if any entry point(Exception: *.fb.js) + // is not whitelisted in the 'files' field in package.json. + packageEntries.forEach(entry => { + if (!whitelistedFiles.includes(entry)) { + console.error( + `Entry point ${entry} in package ${ + packageName + } is not listed in the 'files' field in package.json` + ); + process.exit(1); + } + }); + return Promise.all([ + ...promisesForForwardingModules, + asyncCopyTo(resolve(`${from}/package.json`), `${to}/package.json`), + asyncCopyTo(resolve(`${from}/README.md`), `${to}/README.md`), + asyncCopyTo(resolve('./LICENSE'), `${to}/LICENSE`), + ]); } function createNodePackage(bundleType, packageName, filename) { From 64be5295529ba4cb03042e75096eb4164388fe0a Mon Sep 17 00:00:00 2001 From: Yu Tian Date: Sun, 26 Nov 2017 23:33:01 +1100 Subject: [PATCH 2/3] add mkdirp module as dev dependency, replace directory creation code with mkdirp. --- package.json | 1 + scripts/rollup/packaging.js | 14 ++------------ 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index c8ce7b99bce..06c19559805 100644 --- a/package.json +++ b/package.json @@ -73,6 +73,7 @@ "jest-runtime": "^21.3.0-beta.4", "merge-stream": "^1.0.0", "minimist": "^1.2.0", + "mkdirp": "^0.5.1", "ncp": "^2.0.0", "object-assign": "^4.1.1", "platform": "^1.1.0", diff --git a/scripts/rollup/packaging.js b/scripts/rollup/packaging.js index c0b022d2f0f..d2925d8ecfc 100755 --- a/scripts/rollup/packaging.js +++ b/scripts/rollup/packaging.js @@ -8,6 +8,7 @@ const resolve = require('path').resolve; const Bundles = require('./bundles'); const asyncCopyTo = require('./utils').asyncCopyTo; const glob = require('glob'); +const mkdirp = require('mkdirp'); const UMD_DEV = Bundles.bundleTypes.UMD_DEV; const UMD_PROD = Bundles.bundleTypes.UMD_PROD; @@ -195,8 +196,6 @@ function copyNodePackageTemplate(packageName) { ); process.exit(1); } - fs.mkdirSync(to); - let existingDirCache = {}; // looping through entries(single file / directory / pattern) in `files` const whitelistedFiles = whitelist.reduce((list, pattern) => { const matchedFiles = glob.sync(pattern, { @@ -204,16 +203,7 @@ function copyNodePackageTemplate(packageName) { }); // copy matching files/directories from './npm' to build package. matchedFiles.forEach(file => { - // create all nesting directories ahead to avoid 'No such file or directory' error - const dirnameSegments = dirname(file).split('/'); - dirnameSegments.reduce((prevPath, currentPath) => { - const fullPath = `${prevPath}/${currentPath}`; - if (!existingDirCache[fullPath] && !fs.existsSync(fullPath)) { - existingDirCache[fullPath] = true; - fs.mkdirSync(`${to}/${fullPath}`); - } - return fullPath; - }, ''); + mkdirp.sync(`${to}/${dirname(file)}`); promisesForForwardingModules.push( asyncCopyTo(`${npmFrom}/${file}`, `${to}/${file}`) ); From c2417ebb029e45b586e0e4691e3b3d46c2612391 Mon Sep 17 00:00:00 2001 From: Yu Tian Date: Sun, 26 Nov 2017 23:38:17 +1100 Subject: [PATCH 3/3] reset file permission to 644 --- scripts/rollup/packaging.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 scripts/rollup/packaging.js diff --git a/scripts/rollup/packaging.js b/scripts/rollup/packaging.js old mode 100755 new mode 100644