merged from master and fixed conflict in compiler-container.tsx

pull/2257/head
Milad Gueramian 3 years ago
commit 10af8f5c11
  1. 1
      apps/remix-ide/src/app.js
  2. 18
      apps/remix-ide/src/app/files/truffle-handle.js
  3. 2
      apps/remix-ide/src/app/panels/file-panel.js
  4. 2
      apps/remix-ide/src/app/plugins/remixd-handle.tsx
  5. 2
      apps/remix-ide/src/remixAppManager.js
  6. 1
      apps/remix-ide/src/remixEngine.js
  7. 8
      apps/solidity-compiler/src/app/compiler-api.ts
  8. 1
      libs/remix-lib/src/types/ICompilerApi.ts
  9. 33
      libs/remix-ui/solidity-compiler/src/lib/compiler-container.tsx
  10. 52
      libs/remix-ui/solidity-compiler/src/lib/logic/compileTabLogic.ts
  11. 6
      libs/remix-ui/solidity-compiler/src/lib/solidity-compiler.tsx
  12. 1
      libs/remix-ui/solidity-compiler/src/lib/types/index.ts
  13. 16
      libs/remixd/src/bin/remixd.ts
  14. 2
      libs/remixd/src/index.ts
  15. 1
      libs/remixd/src/serviceList.ts
  16. 50
      libs/remixd/src/services/truffleClient.ts
  17. 3
      libs/remixd/src/websocket.ts

