Fail build when plugins don't compile

Summary:
This adds an option to the compilePlugin function that
allows specifying whether or not to throw an exception
if compiling a plugin fails.

While this seems like a sensible default while development,
it seems like a pretty bad idea when building releases.

Reviewed By: jknoxville

Differential Revision: D12904570

fbshipit-source-id: aee365074af129296a9d493804b959cb9513f9cc
This commit is contained in:
Pascal Hartig
2018-11-04 04:34:12 -08:00
committed by Facebook Github Bot
parent 870f6017ab
commit ac6575850e
2 changed files with 63 additions and 22 deletions

View File

@@ -190,17 +190,20 @@ function compileDefaultPlugins(buildFolder) {
path.join(__dirname, '..', 'src', 'fb', 'plugins'),
],
defaultPluginDir,
).then(defaultPlugins =>
fs.writeFileSync(
path.join(defaultPluginDir, 'index.json'),
JSON.stringify(
defaultPlugins.map(plugin => ({
...plugin,
out: path.join(defaultPluginFolder, path.parse(plugin.out).base),
})),
{force: true, failSilently: false},
)
.then(defaultPlugins =>
fs.writeFileSync(
path.join(defaultPluginDir, 'index.json'),
JSON.stringify(
defaultPlugins.map(plugin => ({
...plugin,
out: path.join(defaultPluginFolder, path.parse(plugin.out).base),
})),
),
),
),
);
)
.catch(die);
}
(async () => {

View File

@@ -3,6 +3,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
* @format
* @flow
*/
const path = require('path');
@@ -12,15 +13,38 @@ const util = require('util');
const recursiveReaddir = require('recursive-readdir');
const HOME_DIR = require('os').homedir();
module.exports = async (reloadCallback, pluginPaths, pluginCache) => {
/* eslint-disable prettier/prettier */
/*::
type CompileOptions = {|
force: boolean,
failSilently: boolean,
|};
*/
const DEFAULT_COMPILE_OPTIONS /*: CompileOptions */ = {
force: false,
failSilently: true,
};
module.exports = async (
reloadCallback,
pluginPaths,
pluginCache,
options = DEFAULT_COMPILE_OPTIONS,
) => {
const plugins = pluginEntryPoints(pluginPaths);
if (!fs.existsSync(pluginCache)) {
fs.mkdirSync(pluginCache);
}
watchChanges(plugins, reloadCallback, pluginCache);
watchChanges(plugins, reloadCallback, pluginCache, options);
const dynamicPlugins = [];
for (let plugin of Object.values(plugins)) {
const compiledPlugin = await compilePlugin(plugin, false, pluginCache);
const dynamicOptions = Object.assign(options, {force: false});
const compiledPlugin = await compilePlugin(
plugin,
pluginCache,
dynamicOptions,
);
if (compiledPlugin) {
dynamicPlugins.push(compiledPlugin);
}
@@ -29,7 +53,12 @@ module.exports = async (reloadCallback, pluginPaths, pluginCache) => {
return dynamicPlugins;
};
function watchChanges(plugins, reloadCallback, pluginCache) {
function watchChanges(
plugins,
reloadCallback,
pluginCache,
options = DEFAULT_COMPILE_OPTIONS,
) {
// eslint-disable-next-line no-console
console.log('🕵️‍ Watching for plugin changes');
@@ -40,7 +69,8 @@ function watchChanges(plugins, reloadCallback, pluginCache) {
if (!filename.startsWith('.')) {
// eslint-disable-next-line no-console
console.log(`🕵️‍ Detected changes in ${plugin.name}`);
compilePlugin(plugin, true, pluginCache).then(reloadCallback);
const watchOptions = Object.assign(options, {force: true});
compilePlugin(plugin, pluginCache, watchOptions).then(reloadCallback);
}
}),
);
@@ -139,15 +169,19 @@ function mostRecentlyChanged(dir) {
}
async function compilePlugin(
{rootDir, name, entry, packageJSON},
force,
pluginCache,
options/*: CompileOptions */,
) {
const fileName = `${name}@${packageJSON.version || '0.0.0'}.js`;
const out = path.join(pluginCache, fileName);
const result = Object.assign({}, packageJSON, {rootDir, name, entry, out});
// check if plugin needs to be compiled
const rootDirCtime = await mostRecentlyChanged(rootDir);
if (!force && fs.existsSync(out) && rootDirCtime < fs.lstatSync(out).ctime) {
if (
!options.force &&
fs.existsSync(out) &&
rootDirCtime < fs.lstatSync(out).ctime
) {
// eslint-disable-next-line no-console
console.log(`🥫 Using cached version of ${name}...`);
return result;
@@ -181,11 +215,15 @@ async function compilePlugin(
},
);
} catch (e) {
console.error(
`❌ Plugin ${name} is ignored, because it could not be compiled.`,
);
console.error(e);
return null;
if (options.failSilently) {
console.error(
`❌ Plugin ${name} is ignored, because it could not be compiled.`,
);
console.error(e);
return null;
} else {
throw e;
}
}
return result;
}