Skip to content

Commit

Permalink
Update to handle patterns in 'files' field, terminate the build if en…
Browse files Browse the repository at this point in the history
…try point not whitelisted, terminate the build if 'files' field is missing from package.json
  • Loading branch information
yu-tian113 authored and Yu Tian committed Nov 13, 2017
1 parent 8a509ae commit e97dff1
Showing 1 changed file with 64 additions and 35 deletions.
99 changes: 64 additions & 35 deletions scripts/rollup/packaging.js
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'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;
Expand Down Expand Up @@ -157,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();
Expand All @@ -166,53 +167,81 @@ function copyNodePackageTemplate(packageName) {
// We already created this package (e.g. due to another entry point).
return Promise.resolve();
}
fs.mkdirSync(to);
const packageJson = resolve(`${from}/package.json`);
const whitelistedFiles = (fs.existsSync(packageJson) &&
require(packageJson).files) || [];
const npmRootFiles = fs.readdirSync(npmFrom);
// Get all entry points in the package root
// Exceptions: *.fb.js
const packageRootEntries = glob.sync('!(*.fb).js', {
const packageEntries = glob.sync('!(*.fb).js', {
cwd: from,
});
packageRootEntries.forEach(entry => {
// Terminate the build if any entry point in the package root
// does not have an equivalent in ./npm.
if (!npmRootFiles.includes(entry)) {
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);
}
});
if (whitelistedFiles.length > 0) {
// Looping through files and folders in ./npm root,
// if whitelisted in package.json, copy to build package root,
// return an array of the promises generated by async copy.
const promisesForForwardingModules = npmRootFiles.reduce(
(promises, file) => {
if (
whitelistedFiles.includes(file) ||
whitelistedFiles.includes(`${file}/`)
) {
promises.push(
asyncCopyTo(resolve(`${npmFrom}/${file}`), `${to}/${file}`)
);
}
return promises;
},
[]
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}`
);
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`),
]);
process.exit(1);
} else {
return Promise.resolve();
// 'files' field exists in package.json,
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 => {
if (fs.lstatSync(`${npmFrom}/${file}`).isFile()) {
// copy source is a file, create all nesting directories ahead
// to avoid 'No such file or directory' error
const fileDirnameSegments = dirname(file).split('/');
fileDirnameSegments.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) {
Expand Down

0 comments on commit e97dff1

Please sign in to comment.