From ddcccb3c2df9b8fcee37e0e01ac760fdf628934a Mon Sep 17 00:00:00 2001 From: emizzle Date: Tue, 7 Aug 2018 14:28:26 +1000 Subject: [PATCH] Initial compile API and Fiddle container/pres components --- embark-ui/src/actions/index.js | 28 ++++++-- embark-ui/src/api/index.js | 4 ++ embark-ui/src/components/Fiddle.js | 10 +-- embark-ui/src/containers/FiddleContainer.js | 48 ++++++-------- embark-ui/src/reducers/fiddleReducer.js | 12 ++++ embark-ui/src/sagas/index.js | 16 ++++- lib/modules/solidity/index.js | 73 ++++++++++++++++++--- 7 files changed, 143 insertions(+), 48 deletions(-) create mode 100644 embark-ui/src/reducers/fiddleReducer.js diff --git a/embark-ui/src/actions/index.js b/embark-ui/src/actions/index.js index 130e7a13f..50b6670b8 100644 --- a/embark-ui/src/actions/index.js +++ b/embark-ui/src/actions/index.js @@ -20,8 +20,6 @@ export const accounts = { failure: (error) => action(ACCOUNTS[FAILURE], {error}) }; -// Fiddle -export const FIDDLE_CODE_CHANGE = 'FIDDLE_CODE_CHANGE'; export const ACCOUNT = createRequestTypes('ACCOUNT'); export const account = { request: (address) => action(ACCOUNT[REQUEST], {address}), @@ -145,8 +143,30 @@ export function listenToContractLogs() { }; } -export function fiddleCodeChange(){ +// Fiddle +export const FETCH_COMPILE_CODE = 'FETCH_COMPILE_CODE'; +export const RECEIVE_COMPILE_CODE = 'RECEIVE_COMPILE_CODE'; +export const RECEIVE_COMPILE_CODE_ERROR = 'RECEIVE_COMPILE_CODE_ERROR'; + +export function fetchCodeCompilation(codeToCompile){ return { - type: FIDDLE_CODE_CHANGE + type: FETCH_COMPILE_CODE, + codeToCompile }; } + + +export function receiveCodeCompilation(compilationResult){ + return { + type: RECEIVE_COMPILE_CODE, + compilationResult + }; +} + +export function receiveCodeCompilationError(){ + return { + type: RECEIVE_COMPILE_CODE_ERROR + }; +} + + diff --git a/embark-ui/src/api/index.js b/embark-ui/src/api/index.js index 09acbfbb0..51673720f 100644 --- a/embark-ui/src/api/index.js +++ b/embark-ui/src/api/index.js @@ -95,3 +95,7 @@ export function webSocketContractLogs() { export function webSocketBlockHeader() { return new WebSocket(`${constants.wsEndpoint}/blockchain/blockHeader`); } + +export function fetchCodeCompilation() { + return axios.post('http://localhost:8000/embark-api/contract/compile'); +} diff --git a/embark-ui/src/components/Fiddle.js b/embark-ui/src/components/Fiddle.js index 8fd989afd..81525d174 100644 --- a/embark-ui/src/components/Fiddle.js +++ b/embark-ui/src/components/Fiddle.js @@ -1,15 +1,11 @@ import React from 'react'; import AceEditor from 'react-ace'; - import 'brace/mode/javascript'; - import 'brace/theme/tomorrow_night_blue'; import 'ace-mode-solidity/build/remix-ide/mode-solidity'; -const Fiddle = ({code, options, editorDidMount, onChange}) => { - options = options || { - selectOnLineNumbers: true - }; +const Fiddle = ({onCodeChange}) => { + return (

Fiddle

