mirror of
https://github.com/status-im/embark-area-51.git
synced 2025-01-11 06:25:57 +00:00
71e92358a8
As part of a bigger refactoring to make Embark's build pipeline pluggable, this commit moves the watcher into its own plugin module so it can be consumed via Embark's event bus. It also introduces new command handlers for all watcher related APIs respectively: - watcher:start - watcher:stop - watcher:restart
208 lines
6.3 KiB
JavaScript
208 lines
6.3 KiB
JavaScript
let chokidar = require('chokidar');
|
|
let path = require('path');
|
|
|
|
let fs = require('../../core/fs.js');
|
|
|
|
const DAPP_PIPELINE_CONFIG_FILE = 'pipeline.js';
|
|
const DAPP_WEBPACK_CONFIG_FILE = 'webpack.config.js';
|
|
const DAPP_BABEL_LOADER_OVERRIDES_CONFIG_FILE = 'babel-loader-overrides.js';
|
|
|
|
// TODO: this should be receiving the config object not re-reading the
|
|
// embark.json file
|
|
class Watcher {
|
|
constructor(embark) {
|
|
this.logger = embark.logger;
|
|
this.events = embark.events;
|
|
this.fileWatchers = [];
|
|
|
|
this.events.setCommandHandler('watcher:start', () => this.start());
|
|
this.events.setCommandHandler('watcher:stop', () => this.stop());
|
|
this.events.setCommandHandler('watcher:restart', () => this.restart());
|
|
}
|
|
|
|
start() {
|
|
let self = this;
|
|
// TODO: should come from the config object instead of reading the file
|
|
// directly
|
|
let embarkConfig = fs.readJSONSync("embark.json");
|
|
|
|
this.watchAssets(embarkConfig, function () {
|
|
self.logger.trace('ready to watch asset changes');
|
|
});
|
|
|
|
this.watchContracts(embarkConfig, function () {
|
|
self.logger.trace('ready to watch contract changes');
|
|
});
|
|
|
|
this.watchContractConfig(embarkConfig, function () {
|
|
self.logger.trace('ready to watch contract config changes');
|
|
});
|
|
|
|
this.watchPipelineConfig(embarkConfig, function () {
|
|
self.logger.trace('ready to watch pipeline config changes');
|
|
});
|
|
|
|
this.watchWebserverConfig(embarkConfig, function () {
|
|
self.logger.trace('ready to watch webserver config changes');
|
|
});
|
|
|
|
this.logger.info(__("ready to watch file changes"));
|
|
}
|
|
|
|
restart() {
|
|
this.stop();
|
|
this.start();
|
|
}
|
|
|
|
stop() {
|
|
this.fileWatchers.forEach(fileWatcher => {
|
|
if (fileWatcher.shouldClose) return;
|
|
if (fileWatcher.isReady) fileWatcher.close();
|
|
fileWatcher.shouldClose = true;
|
|
});
|
|
}
|
|
|
|
watchAssets(embarkConfig, callback) {
|
|
let self = this;
|
|
let appConfig = embarkConfig.app;
|
|
let filesToWatch = [];
|
|
|
|
for (let targetFile in appConfig) {
|
|
let files = appConfig[targetFile];
|
|
let fileGlob = files;
|
|
|
|
// workaround for imports issue
|
|
// so embark reacts to changes made in imported js files
|
|
// chokidar glob patterns only work with front-slashes
|
|
if (!Array.isArray(files)) {
|
|
fileGlob = path.join(path.dirname(files), '**', '*.*').replace(/\\/g, '/');
|
|
} else if (files.length === 1) {
|
|
fileGlob = path.join(path.dirname(files[0]), '**', '*.*').replace(/\\/g, '/');
|
|
}
|
|
|
|
filesToWatch.push(fileGlob);
|
|
}
|
|
filesToWatch = Array.from(new Set(filesToWatch));
|
|
|
|
this.watchFiles(
|
|
filesToWatch,
|
|
function (eventName, path) {
|
|
self.logger.info(`${eventName}: ${path}`);
|
|
self.events.emit('file-' + eventName, 'asset', path);
|
|
self.events.emit('file-event', 'asset', path);
|
|
},
|
|
function () {
|
|
callback();
|
|
}
|
|
);
|
|
}
|
|
|
|
watchContracts(embarkConfig, callback) {
|
|
let self = this;
|
|
this.watchFiles(
|
|
[embarkConfig.contracts],
|
|
function (eventName, path) {
|
|
self.logger.info(`${eventName}: ${path}`);
|
|
self.events.emit('file-' + eventName, 'contract', path);
|
|
self.events.emit('file-event', 'contract', path);
|
|
},
|
|
function () {
|
|
callback();
|
|
}
|
|
);
|
|
}
|
|
|
|
watchWebserverConfig(embarkConfig, callback) {
|
|
let self = this;
|
|
let webserverConfig;
|
|
if (typeof embarkConfig.config === 'object') {
|
|
if (!embarkConfig.config.webserver) {
|
|
return;
|
|
}
|
|
webserverConfig = embarkConfig.config.webserver;
|
|
} else {
|
|
let contractsFolder = embarkConfig.config.replace(/\\/g, '/');
|
|
if (contractsFolder.charAt(contractsFolder.length - 1) !== '/') {
|
|
contractsFolder += '/';
|
|
}
|
|
webserverConfig = [`${contractsFolder}**/webserver.json`, `${contractsFolder}**/webserver.js`];
|
|
}
|
|
this.watchFiles(webserverConfig,
|
|
function (eventName, path) {
|
|
self.logger.info(`${eventName}: ${path}`);
|
|
self.events.emit('webserver:config:change', 'config', path);
|
|
},
|
|
function () {
|
|
callback();
|
|
}
|
|
);
|
|
}
|
|
|
|
watchContractConfig(embarkConfig, callback) {
|
|
let self = this;
|
|
let contractConfig;
|
|
if (typeof embarkConfig.config === 'object' || embarkConfig.config.contracts) {
|
|
contractConfig = embarkConfig.config.contracts;
|
|
} else {
|
|
let contractsFolder = embarkConfig.config.replace(/\\/g, '/');
|
|
if (contractsFolder.charAt(contractsFolder.length - 1) !== '/') {
|
|
contractsFolder += '/';
|
|
}
|
|
contractConfig = [`${contractsFolder}**/contracts.json`, `${contractsFolder}**/contracts.js`];
|
|
}
|
|
this.watchFiles(contractConfig,
|
|
function (eventName, path) {
|
|
self.logger.info(`${eventName}: ${path}`);
|
|
self.events.emit('file-' + eventName, 'config', path);
|
|
self.events.emit('file-event', 'config', path);
|
|
},
|
|
function () {
|
|
callback();
|
|
}
|
|
);
|
|
}
|
|
|
|
watchPipelineConfig(embarkConfig, callback) {
|
|
let filesToWatch = [
|
|
fs.dappPath('', DAPP_WEBPACK_CONFIG_FILE),
|
|
fs.dappPath('', DAPP_BABEL_LOADER_OVERRIDES_CONFIG_FILE)
|
|
];
|
|
|
|
if (typeof embarkConfig.config === 'object' && embarkConfig.config.pipeline) {
|
|
filesToWatch.push(embarkConfig.config.pipeline);
|
|
} else if (typeof embarkConfig.config === 'string') {
|
|
filesToWatch.push(fs.dappPath(embarkConfig.config, DAPP_PIPELINE_CONFIG_FILE));
|
|
}
|
|
|
|
this.watchFiles(filesToWatch, (eventName, path) => {
|
|
this.logger.info(`${eventName}: ${path}`);
|
|
this.events.emit('file-' + eventName, 'config', path);
|
|
this.events.emit('file-event', 'config', path);
|
|
}, callback);
|
|
}
|
|
|
|
watchFiles(files, changeCallback, doneCallback) {
|
|
this.logger.trace('watchFiles');
|
|
this.logger.trace(files);
|
|
|
|
let configWatcher = chokidar.watch(files, {
|
|
ignored: /[\/\\]\.|tmp_/, persistent: true, ignoreInitial: true, followSymlinks: true
|
|
});
|
|
this.fileWatchers.push(configWatcher);
|
|
|
|
configWatcher
|
|
.on('add', path => changeCallback('add', path))
|
|
.on('change', path => changeCallback('change', path))
|
|
.on('unlink', path => changeCallback('remove', path))
|
|
.once('ready', () => {
|
|
configWatcher.isReady = true;
|
|
if (configWatcher.shouldClose) configWatcher.close();
|
|
doneCallback();
|
|
});
|
|
}
|
|
|
|
}
|
|
|
|
module.exports = Watcher;
|
|
|