compilersloaded

desktopoffline
filip mertens 1 year ago
parent 1f276f245f
commit 9ee5b4c3cd
  1. 5
      apps/remix-ide/src/app.js
  2. 31
      apps/remix-ide/src/app/plugins/electron/compilerLoaderPlugin.ts
  3. 1
      apps/remix-ide/src/app/tabs/locales/en/solidity.json
  4. 3
      apps/remixdesktop/src/engine.ts
  5. 10
      apps/remixdesktop/src/main.ts
  6. 70
      apps/remixdesktop/src/plugins/compilerLoader.ts
  7. 2
      apps/remixdesktop/src/preload.ts
  8. 3
      apps/remixdesktop/src/utils/config.ts
  9. 2
      libs/remix-lib/src/types/ICompilerApi.ts
  10. 15
      libs/remix-ui/solidity-compiler/src/lib/api/compiler-api.ts
  11. 45
      libs/remix-ui/solidity-compiler/src/lib/compiler-container.tsx
  12. 10
      libs/remix-ui/solidity-compiler/src/lib/solidity-compiler.tsx
  13. 3
      libs/remix-ui/solidity-compiler/src/lib/types/index.ts
  14. 5
      yarn.lock

@ -55,6 +55,7 @@ import { electronConfig } from './app/plugins/electron/electronConfigPlugin'
import { electronTemplates } from './app/plugins/electron/templatesPlugin'
import { xtermPlugin } from './app/plugins/electron/xtermPlugin'
import { ripgrepPlugin } from './app/plugins/electron/ripgrepPlugin'
import { compilerLoaderPlugin } from './app/plugins/electron/compilerLoaderPlugin'
import {OpenAIGpt} from './app/plugins/openaigpt'
const isElectron = require('is-electron')
@ -365,6 +366,8 @@ class AppComponent {
this.engine.register([xterm])
const ripgrep = new ripgrepPlugin()
this.engine.register([ripgrep])
const compilerloader = new compilerLoaderPlugin()
this.engine.register([compilerloader])
}
// LAYOUT & SYSTEM VIEWS
@ -484,7 +487,7 @@ class AppComponent {
await this.appManager.activatePlugin(['solidity-script', 'remix-templates'])
if(isElectron()){
await this.appManager.activatePlugin(['isogit', 'electronconfig', 'electronTemplates', 'xterm', 'ripgrep'])
await this.appManager.activatePlugin(['isogit', 'electronconfig', 'electronTemplates', 'xterm', 'ripgrep', 'compilerloader'])
}
this.appManager.on(

@ -0,0 +1,31 @@
import { ElectronPlugin } from '@remixproject/engine-electron';
export class compilerLoaderPlugin extends ElectronPlugin {
constructor() {
super({
displayName: 'compilerLoader',
name: 'compilerloader',
description: 'Loads the compiler for offline use',
})
this.methods = []
}
onActivation(): void {
this.on('compilerloader', 'downloadFinished', (path, url) => {
console.log('downloadFinished', path, url)
this.call('terminal', 'logHtml', 'Compiler downloaded from ' + url + ' to ' + path)
})
this.on('solidity', 'loadingCompiler', async (url) => {
console.log('loadingCompiler in compilerloader', url, this)
this.call('terminal', 'logHtml', 'Downloading compiler from ' + url)
await this.call('compilerloader', 'downloadCompiler', url)
const compilerList = await this.call('compilerloader', 'listCompilers')
console.log('compilerList', compilerList)
this.emit('compilersDownloaded', compilerList)
})
}
}

@ -6,6 +6,7 @@
"solidity.addACustomCompiler": "Add a custom compiler",
"solidity.addACustomCompilerWithURL": "Add a custom compiler with URL",
"solidity.includeNightlyBuilds": "Include nightly builds",
"solidity.downloadedCompilers": "Show downloaded only",
"solidity.autoCompile": "Auto compile",
"solidity.hideWarnings": "Hide warnings",
"solidity.enableHardhat": "Enable Hardhat Compilation",

@ -8,6 +8,7 @@ import { IsoGitPlugin } from './plugins/isoGitPlugin';
import { ConfigPlugin } from './plugins/configPlugin';
import { TemplatesPlugin } from './plugins/templates';
import { RipgrepPlugin } from './plugins/ripgrepPlugin';
import { CompilerLoaderPlugin } from './plugins/compilerLoader';
const engine = new Engine()
const appManager = new PluginManager()
@ -17,6 +18,7 @@ const isoGitPlugin = new IsoGitPlugin()
const configPlugin = new ConfigPlugin()
const templatesPlugin = new TemplatesPlugin()
const ripgrepPlugin = new RipgrepPlugin()
const compilerLoaderPlugin = new CompilerLoaderPlugin()
engine.register(appManager)
engine.register(fsPlugin)
engine.register(xtermPlugin)
@ -24,6 +26,7 @@ engine.register(isoGitPlugin)
engine.register(configPlugin)
engine.register(templatesPlugin)
engine.register(ripgrepPlugin)
engine.register(compilerLoaderPlugin)
appManager.activatePlugin('electronconfig')
appManager.activatePlugin('fs')

@ -114,13 +114,3 @@ WindowMenu(commandKeys, execCommand, []),
Menu.setApplicationMenu(Menu.buildFromTemplate(menu))
import express from 'express';
import { cacheDir } from './utils/config'
const appExpress = express()
console.log('cacheDir', cacheDir)
appExpress.use(express.static(cacheDir))
const server = appExpress.listen(0, () => {
console.log('Listening on port:', (server.address() as any).port);
});

@ -1,6 +1,74 @@
import {PluginClient} from '@remixproject/plugin'
import {Profile} from '@remixproject/plugin-utils'
import {
ElectronBasePlugin,
ElectronBasePluginClient,
} from '@remixproject/plugin-electron'
import fs from 'fs/promises'
import express from 'express';
import { cacheDir } from '../utils/config'
const appExpress = express()
console.log('cacheDir', cacheDir)
appExpress.use(express.static(cacheDir))
const server = appExpress.listen(0, () => {
console.log('Listening on port:', (server.address() as any));
});
const profile: Profile = {
displayName: 'compilerLoader',
name: 'compilerloader',
description: 'Compiler Loader',
}
export class CompilerLoaderPlugin extends ElectronBasePlugin {
clients: CompilerLoaderPluginClient[] = []
constructor() {
super(profile, clientProfile, CompilerLoaderPluginClient)
this.methods = [...super.methods, 'getPort']
}
async getPort(): Promise<number> {
return (server.address() as any).port
}
}
const clientProfile: Profile = {
name: 'compilerloader',
displayName: 'compilerloader',
description: 'Compiler Loader',
methods: ['getPort', 'downloadCompiler', 'listCompilers'],
}
class CompilerLoaderPluginClient extends ElectronBasePluginClient {
constructor(webContentsId: number, profile: Profile) {
super(webContentsId, profile)
}
async getPort(): Promise<number> {
return (server.address() as any).port
}
async downloadCompiler(url: string): Promise<void> {
console.log('downloadCompiler', url)
this.emit('downloadStarted', url)
const res = await fetch(url)
const buffer = await res.arrayBuffer()
const file = Buffer.from(buffer)
const fileName = url.split('/').pop()
if (fileName) {
const filePath = cacheDir + '/compilers/' + fileName
await fs.writeFile(filePath, file)
console.log('downloaded', filePath)
this.emit('downloadFinished', fileName, url)
}
}
async listCompilers(): Promise<string[]> {
const compilersDir = cacheDir + '/compilers/'
const compilers = await fs.readdir(compilersDir)
return compilers
}
}

@ -6,7 +6,7 @@ console.log('preload.ts', new Date().toLocaleTimeString())
/* preload script needs statically defined API for each plugin */
const exposedPLugins = ['fs', 'git', 'xterm', 'isogit', 'electronconfig', 'electronTemplates', 'ripgrep']
const exposedPLugins = ['fs', 'git', 'xterm', 'isogit', 'electronconfig', 'electronTemplates', 'ripgrep', 'compilerloader']
let webContentsId: number | undefined

@ -10,6 +10,9 @@ try {
if (!fs.existsSync(cacheDir)) {
fs.mkdirSync(cacheDir)
}
if (!fs.existsSync(cacheDir + '/compilers')) {
fs.mkdirSync(cacheDir + '/compilers')
}
if(!fs.existsSync(cacheDir + '/remixdesktop.json')) {
fs.writeFileSync(cacheDir + '/remixdesktop.json', JSON.stringify({}))
}

@ -46,6 +46,8 @@ export interface ICompilerApi {
compileWithTruffle: (configPath: string) => Promise<string>
statusChanged: (data: { key: string, title?: string, type?: string }) => void,
emit?: (key: string, ...payload: any) => void
compilersDownloaded: (list: string[]) => void
}
export type terminalLog = {

@ -28,6 +28,8 @@ export const CompilerApiMixin = (Base) => class extends Base {
onFileClosed: (name: string) => void
statusChanged: (data: { key: string, title?: string, type?: string }) => void
compilersDownloaded: (list: string[]) => void
initCompilerApi () {
this.configurationSettings = null
@ -278,6 +280,19 @@ export const CompilerApiMixin = (Base) => class extends Base {
this.on('fileManager', 'fileClosed', this.data.eventHandlers.onFileClosed)
this.on('compilerloader', 'downloadFinished', (path, url) => {
console.log('downloadFinished', path, url)
})
this.on('compilerloader', 'downloadStarted', (url) => {
console.log('downloadStarted', url)
})
this.on('compilerloader', 'compilersDownloaded', (list: string[]) => {
console.log('compilersDownloaded', list)
this.compilersDownloaded(list)
})
this.data.eventHandlers.onCompilationFinished = async (success, data, source, input, version) => {
this.compileErrors = data
if (success) {

@ -41,6 +41,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
workspaceName,
configFilePath,
setConfigFilePath,
compilersDownloaded,
//@ts-ignore
pluginProps
} = props // eslint-disable-line
@ -55,6 +56,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
timeout: 300,
allversions: [],
customVersions: [],
downloaded: [],
compilerLicense: null,
selectedVersion: null,
defaultVersion: 'soljson-v0.8.22+commit.4fc1097e.js', // this default version is defined: in makeMockCompiler (for browser test)
@ -63,7 +65,8 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
includeNightlies: false,
language: 'Solidity',
evmVersion: '',
createFileOnce: true
createFileOnce: true,
onlyDownloaded: false
})
const [showFilePathInput, setShowFilePathInput] = useState<boolean>(false)
const [toggleExpander, setToggleExpander] = useState<boolean>(false)
@ -119,6 +122,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
useEffect(() => {
fetchAllVersion((allversions, selectedVersion, isURL) => {
console.log('allversions', allversions)
setState((prevState) => {
return {...prevState, allversions}
})
@ -229,6 +233,28 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
}
}, [configurationSettings])
useEffect(() => {
console.log('compilersDownloaded', compilersDownloaded)
setState((prevState) => {
return {...prevState, downloaded: compilersDownloaded}
})
},[compilersDownloaded])
useEffect(() => {
updateAllVersionsWithDownloadStatus()
}, [state.downloaded])
const updateAllVersionsWithDownloadStatus = () => {
const updatedAllVersions = state.allversions.map((version) => {
version.isDownloaded = state.downloaded.includes(version.path)
return version
})
console.log('updatedAllVersions', updatedAllVersions)
setState((prevState) => {
return {...prevState, allversions: updatedAllVersions}
})
}
const toggleConfigType = () => {
if (state.useFileConfiguration)
if (state.createFileOnce) {
@ -708,6 +734,14 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
})
}
const handleOnlyDownloadedChange = (e) => {
const checked = e.target.checked
if (!checked) handleLoadVersion(state.defaultVersion)
setState((prevState) => {
return {...prevState, onlyDownloaded: checked}
})
}
const handleLanguageChange = (value) => {
compileTabLogic.setLanguage(value)
state.autoCompile && compile()
@ -797,10 +831,11 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
data-id={`dropdown-item-${build.value}`}
>
<div className='d-flex w-100'>
{state.selectedVersion === build.path ? <span className='fas fa-check text-success mr-2'></span> : null}
<span className="">
{build.longVersion}
</span>
<span className='far fa-arrow-circle-down'></span>
{build.isDownloaded?<span className='fas fa-arrow-circle-down text-success'></span>:<span className='far fa-arrow-circle-down'></span>}
</div>
</Dropdown.Item>
) : null
@ -844,6 +879,12 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
<FormattedMessage id="solidity.includeNightlyBuilds" />
</label>
</div>
<div className="mb-2 flex-row-reverse remixui_nightlyBuilds custom-control custom-checkbox">
<input className="mr-2 custom-control-input" id="nightlies" type="checkbox" onChange={handleOnlyDownloadedChange} checked={state.includeNightlies} />
<label htmlFor="nightlies" data-id="compilerNightliesBuild" className="form-check-label custom-control-label">
<FormattedMessage id="solidity.downloadedCompilers" />
</label>
</div>
<div className="mt-2 remixui_compilerConfig custom-control custom-checkbox">
<input
className="remixui_autocompile custom-control-input"

@ -35,7 +35,8 @@ export const SolidityCompiler = (props: SolidityCompilerProps) => {
cancelLabel: '',
cancelFn: () => {},
handleHide: null
}
},
compilersDownloaded: []
})
const [currentVersion, setCurrentVersion] = useState('')
const [hideWarnings, setHideWarnings] = useState<boolean>(false)
@ -135,6 +136,12 @@ export const SolidityCompiler = (props: SolidityCompilerProps) => {
setBadgeStatus({...badgeStatus, [currentFile]: data})
}
api.compilersDownloaded = (list: string[]) => {
setState((prevState) => {
return {...prevState, compilersDownloaded: list}
})
}
const setConfigFilePath = (path: string) => {
setState((prevState) => {
return {...prevState, configFilePath: path}
@ -222,6 +229,7 @@ export const SolidityCompiler = (props: SolidityCompilerProps) => {
configurationSettings={configurationSettings}
configFilePath={state.configFilePath}
setConfigFilePath={setConfigFilePath}
compilersDownloaded={state.compilersDownloaded}
/>
{contractsFile[currentFile] && contractsFile[currentFile].contractsDetails && (

@ -20,7 +20,8 @@ export interface CompilerContainerProps {
updateCurrentVersion: any,
configurationSettings: ConfigurationSettings,
configFilePath: string,
setConfigFilePath: (path: string) => void
setConfigFilePath: (path: string) => void,
compilersDownloaded: string[]
}
export interface ContractSelectionProps {
api: ICompilerApi,

@ -24713,6 +24713,11 @@ rlp@^2.2.4:
dependencies:
bn.js "^5.2.0"
rlp@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/rlp/-/rlp-3.0.0.tgz#5a60725ca4314a3a165feecca1836e4f2c1e2343"
integrity sha512-PD6U2PGk6Vq2spfgiWZdomLvRGDreBLxi5jv5M8EpRo3pU6VEm31KO+HFxE18Q3vgqfDrQ9pZA3FP95rkijNKw==
roarr@^2.15.3:
version "2.15.4"
resolved "https://registry.yarnpkg.com/roarr/-/roarr-2.15.4.tgz#f5fe795b7b838ccfe35dc608e0282b9eba2e7afd"

Loading…
Cancel
Save