@ -309,6 +309,7 @@ class AppComponent {
filePanel.remixdHandle,
filePanel.gitHandle,
filePanel.hardhatHandle,
filePanel.truffleHandle,
filePanel.slitherHandle,
linkLibraries,
deployLibraries,

@ -0,0 +1,18 @@
import { WebsocketPlugin } from '@remixproject/engine-web'
import * as packageJson from '../../../../../package.json'
const profile = {
name: 'truffle',
displayName: 'truffle',
url: 'ws://127.0.0.1:65524',
methods: ['compile'],
description: 'Using Remixd daemon, allow to access truffle API',
kind: 'other',
version: packageJson.version
}
export class TruffleHandle extends WebsocketPlugin {
constructor () {
super(profile)
}
}

@ -7,6 +7,7 @@ import Registry from '../state/registry'
import { RemixdHandle } from '../plugins/remixd-handle'
const { GitHandle } = require('../files/git-handle.js')
const { HardhatHandle } = require('../files/hardhat-handle.js')
const { TruffleHandle } = require('../files/truffle-handle.js')
const { SlitherHandle } = require('../files/slither-handle.js')
/*
@ -51,6 +52,7 @@ module.exports = class Filepanel extends ViewPlugin {
this.remixdHandle = new RemixdHandle(this.fileProviders.localhost, appManager)
this.gitHandle = new GitHandle()
this.hardhatHandle = new HardhatHandle()
this.truffleHandle = new TruffleHandle()
this.slitherHandle = new SlitherHandle()
this.workspaces = []
this.appManager = appManager

@ -40,6 +40,7 @@ export class RemixdHandle extends WebsocketPlugin {
if (super.socket) super.deactivate()
// this.appManager.deactivatePlugin('git') // plugin call doesn't work.. see issue https://github.com/ethereum/remix-plugin/issues/342
if (this.appManager.isActive('hardhat')) this.appManager.deactivatePlugin('hardhat')
if (this.appManager.isActive('truffle')) this.appManager.deactivatePlugin('truffle')
if (this.appManager.isActive('slither')) this.appManager.deactivatePlugin('slither')
this.localhostProvider.close((error) => {
if (error) console.log(error)
@ -88,6 +89,7 @@ export class RemixdHandle extends WebsocketPlugin {
this.call('filePanel', 'setWorkspace', { name: LOCALHOST, isLocalhost: true }, true)
})
this.call('manager', 'activatePlugin', 'hardhat')
this.call('manager', 'activatePlugin', 'truffle')
this.call('manager', 'activatePlugin', 'slither')
}
}

@ -10,7 +10,7 @@ const requiredModules = [ // services + layout views + system views
'filePanel', 'terminal', 'settings', 'pluginManager', 'tabs', 'udapp', 'dGitProvider', 'solidity-logic', 'gistHandler', 'layout',
'notification', 'permissionhandler', 'walkthrough', 'storage', 'restorebackupzip', 'link-libraries', 'deploy-libraries', 'intelligentScriptExecutor']
const dependentModules = ['git', 'hardhat', 'slither'] // module which shouldn't be manually activated (e.g git is activated by remixd)
const dependentModules = ['git', 'hardhat', 'truffle', 'slither'] // module which shouldn't be manually activated (e.g git is activated by remixd)
export function isNative (name) {
const nativePlugins = ['vyper', 'workshops', 'debugger', 'remixd', 'menuicons', 'solidity', 'hardhat-provider', 'solidityStaticAnalysis', 'solidityUnitTesting', 'layout', 'notification']

@ -13,6 +13,7 @@ export class RemixEngine extends Engine {
if (name === 'dGitProvider') return { queueTimeout: 60000 * 4 }
if (name === 'slither') return { queueTimeout: 60000 * 4 } // Requires when a solc version is installed
if (name === 'hardhat') return { queueTimeout: 60000 * 4 }
if (name === 'truffle') return { queueTimeout: 60000 * 4 }
if (name === 'localPlugin') return { queueTimeout: 60000 * 4 }
if (name === 'notification') return { queueTimeout: 60000 * 4 }
if (name === 'sourcify') return { queueTimeout: 60000 * 4 }

@ -1,3 +1,4 @@
import React from 'react';
import { compile, helper } from '@remix-project/remix-solidity'
import { CompileTabLogic, parseContracts } from '@remix-ui/solidity-compiler' // eslint-disable-line
import type { ConfigurationSettings } from '@remix-project/remix-lib-ts'
@ -100,6 +101,10 @@ export const CompilerApiMixin = (Base) => class extends Base {
return this.call('hardhat', 'compile', configFile)
}
compileWithTruffle () {
return this.call('truffle', 'compile')
}
logToTerminal (content) {
return this.call('terminal', 'log', content)
}
@ -323,7 +328,8 @@ export const CompilerApiMixin = (Base) => class extends Base {
// ctrl+s or command+s
if ((e.metaKey || e.ctrlKey) && !e.shiftKey && e.keyCode === 83 && this.currentFile !== '') {
e.preventDefault()
this.compileTabLogic.runCompiler(await this.getAppParameter('hardhat-compilation'))
if(await this.getAppParameter('hardhat-compilation')) this.compileTabLogic.runCompiler('hardhat')
else if(await this.getAppParameter('truffle-compilation')) this.compileTabLogic.runCompiler('truffle')
}
}
window.document.addEventListener('keydown', this.data.eventHandlers.onKeyDown)

@ -41,6 +41,7 @@ export interface ICompilerApi {
logToTerminal: (log: terminalLog) => void
compileWithHardhat: (configPath: string) => Promise<string>
compileWithTruffle: () => Promise<string>
statusChanged: (data: { key: string, title?: string, type?: string }) => void,
emit?: (key: string, ...payload: any) => void
}

@ -20,7 +20,7 @@ declare global {
const _paq = window._paq = window._paq || [] //eslint-disable-line
export const CompilerContainer = (props: CompilerContainerProps) => {
const { api, compileTabLogic, tooltip, modal, compiledFileName, updateCurrentVersion, configurationSettings, isHardhatProject } = props // eslint-disable-line
const { api, compileTabLogic, tooltip, modal, compiledFileName, updateCurrentVersion, configurationSettings, isHardhatProject, isTruffleProject } = props // eslint-disable-line
const [state, setState] = useState({
hideWarnings: false,
autoCompile: false,
@ -42,6 +42,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
const compileIcon = useRef(null)
const promptMessageInput = useRef(null)
const [hhCompilation, sethhCompilation] = useState(false)
const [truffleCompilation, setTruffleCompilation] = useState(false)
const [compilerContainer, dispatch] = useReducer(compilerReducer, compilerInitialState)
useEffect(() => {
@ -325,7 +326,10 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
if (!isSolFileSelected()) return
_setCompilerVersionFromPragma(currentFile)
compileTabLogic.runCompiler(hhCompilation)
let externalCompType
if (hhCompilation) externalCompType = 'hardhat'
else if (truffleCompilation) externalCompType = 'truffle'
compileTabLogic.runCompiler(externalCompType)
}
const _updateVersionSelector = (version, customUrl = '') => {
@ -495,11 +499,18 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
const updatehhCompilation = (event) => {
const checked = event.target.checked
if (checked) setTruffleCompilation(false) // wayaround to reset the variable
sethhCompilation(checked)
api.setAppParameter('hardhat-compilation', checked)
}
const updateTruffleCompilation = (event) => {
const checked = event.target.checked
if (checked) sethhCompilation(false) // wayaround to reset the variable
setTruffleCompilation(checked)
api.setAppParameter('truffle-compilation', checked)
}
/*
The following functions map with the above event handlers.
They are an external API for modifying the compiler configuration.
@ -594,6 +605,22 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
</a>
</div>
}
{
isTruffleProject &&
<div className="mt-3 remixui_compilerConfig custom-control custom-checkbox">
<input className="remixui_autocompile custom-control-input" onChange={updateTruffleCompilation} id="enableTruffle" type="checkbox" title="Enable Truffle Compilation" checked={truffleCompilation} />
<label className="form-check-label custom-control-label" htmlFor="enableTruffle">Enable Truffle Compilation</label>
<a className="mt-1 text-nowrap" href='https://remix-ide.readthedocs.io/en/latest/' target={'_blank'}>
<OverlayTrigger placement={'right'} overlay={
<Tooltip className="text-nowrap" id="overlay-tooltip">
<span className="p-1 pr-3" style={{ backgroundColor: 'black', minWidth: '230px' }}>Learn how to use Truffle Compilation</span>
</Tooltip>
}>
<i style={{ fontSize: 'medium' }} className={'ml-2 fal fa-info-circle'} aria-hidden="true"></i>
</OverlayTrigger>
</a>
</div>
}
<button id="compileBtn" data-id="compilerContainerCompileBtn" className="btn btn-primary d-block w-100 text-break remixui_disabled mt-3" title="Compile" onClick={compile} disabled={disableCompileButton}>
<span>
{ <i ref={compileIcon} className="fas fa-sync remixui_iconbtn" aria-hidden="true"></i> }

@ -109,29 +109,43 @@ export class CompileTabLogic {
} else return false
}
runCompiler (hhCompilation) {
async isTruffleProject () {
if (this.api.getFileManagerMode() === 'localhost') {
return await this.api.fileExists('truffle-config.js')
} else return false
}
runCompiler (externalCompType) {
try {
if (this.api.getFileManagerMode() === 'localhost' && hhCompilation) {
const { currentVersion, optimize, runs } = this.compiler.state
if (currentVersion) {
const fileContent = `module.exports = {
solidity: '${currentVersion.substring(0, currentVersion.indexOf('+commit'))}',
settings: {
optimizer: {
enabled: ${optimize},
runs: ${runs}
if (this.api.getFileManagerMode() === 'localhost') {
if (externalCompType === 'hardhat') {
const { currentVersion, optimize, runs } = this.compiler.state
if (currentVersion) {
const fileContent = `module.exports = {
solidity: '${currentVersion.substring(0, currentVersion.indexOf('+commit'))}',
settings: {
optimizer: {
enabled: ${optimize},
runs: ${runs}
}
}
}
`
const configFilePath = 'remix-compiler.config.js'
this.api.writeFile(configFilePath, fileContent)
_paq.push(['trackEvent', 'compiler', 'compileWithHardhat'])
this.api.compileWithHardhat(configFilePath).then((result) => {
this.api.logToTerminal({ type: 'info', value: result })
}).catch((error) => {
this.api.logToTerminal({ type: 'error', value: error })
})
}
`
const configFilePath = 'remix-compiler.config.js'
this.api.writeFile(configFilePath, fileContent)
_paq.push(['trackEvent', 'compiler', 'compileWithHardhat'])
this.api.compileWithHardhat(configFilePath).then((result) => {
this.api.logToTerminal({ type: 'info', value: result })
}).catch((error) => {
this.api.logToTerminal({ type: 'error', value: error })
})
} else if (externalCompType === 'truffle') {
this.api.compileWithTruffle().then((result) => {
this.api.logToTerminal({ type: 'info', value: result })
}).catch((error) => {
this.api.logToTerminal({ type: 'error', value: error })
})
}
}
// TODO readd saving current file

@ -12,6 +12,7 @@ export const SolidityCompiler = (props: SolidityCompilerProps) => {
const { api, api: { currentFile, compileTabLogic, configurationSettings } } = props
const [state, setState] = useState({
isHardhatProject: false,
isTruffleProject: false,
currentFile,
loading: false,
compileTabLogic: null,
@ -64,8 +65,9 @@ export const SolidityCompiler = (props: SolidityCompilerProps) => {
api.onSetWorkspace = async (isLocalhost: boolean) => {
const isHardhat = isLocalhost && await compileTabLogic.isHardhatProject()
const isTruffle = await compileTabLogic.isTruffleProject()
setState(prevState => {
return { ...prevState, currentFile, isHardhatProject: isHardhat }
return { ...prevState, currentFile, isHardhatProject: isHardhat, isTruffleProject: isTruffle }
})
}
@ -148,7 +150,7 @@ export const SolidityCompiler = (props: SolidityCompilerProps) => {
return (
<>
<div id="compileTabView">
<CompilerContainer api={api} isHardhatProject={state.isHardhatProject} compileTabLogic={compileTabLogic} tooltip={toast} modal={modal} compiledFileName={currentFile} updateCurrentVersion={updateCurrentVersion} configurationSettings={configurationSettings} />
<CompilerContainer api={api} isHardhatProject={state.isHardhatProject} isTruffleProject={state.isTruffleProject} compileTabLogic={compileTabLogic} tooltip={toast} modal={modal} compiledFileName={currentFile} updateCurrentVersion={updateCurrentVersion} configurationSettings={configurationSettings} />
{ contractsFile[currentFile] && contractsFile[currentFile].contractsDetails && <ContractSelection api={api} contractsDetails={contractsFile[currentFile].contractsDetails} contractList={contractsFile[currentFile].contractList} modal={modal} /> }
{ compileErrors[currentFile] &&
<div className="remixui_errorBlobs p-4" data-id="compiledErrors">

@ -10,6 +10,7 @@ export interface CompilerContainerProps {
api: ICompilerApi,
compileTabLogic: CompileTabLogic,
isHardhatProject: boolean,
isTruffleProject: boolean,
tooltip: (message: string | JSX.Element) => void,
modal: (title: string, message: string | JSX.Element, okLabel: string, okFn: () => void, cancelLabel?: string, cancelFn?: () => void) => void,
compiledFileName: string,

@ -25,6 +25,7 @@ async function warnLatestVersion () {
const services = {
git: (readOnly: boolean) => new servicesList.GitClient(readOnly),
hardhat: (readOnly: boolean) => new servicesList.HardhatClient(readOnly),
truffle: (readOnly: boolean) => new servicesList.TruffleClient(readOnly),
slither: (readOnly: boolean) => new servicesList.SlitherClient(readOnly),
folder: (readOnly: boolean) => new servicesList.Sharedfolder(readOnly)
}
@ -34,11 +35,12 @@ const ports = {
git: 65521,
hardhat: 65522,
slither: 65523,
truffle: 65524,
folder: 65520
}
const killCallBack: Array<any> = [] // any is function
function startService<S extends 'git' | 'hardhat' | 'slither' | 'folder'> (service: S, callback: (ws: WS, sharedFolderClient: servicesList.Sharedfolder, error?:Error) => void) {
function startService<S extends 'git' | 'hardhat' | 'truffle' | 'slither' | 'folder'> (service: S, callback: (ws: WS, sharedFolderClient: servicesList.Sharedfolder, error?:Error) => void) {
const socket = new WebSocket(ports[service], { remixIdeUrl: program.remixIde }, () => services[service](program.readOnly || false))
socket.start(callback)
killCallBack.push(socket.close.bind(socket))
@ -100,6 +102,18 @@ function errorHandler (error: any, service: string) {
sharedFolderClient.setWebSocket(ws)
sharedFolderClient.sharedFolder(program.sharedFolder)
})
// Run truffle service if a truffle project is shared as folder
const truffleConfigFilePath = absolutePath('./', program.sharedFolder) + '/truffle-config.js'
if (existsSync(truffleConfigFilePath)) {
startService('truffle', (ws: WS, sharedFolderClient: servicesList.Sharedfolder, error: any) => {
if (error) {
errorHandler(error, 'truffle')
return false
}
sharedFolderClient.setWebSocket(ws)
sharedFolderClient.sharedFolder(program.sharedFolder)
})
}
// Run hardhat service if a hardhat project is shared as folder
const hardhatConfigFilePath = absolutePath('./', program.sharedFolder)
const isHardhatProject = existsSync(hardhatConfigFilePath + '/hardhat.config.js') || existsSync(hardhatConfigFilePath + '/hardhat.config.ts')

@ -2,6 +2,7 @@
import { RemixdClient as sharedFolder } from './services/remixdClient'
import { GitClient } from './services/gitClient'
import { HardhatClient } from './services/hardhatClient'
import { TruffleClient } from './services/truffleClient'
import { SlitherClient } from './services/slitherClient'
import Websocket from './websocket'
import * as utils from './utils'
@ -13,6 +14,7 @@ module.exports = {
sharedFolder,
GitClient,
HardhatClient,
TruffleClient,
SlitherClient
}
}

@ -1,4 +1,5 @@
export { RemixdClient as Sharedfolder } from './services/remixdClient'
export { GitClient } from './services/gitClient'
export { HardhatClient } from './services/hardhatClient'
export { TruffleClient } from './services/truffleClient'
export { SlitherClient } from './services/slitherClient'

@ -0,0 +1,50 @@
import * as WS from 'ws' // eslint-disable-line
import { PluginClient } from '@remixproject/plugin'
const { spawn } = require('child_process') // eslint-disable-line
export class TruffleClient extends PluginClient {
methods: Array<string>
websocket: WS
currentSharedFolder: string
constructor (private readOnly = false) {
super()
this.methods = ['compile']
}
setWebSocket (websocket: WS): void {
this.websocket = websocket
}
sharedFolder (currentSharedFolder: string): void {
this.currentSharedFolder = currentSharedFolder
}
compile () {
return new Promise((resolve, reject) => {
if (this.readOnly) {
const errMsg = '[Truffle Compilation]: Cannot compile in read-only mode'
return reject(new Error(errMsg))
}
const cmd = `truffle compile`
const options = { cwd: this.currentSharedFolder, shell: true }
const child = spawn(cmd, options)
let result = ''
let error = ''
child.stdout.on('data', (data) => {
console.log('data in truffle-->', data)
const msg = `[Truffle Compilation]: ${data.toString()}`
console.log('\x1b[32m%s\x1b[0m', msg)
result += msg + '\n'
})
child.stderr.on('data', (err) => {
error += `[Truffle Compilation]: ${err.toString()} \n`
})
child.on('close', () => {
if (error && result) resolve(error + result)
else if (error) reject(error)
else resolve(result)
})
})
}
}

@ -20,7 +20,8 @@ export default class WebSocket {
65520: 'remixd',
65521: 'git',
65522: 'hardhat',
65523: 'slither'
65523: 'slither',
65524: 'truffle'
}
this.server.on('error', (error: Error) => {

Loading…
Cancel
Save