mirror of
https://github.com/status-im/embark-area-51.git
synced 2025-01-10 14:06:10 +00:00
db9fbef140
We could extend this further to launch the webserver with the placeholder page before building the contracts as well.
267 lines
16 KiB
JavaScript
267 lines
16 KiB
JavaScript
const fs = require('../core/fs.js');
|
|
const async = require('async');
|
|
const ProcessLauncher = require('../process/processLauncher');
|
|
const utils = require('../utils/utils.js');
|
|
const constants = require('../constants');
|
|
|
|
|
|
require("babel-preset-react");
|
|
require("babel-preset-es2015");
|
|
require("babel-preset-es2016");
|
|
require("babel-preset-es2017");
|
|
|
|
class Pipeline {
|
|
|
|
constructor(options) {
|
|
this.buildDir = options.buildDir;
|
|
this.contractsFiles = options.contractsFiles;
|
|
this.assetFiles = options.assetFiles;
|
|
this.events = options.events;
|
|
this.logger = options.logger;
|
|
this.normalizeInput = options.normalizeInput;
|
|
this.plugins = options.plugins;
|
|
this.pipelinePlugins = this.plugins.getPluginsFor('pipeline');
|
|
}
|
|
|
|
build(abi, contractsJSON, path, callback) {
|
|
let self = this;
|
|
const importsList = {};
|
|
let placeholderPage;
|
|
|
|
async.waterfall([
|
|
function createPlaceholderPage(next){
|
|
let html = `
|
|
<!doctype html>
|
|
<html>
|
|
<head>
|
|
<title>${__('Embark is building, please wait...')}</title>
|
|
<meta http-equiv="refresh" content="4">
|
|
<style>
|
|
body{background:#f2f2f5;background-size:cover;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif}.blobs{-webkit-filter:url("#goo");filter:url("#goo");position:absolute;top:0;left:-2.5%;bottom:0;right:0}@-webkit-keyframes blob-left-top-anim{0%{-webkit-transform:scale(1.1) translate(0,0);transform:scale(1.1) translate(0,0)}33%{-webkit-transform:scale(.9) translate(-95px,0);transform:scale(.9) translate(-95px,0)}62%{-webkit-transform:scale(.7) translate(-95px,-95px);transform:scale(.7) translate(-95px,-95px)}94%{-webkit-transform:scale(1.1) translate(0,0);transform:scale(1.1) translate(0,0)}}@keyframes blob-left-top-anim{0%{-webkit-transform:scale(1.1) translate(0,0);transform:scale(1.1) translate(0,0)}33%{-webkit-transform:scale(.9) translate(-95px,0);transform:scale(.9) translate(-95px,0)}62%{-webkit-transform:scale(.7) translate(-95px,-95px);transform:scale(.7) translate(-95px,-95px)}94%{-webkit-transform:scale(1.1) translate(0,0);transform:scale(1.1) translate(0,0)}}@-webkit-keyframes blob-right-top-anim{0%{-webkit-transform:scale(1.1) translate(0,0);transform:scale(1.1) translate(0,0)}33%{-webkit-transform:scale(.9) translate(95px,0);transform:scale(.9) translate(95px,0)}64%{-webkit-transform:scale(.7) translate(95px,-95px);transform:scale(.7) translate(95px,-95px)}96%{-webkit-transform:scale(1.1) translate(0,0);transform:scale(1.1) translate(0,0)}}@keyframes blob-right-top-anim{0%{-webkit-transform:scale(1.1) translate(0,0);transform:scale(1.1) translate(0,0)}33%{-webkit-transform:scale(.9) translate(95px,0);transform:scale(.9) translate(95px,0)}64%{-webkit-transform:scale(.7) translate(95px,-95px);transform:scale(.7) translate(95px,-95px)}96%{-webkit-transform:scale(1.1) translate(0,0);transform:scale(1.1) translate(0,0)}}@-webkit-keyframes blob-left-bottom-anim{0%{-webkit-transform:scale(1.1) translate(0,0);transform:scale(1.1) translate(0,0)}33%{-webkit-transform:scale(.9) translate(-95px,0);transform:scale(.9) translate(-95px,0)}66%{-webkit-transform:scale(.7) translate(-95px,95px);transform:scale(.7) translate(-95px,95px)}98%{-webkit-transform:scale(1.1) translate(0,0);transform:scale(1.1) translate(0,0)}}@keyframes blob-left-bottom-anim{0%{-webkit-transform:scale(1.1) translate(0,0);transform:scale(1.1) translate(0,0)}33%{-webkit-transform:scale(.9) translate(-95px,0);transform:scale(.9) translate(-95px,0)}66%{-webkit-transform:scale(.7) translate(-95px,95px);transform:scale(.7) translate(-95px,95px)}98%{-webkit-transform:scale(1.1) translate(0,0);transform:scale(1.1) translate(0,0)}}@-webkit-keyframes blob-right-bottom-anim{0%{-webkit-transform:scale(1.1) translate(0,0);transform:scale(1.1) translate(0,0)}33%{-webkit-transform:scale(.9) translate(95px,0);transform:scale(.9) translate(95px,0)}68%{-webkit-transform:scale(.7) translate(95px,95px);transform:scale(.7) translate(95px,95px)}100%{-webkit-transform:scale(1.1) translate(0,0);transform:scale(1.1) translate(0,0)}}@keyframes blob-right-bottom-anim{0%{-webkit-transform:scale(1.1) translate(0,0);transform:scale(1.1) translate(0,0)}33%{-webkit-transform:scale(.9) translate(95px,0);transform:scale(.9) translate(95px,0)}68%{-webkit-transform:scale(.7) translate(95px,95px);transform:scale(.7) translate(95px,95px)}100%{-webkit-transform:scale(1.1) translate(0,0);transform:scale(1.1) translate(0,0)}}.blob{position:absolute;background-color:#363763;background-image:url('data:image/svg+xml;charset=UTF-8,<svg width="24" height="24" xmlns="http://www.w3.org/2000/svg"><path d="M20 17H4l8-10z" fill-rule="evenodd" opacity=".05"/></svg>');left:50%;top:50%;width:150px;height:150px;line-height:150px;text-align:center;color:white;font-size:40px;border-radius:100%;margin-top:-50px;margin-left:-50px;-webkit-animation:blob-left-top-anim cubic-bezier(.77,0,.175,1) 4s infinite;animation:blob-left-top-anim cubic-bezier(.77,0,.175,1) 4s infinite}.blob:before{position:absolute;width:100%;height:100%;background-repeat:no-repeat;background-image:url('data:image/svg+xml;charset=UTF-8,<svg width="117" height="27" xmlns="http://www.w3.org/2000/svg"><path d="M12.537 20.599l3.624 1.442c-1.504 2.884-3.994 4.327-7.47 4.327-2.663 0-4.777-.845-6.343-2.534C.783 22.146 0 19.896 0 17.085c0-2.76.783-4.986 2.348-6.675 1.566-1.689 3.63-2.533 6.195-2.533 2.662 0 4.702.863 6.12 2.589 1.418 1.725 2.126 3.87 2.126 6.434v1.184H4.29c.075 1.48.457 2.706 1.147 3.68.69.973 1.763 1.46 3.218 1.46 1.775 0 3.07-.875 3.883-2.625zm-4.031-9.653c-1.208 0-2.17.401-2.885 1.202-.715.802-1.134 1.856-1.257 3.162h8.21c-.05-1.356-.444-2.422-1.184-3.199-.74-.776-1.7-1.165-2.884-1.165zm10.677 14.94V8.359h4.03v2.662c1.16-2.095 2.898-3.143 5.215-3.143 1.233 0 2.311.277 3.236.832a5.273 5.273 0 0 1 2.09 2.311c.566-.862 1.343-1.602 2.33-2.218.985-.617 2.082-.925 3.29-.925 1.677 0 3.07.512 4.18 1.535 1.109 1.023 1.664 2.471 1.664 4.345v12.13h-4.216V14.793c0-1.184-.278-2.06-.832-2.626-.555-.567-1.252-.85-2.09-.85-1.035 0-1.923.468-2.663 1.405-.74.936-1.109 2.23-1.109 3.883v9.282h-4.216V14.793c0-1.184-.283-2.06-.85-2.626-.567-.567-1.27-.85-2.108-.85-1.036 0-1.917.468-2.644 1.405-.728.936-1.091 2.23-1.091 3.883v9.282h-4.216zM58.63 7.878c2.293 0 4.185.844 5.677 2.533 1.491 1.689 2.237 3.926 2.237 6.712 0 2.786-.746 5.024-2.237 6.712-1.492 1.69-3.384 2.534-5.677 2.534-2.564 0-4.462-1.024-5.695-3.07v2.589h-4.03V0h4.215v10.614c1.282-1.825 3.119-2.737 5.51-2.737zm-5.547 8.395v1.7c0 1.677.475 2.94 1.424 3.791s2.028 1.276 3.236 1.276c1.356 0 2.447-.554 3.272-1.664.826-1.11 1.24-2.527 1.24-4.253 0-1.725-.414-3.143-1.24-4.253-.825-1.109-1.916-1.664-3.272-1.664-1.208 0-2.287.426-3.236 1.276-.95.85-1.424 2.114-1.424 3.79zm26.727 9.615c-.247-.444-.37-1.196-.37-2.256-1.282 1.824-3.143 2.737-5.584 2.737-1.775 0-3.199-.45-4.271-1.35-1.073-.9-1.61-2.114-1.61-3.643 0-1.134.303-2.108.907-2.921.604-.814 1.454-1.449 2.552-1.905a15.316 15.316 0 0 1 3.605-.98c1.307-.197 2.75-.296 4.327-.296v-1.11c0-.96-.271-1.725-.814-2.292-.542-.567-1.343-.85-2.403-.85s-1.874.258-2.441.776c-.567.518-.863 1.171-.888 1.96l-4.068-.592c.173-1.652.968-2.946 2.386-3.883 1.417-.937 3.137-1.405 5.159-1.405 2.17 0 3.907.549 5.214 1.646 1.307 1.097 1.96 2.668 1.96 4.715v9.245c0 .789.136 1.59.407 2.404H79.81zm-4.808-2.626c1.184 0 2.207-.351 3.07-1.054.863-.702 1.294-1.633 1.294-2.792v-1.442c-4.832 0-7.248 1.048-7.248 3.143 0 .69.265 1.22.795 1.59.53.37 1.226.555 2.09.555zM98.365 8.284l-.85 3.883c-.518-.444-1.196-.666-2.035-.666-1.134 0-2.126.48-2.977 1.442-.85.962-1.276 2.33-1.276 4.105v8.839h-4.215V8.357h3.957v2.848c.961-2.219 2.687-3.328 5.177-3.328.838 0 1.578.136 2.219.407zm13.34 17.603l-5.954-8.506-1.776 1.627v6.879H99.76V0h4.215v14.645l6.805-6.287h4.918l-6.915 6.435 7.877 11.094h-4.955z" fill="#FFF" fill-rule="evenodd"/></svg>');z-index:10000;content:'';left:18px;top:58px}.blob:nth-child(2){-webkit-animation-name:blob-right-top-anim;animation-name:blob-right-top-anim}.blob:nth-child(3){-webkit-animation-name:blob-left-bottom-anim;animation-name:blob-left-bottom-anim}.blob:nth-child(4){-webkit-animation-name:blob-right-bottom-anim;animation-name:blob-right-bottom-anim}.loading-msg{position:fixed;bottom:5%;width:100%;text-align:center;font-size:1.5rem;font-weight:400}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="blobs">
|
|
<div class="blob"></div>
|
|
<div class="blob"></div>
|
|
<div class="blob"></div>
|
|
<div class="blob"></div>
|
|
</div>
|
|
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
|
|
<defs>
|
|
<filter id="goo">
|
|
<feGaussianBlur in="SourceGraphic" stdDeviation="10" result="blur" />
|
|
<feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 18 -7" result="goo" />
|
|
<feBlend in="SourceGraphic" in2="goo" />
|
|
</filter>
|
|
</defs>
|
|
</svg>
|
|
<h1 class="loading-msg">${__('Embark is building, please wait...')}</h1>
|
|
</body>
|
|
</html>`;
|
|
fs.writeFile(self.buildDir + 'index.html', html, next);
|
|
},
|
|
function buildTheContracts(next) {
|
|
self.buildContracts(next);
|
|
},
|
|
function buildWeb3(next) {
|
|
self.buildWeb3JS(next);
|
|
},
|
|
function createImportList(next) {
|
|
importsList["Embark/EmbarkJS"] = fs.dappPath(".embark", 'embark.js');
|
|
importsList["Embark/web3"] = fs.dappPath(".embark", 'web3_instance.js');
|
|
|
|
self.plugins.getPluginsProperty('imports', 'imports').forEach(function (importObject) {
|
|
let [importName, importLocation] = importObject;
|
|
importsList[importName] = importLocation;
|
|
});
|
|
|
|
next();
|
|
},
|
|
function writeContracts(next) {
|
|
self.events.request('contracts:list', (contracts) => {
|
|
async.each(contracts, (contract, eachCb) => {
|
|
self.events.request('code-generator:contract', contract.className, (contractCode) => {
|
|
let filePath = fs.dappPath(".embark", contract.className + '.js');
|
|
importsList["Embark/contracts/" + contract.className] = filePath;
|
|
fs.writeFile(filePath, contractCode, eachCb);
|
|
});
|
|
}, next);
|
|
});
|
|
},
|
|
function assetFileWrite(next) {
|
|
async.eachOf(self.assetFiles, function (files, targetFile, cb) {
|
|
async.map(files,
|
|
function (file, fileCb) {
|
|
self.logger.trace("reading " + file.filename);
|
|
|
|
// Not a JS file
|
|
if (file.filename.indexOf('.js') < 0) {
|
|
return file.content(function (fileContent) {
|
|
self.runPlugins(file, fileContent, fileCb);
|
|
});
|
|
}
|
|
|
|
// JS files
|
|
async.waterfall([
|
|
function runWebpack(next) {
|
|
const webpackProcess = new ProcessLauncher({
|
|
modulePath: utils.joinPath(__dirname, 'webpackProcess.js'),
|
|
logger: self.logger,
|
|
events: self.events,
|
|
normalizeInput: self.normalizeInput
|
|
});
|
|
webpackProcess.send({action: constants.pipeline.init, options: {}});
|
|
webpackProcess.send({action: constants.pipeline.build, file, importsList});
|
|
|
|
webpackProcess.once('result', constants.pipeline.built, (msg) => {
|
|
webpackProcess.disconnect();
|
|
return next(msg.error);
|
|
});
|
|
},
|
|
|
|
function readFile(next) {
|
|
fs.readFile('./.embark/' + file.filename, (err, data) => {
|
|
if (err) {
|
|
return next(err);
|
|
}
|
|
next(null, data.toString());
|
|
});
|
|
},
|
|
|
|
function runPluginsOnContent(fileContent, next) {
|
|
self.runPlugins(file, fileContent, next);
|
|
}
|
|
|
|
], function (err, contentFile) {
|
|
if (err) {
|
|
self.logger.error(err);
|
|
return fileCb(err);
|
|
}
|
|
|
|
fileCb(null, contentFile);
|
|
});
|
|
},
|
|
function (err, contentFiles) {
|
|
if (err) {
|
|
self.logger.error(__('errors found while generating') + ' ' + targetFile);
|
|
}
|
|
let dir = targetFile.split('/').slice(0, -1).join('/');
|
|
self.logger.trace("creating dir " + self.buildDir + dir);
|
|
fs.mkdirpSync(self.buildDir + dir);
|
|
|
|
// if it's a directory
|
|
if (targetFile.slice(-1) === '/' || targetFile.indexOf('.') === -1) {
|
|
let targetDir = targetFile;
|
|
|
|
if (targetDir.slice(-1) !== '/') {
|
|
targetDir = targetDir + '/';
|
|
}
|
|
|
|
async.each(contentFiles, function (file, mapCb) {
|
|
let filename = file.filename.replace(file.basedir + '/', '');
|
|
self.logger.info("writing file " + (self.buildDir + targetDir + filename).bold.dim);
|
|
|
|
fs.copy(file.path, self.buildDir + targetDir + filename, {overwrite: true}, mapCb);
|
|
}, cb);
|
|
return;
|
|
}
|
|
|
|
let content = contentFiles.map(function (file) {
|
|
if (file === undefined) {
|
|
return "";
|
|
}
|
|
return file.content;
|
|
}).join("\n");
|
|
|
|
self.logger.info(__("writing file") + " " + (self.buildDir + targetFile).bold.dim);
|
|
if(new RegExp(/^index.html?/i).test(targetFile)){
|
|
targetFile = targetFile.replace('index', 'index-temp');
|
|
placeholderPage = targetFile;
|
|
}
|
|
fs.writeFile(self.buildDir + targetFile, content, cb);
|
|
}
|
|
);
|
|
},
|
|
next);
|
|
},
|
|
function removePlaceholderPage(next){
|
|
let placeholderFile = self.buildDir + placeholderPage;
|
|
fs.access(self.buildDir + placeholderPage, (err) => {
|
|
if (err) return next(); // index-temp doesn't exist, do nothing
|
|
|
|
// rename index-temp.htm/l to index.htm/l, effectively replacing our placeholder page
|
|
// with the contents of the built index.html page
|
|
fs.move(placeholderFile, placeholderFile.replace('index-temp', 'index'), {overwrite: true}, next);
|
|
});
|
|
}
|
|
], callback);
|
|
}
|
|
|
|
runPlugins(file, fileContent, fileCb) {
|
|
const self = this;
|
|
if (self.pipelinePlugins.length <= 0) {
|
|
return fileCb(null, {content: fileContent, filename: file.filename, path: file.path, basedir: file.basedir, modified: true});
|
|
}
|
|
async.eachSeries(self.pipelinePlugins,
|
|
function(plugin, pluginCB) {
|
|
if (file.options && file.options.skipPipeline) {
|
|
return pluginCB();
|
|
}
|
|
|
|
fileContent = plugin.runPipeline({targetFile: file.filename, source: fileContent});
|
|
file.modified = true;
|
|
pluginCB();
|
|
},
|
|
function (err) {
|
|
if (err) {
|
|
self.logger.error(err.message);
|
|
}
|
|
return fileCb(null, {content: fileContent, filename: file.filename, path: file.path, basedir: file.basedir, modified: true});
|
|
}
|
|
);
|
|
}
|
|
|
|
buildContracts(cb) {
|
|
const self = this;
|
|
|
|
async.waterfall([
|
|
function makeDirectory(next) {
|
|
fs.mkdirp(fs.dappPath(self.buildDir, 'contracts'), (err, _result) => {
|
|
next(err);
|
|
});
|
|
},
|
|
function getContracts(next) {
|
|
self.events.request('contracts:list', (contracts) => {
|
|
next(null, contracts);
|
|
});
|
|
},
|
|
function writeContractsJSON(contracts, next) {
|
|
async.each(contracts, (contract, eachCb) => {
|
|
fs.writeJson(fs.dappPath(self.buildDir, 'contracts', contract.className + ".json"), contract, {spaces: 2}, eachCb);
|
|
}, () => { next(); });
|
|
}
|
|
], cb);
|
|
}
|
|
|
|
buildWeb3JS(cb) {
|
|
const self = this;
|
|
async.waterfall([
|
|
function makeDirectory(next) {
|
|
fs.mkdirp(fs.dappPath(".embark"), (err, _result) => {
|
|
next(err);
|
|
});
|
|
},
|
|
function getWeb3Code(next) {
|
|
self.events.request('code-generator:web3js', next);
|
|
},
|
|
function writeFile(code, next) {
|
|
fs.writeFile(fs.dappPath(".embark", 'web3_instance.js'), code, next);
|
|
}
|
|
], cb);
|
|
}
|
|
|
|
}
|
|
|
|
module.exports = Pipeline;
|