@@ -20,10 +16,10 @@ const Fiddle = ({code, options, editorDidMount, onChange}) => { name="blah1" height="60em" width="100%" + onChange={(e) => onCodeChange(e)} />
); }; - export default Fiddle; diff --git a/embark-ui/src/containers/FiddleContainer.js b/embark-ui/src/containers/FiddleContainer.js index d3fb17b31..f65b66d03 100644 --- a/embark-ui/src/containers/FiddleContainer.js +++ b/embark-ui/src/containers/FiddleContainer.js @@ -1,41 +1,35 @@ import React, {Component} from 'react'; import {connect} from 'react-redux'; -import {fiddleCodeChange} from '../actions'; +import {fetchCodeCompilation} from '../actions'; import Fiddle from '../components/Fiddle'; class FiddleContainer extends Component { componentWillMount() { - //this.props.fetchAccounts(); + } - render() { - // const { accounts } = this.props; - // if (!accounts.data) { - // return ( - //

- // Loading accounts... - //

- // ) - // } - // if (accounts.error) { - // return ( - //

- // Error API... - //

- // ) - // } - const options = { - selectOnLineNumbers: true, - roundedSelection: false, - readOnly: false, - cursorStyle: 'line', - automaticLayout: false, - }; + render() { + const { compilationResult } = this.props; + const code = 'hello world'; return ( - + + +

Result

+ { + !compilationResult + ? + 'No compilation results yet' + : + compilationResult.error + ? + Error API... + : + compilationResult + } +
); } } @@ -49,6 +43,6 @@ function mapStateToProps(state) { export default connect( mapStateToProps, { - fiddleCodeChange + fetchCodeCompilation }, )(FiddleContainer); diff --git a/embark-ui/src/reducers/fiddleReducer.js b/embark-ui/src/reducers/fiddleReducer.js new file mode 100644 index 000000000..80aab03a6 --- /dev/null +++ b/embark-ui/src/reducers/fiddleReducer.js @@ -0,0 +1,12 @@ +import {RECEIVE_COMPILE_CODE, RECEIVE_COMPILE_CODE_ERROR} from "../actions"; + +export default function processes(state = {}, action) { + switch (action.type) { + case RECEIVE_COMPILE_CODE: + return Object.assign({}, state, {data: action.compilationResult}); + case RECEIVE_COMPILE_CODE_ERROR: + return Object.assign({}, state, {error: true}); + default: + return state; + } +} diff --git a/embark-ui/src/sagas/index.js b/embark-ui/src/sagas/index.js index 7f2fcea85..6b661d450 100644 --- a/embark-ui/src/sagas/index.js +++ b/embark-ui/src/sagas/index.js @@ -157,6 +157,19 @@ export function *watchCommunicationVersion() { yield takeEvery(actions.MESSAGE_VERSION[actions.REQUEST], fetchCommunicationVersion); } +export function* fetchCodeCompilation() { + try { + const codeCompilationResult = yield call(api.fetchCodeCompilation); + yield put(actions.receiveCodeCompilation(codeCompilationResult)); + } catch (e) { + yield put(actions.receiveCodeCompilationError(e)); + } +} + +export function* watchFetchCodeCompilation() { + yield takeEvery(actions.FETCH_COMPILE_CODE, fetchCodeCompilation); +} + export default function *root() { yield all([ fork(watchInitBlockHeader), @@ -177,7 +190,8 @@ export default function *root() { fork(watchSendMessage), fork(watchFetchContract), fork(watchFetchTransaction), - fork(watchFetchContractProfile) + fork(watchFetchContractProfile), + fork(watchFetchCodeCompilation) ]); } diff --git a/lib/modules/solidity/index.js b/lib/modules/solidity/index.js index 1e0b19f1b..065e687e3 100644 --- a/lib/modules/solidity/index.js +++ b/lib/modules/solidity/index.js @@ -14,15 +14,27 @@ class Solidity { this.options = embark.config.embarkConfig.options.solc; embark.registerCompiler(".sol", this.compile_solidity.bind(this)); + + + this.events.setCommandHandler("contract:compile", (contractCode, cb) => { + let input = []; + input['fiddler'] = {content: contractCode.replace(/\r\n/g, '\n')}; + this.compile_solidity_code(input, cb); + }); + + embark.registerAPICall( + 'post', + '/embark-api/contract/compile', + (req, res) => { + this.events.request("contract:compile", req.body.contractCode, (compilationResult) => { + res.send(JSON.stringify({compilationResult: compilationResult})); + }); + } + ); } - compile_solidity(contractFiles, options, cb) { - if (!contractFiles.length) { - return cb(); - } - let self = this; - let input = {}; - let originalFilepath = {}; + compile_solidity_code(codeInputs, originalFilepaths, cb){ + const self = this; async.waterfall([ function prepareInput(callback) { @@ -67,7 +79,7 @@ class Solidity { self.logger.info(__("compiling solidity contracts") + "..."); let jsonObj = { language: 'Solidity', - sources: input, + sources: codeInputs, settings: { optimizer: { enabled: (!options.disableOptimizations && self.options.optimize), @@ -144,7 +156,7 @@ class Solidity { compiled_object[className].functionHashes = contract.evm.methodIdentifiers; compiled_object[className].abiDefinition = contract.abi; compiled_object[className].filename = filename; - compiled_object[className].originalFilename = originalFilepath[filename]; + compiled_object[className].originalFilename = originalFilepaths[filename]; } } @@ -155,6 +167,49 @@ class Solidity { }); } + compile_solidity(contractFiles, cb) { + if (!contractFiles.length) { + return cb(); + } + let self = this; + let input = {}; + let originalFilepath = {}; + + async.waterfall([ + function prepareInput(callback) { + async.each(contractFiles, + function(file, fileCb) { + let filename = file.filename; + + for (let directory of self.contractDirectories) { + let match = new RegExp("^" + directory); + filename = filename.replace(match, ''); + } + + originalFilepath[filename] = file.filename; + + file.content(function(fileContent) { + if (!fileContent) { + self.logger.error(__('Error while loading the content of ') + filename); + return fileCb(); + } + input[filename] = {content: fileContent.replace(/\r\n/g, '\n')}; + fileCb(); + }); + }, + function (err) { + callback(err); + } + ); + }, + function compile(callback) { + self.compile_solidity_code(input, originalFilepath, callback); + } + ], function (err, result) { + cb(err, result); + }); + } + } module.exports = Solidity;