From 449f519a4deb1ac481f855eb22d667b88585ee4a Mon Sep 17 00:00:00 2001 From: eggplantzzz Date: Tue, 11 Jun 2019 15:42:16 +0200 Subject: [PATCH 01/11] Change some variable names --- packages/truffle-core/lib/commands/develop.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/truffle-core/lib/commands/develop.js b/packages/truffle-core/lib/commands/develop.js index d747ee2f09b..96e81d2b312 100644 --- a/packages/truffle-core/lib/commands/develop.js +++ b/packages/truffle-core/lib/commands/develop.js @@ -21,11 +21,11 @@ const command = { const commands = require("./index"); const excluded = ["console", "develop", "unbox", "init"]; - const available_commands = Object.keys(commands).filter( + const availableCommands = Object.keys(commands).filter( name => !excluded.includes(name) ); - const console_commands = available_commands.reduce( + const consoleCommands = availableCommands.reduce( (acc, name) => Object.assign({}, acc, { [name]: commands[name] }), {} ); @@ -33,7 +33,7 @@ const command = { Environment.develop(config, ganacheOptions) .then(() => { const c = new Console( - console_commands, + consoleCommands, config.with({ noAliases: true }) ); c.start(done); From 11b8c358f1da4d05751d2d8beb551e9e626574f6 Mon Sep 17 00:00:00 2001 From: eggplantzzz Date: Tue, 11 Jun 2019 15:53:47 +0200 Subject: [PATCH 02/11] Update some syntax and remove a callback from Develop.start --- packages/truffle-core/lib/develop.js | 56 ++++++++++++++-------------- 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/packages/truffle-core/lib/develop.js b/packages/truffle-core/lib/develop.js index f64f52ce6c0..20ac5c9e291 100644 --- a/packages/truffle-core/lib/develop.js +++ b/packages/truffle-core/lib/develop.js @@ -1,13 +1,13 @@ -var IPC = require("node-ipc").IPC; -var path = require("path"); -var spawn = require("child_process").spawn; -var debug = require("debug"); +const { IPC } = require("node-ipc"); +const path = require("path"); +const { spawn } = require("child_process"); +const debug = require("debug"); -var Develop = { - start: function(ipcNetwork, options, callback) { +const Develop = { + start: async function(ipcNetwork, options) { options = options || {}; - var chainPath; + let chainPath; // The path to the dev env process depends on whether or not // we're running in the bundled version. If not, use chain.js @@ -20,18 +20,16 @@ var Develop = { chainPath = path.join(__dirname, "../", "chain.js"); } - var cmd = spawn("node", [chainPath, ipcNetwork, JSON.stringify(options)], { + return spawn("node", [chainPath, ipcNetwork, JSON.stringify(options)], { detached: true, stdio: "ignore" }); - - callback(); }, connect: function(options, callback) { - var debugServer = debug("develop:ipc:server"); - var debugClient = debug("develop:ipc:client"); - var debugRPC = debug("develop:ganache"); + const debugServer = debug("develop:ipc:server"); + const debugClient = debug("develop:ipc:client"); + const debugRPC = debug("develop:ganache"); if (typeof options === "function") { callback = options; @@ -106,30 +104,30 @@ var Develop = { }, connectOrStart: function(options, ganacheOptions, callback) { - var self = this; + const self = this; options.retry = false; - var ipcNetwork = options.network || "develop"; + const ipcNetwork = options.network || "develop"; - var connectedAlready = false; + let connectedAlready = false; this.connect( options, - function(error, disconnect) { + async function(error, disconnect) { if (error) { - self.start(ipcNetwork, ganacheOptions, function() { - options.retry = true; - self.connect( - options, - function(error, disconnect) { - if (connectedAlready) return; - - connectedAlready = true; - callback(true, disconnect); - } - ); - }); + await self.start(ipcNetwork, ganacheOptions); + + options.retry = true; + self.connect( + options, + function(error, disconnect) { + if (connectedAlready) return; + + connectedAlready = true; + callback(true, disconnect); + } + ); } else { connectedAlready = true; callback(false, disconnect); From b34448f67be8b9cf056c86265cdbba0cc8b24e50 Mon Sep 17 00:00:00 2001 From: eggplantzzz Date: Tue, 11 Jun 2019 16:14:18 +0200 Subject: [PATCH 03/11] Update some more syntax --- packages/truffle-core/lib/commands/console.js | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/truffle-core/lib/commands/console.js b/packages/truffle-core/lib/commands/console.js index 8fe411ce29a..cdb6d928f13 100644 --- a/packages/truffle-core/lib/commands/console.js +++ b/packages/truffle-core/lib/commands/console.js @@ -1,4 +1,4 @@ -var command = { +const command = { command: "console", description: "Run a console with contract abstractions and commands available", @@ -19,29 +19,29 @@ var command = { ] }, run: function(options, done) { - var Config = require("truffle-config"); - var Console = require("../console"); - var Environment = require("../environment"); + const Config = require("truffle-config"); + const Console = require("../console"); + const Environment = require("../environment"); - var config = Config.detect(options); + const config = Config.detect(options); // This require a smell? - var commands = require("./index"); - var excluded = ["console", "init", "watch", "develop"]; + const commands = require("./index"); + const excluded = ["console", "init", "watch", "develop"]; - var available_commands = Object.keys(commands).filter(function(name) { + const availableCommands = Object.keys(commands).filter(name => { return excluded.indexOf(name) === -1; }); - var console_commands = {}; - available_commands.forEach(function(name) { - console_commands[name] = commands[name]; + const consoleCommands = {}; + availableCommands.forEach(name => { + consoleCommands[name] = commands[name]; }); Environment.detect(config) .then(() => { const c = new Console( - console_commands, + consoleCommands, config.with({ noAliases: true }) ); c.start(done); From c67ebc292e50a0a85a7a9502e664a6408ca9d9d7 Mon Sep 17 00:00:00 2001 From: eggplantzzz Date: Tue, 11 Jun 2019 16:18:48 +0200 Subject: [PATCH 04/11] Update syntax to class syntax for truffle-core/lib/console --- packages/truffle-core/lib/console.js | 434 ++++++++++++++------------- 1 file changed, 218 insertions(+), 216 deletions(-) diff --git a/packages/truffle-core/lib/console.js b/packages/truffle-core/lib/console.js index 763d59efd40..70e71629764 100644 --- a/packages/truffle-core/lib/console.js +++ b/packages/truffle-core/lib/console.js @@ -1,248 +1,250 @@ -var ReplManager = require("./repl"); -var Command = require("./command"); -var provision = require("truffle-provisioner"); -var contract = require("truffle-contract"); -var Web3Shim = require("truffle-interface-adapter").Web3Shim; -var vm = require("vm"); -var expect = require("truffle-expect"); -var TruffleError = require("truffle-error"); -var fs = require("fs"); -var path = require("path"); -var EventEmitter = require("events"); -var inherits = require("util").inherits; +const ReplManager = require("./repl"); +const Command = require("./command"); +const provision = require("truffle-provisioner"); +const contract = require("truffle-contract"); +const { Web3Shim } = require("truffle-interface-adapter"); +const vm = require("vm"); +const expect = require("truffle-expect"); +const TruffleError = require("truffle-error"); +const fs = require("fs"); +const path = require("path"); +const EventEmitter = require("events"); +const { inherits } = require("util"); inherits(Console, EventEmitter); -function Console(tasks, options) { - EventEmitter.call(this); - - var self = this; - - expect.options(options, [ - "working_directory", - "contracts_directory", - "contracts_build_directory", - "migrations_directory", - "networks", - "network", - "network_id", - "provider", - "resolver", - "build_directory" - ]); - - this.options = options; - - this.repl = options.repl || new ReplManager(options); - this.command = new Command(tasks); - - this.web3 = new Web3Shim({ - provider: options.provider, - networkType: options.networks[options.network].type - }); - - // Bubble the ReplManager's exit event - this.repl.on("exit", function() { - self.emit("exit"); - }); -} - -Console.prototype.start = function(callback) { - var self = this; +class Console { + constructor(tasks, options) { + EventEmitter.call(this); + + var self = this; + + expect.options(options, [ + "working_directory", + "contracts_directory", + "contracts_build_directory", + "migrations_directory", + "networks", + "network", + "network_id", + "provider", + "resolver", + "build_directory" + ]); + + this.options = options; + + this.repl = options.repl || new ReplManager(options); + this.command = new Command(tasks); + + this.web3 = new Web3Shim({ + provider: options.provider, + networkType: options.networks[options.network].type + }); - if (!this.repl) { - this.repl = new Repl(this.options); + // Bubble the ReplManager's exit event + this.repl.on("exit", function() { + self.emit("exit"); + }); } - // TODO: This should probalby be elsewhere. - // It's here to ensure the repl manager instance gets - // passed down to commands. - this.options.repl = this.repl; - - this.provision(function(err, abstractions) { - if (err) { - self.options.logger.log( - "Unexpected error: Cannot provision contracts while instantiating the console." - ); - self.options.logger.log(err.stack || err.message || err); + start(callback) { + var self = this; + + if (!this.repl) { + this.repl = new Repl(this.options); } - self.repl.start({ - prompt: "truffle(" + self.options.network + ")> ", - context: { - web3: self.web3 - }, - interpreter: self.interpret.bind(self), - done: callback - }); + // TODO: This should probalby be elsewhere. + // It's here to ensure the repl manager instance gets + // passed down to commands. + this.options.repl = this.repl; - self.resetContractsInConsoleContext(abstractions); - }); -}; + this.provision(function(err, abstractions) { + if (err) { + self.options.logger.log( + "Unexpected error: Cannot provision contracts while instantiating the console." + ); + self.options.logger.log(err.stack || err.message || err); + } -Console.prototype.provision = function(callback) { - var self = this; + self.repl.start({ + prompt: "truffle(" + self.options.network + ")> ", + context: { + web3: self.web3 + }, + interpreter: self.interpret.bind(self), + done: callback + }); - fs.readdir(this.options.contracts_build_directory, function(err, files) { - if (err) { - // Error reading the build directory? Must mean it doesn't exist or we don't have access to it. - // Couldn't provision the contracts if we wanted. It's possible we're hiding very rare FS - // errors, but that's better than showing the user error messages that will be "build folder - // doesn't exist" 99.9% of the time. - } + self.resetContractsInConsoleContext(abstractions); + }); + } - var promises = []; - files = files || []; - - files.forEach(function(file) { - promises.push( - new Promise(function(accept, reject) { - fs.readFile( - path.join(self.options.contracts_build_directory, file), - "utf8", - function(err, body) { - if (err) return reject(err); - try { - body = JSON.parse(body); - } catch (e) { - return reject( - new Error("Cannot parse " + file + ": " + e.message) - ); - } + provision(callback) { + var self = this; - accept(body); - } - ); - }) - ); - }); + fs.readdir(this.options.contracts_build_directory, function(err, files) { + if (err) { + // Error reading the build directory? Must mean it doesn't exist or we don't have access to it. + // Couldn't provision the contracts if we wanted. It's possible we're hiding very rare FS + // errors, but that's better than showing the user error messages that will be "build folder + // doesn't exist" 99.9% of the time. + } - Promise.all(promises) - .then(function(json_blobs) { - var abstractions = json_blobs.map(function(json) { - var abstraction = contract(json); - provision(abstraction, self.options); - return abstraction; - }); + var promises = []; + files = files || []; + + files.forEach(function(file) { + promises.push( + new Promise(function(accept, reject) { + fs.readFile( + path.join(self.options.contracts_build_directory, file), + "utf8", + function(err, body) { + if (err) return reject(err); + try { + body = JSON.parse(body); + } catch (e) { + return reject( + new Error("Cannot parse " + file + ": " + e.message) + ); + } + + accept(body); + } + ); + }) + ); + }); - self.resetContractsInConsoleContext(abstractions); + Promise.all(promises) + .then(function(json_blobs) { + var abstractions = json_blobs.map(function(json) { + var abstraction = contract(json); + provision(abstraction, self.options); + return abstraction; + }); - callback(null, abstractions); - }) - .catch(callback); - }); -}; + self.resetContractsInConsoleContext(abstractions); -Console.prototype.resetContractsInConsoleContext = function(abstractions) { - var self = this; + callback(null, abstractions); + }) + .catch(callback); + }); + } - abstractions = abstractions || []; + resetContractsInConsoleContext(abstractions) { + var self = this; - var contextVars = {}; + abstractions = abstractions || []; - abstractions.forEach(function(abstraction) { - contextVars[abstraction.contract_name] = abstraction; - }); + var contextVars = {}; - self.repl.setContextVars(contextVars); -}; + abstractions.forEach(function(abstraction) { + contextVars[abstraction.contract_name] = abstraction; + }); -Console.prototype.interpret = function(cmd, context, filename, callback) { - var self = this; + self.repl.setContextVars(contextVars); + } - if (this.command.getCommand(cmd.trim(), this.options.noAliases) != null) { - return self.command.run(cmd.trim(), this.options, function(err) { - if (err) { - // Perform error handling ourselves. - if (err instanceof TruffleError) { - console.log(err.message); - } else { - // Bubble up all other unexpected errors. - console.log(err.stack || err.toString()); + interpret(cmd, context, filename, callback) { + var self = this; + + if (this.command.getCommand(cmd.trim(), this.options.noAliases) != null) { + return self.command.run(cmd.trim(), this.options, function(err) { + if (err) { + // Perform error handling ourselves. + if (err instanceof TruffleError) { + console.log(err.message); + } else { + // Bubble up all other unexpected errors. + console.log(err.stack || err.toString()); + } + return callback(); } - return callback(); - } - // Reprovision after each command as it may change contracts. - self.provision(function(err) { - // Don't pass abstractions to the callback if they're there or else - // they'll get printed in the repl. - callback(err); + // Reprovision after each command as it may change contracts. + self.provision(function(err) { + // Don't pass abstractions to the callback if they're there or else + // they'll get printed in the repl. + callback(err); + }); }); - }); - } + } - // Much of the following code is from here, though spruced up: - // https://github.com/nfcampos/await-outside - - /* - - allow whitespace before everything else - - optionally capture `var|let|const = ` - - varname only matches if it starts with a-Z or _ or $ - and if contains only those chars or numbers - - this is overly restrictive but is easier to maintain - - capture `await ` - */ - let includesAwait = /^\s*((?:(?:var|const|let)\s+)?[a-zA-Z_$][0-9a-zA-Z_$]*\s*=\s*)?(\(?\s*await[\s\S]*)/; - - var match = cmd.match(includesAwait); - var source = cmd; - var assignment = null; - - // If our code includes an await, add special processing to ensure it's evaluated properly. - if (match) { - var assign = match[1]; - var expression = match[2]; - - var RESULT = "__await_outside_result"; - - // Wrap the await inside an async function. - // Strange indentation keeps column offset correct in stack traces - source = `(async function() { try { ${ - assign ? `global.${RESULT} =` : "return" - } ( -${expression.trim()} -); } catch(e) { global.ERROR = e; throw e; } }())`; - - assignment = assign - ? `${assign.trim()} global.${RESULT}; void delete global.${RESULT};` - : null; - } + // Much of the following code is from here, though spruced up: + // https://github.com/nfcampos/await-outside + + /* + - allow whitespace before everything else + - optionally capture `var|let|const = ` + - varname only matches if it starts with a-Z or _ or $ + and if contains only those chars or numbers + - this is overly restrictive but is easier to maintain + - capture `await ` + */ + let includesAwait = /^\s*((?:(?:var|const|let)\s+)?[a-zA-Z_$][0-9a-zA-Z_$]*\s*=\s*)?(\(?\s*await[\s\S]*)/; + + var match = cmd.match(includesAwait); + var source = cmd; + var assignment = null; + + // If our code includes an await, add special processing to ensure it's evaluated properly. + if (match) { + var assign = match[1]; + var expression = match[2]; + + var RESULT = "__await_outside_result"; + + // Wrap the await inside an async function. + // Strange indentation keeps column offset correct in stack traces + source = `(async function() { try { ${ + assign ? `global.${RESULT} =` : "return" + } ( + ${expression.trim()} + ); } catch(e) { global.ERROR = e; throw e; } }())`; + + assignment = assign + ? `${assign.trim()} global.${RESULT}; void delete global.${RESULT};` + : null; + } - var runScript = function(s) { - const options = { - displayErrors: true, - breakOnSigint: true, - filename: filename + var runScript = function(s) { + const options = { + displayErrors: true, + breakOnSigint: true, + filename: filename + }; + return s.runInContext(context, options); }; - return s.runInContext(context, options); - }; - - try { - const options = { displayErrors: true, lineOffset: -1 }; - var script = vm.createScript(source, options); - } catch (e) { - // If syntax error, or similar, bail. - return callback(e); - } - // Ensure our script returns a promise whether we're using an - // async function or not. If our script is an async function, - // this will ensure the console waits until that await is finished. - Promise.resolve(runScript(script)) - .then(function(value) { - // If there's an assignment to run, run that. - if (assignment) { - return runScript(vm.createScript(assignment)); - } else { - return value; - } - }) - .then(function(value) { - // All good? Return the value (e.g., eval'd script or assignment) - callback(null, value); - }) - .catch(callback); -}; + try { + const options = { displayErrors: true, lineOffset: -1 }; + var script = vm.createScript(source, options); + } catch (e) { + // If syntax error, or similar, bail. + return callback(e); + } + + // Ensure our script returns a promise whether we're using an + // async function or not. If our script is an async function, + // this will ensure the console waits until that await is finished. + Promise.resolve(runScript(script)) + .then(function(value) { + // If there's an assignment to run, run that. + if (assignment) { + return runScript(vm.createScript(assignment)); + } else { + return value; + } + }) + .then(function(value) { + // All good? Return the value (e.g., eval'd script or assignment) + callback(null, value); + }) + .catch(callback); + } +} module.exports = Console; From 2e4ef9d8e36211880d1a74b768f97bd9e11722db Mon Sep 17 00:00:00 2001 From: eggplantzzz Date: Tue, 11 Jun 2019 16:27:38 +0200 Subject: [PATCH 05/11] Use extends rather than discouraged 'inherits' module --- packages/truffle-core/lib/console.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/truffle-core/lib/console.js b/packages/truffle-core/lib/console.js index 70e71629764..c6593121344 100644 --- a/packages/truffle-core/lib/console.js +++ b/packages/truffle-core/lib/console.js @@ -9,12 +9,10 @@ const TruffleError = require("truffle-error"); const fs = require("fs"); const path = require("path"); const EventEmitter = require("events"); -const { inherits } = require("util"); -inherits(Console, EventEmitter); - -class Console { +class Console extends EventEmitter { constructor(tasks, options) { + super(); EventEmitter.call(this); var self = this; From 91ed588943616b76cec499b0fbde0de13f3f5233 Mon Sep 17 00:00:00 2001 From: eggplantzzz Date: Tue, 11 Jun 2019 17:11:57 +0200 Subject: [PATCH 06/11] Make Console.provision an async method and pull out the callback --- packages/truffle-core/lib/console.js | 130 ++++++++++++++------------- 1 file changed, 67 insertions(+), 63 deletions(-) diff --git a/packages/truffle-core/lib/console.js b/packages/truffle-core/lib/console.js index c6593121344..3401aac42ac 100644 --- a/packages/truffle-core/lib/console.js +++ b/packages/truffle-core/lib/console.js @@ -58,78 +58,79 @@ class Console extends EventEmitter { // passed down to commands. this.options.repl = this.repl; - this.provision(function(err, abstractions) { - if (err) { + this.provision() + .then(abstractions => { + self.repl.start({ + prompt: "truffle(" + self.options.network + ")> ", + context: { + web3: self.web3 + }, + interpreter: self.interpret.bind(self), + done: callback + }); + + self.resetContractsInConsoleContext(abstractions); + }) + .catch(error => { self.options.logger.log( "Unexpected error: Cannot provision contracts while instantiating the console." ); - self.options.logger.log(err.stack || err.message || err); - } - - self.repl.start({ - prompt: "truffle(" + self.options.network + ")> ", - context: { - web3: self.web3 - }, - interpreter: self.interpret.bind(self), - done: callback + self.options.logger.log(error.stack || error.message || error); }); - - self.resetContractsInConsoleContext(abstractions); - }); } - provision(callback) { + async provision() { var self = this; - fs.readdir(this.options.contracts_build_directory, function(err, files) { - if (err) { - // Error reading the build directory? Must mean it doesn't exist or we don't have access to it. - // Couldn't provision the contracts if we wanted. It's possible we're hiding very rare FS - // errors, but that's better than showing the user error messages that will be "build folder - // doesn't exist" 99.9% of the time. - } - - var promises = []; - files = files || []; - - files.forEach(function(file) { - promises.push( - new Promise(function(accept, reject) { - fs.readFile( + let files; + try { + files = fs.readdirSync(this.options.contracts_build_directory); + } catch (error) { + // Error reading the build directory? Must mean it doesn't exist or we don't have access to it. + // Couldn't provision the contracts if we wanted. It's possible we're hiding very rare FS + // errors, but that's better than showing the user error messages that will be "build folder + // doesn't exist" 99.9% of the time. + } + + var promises = []; + files = files || []; + + files.forEach(file => { + promises.push( + new Promise((accept, reject) => { + let body; + try { + body = fs.readFileSync( path.join(self.options.contracts_build_directory, file), - "utf8", - function(err, body) { - if (err) return reject(err); - try { - body = JSON.parse(body); - } catch (e) { - return reject( - new Error("Cannot parse " + file + ": " + e.message) - ); - } - - accept(body); - } + "utf8" ); - }) - ); - }); - - Promise.all(promises) - .then(function(json_blobs) { - var abstractions = json_blobs.map(function(json) { - var abstraction = contract(json); - provision(abstraction, self.options); - return abstraction; - }); + } catch (error) { + reject(error); + } - self.resetContractsInConsoleContext(abstractions); + try { + body = JSON.parse(body); + } catch (error) { + return reject( + new Error("Cannot parse " + file + ": " + error.message) + ); + } - callback(null, abstractions); + accept(body); }) - .catch(callback); + ); }); + + const jsonBlobs = await Promise.all(promises); + const abstractions = jsonBlobs.map(json => { + const abstraction = contract(json); + provision(abstraction, self.options); + return abstraction; + }); + + self.resetContractsInConsoleContext(abstractions); + + return abstractions; } resetContractsInConsoleContext(abstractions) { @@ -163,11 +164,14 @@ class Console extends EventEmitter { } // Reprovision after each command as it may change contracts. - self.provision(function(err) { - // Don't pass abstractions to the callback if they're there or else - // they'll get printed in the repl. - callback(err); - }); + self + .provision() + .then(() => callback()) + .catch(error => { + // Don't pass abstractions to the callback if they're there or else + // they'll get printed in the repl. + callback(error); + }); }); } From 25dcd2df5690b5e986af2a257dd08c36bb7696fa Mon Sep 17 00:00:00 2001 From: eggplantzzz Date: Wed, 12 Jun 2019 17:27:41 +0200 Subject: [PATCH 07/11] Clean up provision method --- packages/truffle-core/lib/console.js | 42 ++++++++++------------------ 1 file changed, 15 insertions(+), 27 deletions(-) diff --git a/packages/truffle-core/lib/console.js b/packages/truffle-core/lib/console.js index 3401aac42ac..38e3f190d49 100644 --- a/packages/truffle-core/lib/console.js +++ b/packages/truffle-core/lib/console.js @@ -6,7 +6,7 @@ const { Web3Shim } = require("truffle-interface-adapter"); const vm = require("vm"); const expect = require("truffle-expect"); const TruffleError = require("truffle-error"); -const fs = require("fs"); +const fse = require("fs-extra"); const path = require("path"); const EventEmitter = require("events"); @@ -80,11 +80,9 @@ class Console extends EventEmitter { } async provision() { - var self = this; - let files; try { - files = fs.readdirSync(this.options.contracts_build_directory); + files = fse.readdirSync(this.options.contracts_build_directory); } catch (error) { // Error reading the build directory? Must mean it doesn't exist or we don't have access to it. // Couldn't provision the contracts if we wanted. It's possible we're hiding very rare FS @@ -92,43 +90,33 @@ class Console extends EventEmitter { // doesn't exist" 99.9% of the time. } - var promises = []; + let promises = []; files = files || []; files.forEach(file => { promises.push( - new Promise((accept, reject) => { - let body; - try { - body = fs.readFileSync( - path.join(self.options.contracts_build_directory, file), - "utf8" - ); - } catch (error) { - reject(error); - } - - try { - body = JSON.parse(body); - } catch (error) { - return reject( - new Error("Cannot parse " + file + ": " + error.message) + fse + .readFile( + path.join(this.options.contracts_build_directory, file), + "utf8" + ) + .then(body => JSON.parse(body)) + .catch(error => { + throw new Error( + `Error parsing or reading ${file}: ${error.message}` ); - } - - accept(body); - }) + }) ); }); const jsonBlobs = await Promise.all(promises); const abstractions = jsonBlobs.map(json => { const abstraction = contract(json); - provision(abstraction, self.options); + provision(abstraction, this.options); return abstraction; }); - self.resetContractsInConsoleContext(abstractions); + this.resetContractsInConsoleContext(abstractions); return abstractions; } From a43e4f4f1a2eeb6df2e344567d434c78b8e4abc3 Mon Sep 17 00:00:00 2001 From: eggplantzzz Date: Wed, 12 Jun 2019 17:31:50 +0200 Subject: [PATCH 08/11] Remove self=this and adjust code --- packages/truffle-core/lib/console.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/truffle-core/lib/console.js b/packages/truffle-core/lib/console.js index 38e3f190d49..e699e537616 100644 --- a/packages/truffle-core/lib/console.js +++ b/packages/truffle-core/lib/console.js @@ -122,17 +122,15 @@ class Console extends EventEmitter { } resetContractsInConsoleContext(abstractions) { - var self = this; - abstractions = abstractions || []; - var contextVars = {}; + const contextVars = {}; - abstractions.forEach(function(abstraction) { + abstractions.forEach(abstraction => { contextVars[abstraction.contract_name] = abstraction; }); - self.repl.setContextVars(contextVars); + this.repl.setContextVars(contextVars); } interpret(cmd, context, filename, callback) { From 43406d14742975a756104bc079f7e2cfe5ad35de Mon Sep 17 00:00:00 2001 From: eggplantzzz Date: Wed, 12 Jun 2019 17:51:32 +0200 Subject: [PATCH 09/11] Use some arrow functions and remove self=this --- packages/truffle-core/lib/console.js | 63 +++++++++++----------------- 1 file changed, 25 insertions(+), 38 deletions(-) diff --git a/packages/truffle-core/lib/console.js b/packages/truffle-core/lib/console.js index e699e537616..89f886052ba 100644 --- a/packages/truffle-core/lib/console.js +++ b/packages/truffle-core/lib/console.js @@ -15,8 +15,6 @@ class Console extends EventEmitter { super(); EventEmitter.call(this); - var self = this; - expect.options(options, [ "working_directory", "contracts_directory", @@ -41,17 +39,11 @@ class Console extends EventEmitter { }); // Bubble the ReplManager's exit event - this.repl.on("exit", function() { - self.emit("exit"); - }); + this.repl.on("exit", () => this.emit("exit")); } start(callback) { - var self = this; - - if (!this.repl) { - this.repl = new Repl(this.options); - } + if (!this.repl) this.repl = new Repl(this.options); // TODO: This should probalby be elsewhere. // It's here to ensure the repl manager instance gets @@ -60,22 +52,22 @@ class Console extends EventEmitter { this.provision() .then(abstractions => { - self.repl.start({ - prompt: "truffle(" + self.options.network + ")> ", + this.repl.start({ + prompt: "truffle(" + this.options.network + ")> ", context: { - web3: self.web3 + web3: this.web3 }, - interpreter: self.interpret.bind(self), + interpreter: this.interpret.bind(this), done: callback }); - self.resetContractsInConsoleContext(abstractions); + this.resetContractsInConsoleContext(abstractions); }) .catch(error => { - self.options.logger.log( + this.options.logger.log( "Unexpected error: Cannot provision contracts while instantiating the console." ); - self.options.logger.log(error.stack || error.message || error); + this.options.logger.log(error.stack || error.message || error); }); } @@ -134,24 +126,21 @@ class Console extends EventEmitter { } interpret(cmd, context, filename, callback) { - var self = this; - if (this.command.getCommand(cmd.trim(), this.options.noAliases) != null) { - return self.command.run(cmd.trim(), this.options, function(err) { - if (err) { + return this.command.run(cmd.trim(), this.options, error => { + if (error) { // Perform error handling ourselves. - if (err instanceof TruffleError) { - console.log(err.message); + if (error instanceof TruffleError) { + console.log(error.message); } else { // Bubble up all other unexpected errors. - console.log(err.stack || err.toString()); + console.log(error.stack || error.toString()); } return callback(); } // Reprovision after each command as it may change contracts. - self - .provision() + this.provision() .then(() => callback()) .catch(error => { // Don't pass abstractions to the callback if they're there or else @@ -198,36 +187,34 @@ class Console extends EventEmitter { : null; } - var runScript = function(s) { + const runScript = script => { const options = { displayErrors: true, breakOnSigint: true, filename: filename }; - return s.runInContext(context, options); + return script.runInContext(context, options); }; + let script; try { const options = { displayErrors: true, lineOffset: -1 }; - var script = vm.createScript(source, options); - } catch (e) { + script = vm.createScript(source, options); + } catch (error) { // If syntax error, or similar, bail. - return callback(e); + return callback(error); } // Ensure our script returns a promise whether we're using an // async function or not. If our script is an async function, // this will ensure the console waits until that await is finished. Promise.resolve(runScript(script)) - .then(function(value) { + .then(value => { // If there's an assignment to run, run that. - if (assignment) { - return runScript(vm.createScript(assignment)); - } else { - return value; - } + if (assignment) return runScript(vm.createScript(assignment)); + return value; }) - .then(function(value) { + .then(value => { // All good? Return the value (e.g., eval'd script or assignment) callback(null, value); }) From 0087ffb74f0ebd970a8f5727e7d8ec51d252ea0c Mon Sep 17 00:00:00 2001 From: eggplantzzz Date: Mon, 24 Jun 2019 20:38:27 -0400 Subject: [PATCH 10/11] Update some vars --- packages/truffle-core/lib/console.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/truffle-core/lib/console.js b/packages/truffle-core/lib/console.js index 89f886052ba..16023e2de12 100644 --- a/packages/truffle-core/lib/console.js +++ b/packages/truffle-core/lib/console.js @@ -163,16 +163,16 @@ class Console extends EventEmitter { */ let includesAwait = /^\s*((?:(?:var|const|let)\s+)?[a-zA-Z_$][0-9a-zA-Z_$]*\s*=\s*)?(\(?\s*await[\s\S]*)/; - var match = cmd.match(includesAwait); - var source = cmd; - var assignment = null; + const match = cmd.match(includesAwait); + let source = cmd; + let assignment = null; // If our code includes an await, add special processing to ensure it's evaluated properly. if (match) { - var assign = match[1]; - var expression = match[2]; + let assign = match[1]; + const expression = match[2]; - var RESULT = "__await_outside_result"; + const RESULT = "__await_outside_result"; // Wrap the await inside an async function. // Strange indentation keeps column offset correct in stack traces From a3c1e0f8d6201b48924d9d53841329ca418cff01 Mon Sep 17 00:00:00 2001 From: eggplantzzz Date: Tue, 25 Jun 2019 13:37:47 -0400 Subject: [PATCH 11/11] Use synchronous version of readFile --- packages/truffle-core/lib/console.js | 77 +++++++++++++--------------- 1 file changed, 36 insertions(+), 41 deletions(-) diff --git a/packages/truffle-core/lib/console.js b/packages/truffle-core/lib/console.js index 16023e2de12..65f4bdd3f53 100644 --- a/packages/truffle-core/lib/console.js +++ b/packages/truffle-core/lib/console.js @@ -50,28 +50,27 @@ class Console extends EventEmitter { // passed down to commands. this.options.repl = this.repl; - this.provision() - .then(abstractions => { - this.repl.start({ - prompt: "truffle(" + this.options.network + ")> ", - context: { - web3: this.web3 - }, - interpreter: this.interpret.bind(this), - done: callback - }); - - this.resetContractsInConsoleContext(abstractions); - }) - .catch(error => { - this.options.logger.log( - "Unexpected error: Cannot provision contracts while instantiating the console." - ); - this.options.logger.log(error.stack || error.message || error); + try { + const abstractions = this.provision(); + this.repl.start({ + prompt: "truffle(" + this.options.network + ")> ", + context: { + web3: this.web3 + }, + interpreter: this.interpret.bind(this), + done: callback }); + + this.resetContractsInConsoleContext(abstractions); + } catch (error) { + this.options.logger.log( + "Unexpected error: Cannot provision contracts while instantiating the console." + ); + this.options.logger.log(error.stack || error.message || error); + } } - async provision() { + provision() { let files; try { files = fse.readdirSync(this.options.contracts_build_directory); @@ -82,26 +81,21 @@ class Console extends EventEmitter { // doesn't exist" 99.9% of the time. } - let promises = []; + let jsonBlobs = []; files = files || []; files.forEach(file => { - promises.push( - fse - .readFile( - path.join(this.options.contracts_build_directory, file), - "utf8" - ) - .then(body => JSON.parse(body)) - .catch(error => { - throw new Error( - `Error parsing or reading ${file}: ${error.message}` - ); - }) - ); + try { + const body = fse.readFileSync( + path.join(this.options.contracts_build_directory, file), + "utf8" + ); + jsonBlobs.push(JSON.parse(body)); + } catch (error) { + throw new Error(`Error parsing or reading ${file}: ${error.message}`); + } }); - const jsonBlobs = await Promise.all(promises); const abstractions = jsonBlobs.map(json => { const abstraction = contract(json); provision(abstraction, this.options); @@ -140,13 +134,14 @@ class Console extends EventEmitter { } // Reprovision after each command as it may change contracts. - this.provision() - .then(() => callback()) - .catch(error => { - // Don't pass abstractions to the callback if they're there or else - // they'll get printed in the repl. - callback(error); - }); + try { + this.provision(); + callback(); + } catch (error) { + // Don't pass abstractions to the callback if they're there or else + // they'll get printed in the repl. + callback(error); + } }); }