Merge pull request #405 from embark-framework/i18n

I18n
This commit is contained in:
Iuri Matias 2018-05-10 16:04:30 -04:00 committed by GitHub
commit ab5dc059e7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
42 changed files with 877 additions and 351 deletions

View File

@ -9,6 +9,9 @@
"sourceType": "module", "sourceType": "module",
"ecmaVersion": 2017 "ecmaVersion": 2017
}, },
"globals": {
"__": true
},
"rules": { "rules": {
"accessor-pairs": "error", "accessor-pairs": "error",
"array-bracket-newline": "error", "array-bracket-newline": "error",

1
.gitignore vendored
View File

@ -24,3 +24,4 @@ test_apps/contracts_app/chains.json
.embark/ .embark/
NOTES NOTES
npm-debug.log npm-debug.log
.tern-port

View File

@ -2,6 +2,7 @@ const program = require('commander');
const promptly = require('promptly'); const promptly = require('promptly');
const utils = require('./utils/utils.js'); const utils = require('./utils/utils.js');
const Embark = require('../lib/index'); const Embark = require('../lib/index');
const i18n = require('./i18n/i18n.js');
let embark = new Embark; let embark = new Embark;
class Cmd { class Cmd {
@ -37,22 +38,24 @@ class Cmd {
try { try {
if (value.match(/^[a-zA-Z\s-]+$/)) return value; if (value.match(/^[a-zA-Z\s-]+$/)) return value;
} catch (e) { } catch (e) {
throw new Error('Name must be only letters, spaces, or dashes'); throw new Error(__('Name must be only letters, spaces, or dashes'));
} }
}; };
program program
.command('new [name]') .command('new [name]')
.description('new application') .description(__('New Application'))
.option('--simple', 'create a barebones project meant only for contract development') .option('--simple', __('create a barebones project meant only for contract development'))
.option('--locale [locale]', __('language to use (default: en)'))
.action(function (name, options) { .action(function (name, options) {
i18n.setOrDetectLocale(options.locale);
if (name === undefined) { if (name === undefined) {
return promptly.prompt("Name your app (default is embarkDApp):", { return promptly.prompt(__("Name your app (default is %s):", 'embarkDapp'), {
default: "embarkDApp", default: "embarkDApp",
validator: validateName validator: validateName
}, function (err, inputvalue) { }, function (err, inputvalue) {
if (err) { if (err) {
console.error('Invalid name:', err.message); console.error(__('Invalid name') + ':', err.message);
// Manually call retry // Manually call retry
// The passed error has a retry method to easily prompt again. // The passed error has a retry method to easily prompt again.
err.retry(); err.retry();
@ -78,8 +81,10 @@ class Cmd {
demo() { demo() {
program program
.command('demo') .command('demo')
.description('create a working dapp with a SimpleStorage contract') .option('--locale [locale]', __('language to use (default: en)'))
.action(function () { .description(__('create a working dapp with a SimpleStorage contract'))
.action(function (options) {
i18n.setOrDetectLocale(options.locale);
embark.generateTemplate('demo', './', 'embark_demo'); embark.generateTemplate('demo', './', 'embark_demo');
}); });
} }
@ -87,10 +92,12 @@ class Cmd {
build() { build() {
program program
.command('build [environment]') .command('build [environment]')
.option('--logfile [logfile]', 'filename to output logs (default: none)') .option('--logfile [logfile]', __('filename to output logs (default: none)'))
.option('--loglevel [loglevel]', 'level of logging to display ["error", "warn", "info", "debug", "trace"]', /^(error|warn|info|debug|trace)$/i, 'debug') .option('--loglevel [loglevel]', __('level of logging to display') + ' ["error", "warn", "info", "debug", "trace"]', /^(error|warn|info|debug|trace)$/i, 'debug')
.description('deploy and build dapp at dist/ (default: development)') .option('--locale [locale]', __('language to use (default: en)'))
.description(__('deploy and build dapp at ') + 'dist/ (default: development)')
.action(function (env, _options) { .action(function (env, _options) {
i18n.setOrDetectLocale(_options.locale);
_options.env = env || 'development'; _options.env = env || 'development';
_options.logFile = _options.logfile; // fix casing _options.logFile = _options.logfile; // fix casing
_options.logLevel = _options.loglevel; // fix casing _options.logLevel = _options.loglevel; // fix casing
@ -101,15 +108,17 @@ class Cmd {
run() { run() {
program program
.command('run [environment]') .command('run [environment]')
.option('-p, --port [port]', 'port to run the dev webserver (default: 8000)') .option('-p, --port [port]', __('port to run the dev webserver (default: %s)', '8000'))
.option('-b, --host [host]', 'host to run the dev webserver (default: localhost)') .option('-b, --host [host]', __('host to run the dev webserver (default: %s)', 'localhost'))
.option('--noserver', 'disable the development webserver') .option('--noserver', __('disable the development webserver'))
.option('--nodashboard', 'simple mode, disables the dashboard') .option('--nodashboard', __('simple mode, disables the dashboard'))
.option('--no-color', 'no colors in case it\'s needed for compatbility purposes') .option('--no-color', __('no colors in case it\'s needed for compatbility purposes'))
.option('--logfile [logfile]', 'filename to output logs (default: none)') .option('--logfile [logfile]', __('filename to output logs (default: %s)', 'none'))
.option('--loglevel [loglevel]', 'level of logging to display ["error", "warn", "info", "debug", "trace"]', /^(error|warn|info|debug|trace)$/i, 'debug') .option('--loglevel [loglevel]', __('level of logging to display') + ' ["error", "warn", "info", "debug", "trace"]', /^(error|warn|info|debug|trace)$/i, 'debug')
.description('run dapp (default: development)') .option('--locale [locale]', __('language to use (default: en)'))
.description(__('run dapp (default: %s)', 'development'))
.action(function (env, options) { .action(function (env, options) {
i18n.setOrDetectLocale(options.locale);
embark.run({ embark.run({
env: env || 'development', env: env || 'development',
serverPort: options.port, serverPort: options.port,
@ -125,9 +134,11 @@ class Cmd {
blockchain() { blockchain() {
program program
.command('blockchain [environment]') .command('blockchain [environment]')
.option('-c, --client [client]', 'Use a specific ethereum client or simulator (supported: geth, testrpc)') .option('-c, --client [client]', __('Use a specific ethereum client or simulator (supported: %s)', 'geth, testrpc'))
.description('run blockchain server (default: development)') .option('--locale [locale]', __('language to use (default: en)'))
.description(__('run blockchain server (default: %s)', 'development'))
.action(function (env, options) { .action(function (env, options) {
i18n.setOrDetectLocale(options.locale);
embark.initConfig(env || 'development', { embark.initConfig(env || 'development', {
embarkConfig: 'embark.json', embarkConfig: 'embark.json',
interceptLogs: false interceptLogs: false
@ -139,15 +150,17 @@ class Cmd {
simulator() { simulator() {
program program
.command('simulator [environment]') .command('simulator [environment]')
.description('run a fast ethereum rpc simulator') .description(__('run a fast ethereum rpc simulator'))
.option('--testrpc', 'use testrpc as the rpc simulator [default]') .option('--testrpc', __('use testrpc as the rpc simulator [%s]', 'default'))
.option('-p, --port [port]', 'port to run the rpc simulator (default: 8545)') .option('-p, --port [port]', __('port to run the rpc simulator (default: %s)', '8545'))
.option('-h, --host [host]', 'host to run the rpc simulator (default: localhost)') .option('-h, --host [host]', __('host to run the rpc simulator (default: %s)', 'localhost'))
.option('-a, --accounts [numAccounts]', 'number of accounts (default: 10)') .option('-a, --accounts [numAccounts]', __('number of accounts (default: %s)', '10'))
.option('-e, --defaultBalanceEther [balance]', 'Amount of ether to assign each test account (default: 100)') .option('-e, --defaultBalanceEther [balance]', __('Amount of ether to assign each test account (default: %s)', '100'))
.option('-l, --gasLimit [gasLimit]', 'custom gas limit (default: 8000000)') .option('-l, --gasLimit [gasLimit]', __('custom gas limit (default: %s)', '8000000'))
.option('--locale [locale]', __('language to use (default: en)'))
.action(function (env, options) { .action(function (env, options) {
i18n.setOrDetectLocale(options.locale);
embark.initConfig(env || 'development', { embark.initConfig(env || 'development', {
embarkConfig: 'embark.json', embarkConfig: 'embark.json',
interceptLogs: false interceptLogs: false
@ -165,8 +178,10 @@ class Cmd {
test() { test() {
program program
.command('test [file]') .command('test [file]')
.description('run tests') .option('--locale [locale]', __('language to use (default: en)'))
.action(function (file) { .description(__('run tests'))
.action(function (file, options) {
i18n.setOrDetectLocale(options.locale);
embark.initConfig('development', { embark.initConfig('development', {
embarkConfig: 'embark.json', interceptLogs: false embarkConfig: 'embark.json', interceptLogs: false
}); });
@ -177,10 +192,12 @@ class Cmd {
upload() { upload() {
program program
.command('upload <platform> [environment]') .command('upload <platform> [environment]')
.option('--logfile [logfile]', 'filename to output logs (default: none)') .option('--logfile [logfile]', __('filename to output logs (default: %s)', 'none'))
.option('--loglevel [loglevel]', 'level of logging to display ["error", "warn", "info", "debug", "trace"]', /^(error|warn|info|debug|trace)$/i, 'debug') .option('--loglevel [loglevel]', __('level of logging to display') + ' ["error", "warn", "info", "debug", "trace"]', /^(error|warn|info|debug|trace)$/i, 'debug')
.description('Upload your dapp to a decentralized storage (e.g embark upload ipfs).') .option('--locale [locale]', __('language to use (default: en)'))
.description(__('Upload your dapp to a decentralized storage') + ' (e.g embark upload ipfs).')
.action(function (platform, env, _options) { .action(function (platform, env, _options) {
i18n.setOrDetectLocale(_options.locale);
_options.env = env || 'development'; _options.env = env || 'development';
_options.logFile = _options.logfile; // fix casing _options.logFile = _options.logfile; // fix casing
_options.logLevel = _options.loglevel; // fix casing _options.logLevel = _options.loglevel; // fix casing
@ -191,11 +208,13 @@ class Cmd {
graph() { graph() {
program program
.command('graph [environment]') .command('graph [environment]')
.option('--skip-undeployed', 'Graph will not include undeployed contracts') .option('--skip-undeployed', __('Graph will not include undeployed contracts'))
.option('--skip-functions', 'Graph will not include functions') .option('--skip-functions', __('Graph will not include functions'))
.option('--skip-events', 'Graph will not include events') .option('--skip-events', __('Graph will not include events'))
.description('generates documentation based on the smart contracts configured') .option('--locale [locale]', __('language to use (default: en)'))
.description(__('generates documentation based on the smart contracts configured'))
.action(function (env, options) { .action(function (env, options) {
i18n.setOrDetectLocale(options.locale);
embark.graph({ embark.graph({
env: env || 'development', env: env || 'development',
logFile: options.logfile, logFile: options.logfile,
@ -209,8 +228,10 @@ class Cmd {
reset() { reset() {
program program
.command('reset') .command('reset')
.description('resets embarks state on this dapp including clearing cache') .option('--locale [locale]', __('language to use (default: en)'))
.action(function () { .description(__('resets embarks state on this dapp including clearing cache'))
.action(function (options) {
i18n.setOrDetectLocale(options.locale);
embark.initConfig('development', { embark.initConfig('development', {
embarkConfig: 'embark.json', interceptLogs: false embarkConfig: 'embark.json', interceptLogs: false
}); });
@ -221,7 +242,7 @@ class Cmd {
versionCmd() { versionCmd() {
program program
.command('version') .command('version')
.description('output the version number') .description(__('output the version number'))
.action(function () { .action(function () {
console.log(embark.version); console.log(embark.version);
process.exit(0); process.exit(0);
@ -231,18 +252,17 @@ class Cmd {
otherCommands() { otherCommands() {
program program
.action(function (cmd) { .action(function (cmd) {
console.log('unknown command "%s"'.red, cmd); console.log((__('unknown command') + ' "%s"').red, cmd);
let dictionary = ['new', 'demo', 'build', 'run', 'blockchain', 'simulator', 'test', 'upload', 'version']; let dictionary = ['new', 'demo', 'build', 'run', 'blockchain', 'simulator', 'test', 'upload', 'version'];
let suggestion = utils.proposeAlternative(cmd, dictionary); let suggestion = utils.proposeAlternative(cmd, dictionary);
if (suggestion) { if (suggestion) {
console.log('did you mean "%s"?'.green, suggestion); console.log((__('did you mean') + ' "%s"?').green, suggestion);
} }
console.log("type embark --help to see the available commands"); console.log("type embark --help to see the available commands");
process.exit(0); process.exit(0);
}); });
} }
} }
module.exports = Cmd; module.exports = Cmd;

View File

@ -11,7 +11,7 @@ var Blockchain = function(options) {
this.client = options.client; this.client = options.client;
if ((this.blockchainConfig === {} || JSON.stringify(this.blockchainConfig) === '{"enabled":true}') && this.env !== 'development') { if ((this.blockchainConfig === {} || JSON.stringify(this.blockchainConfig) === '{"enabled":true}') && this.env !== 'development') {
console.log("===> warning: running default config on a non-development environment"); console.log("===> " + __("warning: running default config on a non-development environment"));
} }
this.config = { this.config = {
@ -62,12 +62,12 @@ var Blockchain = function(options) {
}; };
Blockchain.prototype.runCommand = function(cmd, options) { Blockchain.prototype.runCommand = function(cmd, options) {
console.log(("running: " + cmd.underline).green); console.log(__("running: %s", cmd.underline).green);
return shelljs.exec(cmd, options, (err, stdout, _stderr) => { return shelljs.exec(cmd, options, (err, stdout, _stderr) => {
if (err && this.env === 'development' && stdout.indexOf('Failed to unlock developer account') > 0) { if (err && this.env === 'development' && stdout.indexOf('Failed to unlock developer account') > 0) {
console.warn('\nDevelopment blockchain has changed to use the --dev option.'.yellow); console.warn('\n' + __('Development blockchain has changed to use the --dev option.').yellow);
console.warn('You can reset your workspace to fix the problem with'.yellow + ' embark reset'.cyan); console.warn(__('You can reset your workspace to fix the problem with').yellow + ' embark reset'.cyan);
console.warn('Otherwise, you can change your data directory in blockchain.json (datadir)'.yellow); console.warn(__('Otherwise, you can change your data directory in blockchain.json (datadir)').yellow);
} }
}); });
}; };
@ -76,11 +76,11 @@ Blockchain.prototype.run = function() {
var self = this; var self = this;
console.log("===============================================================================".magenta); console.log("===============================================================================".magenta);
console.log("===============================================================================".magenta); console.log("===============================================================================".magenta);
console.log(("Embark Blockchain Using: " + this.client.name.underline).magenta); console.log(__("Embark Blockchain Using: %s", this.client.name.underline).magenta);
console.log("===============================================================================".magenta); console.log("===============================================================================".magenta);
console.log("===============================================================================".magenta); console.log("===============================================================================".magenta);
if (!this.isClientInstalled()) { if (!this.isClientInstalled()) {
console.log(("could not find " + this.config.geth_bin + " command; is " + this.client.name + " installed or in the PATH?").green); console.log(__("could not find {{geth_bin}} command; is {{client_name}} installed or in the PATH?", {geth_bin: this.config.geth_bin, client_name: this.client.name}).green);
return; return;
} }
let address = ''; let address = '';
@ -115,16 +115,16 @@ Blockchain.prototype.initChainAndGetAddress = function() {
// check if an account already exists, create one if not, return address // check if an account already exists, create one if not, return address
result = this.runCommand(this.client.listAccountsCommand()); result = this.runCommand(this.client.listAccountsCommand());
if (result.output === undefined || result.output.match(/{(\w+)}/) === null || result.output.indexOf("Fatal") >= 0) { if (result.output === undefined || result.output.match(/{(\w+)}/) === null || result.output.indexOf("Fatal") >= 0) {
console.log("no accounts found".green); console.log(__("no accounts found").green);
if (this.config.genesisBlock) { if (this.config.genesisBlock) {
console.log("initializing genesis block".green); console.log(__("initializing genesis block").green);
result = this.runCommand(this.client.initGenesisCommmand()); result = this.runCommand(this.client.initGenesisCommmand());
} }
result = this.runCommand(this.client.newAccountCommand()); result = this.runCommand(this.client.newAccountCommand());
address = result.output.match(/{(\w+)}/)[1]; address = result.output.match(/{(\w+)}/)[1];
} else { } else {
console.log("already initialized".green); console.log(__("already initialized").green);
address = result.output.match(/{(\w+)}/)[1]; address = result.output.match(/{(\w+)}/)[1];
} }

View File

@ -80,14 +80,14 @@ class GethCommands {
if (config.rpcCorsDomain) { if (config.rpcCorsDomain) {
if (config.rpcCorsDomain === '*') { if (config.rpcCorsDomain === '*') {
console.log('=================================='); console.log('==================================');
console.log('rpcCorsDomain set to *'); console.log(__('rpcCorsDomain set to *'));
console.log('make sure you know what you are doing'); console.log(__('make sure you know what you are doing'));
console.log('=================================='); console.log('==================================');
} }
cmd += "--rpccorsdomain=\"" + config.rpcCorsDomain + "\" "; cmd += "--rpccorsdomain=\"" + config.rpcCorsDomain + "\" ";
} else { } else {
console.log('=================================='); console.log('==================================');
console.log('warning: cors is not set'); console.log(__('warning: cors is not set'));
console.log('=================================='); console.log('==================================');
} }
@ -104,14 +104,14 @@ class GethCommands {
if (config.wsOrigins) { if (config.wsOrigins) {
if (config.wsOrigins === '*') { if (config.wsOrigins === '*') {
console.log('=================================='); console.log('==================================');
console.log('wsOrigins set to *'); console.log(__('wsOrigins set to *'));
console.log('make sure you know what you are doing'); console.log(__('make sure you know what you are doing'));
console.log('=================================='); console.log('==================================');
} }
cmd += "--wsorigins \"" + config.wsOrigins + "\" "; cmd += "--wsorigins \"" + config.wsOrigins + "\" ";
} else { } else {
console.log('=================================='); console.log('==================================');
console.log('warning: wsOrigins is not set'); console.log(__('warning: wsOrigins is not set'));
console.log('=================================='); console.log('==================================');
} }
} }

View File

@ -4,5 +4,5 @@ module.exports = function() {
fs.removeSync('./chains.json'); fs.removeSync('./chains.json');
fs.removeSync('.embark/'); fs.removeSync('.embark/');
fs.removeSync('dist/'); fs.removeSync('dist/');
console.log("reset done!".green); console.log(__("reset done!").green);
}; };

View File

@ -12,8 +12,8 @@ class Simulator {
const testrpc = shelljs.which('testrpc'); const testrpc = shelljs.which('testrpc');
const ganache = shelljs.which('ganache-cli'); const ganache = shelljs.which('ganache-cli');
if (!testrpc && !ganache) { if (!testrpc && !ganache) {
this.logger.warn('Ganache CLI (TestRPC) is not installed on your machine'); this.logger.warn(__('%s is not installed on your machine', 'Ganache CLI (TestRPC)'));
this.logger.info('You can install it by running: npm -g install ganache-cli'); this.logger.info(__('You can install it by running: %s', 'npm -g install ganache-cli'));
process.exit(); process.exit();
} }

View File

@ -8,7 +8,7 @@ class TemplateGenerator {
generate(destinationFolder, name) { generate(destinationFolder, name) {
let templatePath = fs.embarkPath(utils.joinPath('templates', this.templateName)); let templatePath = fs.embarkPath(utils.joinPath('templates', this.templateName));
console.log('Initializing Embark Template....'.green); console.log(__('Initializing Embark Template....').green);
let fspath = utils.joinPath(destinationFolder, name); let fspath = utils.joinPath(destinationFolder, name);
fs.copySync(templatePath, fspath); fs.copySync(templatePath, fspath);
@ -16,21 +16,21 @@ class TemplateGenerator {
utils.sed('package.json', '%APP_NAME%', name); utils.sed('package.json', '%APP_NAME%', name);
if (name === 'embark_demo') { if (name === 'embark_demo') {
console.log('Installing packages...'.green); console.log(__('Installing packages...').green);
utils.runCmd('npm install'); utils.runCmd('npm install');
} }
console.log('Init complete'.green); console.log(__('Init complete').green);
console.log('\nApp ready at '.green + fspath); console.log('\n' + __('App ready at ').green + fspath);
if (name === 'embark_demo') { if (name === 'embark_demo') {
console.log('-------------------'.yellow); console.log('-------------------'.yellow);
console.log('Next steps:'.green); console.log(__('Next steps:').green);
console.log(('-> ' + ('cd ' + fspath).bold.cyan).green); console.log(('-> ' + ('cd ' + fspath).bold.cyan).green);
console.log('-> '.green + 'embark blockchain'.bold.cyan + ' or '.green + 'embark simulator'.bold.cyan); console.log('-> '.green + 'embark blockchain'.bold.cyan + ' or '.green + 'embark simulator'.bold.cyan);
console.log('open another console in the same directory and run'.green); console.log(__('open another console in the same directory and run').green);
console.log('-> '.green + 'embark run'.bold.cyan); console.log('-> '.green + 'embark run'.bold.cyan);
console.log('For more info go to http://embark.status.im'.green); console.log(__('For more info go to http://embark.status.im').green);
} }
} }
} }

View File

@ -40,7 +40,7 @@ class Compiler {
function (err) { function (err) {
contractFiles.forEach(file => { contractFiles.forEach(file => {
if (!file.compiled) { if (!file.compiled) {
self.logger.warn(`${file.filename} doesn't have a compatible contract compiler. Maybe a plugin exists for it.`); self.logger.warn(__("%s doesn't have a compatible contract compiler. Maybe a plugin exists for it.", file.filename));
} }
}); });

View File

@ -86,7 +86,7 @@ class ContractsManager {
} }
if (contract.code === "") { if (contract.code === "") {
self.logger.info("assuming " + className + " to be an interface"); self.logger.info(__("assuming %s to be an interface", className));
contract.deploy = false; contract.deploy = false;
} }
} }
@ -108,15 +108,15 @@ class ContractsManager {
parentContract = self.contracts[parentContractName]; parentContract = self.contracts[parentContractName];
if (parentContract === className) { if (parentContract === className) {
self.logger.error(className + ": instanceOf is set to itself"); self.logger.error(__("%s : instanceOf is set to itself", className));
continue; continue;
} }
if (parentContract === undefined) { if (parentContract === undefined) {
self.logger.error(className + ": couldn't find instanceOf contract " + parentContractName); self.logger.error(__("{{className}}: couldn't find instanceOf contract {{parentContractName}}", {className: className, parentContractName: parentContractName}));
let suggestion = utils.proposeAlternative(parentContractName, dictionary, [className, parentContractName]); let suggestion = utils.proposeAlternative(parentContractName, dictionary, [className, parentContractName]);
if (suggestion) { if (suggestion) {
self.logger.warn('did you mean "' + suggestion + '"?'); self.logger.warn(__('did you mean "%s"?', suggestion));
} }
continue; continue;
} }
@ -126,7 +126,7 @@ class ContractsManager {
} }
if (contract.code !== undefined) { if (contract.code !== undefined) {
self.logger.error(className + " has code associated to it but it's configured as an instanceOf " + parentContractName); self.logger.error(__("{{className}} has code associated to it but it's configured as an instanceOf {{parentContractName}}", {className: className, parentContractName: parentContractName}));
} }
contract.code = parentContract.code; contract.code = parentContract.code;
@ -149,10 +149,10 @@ class ContractsManager {
contract = self.contracts[className]; contract = self.contracts[className];
if (contract.code === undefined) { if (contract.code === undefined) {
self.logger.error(className + " has no code associated"); self.logger.error(__("%s has no code associated", className));
let suggestion = utils.proposeAlternative(className, dictionary, [className]); let suggestion = utils.proposeAlternative(className, dictionary, [className]);
if (suggestion) { if (suggestion) {
self.logger.warn('did you mean "' + suggestion + '"?'); self.logger.warn(__('did you mean "%s"?', suggestion));
} }
delete self.contracts[className]; delete self.contracts[className];
} }
@ -216,7 +216,7 @@ class ContractsManager {
} }
], function (err, _result) { ], function (err, _result) {
if (err) { if (err) {
self.logger.error("Error Compiling/Building contracts: " + err); self.logger.error(__("Error Compiling/Building contracts: ") + err);
} }
self.logger.trace("finished".underline); self.logger.trace("finished".underline);
done(err, self); done(err, self);
@ -242,9 +242,9 @@ class ContractsManager {
try { try {
orderedDependencies = toposort(converted_dependencies.filter((x) => x[0] != x[1])).reverse(); orderedDependencies = toposort(converted_dependencies.filter((x) => x[0] != x[1])).reverse();
} catch(e) { } catch(e) {
this.logger.error(("Error: " + e.message).red); this.logger.error((__("Error: ") + e.message).red);
this.logger.error("there are two or more contracts that depend on each other in a cyclic manner".bold.red); this.logger.error(__("there are two or more contracts that depend on each other in a cyclic manner").bold.red);
this.logger.error("Embark couldn't determine which one to deploy first".red); this.logger.error(__("Embark couldn't determine which one to deploy first").red);
throw new Error("CyclicDependencyError"); throw new Error("CyclicDependencyError");
//process.exit(0); //process.exit(0);
} }
@ -279,7 +279,7 @@ class ContractsManager {
if (contract.deploy === false) { if (contract.deploy === false) {
contractData = [ contractData = [
className.green, className.green,
'Interface or set to not deploy'.green, __('Interface or set to not deploy').green,
"\t\tn/a".green "\t\tn/a".green
]; ];
} else if (contract.error) { } else if (contract.error) {
@ -292,7 +292,7 @@ class ContractsManager {
contractData = [ contractData = [
className.green, className.green,
(contract.deployedAddress || '...').green, (contract.deployedAddress || '...').green,
((contract.deployedAddress !== undefined) ? "\t\tDeployed".green : "\t\tPending".magenta) ((contract.deployedAddress !== undefined) ? ("\t\t" + __("Deployed")).green : ("\t\t" + __("Pending")).magenta)
]; ];
} }

View File

@ -40,7 +40,7 @@ class Deploy {
for (let input of abi.inputs) { for (let input of abi.inputs) {
let inputValue = suppliedArgs[input.name]; let inputValue = suppliedArgs[input.name];
if (!inputValue) { if (!inputValue) {
this.logger.error(input.name + " has not been defined for " + contract.className + " constructor"); this.logger.error(__("{{inputName}} has not been defined for {{className}} constructor", {inputName: input.name, className: contract.className}));
} }
args.push(inputValue || ""); args.push(inputValue || "");
} }
@ -88,14 +88,14 @@ class Deploy {
try { try {
this.web3.utils.toChecksumAddress(contract.address); this.web3.utils.toChecksumAddress(contract.address);
} catch(e) { } catch(e) {
self.logger.error("error deploying " + contract.className); self.logger.error(__("error deploying %s", contract.className));
self.logger.error(e.message); self.logger.error(e.message);
contract.error = e.message; contract.error = e.message;
self.events.emit('contractsState', self.contractsManager.contractsState()); self.events.emit('contractsState', self.contractsManager.contractsState());
return callback(e.message); return callback(e.message);
} }
contract.deployedAddress = contract.address; contract.deployedAddress = contract.address;
self.logger.info(contract.className.bold.cyan + " already deployed at ".green + contract.address.bold.cyan); self.logger.info(contract.className.bold.cyan + __(" already deployed at ").green + contract.address.bold.cyan);
if (this.deployTracker) { if (this.deployTracker) {
self.deployTracker.trackContract(contract.className, contract.realRuntimeBytecode, realArgs, contract.address); self.deployTracker.trackContract(contract.className, contract.realRuntimeBytecode, realArgs, contract.address);
self.deployTracker.save(); self.deployTracker.save();
@ -124,7 +124,7 @@ class Deploy {
contractAlreadyDeployed(contract, trackedContract, callback) { contractAlreadyDeployed(contract, trackedContract, callback) {
const self = this; const self = this;
self.logger.info(contract.className.bold.cyan + " already deployed at ".green + trackedContract.address.bold.cyan); self.logger.info(contract.className.bold.cyan + __(" already deployed at ").green + trackedContract.address.bold.cyan);
contract.deployedAddress = trackedContract.address; contract.deployedAddress = trackedContract.address;
self.events.emit('contractsState', self.contractsManager.contractsState()); self.events.emit('contractsState', self.contractsManager.contractsState());
@ -154,7 +154,7 @@ class Deploy {
RunCode.doEval(contractCode, self.web3); RunCode.doEval(contractCode, self.web3);
if (contract.onDeploy !== undefined) { if (contract.onDeploy !== undefined) {
self.logger.info('executing onDeploy commands'); self.logger.info(__('executing onDeploy commands'));
let contractCode = codeGenerator.generateContractCode(contract, self.gasLimit); let contractCode = codeGenerator.generateContractCode(contract, self.gasLimit);
RunCode.doEval(contractCode, self.web3); RunCode.doEval(contractCode, self.web3);
@ -166,23 +166,23 @@ class Deploy {
let referedContractName = match.slice(1); let referedContractName = match.slice(1);
let referedContract = self.contractsManager.getContract(referedContractName); let referedContract = self.contractsManager.getContract(referedContractName);
if (!referedContract) { if (!referedContract) {
self.logger.error('error executing onDeploy for ' + contract.className); self.logger.error(__('error executing onDeploy for ') + contract.className.cyan);
self.logger.error(referedContractName + ' does not exist'); self.logger.error(referedContractName + __(' does not exist'));
self.logger.error("error running onDeploy: " + cmd); self.logger.error(__("error running onDeploy: ") + cmd);
withErrors = true; withErrors = true;
return; return;
} }
if (referedContract && referedContract.deploy === false) { if (referedContract && referedContract.deploy === false) {
self.logger.error('error executing onDeploy for ' + contract.className); self.logger.error(__('error executing onDeploy for ') + contract.className.cyan);
self.logger.error(referedContractName + " exists but has been set to not deploy"); self.logger.error(referedContractName + __(" exists but has been set to not deploy"));
self.logger.error("error running onDeploy: " + cmd); self.logger.error(__("error running onDeploy: ") + cmd);
withErrors = true; withErrors = true;
return; return;
} }
if (referedContract && !referedContract.deployedAddress) { if (referedContract && !referedContract.deployedAddress) {
self.logger.error('error executing onDeploy for ' + contract.className); self.logger.error(__('error executing onDeploy for ') + contract.className.cyan);
self.logger.error("couldn't find a valid address for " + referedContractName + ". has it been deployed?"); self.logger.error(__("couldn't find a valid address for %s has it been deployed?", referedContractName));
self.logger.error("error running onDeploy: " + cmd); self.logger.error(__("error running onDeploy: ") + cmd);
withErrors = true; withErrors = true;
return; return;
} }
@ -198,12 +198,12 @@ class Deploy {
// TODO: convert to for to avoid repeated callback // TODO: convert to for to avoid repeated callback
for(let cmd of onDeployCode) { for(let cmd of onDeployCode) {
self.logger.info("executing: " + cmd); self.logger.info(__("executing: ") + cmd);
try { try {
RunCode.doEval(cmd, self.web3); RunCode.doEval(cmd, self.web3);
} catch(e) { } catch(e) {
if (e.message.indexOf("invalid opcode") >= 0) { if (e.message.indexOf("invalid opcode") >= 0) {
self.logger.error('the transaction was rejected; this usually happens due to a throw or a require, it can also happen due to an invalid operation'); self.logger.error(__('the transaction was rejected; this usually happens due to a throw or a require, it can also happen due to an invalid operation'));
} }
return callback(new Error(e)); return callback(new Error(e));
} }
@ -234,11 +234,11 @@ class Deploy {
if (typeof contract.fromIndex == 'number') { if (typeof contract.fromIndex == 'number') {
deploymentAccount = accounts[contract.fromIndex]; deploymentAccount = accounts[contract.fromIndex];
if (deploymentAccount === undefined) { if (deploymentAccount === undefined) {
return next("error deploying " + contract.className + ": no account found at index " + contract.fromIndex + " check the config"); return next(__("error deploying") + " " + contract.className + ": " + __("no account found at index") + " " + contract.fromIndex + __(" check the config"));
} }
} }
if (typeof contract.from == 'string' && typeof contract.fromIndex != 'undefined') { if (typeof contract.from == 'string' && typeof contract.fromIndex != 'undefined') {
self.logger.warn('Both "from" and "fromIndex" are defined for contract "'+contract.className+'". Using "from" as deployer account.'); self.logger.warn(__('Both "from" and "fromIndex" are defined for contract') + ' "' + contract.className + '". ' + __('Using "from" as deployer account.'));
} }
if (typeof contract.from == 'string') { if (typeof contract.from == 'string') {
deploymentAccount = contract.from; deploymentAccount = contract.from;
@ -262,12 +262,12 @@ class Deploy {
continue; continue;
} }
if (linkReference.length > 40) { if (linkReference.length > 40) {
return next(new Error(linkReference + " is too long, try reducing the path of the contract (" + filename + ") and/or its name " + contractObj.className)); return next(new Error(__("{{linkReference}} is too long, try reducing the path of the contract ({{filename}}) and/or its name {{contractName}}", {linkReference: linkReference, filename: filename, contractName: contractObj.className})));
} }
let toReplace = linkReference + "_".repeat(40 - linkReference.length); let toReplace = linkReference + "_".repeat(40 - linkReference.length);
if (deployedAddress === undefined) { if (deployedAddress === undefined) {
let libraryName = contractObj.className; let libraryName = contractObj.className;
return next(new Error(contract.className + " needs " + libraryName + " but an address was not found, did you deploy it or configured an address?")); return next(new Error(__("{{contractName}} needs {{libraryName}} but an address was not found, did you deploy it or configured an address?", {contractName: contract.className, libraryName: libraryName})));
} }
contractCode = contractCode.replace(new RegExp(toReplace, "g"), deployedAddress); contractCode = contractCode.replace(new RegExp(toReplace, "g"), deployedAddress);
} }
@ -280,7 +280,7 @@ class Deploy {
//self.logger.info("applying beforeDeploy plugins...", beforeDeployPlugins.length); //self.logger.info("applying beforeDeploy plugins...", beforeDeployPlugins.length);
async.eachSeries(beforeDeployPlugins, (plugin, eachPluginCb) => { async.eachSeries(beforeDeployPlugins, (plugin, eachPluginCb) => {
self.logger.info("running beforeDeploy plugin " + plugin.name + " ."); self.logger.info(__("running beforeDeploy plugin %s .", plugin.name));
// calling each beforeDeploy handler declared by the plugin // calling each beforeDeploy handler declared by the plugin
async.eachSeries(plugin.beforeDeploy, (beforeDeployFn, eachCb) => { async.eachSeries(plugin.beforeDeploy, (beforeDeployFn, eachCb) => {
@ -313,7 +313,7 @@ class Deploy {
deployObject = contractObject.deploy({arguments: contractParams, data: dataCode}); deployObject = contractObject.deploy({arguments: contractParams, data: dataCode});
} catch(e) { } catch(e) {
if (e.message.indexOf('Invalid number of parameters for "undefined"') >= 0) { if (e.message.indexOf('Invalid number of parameters for "undefined"') >= 0) {
return next(new Error("attempted to deploy " + contract.className + " without specifying parameters")); return next(new Error(__("attempted to deploy %s without specifying parameters", contract.className)));
} else { } else {
return next(new Error(e)); return next(new Error(e));
} }
@ -330,7 +330,7 @@ class Deploy {
next(); next();
}, },
function deployTheContract(next) { function deployTheContract(next) {
self.logger.info("deploying " + contract.className.bold.cyan + " with ".green + contract.gas + " gas".green); self.logger.info(__("deploying") + " " + contract.className.bold.cyan + " " + __("with").green + " " + contract.gas + " " + __("gas").green);
deployObject.send({ deployObject.send({
from: deploymentAccount, from: deploymentAccount,
@ -338,7 +338,7 @@ class Deploy {
gasPrice: contract.gasPrice gasPrice: contract.gasPrice
}).on('receipt', function(receipt) { }).on('receipt', function(receipt) {
if (receipt.contractAddress !== undefined) { if (receipt.contractAddress !== undefined) {
self.logger.info(contract.className.bold.cyan + " deployed at ".green + receipt.contractAddress.bold.cyan); self.logger.info(contract.className.bold.cyan + " " + __("deployed at").green + " " + receipt.contractAddress.bold.cyan);
contract.deployedAddress = receipt.contractAddress; contract.deployedAddress = receipt.contractAddress;
contract.transactionHash = receipt.transactionHash; contract.transactionHash = receipt.transactionHash;
self.events.emit('contractsState', self.contractsManager.contractsState()); self.events.emit('contractsState', self.contractsManager.contractsState());
@ -347,7 +347,7 @@ class Deploy {
self.events.emit('contractsState', self.contractsManager.contractsState()); self.events.emit('contractsState', self.contractsManager.contractsState());
}).on('error', function(error) { }).on('error', function(error) {
self.events.emit('contractsState', self.contractsManager.contractsState()); self.events.emit('contractsState', self.contractsManager.contractsState());
return next(new Error("error deploying =" + contract.className + "= due to error: " + error.message)); return next(new Error(__("error deploying") + " =" + contract.className + "= " + __("due to error") + ": " + error.message));
}); });
} }
], callback); ], callback);
@ -355,7 +355,7 @@ class Deploy {
deployAll(done) { deployAll(done) {
let self = this; let self = this;
this.logger.info("deploying contracts"); this.logger.info(__("deploying contracts"));
let contracts = this.contractsManager.listContracts(); let contracts = this.contractsManager.listContracts();
async.eachOfSeries(contracts, async.eachOfSeries(contracts,
@ -365,15 +365,15 @@ class Deploy {
}, },
function (err, _results) { function (err, _results) {
if (err) { if (err) {
self.logger.error("error deploying contracts"); self.logger.error(__("error deploying contracts"));
self.logger.error(err.message); self.logger.error(err.message);
self.logger.debug(err.stack); self.logger.debug(err.stack);
} }
if (contracts.length === 0) { if (contracts.length === 0) {
self.logger.info("no contracts found"); self.logger.info(__("no contracts found"));
return done(); return done();
} }
self.logger.info("finished deploying contracts"); self.logger.info(__("finished deploying contracts"));
self.logger.trace(arguments); self.logger.trace(arguments);
done(err); done(err);
} }

View File

@ -24,7 +24,7 @@ class DeployManager {
let self = this; let self = this;
if (self.blockchainConfig === {} || self.blockchainConfig.enabled === false) { if (self.blockchainConfig === {} || self.blockchainConfig.enabled === false) {
self.logger.info("Blockchain component is disabled in the config".underline); self.logger.info(__("Blockchain component is disabled in the config").underline);
this.events.emit('blockchainDisabled', {}); this.events.emit('blockchainDisabled', {});
return done(); return done();
} }
@ -47,15 +47,15 @@ class DeployManager {
} }
if (self.web3.currentProvider === undefined) { if (self.web3.currentProvider === undefined) {
self.logger.error(("Couldn't connect to an Ethereum node are you sure it's on?").red); self.logger.error(__("Couldn't connect to an Ethereum node are you sure it's on?").red);
self.logger.info("make sure you have an Ethereum node or simulator running. e.g 'embark blockchain'".magenta); self.logger.info(__("make sure you have an Ethereum node or simulator running. e.g '%s'", 'embark blockchain').magenta);
return callback(Error("error connecting to blockchain node")); return callback(Error("error connecting to blockchain node"));
} }
self.web3.eth.getAccounts(function(err, _accounts) { self.web3.eth.getAccounts(function(err, _accounts) {
if (err) { if (err) {
self.logger.error(("Couldn't connect to an Ethereum node are you sure it's on?").red); self.logger.error(__("Couldn't connect to an Ethereum node are you sure it's on?").red);
self.logger.info("make sure you have an Ethereum node or simulator running. e.g 'embark blockchain'".magenta); self.logger.info(__("make sure you have an Ethereum node or simulator running. e.g '%s'", 'embark blockchain').magenta);
return callback(Error("error connecting to blockchain node")); return callback(Error("error connecting to blockchain node"));
} }
return callback(null, contractsManager, self.web3); return callback(null, contractsManager, self.web3);
@ -108,19 +108,19 @@ class DeployManager {
let referedContract = contractsManager.getContract(referedContractName); let referedContract = contractsManager.getContract(referedContractName);
if (!referedContract) { if (!referedContract) {
self.logger.error(referedContractName + ' does not exist'); self.logger.error(referedContractName + ' does not exist');
self.logger.error("error running afterDeploy: " + cmd); self.logger.error(__("error running afterDeploy: ") + cmd);
withErrors = true; withErrors = true;
return; return;
} }
if (referedContract && referedContract.deploy === false) { if (referedContract && referedContract.deploy === false) {
self.logger.error(referedContractName + " exists but has been set to not deploy"); self.logger.error(referedContractName + " exists but has been set to not deploy");
self.logger.error("error running afterDeploy: " + cmd); self.logger.error(__("error running afterDeploy: ") + cmd);
withErrors = true; withErrors = true;
return; return;
} }
if (referedContract && !referedContract.deployedAddress) { if (referedContract && !referedContract.deployedAddress) {
self.logger.error("couldn't find a valid address for " + referedContractName + ". has it been deployed?"); self.logger.error("couldn't find a valid address for " + referedContractName + ". has it been deployed?");
self.logger.error("error running afterDeploy: " + cmd); self.logger.error(__("error running afterDeploy: ") + cmd);
withErrors = true; withErrors = true;
return; return;
} }
@ -135,12 +135,12 @@ class DeployManager {
// TODO: convert to for to avoid repeated callback // TODO: convert to for to avoid repeated callback
for(let cmd of onDeployCode) { for(let cmd of onDeployCode) {
self.logger.info("executing: " + cmd); self.logger.info(__("executing") + ": " + cmd);
try { try {
RunCode.doEval(cmd, web3); RunCode.doEval(cmd, web3);
} catch(e) { } catch(e) {
if (e.message.indexOf("invalid opcode") >= 0) { if (e.message.indexOf("invalid opcode") >= 0) {
self.logger.error('the transaction was rejected; this usually happens due to a throw or a require, it can also happen due to an invalid operation'); self.logger.error(__('the transaction was rejected; this usually happens due to a throw or a require, it can also happen due to an invalid operation'));
} }
return callback(new Error(e)); return callback(new Error(e));
} }

View File

@ -31,7 +31,7 @@ Config.prototype.loadConfigFiles = function(options) {
} }
if (!fs.existsSync(options.embarkConfig)){ if (!fs.existsSync(options.embarkConfig)){
this.logger.error('Cannot find file ' + options.embarkConfig + '. Please ensure you are running this command inside the Dapp folder'); this.logger.error(__('Cannot find file %s Please ensure you are running this command inside the Dapp folder', options.embarkConfig));
process.exit(1); process.exit(1);
} }
@ -78,7 +78,7 @@ Config.prototype._mergeConfig = function(configFilePath, defaultConfig, env, ena
if (!fs.existsSync(configFilePath)) { if (!fs.existsSync(configFilePath)) {
// TODO: remove this if // TODO: remove this if
if (this.logger) { if (this.logger) {
this.logger.warn("no config file found at " + configFilePath + ". using default config"); this.logger.warn(__("no config file found at %s using default config", configFilePath));
} }
return defaultConfig['default'] || {}; return defaultConfig['default'] || {};
} }
@ -162,7 +162,7 @@ Config.prototype.loadExternalContractsFiles = function() {
if (contract.file.startsWith('http') || contract.file.startsWith('git')) { if (contract.file.startsWith('http') || contract.file.startsWith('git')) {
const fileObj = utils.getExternalContractUrl(contract.file); const fileObj = utils.getExternalContractUrl(contract.file);
if (!fileObj) { if (!fileObj) {
return this.logger.error("HTTP contract file not found: " + contract.file); return this.logger.error(__("HTTP contract file not found") + ": " + contract.file);
} }
const localFile = fileObj.filePath; const localFile = fileObj.filePath;
this.contractsFiles.push(new File({filename: localFile, type: File.types.http, basedir: '', path: fileObj.url})); this.contractsFiles.push(new File({filename: localFile, type: File.types.http, basedir: '', path: fileObj.url}));
@ -171,7 +171,7 @@ Config.prototype.loadExternalContractsFiles = function() {
} else if (fs.existsSync(path.join('./node_modules/', contract.file))) { } else if (fs.existsSync(path.join('./node_modules/', contract.file))) {
this.contractsFiles.push(new File({filename: path.join('./node_modules/', contract.file), type: File.types.dapp_file, basedir: '', path: path.join('./node_modules/', contract.file)})); this.contractsFiles.push(new File({filename: path.join('./node_modules/', contract.file), type: File.types.dapp_file, basedir: '', path: path.join('./node_modules/', contract.file)}));
} else { } else {
this.logger.error("contract file not found: " + contract.file); this.logger.error(__("contract file not found") + ": " + contract.file);
} }
} }
}; };
@ -253,7 +253,7 @@ Config.prototype.loadPipelineConfigFile = function() {
Config.prototype.loadChainTrackerFile = function() { Config.prototype.loadChainTrackerFile = function() {
if (!fs.existsSync(this.chainsFile)) { if (!fs.existsSync(this.chainsFile)) {
this.logger.info(this.chainsFile + ' file not found, creating it...'); this.logger.info(this.chainsFile + ' ' + __('file not found, creating it...'));
fs.writeJSONSync(this.chainsFile, {}); fs.writeJSONSync(this.chainsFile, {});
} }

View File

@ -280,18 +280,18 @@ class Engine {
self.servicesMonitor.addCheck('Ethereum', function (cb) { self.servicesMonitor.addCheck('Ethereum', function (cb) {
if (self.web3.currentProvider === undefined) { if (self.web3.currentProvider === undefined) {
return cb({name: "No Blockchain node found", status: 'off'}); return cb({name: __("No Blockchain node found"), status: 'off'});
} }
self.web3.eth.getAccounts(function(err, _accounts) { self.web3.eth.getAccounts(function(err, _accounts) {
if (err) { if (err) {
return cb({name: "No Blockchain node found", status: 'off'}); return cb({name: __("No Blockchain node found"), status: 'off'});
} }
// TODO: web3_clientVersion method is currently not implemented in web3.js 1.0 // TODO: web3_clientVersion method is currently not implemented in web3.js 1.0
self.web3._requestManager.send({method: 'web3_clientVersion', params: []}, (err, version) => { self.web3._requestManager.send({method: 'web3_clientVersion', params: []}, (err, version) => {
if (err) { if (err) {
return cb({name: "Ethereum node (version unknown)", status: 'on'}); return cb({name: __("Ethereum node (version unknown)"), status: 'on'});
} }
if (version.indexOf("/") < 0) { if (version.indexOf("/") < 0) {
return cb({name: version, status: 'on'}); return cb({name: version, status: 'on'});

View File

@ -3,7 +3,7 @@ var EventEmitter = require('events');
function warnIfLegacy(eventName) { function warnIfLegacy(eventName) {
const legacyEvents = ['abi-vanila', 'abi', 'abi-contracts-vanila', 'abi-vanila-deployment']; const legacyEvents = ['abi-vanila', 'abi', 'abi-contracts-vanila', 'abi-vanila-deployment'];
if (legacyEvents.indexOf(eventName) >= 0) { if (legacyEvents.indexOf(eventName) >= 0) {
console.info("this event is deprecated and will be removed in future versions: " + eventName); console.info(__("this event is deprecated and will be removed in future versions %s", eventName));
} }
} }

View File

@ -93,7 +93,7 @@ class File {
} }
], (err, content) => { ], (err, content) => {
if (err) { if (err) {
console.error('Error while downloading the file', err); console.error(__('Error while downloading the file'), err);
return callback(''); return callback('');
} }
callback(content.toString()); callback(content.toString());

View File

@ -56,7 +56,7 @@ Plugin.prototype.hasContext = function(context) {
Plugin.prototype.loadPlugin = function() { Plugin.prototype.loadPlugin = function() {
if (!this.isContextValid()) { if (!this.isContextValid()) {
console.log(this.acceptedContext); console.log(this.acceptedContext);
this.logger.warn(`Plugin ${this.name} can only be loaded in the context of "${this.acceptedContext.join(', ')}"`); this.logger.warn(__('Plugin {{name}} can only be loaded in the context of "{{contextes}}"', {name: this.name, contextes: this.acceptedContext.join(', ')}));
return false; return false;
} }
this.loaded = true; this.loaded = true;

View File

@ -70,7 +70,7 @@ ServicesMonitor.prototype.startMonitor = function () {
callback(); callback();
}, function (err) { }, function (err) {
if (err) { if (err) {
self.logger.error("error running service check"); self.logger.error(__("error running service check"));
self.logger.error(err.message); self.logger.error(err.message);
} }
}); });

View File

@ -14,21 +14,21 @@ class Console {
} }
processEmbarkCmd (cmd) { processEmbarkCmd (cmd) {
if (cmd === 'help') { if (cmd === 'help' || cmd === __('help')) {
let helpText = [ let helpText = [
'Welcome to Embark ' + this.version, __('Welcome to Embark') + ' ' + this.version,
'', '',
'possible commands are:', __('possible commands are:'),
'versions - display versions in use for libraries and tools like web3 and solc', 'versions - ' + __('display versions in use for libraries and tools like web3 and solc'),
// TODO: only if the blockchain is actually active! // TODO: only if the blockchain is actually active!
// will need to pass te current embark state here // will need to pass te current embark state here
'web3 - instantiated web3.js object configured to the current environment', 'web3 - ' + __('instantiated web3.js object configured to the current environment'),
'quit - to immediatly exit (alias: exit)', 'quit - ' + __('to immediatly exit (alias: exit)'),
'', '',
'The web3 object and the interfaces for the deployed contracts and their methods are also available' __('The web3 object and the interfaces for the deployed contracts and their methods are also available')
]; ];
return helpText.join('\n'); return helpText.join('\n');
} else if (['quit', 'exit', 'sair', 'sortir'].indexOf(cmd) >= 0) { } else if (['quit', 'exit', 'sair', 'sortir', __('quit')].indexOf(cmd) >= 0) {
utils.exit(); utils.exit();
} }
return false; return false;
@ -52,7 +52,7 @@ class Console {
} }
catch (e) { catch (e) {
if (e.message.indexOf('not defined') > 0) { if (e.message.indexOf('not defined') > 0) {
return callback(("error: " + e.message).red + ("\nType " + "help".bold + " to see the list of available commands").cyan); return callback(("error: " + e.message).red + ("\n" + __("Type") + " " + "help".bold + " " + __("to see the list of available commands")).cyan);
} else { } else {
return callback(e.message); return callback(e.message);
} }

View File

@ -38,7 +38,7 @@ class Dashboard {
self.events.setCommandHandler("console:command", monitor.executeCmd.bind(monitor)); self.events.setCommandHandler("console:command", monitor.executeCmd.bind(monitor));
self.logger.info('========================'.bold.green); self.logger.info('========================'.bold.green);
self.logger.info(('Welcome to Embark ' + self.version).yellow.bold); self.logger.info((__('Welcome to Embark') + ' ' + self.version).yellow.bold);
self.logger.info('========================'.bold.green); self.logger.info('========================'.bold.green);
// TODO: do this after monitor is rendered // TODO: do this after monitor is rendered

View File

@ -67,7 +67,7 @@ class Dashboard {
setContracts(contracts) { setContracts(contracts) {
let data = []; let data = [];
data.push(["Contract Name", "Address", "Status"]); data.push([__("Contract Name"), __("Address"), __("Status")]);
contracts.forEach(function (row) { contracts.forEach(function (row) {
data.push(row); data.push(row);
@ -84,7 +84,7 @@ class Dashboard {
layoutLog() { layoutLog() {
this.log = blessed.box({ this.log = blessed.box({
label: "Logs", label: __("Logs"),
padding: 1, padding: 1,
width: "100%", width: "100%",
height: "55%", height: "55%",
@ -123,7 +123,7 @@ class Dashboard {
layoutModules() { layoutModules() {
this.modules = blessed.box({ this.modules = blessed.box({
label: "Contracts", label: __("Contracts"),
tags: true, tags: true,
padding: 1, padding: 1,
width: "75%", width: "75%",
@ -166,7 +166,7 @@ class Dashboard {
layoutAssets() { layoutAssets() {
this.assets = blessed.box({ this.assets = blessed.box({
label: "Asset Pipeline", label: __("Asset Pipeline"),
tags: true, tags: true,
padding: 1, padding: 1,
width: "50%", width: "50%",
@ -217,7 +217,7 @@ class Dashboard {
this.status = blessed.box({ this.status = blessed.box({
parent: this.wrapper, parent: this.wrapper,
label: "Environment", label: __("Environment"),
tags: true, tags: true,
padding: { padding: {
left: 1 left: 1
@ -238,7 +238,7 @@ class Dashboard {
this.operations = blessed.box({ this.operations = blessed.box({
parent: this.wrapper, parent: this.wrapper,
label: "Status", label: __("Status"),
tags: true, tags: true,
padding: { padding: {
left: 1 left: 1
@ -259,7 +259,7 @@ class Dashboard {
this.progress = blessed.box({ this.progress = blessed.box({
parent: this.wrapper, parent: this.wrapper,
label: "Available Services", label: __("Available Services"),
tags: true, tags: true,
padding: this.minimal ? { padding: this.minimal ? {
left: 1 left: 1
@ -283,7 +283,7 @@ class Dashboard {
layoutCmd() { layoutCmd() {
this.consoleBox = blessed.box({ this.consoleBox = blessed.box({
label: 'Console', label: __('Console'),
tags: true, tags: true,
padding: 0, padding: 0,
width: '100%', width: '100%',

42
lib/i18n/i18n.js Normal file
View File

@ -0,0 +1,42 @@
const i18n = require('i18n');
const osLocale = require('os-locale');
const path = require('path');
const supported_languages = ['en', 'pt'];
i18n.configure({
locales: supported_languages,
register: global,
//updateFiles: false,
directory: path.join(__dirname, 'locales')
});
function isSupported(locale) {
return (supported_languages.indexOf(locale.substr(0, 2)) >= 0);
}
function setLocale(locale) {
i18n.setLocale(locale.substr(0, 2));
}
function setDefaultLocale() {
osLocale().then(setLocale).catch();
}
function setOrDetectLocale(locale) {
if (locale && !isSupported(locale)) {
console.log("===== locale " + locale + " not supported =====");
}
if (locale) {
return i18n.setLocale(locale.substr(0, 2));
}
setDefaultLocale();
}
setDefaultLocale();
module.exports = {
i18n: i18n,
setOrDetectLocale: setOrDetectLocale
};

79
lib/i18n/locales/en.json Normal file
View File

@ -0,0 +1,79 @@
{
"new_application": "new_application",
"Contract Name": "Contract Name",
"New Application": "New Application",
"create a barebones project meant only for contract development": "create a barebones project meant only for contract development",
"create a working dapp with a SimpleStorage contract": "create a working dapp with a SimpleStorage contract",
"filename to output logs (default: none)": "filename to output logs (default: none)",
"level of logging to display": "level of logging to display",
"deploy and build dapp at ": "deploy and build dapp at ",
"port to run the dev webserver (default: %s)": "port to run the dev webserver (default: %s)",
"host to run the dev webserver (default: %s)": "host to run the dev webserver (default: %s)",
"disable the development webserver": "disable the development webserver",
"simple mode, disables the dashboard": "simple mode, disables the dashboard",
"no colors in case it's needed for compatbility purposes": "no colors in case it's needed for compatbility purposes",
"filename to output logs (default: %s)": "filename to output logs (default: %s)",
"run dapp (default: %s)": "run dapp (default: %s)",
"Use a specific ethereum client or simulator (supported: %s)": "Use a specific ethereum client or simulator (supported: %s)",
"run blockchain server (default: %s)": "run blockchain server (default: %s)",
"run a fast ethereum rpc simulator": "run a fast ethereum rpc simulator",
"use testrpc as the rpc simulator [%s]": "use testrpc as the rpc simulator [%s]",
"port to run the rpc simulator (default: %s)": "port to run the rpc simulator (default: %s)",
"host to run the rpc simulator (default: %s)": "host to run the rpc simulator (default: %s)",
"number of accounts (default: %s)": "number of accounts (default: %s)",
"Amount of ether to assign each test account (default: %s)": "Amount of ether to assign each test account (default: %s)",
"custom gas limit (default: %s)": "custom gas limit (default: %s)",
"run tests": "run tests",
"resets embarks state on this dapp including clearing cache": "resets embarks state on this dapp including clearing cache",
"generates documentation based on the smart contracts configured": "generates documentation based on the smart contracts configured",
"Upload your dapp to a decentralized storage": "Upload your dapp to a decentralized storage",
"output the version number": "output the version number",
"Logs": "Logs",
"Environment": "Environment",
"Status": "Status",
"Available Services": "Available Services",
"Contracts": "Contracts",
"Console": "Console",
"Welcome to Embark": "Welcome to Embark",
"dashboard start": "dashboard start",
"loaded plugins": "loaded plugins",
"loading solc compiler": "loading solc compiler",
"compiling solidity contracts": "compiling solidity contracts",
"%s doesn't have a compatible contract compiler. Maybe a plugin exists for it.": "%s doesn't have a compatible contract compiler. Maybe a plugin exists for it.",
"assuming %s to be an interface": "assuming %s to be an interface",
"{{className}}: couldn't find instanceOf contract {{parentContractName}}": "{{className}}: couldn't find instanceOf contract {{parentContractName}}",
"did you mean \"%s\"?": "did you mean \"%s\"?",
"%s has no code associated": "%s has no code associated",
"deploying contracts": "deploying contracts",
" already deployed at ": " already deployed at ",
"Pending": "Pending",
"Interface or set to not deploy": "Interface or set to not deploy",
"Deployed": "Deployed",
"Address": "Address",
"running beforeDeploy plugin %s .": "running beforeDeploy plugin %s .",
"deploying": "deploying",
"with": "with",
"gas": "gas",
"error deploying": "error deploying",
"due to error": "due to error",
"error deploying contracts": "error deploying contracts",
"finished deploying contracts": "finished deploying contracts",
"error running afterDeploy: ": "error running afterDeploy: ",
"ready to watch file changes": "ready to watch file changes",
"Starting Server": "Starting Server",
"webserver available at": "webserver available at",
"Webserver": "Webserver",
"versions": "versions",
"possible commands are:": "possible commands are:",
"display versions in use for libraries and tools like web3 and solc": "display versions in use for libraries and tools like web3 and solc",
"instantiated web3.js object configured to the current environment": "instantiated web3.js object configured to the current environment",
"to immediatly exit (alias: exit)": "to immediatly exit (alias: exit)",
"The web3 object and the interfaces for the deployed contracts and their methods are also available": "The web3 object and the interfaces for the deployed contracts and their methods are also available",
"versions in use": "versions in use",
"language to use (default: en)": "language to use (default: en)",
"executing": "executing",
"writing file": "writing file",
"errors found while generating": "errors found while generating",
"Looking for documentation? You can find it at": "Looking for documentation? You can find it at",
"Ready": "Ready"
}

188
lib/i18n/locales/pt.json Normal file
View File

@ -0,0 +1,188 @@
{
"New Application": "Nova Aplicacao",
"Contract Name": "Contracto",
"Address": "Endereço",
"Status": "Estado",
"Embark Blockchain Using: %s": "Embark Blockchain esta usando o commando: %s",
"running: %s": "executando: %s",
"already initialized": "ja esta inicializado",
"create a barebones project meant only for contract development": "criar um projeto vazio destinado apenas ao desenvolvimento de contratos",
"loading solc compiler": "carregando o compilador solc",
"Welcome to Embark": "Bem-vindo ao Embark",
"possible commands are:": "comandos possíveis são:",
"display versions in use for libraries and tools like web3 and solc": "lista versões em uso para bibliotecas e ferramentas como web3 e solc",
"instantiated web3.js object configured to the current environment": "objeto web3.js instanciado configurado para o ambiente atual",
"to immediatly exit (alias: exit)": "para sair imediatamente (alias: exit)",
"The web3 object and the interfaces for the deployed contracts and their methods are also available": "O objeto web3 e as interfaces para os contratos implantados e seus métodos também estão disponíveis",
"create a working dapp with a SimpleStorage contract": "Cria uma dapp funcional com o contrato SimpleStorage",
"filename to output logs (default: none)": "ficheiro/arquivo para saída dos logs (predefinido: none)",
"level of logging to display": "nivel do log",
"deploy and build dapp at ": "Publica os contractos e constroi a applicacao em ",
"port to run the dev webserver (default: %s)": "porta para correr o servidor web para desenvolvimento (default: %s)",
"host to run the dev webserver (default: %s)": "host para correr o servidor web para desenvolvimento (default: %s)",
"disable the development webserver": "disativa o servidor web para desenvolvimento",
"simple mode, disables the dashboard": "modo simples, disativa o dashboard",
"no colors in case it's needed for compatbility purposes": "sem cores, em caso seja necessario para compabitilidade com a terminal",
"filename to output logs (default: %s)": "ficheiro/arquivo para os logs (predefinido: %s)",
"run dapp (default: %s)": "executa a dapp (applicacao decentralizada) (predefinido: %s)",
"Use a specific ethereum client or simulator (supported: %s)": "Usa um cliente ou simulador de ethereum específico (supportado: %s)",
"run blockchain server (default: %s)": "executa un node de blockchain (predefinido: %s)",
"run a fast ethereum rpc simulator": "executa um simulador RPC de ethereum",
"use testrpc as the rpc simulator [%s]": "usa testrpc como simulator de rpc [%s]",
"port to run the rpc simulator (default: %s)": "porta para executar simulador de rpc (predefinido: %s)",
"host to run the rpc simulator (default: %s)": "host para executar servidor de rpc (predefinido: %s)",
"number of accounts (default: %s)": "numero de contas (predefinido: %s)",
"Amount of ether to assign each test account (default: %s)": "Quantidade de éter para atribuir cada conta de teste (predefinido: %s)",
"custom gas limit (default: %s)": "limite de gás (predefinido: %s)",
"run tests": "executar os testes",
"resets embarks state on this dapp including clearing cache": "recomenca o estado do Embark nesta appliacao, incluindo a cache",
"generates documentation based on the smart contracts configured": "gera documentação baseada nos contratos configurados",
"Upload your dapp to a decentralized storage": "Carrega a appliacao para armazenamento descentralizado",
"output the version number": "produz a versão actual",
"Logs": "Logs",
"Environment": "Ambiente",
"Available Services": "Serviços Disponíveis",
"Contracts": "Contratos",
"Console": "Consola",
"dashboard start": "inicia o painel de controle",
"loaded plugins": "plugins carregados",
"compiling solidity contracts": "Compilando contratos Solidity",
"%s doesn't have a compatible contract compiler. Maybe a plugin exists for it.": "%s não tem um compilador de contrato compatível. Talvez exista um plugin para isso.",
"assuming %s to be an interface": "assumindo que %s é uma interface",
"{{className}}: couldn't find instanceOf contract {{parentContractName}}": "{{className}}: não foi possível encontrar instancia de (instanceOf) do contrato {{parentContractName}}",
"did you mean \"%s\"?": "você quis dizer \"%s\"?",
"%s has no code associated": "%s não tem código associado",
"deploying contracts": "publicando contratos",
"running beforeDeploy plugin %s .": "executando plugin beforeDeploy %s .",
"deploying": "publicando",
"with": "com",
"gas": "gas",
"Pending": "Pendente",
"Interface or set to not deploy": "Interface ou configurado para não ser publicado",
"error deploying": "erro de publicação",
"due to error": "devido a erro",
"error deploying contracts": "erro publicando contratos",
"finished deploying contracts": "publicação de contratos concluida",
"error running afterDeploy: ": "erro executado afterDeploy: ",
"ready to watch file changes": "pronto para monitorar alterações em ficheiros/arquivos",
"Starting Server": "iniciando o servidor",
"webserver available at": "servidor web disponivel em",
"Webserver": "Servidor Web",
" already deployed at ": " já publicado em ",
"Deployed": "Publicado",
"Name must be only letters, spaces, or dashes": "O nome deve ser apenas letras, espaços ou traços",
"Name your app (default is %s)": "Nome da aplicacao (predefinido is %s)",
"Invalid name": "Nome inválido",
"unknown command": "comando desconhecido",
"did you mean": "você quis dizer",
"warning: running default config on a non-development environment": "aviso: executando a configuração padrão em um ambiente de não desenvolvimento",
"could not find {{geth_bin}} command; is {{client_name}} installed or in the PATH?": "não foi possível encontrar o comando {{geth_bin}}; o {{client_name}} instalado ou no PATH?",
"no accounts found": "nenhuma conta encontrada",
"initializing genesis block": "inicializando o bloco de gênese",
"rpcCorsDomain set to *": "rpcCorsDomain definido como *",
"make sure you know what you are doing": "certifique-se de saber o que está fazendo",
"warning: cors is not set": "aviso: cors não está definido",
"wsOrigins set to *": "wsOrigins definido como *",
"warning: wsOrigins is not set": "aviso: wsOrigins não está definido",
"reset done!": "reset feito!",
"%s is not installed on your machine": "%s não está instalado na sua máquina",
"You can install it by running: %s": "Você pode instalá-lo executando: %s",
"Initializing Embark Template....": "Inicializando Embark Template....",
"Installing packages...": "Instalando pacotes...",
"Init complete": "Init complete",
"App ready at ": "App ready at ",
"Next steps:": "Next steps:",
"open another console in the same directory and run": "open another console in the same directory and run",
"For more info go to http://embark.status.im": "For more info go to http://embark.status.im",
"%s : instanceOf is set to itself": "%s : instanceOf is set to itself",
"{{className}} has code associated to it but it's configured as an instanceOf {{parentContractName}}": "{{className}} has code associated to it but it's configured as an instanceOf {{parentContractName}}",
"Error Compiling/Building contracts: ": "Error Compiling/Building contracts: ",
"Error: ": "Error: ",
"there are two or more contracts that depend on each other in a cyclic manner": "there are two or more contracts that depend on each other in a cyclic manner",
"Embark couldn't determine which one to deploy first": "Embark couldn't determine which one to deploy first",
"{{inputName}} has not been defined for {{className}} constructor": "{{inputName}} has not been defined for {{className}} constructor",
"error deploying %s": "error deploying %s",
"executing onDeploy commands": "executing onDeploy commands",
"error executing onDeploy for ": "error executing onDeploy for ",
" does not exist": " does not exist",
"error running onDeploy: ": "error running onDeploy: ",
" exists but has been set to not deploy": " exists but has been set to not deploy",
"couldn't find a valid address for %s has it been deployed?": "couldn't find a valid address for %s has it been deployed?",
"executing: ": "executing: ",
"the transaction was rejected; this usually happens due to a throw or a require": "the transaction was rejected; this usually happens due to a throw or a require",
"no account found at index": "no account found at index",
" check the config": " check the config",
"Both \"from\" and \"fromIndex\" are defined for contract": "Both \"from\" and \"fromIndex\" are defined for contract",
"Using \"from\" as deployer account.": "Using \"from\" as deployer account.",
"{{linkReference}} is too long": "{{linkReference}} is too long",
"{{contractName}} needs {{libraryName}} but an address was not found, did you deploy it or configured an address?": "{{contractName}} needs {{libraryName}} but an address was not found, did you deploy it or configured an address?",
"attempted to deploy %s without specifying parameters": "attempted to deploy %s without specifying parameters",
"deployed at": "deployed at",
"no contracts found": "no contracts found",
"Blockchain component is disabled in the config": "Blockchain component is disabled in the config",
"Couldn't connect to an Ethereum node are you sure it's on?": "Couldn't connect to an Ethereum node are you sure it's on?",
"make sure you have an Ethereum node or simulator running. e.g '%s'": "make sure you have an Ethereum node or simulator running. e.g '%s'",
"executing": "executing",
"the transaction was rejected; this usually happens due to a throw or a require, it can also happen due to an invalid operation": "the transaction was rejected; this usually happens due to a throw or a require, it can also happen due to an invalid operation",
"Cannot find file %s Please ensure you are running this command inside the Dapp folder": "Cannot find file %s Please ensure you are running this command inside the Dapp folder",
"no config file found at %s using default config": "no config file found at %s using default config",
"HTTP contract file not found": "HTTP contract file not found",
"contract file not found": "contract file not found",
"file not found, creating it...": "file not found, creating it...",
"No Blockchain node found": "No Blockchain node found",
"Ethereum node (version unknown)": "Ethereum node (version unknown)",
"this event is deprecated and will be removed in future versions %s": "this event is deprecated and will be removed in future versions %s",
"Error while downloading the file": "Error while downloading the file",
"Plugin {{name}} can only be loaded in the context of \"{{contextes}}\"": "Plugin {{name}} can only be loaded in the context of \"{{contextes}}\"",
"error running service check": "error running service check",
"help": "ajuda",
"quit": "sair",
"Type": "Type",
"to see the list of available commands": "to see the list of available commands",
"Asset Pipeline": "Asset Pipeline",
"Ethereum node detected": "Ethereum node detected",
"Deployment Done": "Deployment Done",
"Looking for documentation? You can find it at": "A procura de Documentacao? pode encontra-la em",
"Ready": "Ready",
"tip: you can resize the terminal or disable the dashboard with": "tip: you can resize the terminal or disable the dashboard with",
"finished building": "finished building",
"Done": "Done",
"Cannot upload: {{platform}} node is not running on {{url}}.": "Cannot upload: {{platform}} node is not running on {{url}}.",
"try \"{{ipfs}}\" or \"{{swarm}}\"": "try \"{{ipfs}}\" or \"{{swarm}}\"",
"finished deploying": "finished deploying",
"finished building DApp and deploying to": "finished building DApp and deploying to",
"IPFS node detected": "IPFS node detected",
"IPFS node is offline": "IPFS node is offline",
"not found or not in the path. Guessing %s for path": "not found or not in the path. Guessing %s for path",
"adding %s to ipfs": "adding %s to ipfs",
"DApp available at": "DApp available at",
"error uploading to ipfs": "error uploading to ipfs",
"successfully uploaded to ipfs": "successfully uploaded to ipfs",
"Error while loading the content of ": "Error while loading the content of ",
"error compiling for unknown reasons": "error compiling for unknown reasons",
"error compiling. There are sources available but no code could be compiled, likely due to fatal errors in the solidity code": "error compiling. There are sources available but no code could be compiled, likely due to fatal errors in the solidity code",
"Swarm node detected...": "Swarm node detected...",
"Swarm node is offline...": "Swarm node is offline...",
"deploying to swarm!": "deploying to swarm!",
"adding %s to swarm": "adding %s to swarm",
"error uploading to swarm": "error uploading to swarm",
"successfully uploaded to swarm": "successfully uploaded to swarm",
"Vyper exited with error code ": "Vyper exited with error code ",
"Execution returned no result": "Execution returned no result",
"compiling Vyper contracts": "compiling Vyper contracts",
"Webserver is offline": "Webserver is offline",
"stopping webserver": "stopping webserver",
"a webserver is already running at": "a webserver is already running at",
"no webserver is currently running": "no webserver is currently running",
"couldn't find file": "couldn't find file",
"errors found while generating": "errors found while generating",
"writing file": "escrevendo ficheiro",
"Simulator not found; Please install it with \"%s\"": "Simulator not found; Please install it with \"%s\"",
"Tried to load testrpc but an error occurred. This is a problem with testrpc": "Tried to load testrpc but an error occurred. This is a problem with testrpc",
"IMPORTANT: if you using a NodeJS version older than 6.9.1 then you need to install an older version of testrpc \"%s\". Alternatively install node 6.9.1 and the testrpc 3.0": "IMPORTANT: if you using a NodeJS version older than 6.9.1 then you need to install an older version of testrpc \"%s\". Alternatively install node 6.9.1 and the testrpc 3.0",
"terminating due to error": "terminating due to error",
"There a a space in the version of {{versionKey}}. We corrected it for you ({{correction})": "There a a space in the version of {{versionKey}}. We corrected it for you ({{correction})",
"versions": "versions",
"versions in use": "versions in use",
"downloading {{packageName}} {{version}}....": "downloading {{packageName}} {{version}}...."
}

View File

@ -87,7 +87,7 @@ class Embark {
if (!options.useDashboard) { if (!options.useDashboard) {
engine.logger.info('========================'.bold.green); engine.logger.info('========================'.bold.green);
engine.logger.info(('Welcome to Embark ' + this.version).yellow.bold); engine.logger.info((__('Welcome to Embark') + ' ' + this.version).yellow.bold);
engine.logger.info('========================'.bold.green); engine.logger.info('========================'.bold.green);
} }
@ -106,14 +106,14 @@ class Embark {
contractsConfig: engine.config.contractsConfig contractsConfig: engine.config.contractsConfig
}); });
dashboard.start(function () { dashboard.start(function () {
engine.logger.info('dashboard start'); engine.logger.info(__('dashboard start'));
callback(); callback();
}); });
}, },
function (callback) { function (callback) {
let pluginList = engine.plugins.listPlugins(); let pluginList = engine.plugins.listPlugins();
if (pluginList.length > 0) { if (pluginList.length > 0) {
engine.logger.info("loaded plugins: " + pluginList.join(", ")); engine.logger.info(__("loaded plugins") + ": " + pluginList.join(", "));
} }
engine.startMonitor(); engine.startMonitor();
@ -125,17 +125,17 @@ class Embark {
engine.startService(engine.config.storageConfig.provider, {bzz: engine.web3.bzz}); engine.startService(engine.config.storageConfig.provider, {bzz: engine.web3.bzz});
engine.events.on('check:backOnline:Ethereum', function () { engine.events.on('check:backOnline:Ethereum', function () {
engine.logger.info('Ethereum node detected..'); engine.logger.info(__('Ethereum node detected') + '..');
engine.config.reloadConfig(); engine.config.reloadConfig();
engine.deployManager.deployContracts(function () { engine.deployManager.deployContracts(function () {
engine.logger.info('Deployment Done'); engine.logger.info(__('Deployment Done'));
}); });
}); });
engine.events.on('outputDone', function () { engine.events.on('outputDone', function () {
engine.logger.info("Looking for documentation? You can find it at ".cyan + "http://embark.readthedocs.io/".green.underline + ".".cyan); engine.logger.info((__("Looking for documentation? You can find it at") + " ").cyan + "http://embark.status.im/docs/".green.underline + ".".cyan);
engine.logger.info("Ready".underline); engine.logger.info(__("Ready").underline);
engine.events.emit("status", "Ready".green); engine.events.emit("status", __("Ready").green);
}); });
engine.deployManager.deployContracts(function (err) { engine.deployManager.deployContracts(function (err) {
@ -158,7 +158,7 @@ class Embark {
let size = windowSize.get(); let size = windowSize.get();
if (size.height < 40 || size.width < 118) { if (size.height < 40 || size.width < 118) {
engine.logger.warn("tip: you can resize the terminal or disable the dashboard with " + "embark run --nodashboard".bold.underline); engine.logger.warn(__("tip: you can resize the terminal or disable the dashboard with") + " embark run --nodashboard".bold.underline);
} }
} }
}); });
@ -186,7 +186,7 @@ class Embark {
function startServices(callback) { function startServices(callback) {
let pluginList = engine.plugins.listPlugins(); let pluginList = engine.plugins.listPlugins();
if (pluginList.length > 0) { if (pluginList.length > 0) {
engine.logger.info("loaded plugins: " + pluginList.join(", ")); engine.logger.info(__("loaded plugins") + ": " + pluginList.join(", "));
} }
engine.startService("libraryManager"); engine.startService("libraryManager");
@ -208,7 +208,7 @@ class Embark {
engine.logger.error(err.message); engine.logger.error(err.message);
engine.logger.debug(err.stack); engine.logger.debug(err.stack);
} else { } else {
engine.logger.info("finished building".underline); engine.logger.info(__("finished building").underline);
} }
// needed due to child processes // needed due to child processes
process.exit(); process.exit();
@ -235,13 +235,12 @@ class Embark {
}); });
engine.init(); engine.init();
async.parallel([ async.parallel([
function (callback) { function (callback) {
let pluginList = engine.plugins.listPlugins(); let pluginList = engine.plugins.listPlugins();
if (pluginList.length > 0) { if (pluginList.length > 0) {
engine.logger.info("loaded plugins: " + pluginList.join(", ")); engine.logger.info(__("loaded plugins") + ": " + pluginList.join(", "));
} }
engine.startMonitor(); engine.startMonitor();
@ -264,7 +263,7 @@ class Embark {
let graphGen = new GraphGenerator(engine); let graphGen = new GraphGenerator(engine);
graphGen.generate(options); graphGen.generate(options);
engine.logger.info("Done. ./diagram.svg generated".underline); engine.logger.info(__("Done. %s generated", "./diagram.svg").underline);
process.exit(); process.exit();
} }
}); });
@ -322,7 +321,7 @@ class Embark {
} }
checkFn.fn(function (serviceCheckResult) { checkFn.fn(function (serviceCheckResult) {
if (!serviceCheckResult.status || serviceCheckResult.status === 'off') { if (!serviceCheckResult.status || serviceCheckResult.status === 'off') {
return callback({message: `Cannot upload: ${platform} node is not running on http://${engine.config.storageConfig.host}:${engine.config.storageConfig.port}.`}); return callback({message: __('Cannot upload: {{platform}} node is not running on {{url}}.', {platform: platform, url: `http://${engine.config.storageConfig.host}:${engine.config.storageConfig.port}`})});
} }
callback(); callback();
}); });
@ -330,7 +329,7 @@ class Embark {
function setupStoragePlugin(callback){ function setupStoragePlugin(callback){
let pluginList = engine.plugins.listPlugins(); let pluginList = engine.plugins.listPlugins();
if (pluginList.length > 0) { if (pluginList.length > 0) {
engine.logger.info("loaded plugins: " + pluginList.join(", ")); engine.logger.info(__("loaded plugins") + ": " + pluginList.join(", "));
} }
// check use has input existing storage plugin // check use has input existing storage plugin
@ -344,7 +343,7 @@ class Embark {
}); });
} }
if (!cmdPlugin) { if (!cmdPlugin) {
engine.logger.info('try "embark upload ipfs" or "embark upload swarm"'.green); engine.logger.info(__('try "{{ipfs}}" or "{{swarm}}"', {ipfs: 'embark upload ipfs', swarm: 'embark upload swarm'}).green);
return callback({message: 'unknown platform: ' + platform}); return callback({message: 'unknown platform: ' + platform});
} }
callback(); callback();
@ -360,7 +359,7 @@ class Embark {
}); });
// 1. build the contracts and dapp webpack // 1. build the contracts and dapp webpack
engine.deployManager.deployContracts(function (err) { engine.deployManager.deployContracts(function (err) {
engine.logger.info("finished deploying".underline); engine.logger.info(__("finished deploying").underline);
if(err){ if(err){
callback(err); callback(err);
} }
@ -371,7 +370,7 @@ class Embark {
engine.logger.error(err.message); engine.logger.error(err.message);
engine.logger.debug(err.stack); engine.logger.debug(err.stack);
} else { } else {
engine.logger.info(`finished building DApp and deploying to ${platform}`.underline); engine.logger.info((__("finished building DApp and deploying to") + " " + platform).underline);
} }
// needed due to child processes // needed due to child processes

View File

@ -43,11 +43,11 @@ class IPFS {
} }
self.events.on('check:backOnline:IPFS', function () { self.events.on('check:backOnline:IPFS', function () {
self.logger.info('IPFS node detected..'); self.logger.info(__('IPFS node detected') + '..');
}); });
self.events.on('check:wentOffline:IPFS', function () { self.events.on('check:wentOffline:IPFS', function () {
self.logger.info('IPFS node is offline..'); self.logger.info(__('IPFS node is offline') + '..');
}); });
if (!self.addCheck) { if (!self.addCheck) {

View File

@ -20,7 +20,7 @@ class IPFS {
let ipfs_bin = shelljs.which(self.configIpfsBin); let ipfs_bin = shelljs.which(self.configIpfsBin);
if (ipfs_bin === 'ipfs not found' || !ipfs_bin) { if (ipfs_bin === 'ipfs not found' || !ipfs_bin) {
console.log(('=== WARNING: ' + self.configIpfsBin + ' not found or not in the path. Guessing ~/go/bin/ipfs for path').yellow); console.log(('=== WARNING: ' + self.configIpfsBin + ' ' + __('not found or not in the path. Guessing %s for path', '~/go/bin/ipfs')).yellow);
ipfs_bin = "~/go/bin/ipfs"; ipfs_bin = "~/go/bin/ipfs";
} }
@ -28,7 +28,7 @@ class IPFS {
}, },
function runCommand(ipfs_bin, callback) { function runCommand(ipfs_bin, callback) {
let cmd = `"${ipfs_bin}" add -r ${self.buildDir}`; let cmd = `"${ipfs_bin}" add -r ${self.buildDir}`;
console.log(("=== adding " + self.buildDir + " to ipfs").green); console.log(("=== " + __("adding %s to ipfs", self.buildDir)).green);
console.debug(cmd); console.debug(cmd);
shelljs.exec(cmd, {silent:true}, function(code, stdout, stderr){ // {silent:true}: don't echo cmd output so it can be controlled via logLevel shelljs.exec(cmd, {silent:true}, function(code, stdout, stderr){ // {silent:true}: don't echo cmd output so it can be controlled via logLevel
console.log(stdout.green); console.log(stdout.green);
@ -43,18 +43,18 @@ class IPFS {
callback(null, dir_hash); callback(null, dir_hash);
}, },
function printUrls(dir_hash, callback) { function printUrls(dir_hash, callback) {
console.log(("=== DApp available at http://localhost:8080/ipfs/" + dir_hash + "/").green); console.log(("=== " + __("DApp available at") + " http://localhost:8080/ipfs/" + dir_hash + "/").green);
console.log(("=== DApp available at http://gateway.ipfs.io/ipfs/" + dir_hash + "/").green); console.log(("=== " + __("DApp available at") + " http://gateway.ipfs.io/ipfs/" + dir_hash + "/").green);
callback(); callback();
} }
], function (err, _result) { ], function (err, _result) {
if (err) { if (err) {
console.log("error uploading to ipfs".red); console.log(__("error uploading to ipfs").red);
console.log(err); console.log(err);
reject(err); reject(err);
} }
else resolve('successfully uploaded to ipfs'); else resolve(__('successfully uploaded to ipfs'));
}); });
}); });
} }

View File

@ -28,7 +28,7 @@ class Solidity {
file.content(function(fileContent) { file.content(function(fileContent) {
if (!fileContent) { if (!fileContent) {
self.logger.error('Error while loading the content of ' + filename); self.logger.error(__('Error while loading the content of ') + filename);
return fileCb(); return fileCb();
} }
input[filename] = {content: fileContent.replace(/\r\n/g, '\n')}; input[filename] = {content: fileContent.replace(/\r\n/g, '\n')};
@ -47,13 +47,13 @@ class Solidity {
return callback(); return callback();
} }
self.logger.info("loading solc compiler.."); self.logger.info(__("loading solc compiler") + "..");
solcW.load_compiler(function (err) { solcW.load_compiler(function (err) {
callback(err); callback(err);
}); });
}, },
function compileContracts(callback) { function compileContracts(callback) {
self.logger.info("compiling solidity contracts..."); self.logger.info(__("compiling solidity contracts") + "...");
let jsonObj = { let jsonObj = {
language: 'Solidity', language: 'Solidity',
sources: input, sources: input,
@ -88,11 +88,11 @@ class Solidity {
let json = output.contracts; let json = output.contracts;
if (!output || !output.contracts) { if (!output || !output.contracts) {
return callback(new Error("error compiling for unknown reasons")); return callback(new Error(__("error compiling for unknown reasons")));
} }
if (Object.keys(output.contracts).length === 0 && output.sourceList.length > 0) { if (Object.keys(output.contracts).length === 0 && output.sourceList.length > 0) {
return callback(new Error("error compiling. There are sources available but no code could be compiled, likely due to fatal errors in the solidity code").message); return callback(new Error(__("error compiling. There are sources available but no code could be compiled, likely due to fatal errors in the solidity code")).message);
} }
let compiled_object = {}; let compiled_object = {};

View File

@ -52,11 +52,11 @@ class Swarm {
} }
this.events.on('check:backOnline:Swarm', function () { this.events.on('check:backOnline:Swarm', function () {
self.logger.info('Swarm node detected...'); self.logger.info(__('Swarm node detected...'));
}); });
this.events.on('check:wentOffline:Swarm', function () { this.events.on('check:wentOffline:Swarm', function () {
self.logger.info('Swarm node is offline...'); self.logger.info(__('Swarm node is offline...'));
}); });
if (!this.addCheck) { if (!this.addCheck) {

View File

@ -11,12 +11,12 @@ class Swarm {
deploy() { deploy() {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
console.log("deploying to swarm!"); console.log(__("deploying to swarm!"));
let self = this; let self = this;
let bzz = this.bzz; let bzz = this.bzz;
async.waterfall([ async.waterfall([
function runCommand(callback) { function runCommand(callback) {
console.log(("=== adding " + self.buildDir + " to swarm").green); console.log(("=== " + __("adding %s to swarm", self.buildDir)).green);
bzz.upload({ bzz.upload({
path: self.buildDir, // path to data / file / directory path: self.buildDir, // path to data / file / directory
kind: "directory", // could also be "file" or "data" kind: "directory", // could also be "file" or "data"
@ -31,17 +31,17 @@ class Swarm {
if (!dir_hash) { if (!dir_hash) {
return callback('No directory hash was returned'); return callback('No directory hash was returned');
} }
console.log((`=== DApp available at ${self.storageConfig.getUrl}${dir_hash}/`).green); console.log(("=== " + __("DApp available at") + `${self.storageConfig.getUrl}${dir_hash}/`).green);
callback(); callback();
} }
], function (err, _result) { ], function (err, _result) {
if (err) { if (err) {
console.log("error uploading to swarm".red); console.log(__("error uploading to swarm").red);
console.log(err); console.log(err);
return reject(err); return reject(err);
} }
resolve('successfully uploaded to swarm'); resolve(__('successfully uploaded to swarm'));
}); });
}); });
} }

View File

@ -19,10 +19,10 @@ class Vyper {
return callback(stderr); return callback(stderr);
} }
if (code !== 0) { if (code !== 0) {
return callback(`Vyper exited with error code ${code}`); return callback(__('Vyper exited with error code ') + code);
} }
if (!stdout) { if (!stdout) {
return callback('Execution returned no result'); return callback(__('Execution returned no result'));
} }
callback(null, stdout.replace(/\n/g, '')); callback(null, stdout.replace(/\n/g, ''));
}); });
@ -33,7 +33,7 @@ class Vyper {
if (!contractFiles || !contractFiles.length) { if (!contractFiles || !contractFiles.length) {
return cb(); return cb();
} }
self.logger.info("compiling Vyper contracts..."); self.logger.info(__("compiling Vyper contracts") + "...");
const compiled_object = {}; const compiled_object = {};
async.each(contractFiles, async.each(contractFiles,
function (file, fileCb) { function (file, fileCb) {

View File

@ -16,7 +16,7 @@ class WebServer {
this.host = options.host || this.webServerConfig.host; this.host = options.host || this.webServerConfig.host;
this.port = options.port || this.webServerConfig.port; this.port = options.port || this.webServerConfig.port;
this.events.emit("status", "Starting Server"); this.events.emit("status", __("Starting Server"));
this.server = new Server({logger: this.logger, host: this.host, port: this.port}); this.server = new Server({logger: this.logger, host: this.host, port: this.port});
this.setServiceCheck(); this.setServiceCheck();
@ -32,14 +32,14 @@ class WebServer {
//embark.registerServiceCheck('WebserverService', function (cb) { //embark.registerServiceCheck('WebserverService', function (cb) {
this.addCheck('Webserver', function (cb) { this.addCheck('Webserver', function (cb) {
utils.checkIsAvailable(url, function (available) { utils.checkIsAvailable(url, function (available) {
let devServer = 'Webserver (' + url + ')'; let devServer = __('Webserver') + ' (' + url + ')';
let serverStatus = (available ? 'on' : 'off'); let serverStatus = (available ? 'on' : 'off');
return cb({name: devServer, status: serverStatus}); return cb({name: devServer, status: serverStatus});
}); });
}); });
this.events.on('check:wentOffline:Webserver', () => { this.events.on('check:wentOffline:Webserver', () => {
this.logger.info("Webserver is offline"); this.logger.info(__("Webserver is offline"));
}); });
} }
@ -57,7 +57,7 @@ class WebServer {
} }
if (cmd === 'webserver stop') { if (cmd === 'webserver stop') {
self.events.request("stop-webserver"); self.events.request("stop-webserver");
return "stopping webserver..."; return __("stopping webserver") + "...";
} }
return false; return false;
}); });

View File

@ -13,7 +13,7 @@ class Server {
start(callback) { start(callback) {
if (this.server && this.server.listening) { if (this.server && this.server.listening) {
this.logger.warn("a webserver is already running at " + ("http://" + this.hostname + ":" + this.port).bold.underline.green); this.logger.warn(__("a webserver is already running at") + " " + ("http://" + this.hostname + ":" + this.port).bold.underline.green);
if (callback) { if (callback) {
callback(); callback();
} }
@ -25,7 +25,7 @@ class Server {
serve(req, res, finalhandler(req, res)); serve(req, res, finalhandler(req, res));
}).withShutdown(); }).withShutdown();
this.logger.info("webserver available at " + ("http://" + this.hostname + ":" + this.port).bold.underline.green); this.logger.info(__("webserver available at") + " " + ("http://" + this.hostname + ":" + this.port).bold.underline.green);
this.server.listen(this.port, this.hostname); this.server.listen(this.port, this.hostname);
if (callback) { if (callback) {
callback(); callback();
@ -34,7 +34,7 @@ class Server {
stop(callback) { stop(callback) {
if (!this.server || !this.server.listening) { if (!this.server || !this.server.listening) {
this.logger.warn("no webserver is currently running"); this.logger.warn(__("no webserver is currently running"));
if (callback) { if (callback) {
callback(); callback();
} }

View File

@ -112,7 +112,7 @@ class Pipeline {
}, },
function (err, contentFiles) { function (err, contentFiles) {
if (err) { if (err) {
self.logger.error('errors found while generating ' + targetFile); self.logger.error(__('errors found while generating') + ' ' + targetFile);
} }
let dir = targetFile.split('/').slice(0, -1).join('/'); let dir = targetFile.split('/').slice(0, -1).join('/');
self.logger.trace("creating dir " + self.buildDir + dir); self.logger.trace("creating dir " + self.buildDir + dir);
@ -142,7 +142,7 @@ class Pipeline {
return file.content; return file.content;
}).join("\n"); }).join("\n");
self.logger.info("writing file " + (self.buildDir + targetFile).bold.dim); self.logger.info(__("writing file") + " " + (self.buildDir + targetFile).bold.dim);
fs.writeFile(self.buildDir + targetFile, content, cb); fs.writeFile(self.buildDir + targetFile, content, cb);
} }
); );

View File

@ -31,7 +31,7 @@ class Watch {
self.logger.trace('ready to watch config changes'); self.logger.trace('ready to watch config changes');
}); });
this.logger.info("ready to watch file changes"); this.logger.info(__("ready to watch file changes"));
} }
restart() { restart() {

View File

@ -11,15 +11,15 @@ var getSimulator = function() {
return sim; return sim;
} catch (e) { } catch (e) {
if (e.code === 'MODULE_NOT_FOUND') { if (e.code === 'MODULE_NOT_FOUND') {
console.log('Simulator not found; Please install it with "npm install ethereumjs-testrpc --save"'); console.log(__('Simulator not found; Please install it with "%s"', 'npm install ethereumjs-testrpc --save'));
console.log('IMPORTANT: if you using a NodeJS version older than 6.9.1 then you need to install an older version of testrpc "npm install ethereumjs-testrpc@2.0 --save"'); console.log(__('IMPORTANT: if you using a NodeJS version older than 6.9.1 then you need to install an older version of testrpc "%s"', 'npm install ethereumjs-testrpc@2.0 --save'));
console.log('For more information see https://github.com/ethereumjs/testrpc'); console.log('For more information see https://github.com/ethereumjs/testrpc');
// TODO: should throw exception instead // TODO: should throw exception instead
return process.exit(); return process.exit();
} }
console.log("=============="); console.log("==============");
console.log("Tried to load testrpc but an error occurred. This is a problem with testrpc"); console.log(__("Tried to load testrpc but an error occurred. This is a problem with testrpc"));
console.log('IMPORTANT: if you using a NodeJS version older than 6.9.1 then you need to install an older version of testrpc "npm install ethereumjs-testrpc@2.0 --save". Alternatively install node 6.9.1 and the testrpc 3.0'); console.log(__('IMPORTANT: if you using a NodeJS version older than 6.9.1 then you need to install an older version of testrpc "%s". Alternatively install node 6.9.1 and the testrpc 3.0', 'npm install ethereumjs-testrpc@2.0 --save'));
console.log("=============="); console.log("==============");
throw e; throw e;
} }
@ -88,7 +88,7 @@ Test.prototype.deployAll = function(contractsConfig, cb) {
} }
], function(err, result) { ], function(err, result) {
if (err) { if (err) {
console.log('terminating due to error'); console.log(__('terminating due to error'));
process.exit(1); process.exit(1);
} }
// this should be part of the waterfall and not just something done at the // this should be part of the waterfall and not just something done at the

View File

@ -31,7 +31,7 @@ class LibraryManager {
Object.keys(this.versions).forEach(versionKey => { Object.keys(this.versions).forEach(versionKey => {
const newVersion = this.versions[versionKey].trim(); const newVersion = this.versions[versionKey].trim();
if (newVersion !== this.versions[versionKey]) { if (newVersion !== this.versions[versionKey]) {
this.embark.logger.warn(`There a a space in the version of ${versionKey}. We corrected it for you ("${this.versions[versionKey]}" => "${newVersion}").`); this.embark.logger.warn(__('There a a space in the version of {{versionKey}}. We corrected it for you ({{correction}}).', {versionKey: versionKey, correction: `"${this.versions[versionKey]}" => "${newVersion}"`}));
this.versions[versionKey] = newVersion; this.versions[versionKey] = newVersion;
} }
}); });
@ -40,8 +40,8 @@ class LibraryManager {
registerCommands() { registerCommands() {
const self = this; const self = this;
this.embark.registerConsoleCommand((cmd, _options) => { this.embark.registerConsoleCommand((cmd, _options) => {
if (cmd === "versions") { if (cmd === "versions" || cmd === __('versions')) {
let text = ['versions in use:']; let text = [__('versions in use') + ':'];
for (let lib in self.versions) { for (let lib in self.versions) {
text.push(lib + ": " + self.versions[lib]); text.push(lib + ": " + self.versions[lib]);
} }

View File

@ -18,6 +18,7 @@ class Npm {
} }
this.logger.info("downloading " + packageName + " " + version + "...."); this.logger.info("downloading " + packageName + " " + version + "....");
this.logger.info(__("downloading {{packageName}} {{version}}....", {packageName: packageName, version: version}));
manager.install(packageName, version).then((result) => { manager.install(packageName, version).then((result) => {
callback(null , result.location); callback(null , result.location);
}).catch(callback); }).catch(callback);

453
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -46,10 +46,12 @@
"globule": "^1.1.0", "globule": "^1.1.0",
"hard-source-webpack-plugin": "^0.6.6", "hard-source-webpack-plugin": "^0.6.6",
"http-shutdown": "^1.2.0", "http-shutdown": "^1.2.0",
"i18n": "^0.8.3",
"ipfs-api": "17.2.4", "ipfs-api": "17.2.4",
"live-plugin-manager": "https://github.com/iurimatias/live-plugin-manager.git", "live-plugin-manager": "https://github.com/iurimatias/live-plugin-manager.git",
"merge": "^1.2.0", "merge": "^1.2.0",
"orbit-db": "^0.17.3", "orbit-db": "^0.17.3",
"os-locale": "^2.1.0",
"parse-json": "^4.0.0", "parse-json": "^4.0.0",
"promptly": "^2.1.0", "promptly": "^2.1.0",
"propose": "0.0.5", "propose": "0.0.5",

View File

@ -152,6 +152,11 @@
"ua-parser-js": "0.7.17" "ua-parser-js": "0.7.17"
} }
}, },
"haml": {
"version": "0.4.3",
"resolved": "https://registry.npmjs.org/haml/-/haml-0.4.3.tgz",
"integrity": "sha1-90BTGPPC7dGXpIsbjysvE+C7U3g="
},
"has-ansi": { "has-ansi": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",

View File

@ -15,6 +15,7 @@
"dependencies": { "dependencies": {
"bootstrap": "^3.3.6", "bootstrap": "^3.3.6",
"embark-service": "file:extensions/embark-service", "embark-service": "file:extensions/embark-service",
"haml": "^0.4.3",
"jquery": "^1.11.3", "jquery": "^1.11.3",
"react": "^16.0.0", "react": "^16.0.0",
"react-bootstrap": "^0.32.0", "react-bootstrap": "^0.32.0",