UNPKG

truffle

Version:

Truffle - Simple development framework for Ethereum

565 lines (478 loc) 15.2 kB
#!/usr/bin/env node /******/ (() => { // webpackBootstrap /******/ var __webpack_modules__ = ({ /***/ 97610: /***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { __webpack_require__(20406); const IPC = (__webpack_require__(39813).IPC); const Ganache = __webpack_require__(11651); const path = __webpack_require__(71017); const debug = __webpack_require__(15158); const util = __webpack_require__(73837); /* * Loggers */ const ipcDebug = debug("chain:ipc"); /* * Options */ // This script is expected to take two arguments: The first a networkName string, // the second an options string encoded as base64. // The options string is decoded, parsed, & then passed to Ganache.server(). const args = process.argv.slice(2); const ipcNetwork = args[0]; const base64OptionsString = args[1]; const optionsBuffer = Buffer.from(base64OptionsString, "base64"); let optionsString = optionsBuffer.toString(); let options; try { options = JSON.parse(optionsString); } catch (e) { throw new Error( "Fatal: Error parsing arguments; please contact the Truffle developers for help." ); } options.time = options.time ? new Date(options.time) : new Date(); /* * Logging */ // constructor class Logger { constructor() { this.messages = []; this.nextSubscriberID = 1; this.subscribers = {}; } // subscribe to log events with provided callback // sends prior unsent messages, as well as new messages // returns `unsubscribe` cleanup function subscribe(callback) { // flush messages const messages = this.messages; this.messages = []; messages.forEach(message => { callback(message); }); // save subscriber const subscriberID = this.nextSubscriberID++; this.subscribers[subscriberID] = callback; // return cleanup func const unsubscribe = () => { delete this.subscribers[subscriberID]; }; return unsubscribe; } // log a message to be sent to all active subscribers // buffers if there are no active subscribers (to send on first subscribe) log(...messages) { const subscriberIDs = Object.keys(this.subscribers); const formattedMessages = util.formatWithOptions( { colors: true }, ...messages ); if (subscriberIDs.length === 0) { this.messages.push(formattedMessages); return; } subscriberIDs.forEach(subscriberID => { const callback = this.subscribers[subscriberID]; callback(formattedMessages); }); } } /* * Supervisor */ // constructor - accepts an object to assign to `ipc.config` class Supervisor { constructor(ipcConfig) { // init IPC this.ipc = new IPC(); // set config Object.keys(ipcConfig).forEach(key => { this.ipc.config[key] = ipcConfig[key]; }); this.mixins = []; } // include mixin use(mixin) { this.mixins.push(mixin); } // dispatch event to all relevant mixins (ones that define `event` method) handle(event, args) { args = Array.prototype.slice.call(args); this.mixins.forEach(mixin => { if (mixin[event]) { mixin[event].apply(mixin, [this].concat(args)); } }); } // start the IPC server and hook up all the mixins start() { const self = this; const ipc = this.ipc; // socket filename const dirname = ipc.config.socketRoot; const basename = `${ipc.config.appspace}${ipc.config.id}`; const servePath = path.join(dirname, basename); ipc.serve(servePath, function () { self.handle("start", arguments); ipc.server.on("connect", function () { self.handle("connect", arguments); }); ipc.server.on("socket.disconnected", function () { self.handle("disconnect", arguments); }); }); ipc.server.start(); } // external interface for mixin to emit socket events emit(socket, message, data, options = {}) { options.silent = options.silent || false; // possibly override silent const currentlySilent = this.ipc.config.silent; if (options.silent) { this.ipc.config.silent = true; } this.ipc.server.emit(socket, message, data); // reset this.ipc.config.silent = currentlySilent; } // external interface for mixin to exit exit() { this.ipc.server.stop(); this.handle("exit", arguments); } } /* * Lifecycle * (quit on last connection) */ class LifecycleMixin { // start counting active connections start(_supervisor) { this.connections = 0; } // increment connect(_supervisor) { this.connections++; } // decrement - invoke supervisor exit if no connections remain disconnect(supervisor) { this.connections--; if (this.connections <= 0) { supervisor.exit(); } } } /* * Ganache Server */ // constructor - accepts options for Ganache class GanacheMixin { constructor(options, ganacheConsoleLogger) { this.ganache = Ganache.server(options); this.ganacheConsoleLogger = ganacheConsoleLogger; } // start Ganache and capture promise that resolves when ready start(_supervisor) { this.ready = new Promise((accept, reject) => { this.ganache.listen(options.port, options.hostname, (err, state) => { if (err) { reject(err); } accept(state); }); }); } // wait for Ganache to be ready then emit signal to client socket connect(supervisor, socket) { this.ready.then(() => { supervisor.emit(socket, "truffle.ready"); // hook into ganache console.log events this.ganache.provider.on("ganache:vm:tx:console.log", ({ logs }) => { this.ganacheConsoleLogger.log( // Format and colorize ganache log data which may or may not // include a format string as the first argument. util.formatWithOptions({ colors: true }, ...logs) ); }); }); } // cleanup Ganache process on exit exit(_supervisor) { this.ganache .close() .then(() => (process.exitCode = 0)) .catch(err => { console.error(err.stack || err); process.exitCode = 1; }); } } /* * Logging over IPC */ // constructor - takes Logger instance and message key (e.g. `truffle.ipc.log`) class LoggerMixin { constructor(logger, message) { this.logger = logger; this.message = message; } // on connect, subscribe client socket to logger connect(supervisor, socket) { const unsubscribe = this.logger.subscribe(data => { supervisor.emit(socket, this.message, data, { silent: true }); }); socket.on("close", unsubscribe); } } /* * Process event handling */ process.on("uncaughtException", ({ stack }) => { console.error(stack); process.exit(1); }); /* * Main */ const ipcLogger = new Logger(); const ganacheLogger = new Logger(); const ganacheConsoleLogger = new Logger(); const supervisor = new Supervisor({ appspace: "truffle.", id: ipcNetwork, retry: 1500, logger: ipcLogger.log.bind(ipcLogger) }); ipcLogger.subscribe(ipcDebug); options.logger = { log: ganacheLogger.log.bind(ganacheLogger) }; ganacheConsoleLogger.log = ganacheConsoleLogger.log.bind(ganacheConsoleLogger); const ganacheMixin = new GanacheMixin(options, ganacheConsoleLogger); supervisor.use(new LifecycleMixin()); supervisor.use(ganacheMixin); supervisor.use(new LoggerMixin(ipcLogger, "truffle.ipc.log")); supervisor.use(new LoggerMixin(ganacheLogger, "truffle.ganache.log")); supervisor.use(new LoggerMixin(ganacheConsoleLogger, "truffle.solidity.log")); supervisor.start(); /***/ }), /***/ 11651: /***/ ((module) => { "use strict"; module.exports = require("ganache"); /***/ }), /***/ 71891: /***/ ((module) => { "use strict"; module.exports = require("dgram"); /***/ }), /***/ 57147: /***/ ((module) => { "use strict"; module.exports = require("fs"); /***/ }), /***/ 41808: /***/ ((module) => { "use strict"; module.exports = require("net"); /***/ }), /***/ 22037: /***/ ((module) => { "use strict"; module.exports = require("os"); /***/ }), /***/ 71017: /***/ ((module) => { "use strict"; module.exports = require("path"); /***/ }), /***/ 24404: /***/ ((module) => { "use strict"; module.exports = require("tls"); /***/ }), /***/ 76224: /***/ ((module) => { "use strict"; module.exports = require("tty"); /***/ }), /***/ 73837: /***/ ((module) => { "use strict"; module.exports = require("util"); /***/ }) /******/ }); /************************************************************************/ /******/ // The module cache /******/ var __webpack_module_cache__ = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ var cachedModule = __webpack_module_cache__[moduleId]; /******/ if (cachedModule !== undefined) { /******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { /******/ id: moduleId, /******/ loaded: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.loaded = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = __webpack_modules__; /******/ /******/ // the startup function /******/ __webpack_require__.x = () => { /******/ // Load entry module and return exports /******/ // This entry module depends on other loaded chunks and execution need to be delayed /******/ var __webpack_exports__ = __webpack_require__.O(undefined, [5158,406,9813], () => (__webpack_require__(97610))) /******/ __webpack_exports__ = __webpack_require__.O(__webpack_exports__); /******/ return __webpack_exports__; /******/ }; /******/ /************************************************************************/ /******/ /* webpack/runtime/chunk loaded */ /******/ (() => { /******/ var deferred = []; /******/ __webpack_require__.O = (result, chunkIds, fn, priority) => { /******/ if(chunkIds) { /******/ priority = priority || 0; /******/ for(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1]; /******/ deferred[i] = [chunkIds, fn, priority]; /******/ return; /******/ } /******/ var notFulfilled = Infinity; /******/ for (var i = 0; i < deferred.length; i++) { /******/ var [chunkIds, fn, priority] = deferred[i]; /******/ var fulfilled = true; /******/ for (var j = 0; j < chunkIds.length; j++) { /******/ if ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every((key) => (__webpack_require__.O[key](chunkIds[j])))) { /******/ chunkIds.splice(j--, 1); /******/ } else { /******/ fulfilled = false; /******/ if(priority < notFulfilled) notFulfilled = priority; /******/ } /******/ } /******/ if(fulfilled) { /******/ deferred.splice(i--, 1) /******/ var r = fn(); /******/ if (r !== undefined) result = r; /******/ } /******/ } /******/ return result; /******/ }; /******/ })(); /******/ /******/ /* webpack/runtime/ensure chunk */ /******/ (() => { /******/ __webpack_require__.f = {}; /******/ // This file contains only the entry chunk. /******/ // The chunk loading function for additional chunks /******/ __webpack_require__.e = (chunkId) => { /******/ return Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => { /******/ __webpack_require__.f[key](chunkId, promises); /******/ return promises; /******/ }, [])); /******/ }; /******/ })(); /******/ /******/ /* webpack/runtime/get javascript chunk filename */ /******/ (() => { /******/ // This function allow to reference async chunks and sibling chunks for the entrypoint /******/ __webpack_require__.u = (chunkId) => { /******/ // return url for filenames based on template /******/ return "" + chunkId + ".bundled.js"; /******/ }; /******/ })(); /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); /******/ /******/ /* webpack/runtime/node module decorator */ /******/ (() => { /******/ __webpack_require__.nmd = (module) => { /******/ module.paths = []; /******/ if (!module.children) module.children = []; /******/ return module; /******/ }; /******/ })(); /******/ /******/ /* webpack/runtime/require chunk loading */ /******/ (() => { /******/ // no baseURI /******/ /******/ // object to store loaded chunks /******/ // "1" means "loaded", otherwise not loaded yet /******/ var installedChunks = { /******/ 8507: 1 /******/ }; /******/ /******/ __webpack_require__.O.require = (chunkId) => (installedChunks[chunkId]); /******/ /******/ var installChunk = (chunk) => { /******/ var moreModules = chunk.modules, chunkIds = chunk.ids, runtime = chunk.runtime; /******/ for(var moduleId in moreModules) { /******/ if(__webpack_require__.o(moreModules, moduleId)) { /******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; /******/ } /******/ } /******/ if(runtime) runtime(__webpack_require__); /******/ for(var i = 0; i < chunkIds.length; i++) /******/ installedChunks[chunkIds[i]] = 1; /******/ __webpack_require__.O(); /******/ }; /******/ /******/ // require() chunk loading for javascript /******/ __webpack_require__.f.require = (chunkId, promises) => { /******/ // "1" is the signal for "already loaded" /******/ if(!installedChunks[chunkId]) { /******/ if(true) { // all chunks have JS /******/ installChunk(require("./" + __webpack_require__.u(chunkId))); /******/ } else installedChunks[chunkId] = 1; /******/ } /******/ }; /******/ /******/ // no external install chunk /******/ /******/ // no HMR /******/ /******/ // no HMR manifest /******/ })(); /******/ /******/ /* webpack/runtime/startup chunk dependencies */ /******/ (() => { /******/ var next = __webpack_require__.x; /******/ __webpack_require__.x = () => { /******/ __webpack_require__.e(5158); /******/ __webpack_require__.e(406); /******/ __webpack_require__.e(9813); /******/ return next(); /******/ }; /******/ })(); /******/ /************************************************************************/ /******/ /******/ // run startup /******/ var __webpack_exports__ = __webpack_require__.x(); /******/ var __webpack_export_target__ = exports; /******/ for(var i in __webpack_exports__) __webpack_export_target__[i] = __webpack_exports__[i]; /******/ if(__webpack_exports__.__esModule) Object.defineProperty(__webpack_export_target__, "__esModule", { value: true }); /******/ /******/ })() ; //# sourceMappingURL=chain.bundled.js.map