From 9ee5b4c3cd334216910e15da4ce4060823b94c37 Mon Sep 17 00:00:00 2001 From: filip mertens Date: Wed, 8 Nov 2023 18:17:51 +0100 Subject: [PATCH] compilersloaded --- apps/remix-ide/src/app.js | 5 +- .../plugins/electron/compilerLoaderPlugin.ts | 31 ++++++++ .../src/app/tabs/locales/en/solidity.json | 1 + apps/remixdesktop/src/engine.ts | 3 + apps/remixdesktop/src/main.ts | 10 --- .../src/plugins/compilerLoader.ts | 70 ++++++++++++++++++- apps/remixdesktop/src/preload.ts | 2 +- apps/remixdesktop/src/utils/config.ts | 3 + libs/remix-lib/src/types/ICompilerApi.ts | 2 + .../src/lib/api/compiler-api.ts | 15 ++++ .../src/lib/compiler-container.tsx | 45 +++++++++++- .../src/lib/solidity-compiler.tsx | 10 ++- .../solidity-compiler/src/lib/types/index.ts | 3 +- yarn.lock | 5 ++ 14 files changed, 188 insertions(+), 17 deletions(-) create mode 100644 apps/remix-ide/src/app/plugins/electron/compilerLoaderPlugin.ts diff --git a/apps/remix-ide/src/app.js b/apps/remix-ide/src/app.js index 01b1b6ff08..6f4a98e363 100644 --- a/apps/remix-ide/src/app.js +++ b/apps/remix-ide/src/app.js @@ -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( diff --git a/apps/remix-ide/src/app/plugins/electron/compilerLoaderPlugin.ts b/apps/remix-ide/src/app/plugins/electron/compilerLoaderPlugin.ts new file mode 100644 index 0000000000..432ce4648b --- /dev/null +++ b/apps/remix-ide/src/app/plugins/electron/compilerLoaderPlugin.ts @@ -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) + }) + } + + +} \ No newline at end of file diff --git a/apps/remix-ide/src/app/tabs/locales/en/solidity.json b/apps/remix-ide/src/app/tabs/locales/en/solidity.json index 6d845ce618..adddb8dfdd 100644 --- a/apps/remix-ide/src/app/tabs/locales/en/solidity.json +++ b/apps/remix-ide/src/app/tabs/locales/en/solidity.json @@ -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", diff --git a/apps/remixdesktop/src/engine.ts b/apps/remixdesktop/src/engine.ts index ab60641257..bd7962bd60 100644 --- a/apps/remixdesktop/src/engine.ts +++ b/apps/remixdesktop/src/engine.ts @@ -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') diff --git a/apps/remixdesktop/src/main.ts b/apps/remixdesktop/src/main.ts index b515806051..6a95f3206b 100644 --- a/apps/remixdesktop/src/main.ts +++ b/apps/remixdesktop/src/main.ts @@ -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); -}); \ No newline at end of file diff --git a/apps/remixdesktop/src/plugins/compilerLoader.ts b/apps/remixdesktop/src/plugins/compilerLoader.ts index 4bed80ee16..3b40a4bfa1 100644 --- a/apps/remixdesktop/src/plugins/compilerLoader.ts +++ b/apps/remixdesktop/src/plugins/compilerLoader.ts @@ -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 { + 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 { + return (server.address() as any).port + } + + async downloadCompiler(url: string): Promise { + 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 { + const compilersDir = cacheDir + '/compilers/' + const compilers = await fs.readdir(compilersDir) + return compilers + } +} \ No newline at end of file diff --git a/apps/remixdesktop/src/preload.ts b/apps/remixdesktop/src/preload.ts index f7eb174569..007fe098e9 100644 --- a/apps/remixdesktop/src/preload.ts +++ b/apps/remixdesktop/src/preload.ts @@ -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 diff --git a/apps/remixdesktop/src/utils/config.ts b/apps/remixdesktop/src/utils/config.ts index 6fa25244c8..6491a6e557 100644 --- a/apps/remixdesktop/src/utils/config.ts +++ b/apps/remixdesktop/src/utils/config.ts @@ -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({})) } diff --git a/libs/remix-lib/src/types/ICompilerApi.ts b/libs/remix-lib/src/types/ICompilerApi.ts index 168107e660..014fa3966e 100644 --- a/libs/remix-lib/src/types/ICompilerApi.ts +++ b/libs/remix-lib/src/types/ICompilerApi.ts @@ -46,6 +46,8 @@ export interface ICompilerApi { compileWithTruffle: (configPath: string) => Promise statusChanged: (data: { key: string, title?: string, type?: string }) => void, emit?: (key: string, ...payload: any) => void + + compilersDownloaded: (list: string[]) => void } export type terminalLog = { diff --git a/libs/remix-ui/solidity-compiler/src/lib/api/compiler-api.ts b/libs/remix-ui/solidity-compiler/src/lib/api/compiler-api.ts index e20134f331..e5094000fa 100644 --- a/libs/remix-ui/solidity-compiler/src/lib/api/compiler-api.ts +++ b/libs/remix-ui/solidity-compiler/src/lib/api/compiler-api.ts @@ -27,6 +27,8 @@ export const CompilerApiMixin = (Base) => class extends Base { onContentChanged: () => void 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) { diff --git a/libs/remix-ui/solidity-compiler/src/lib/compiler-container.tsx b/libs/remix-ui/solidity-compiler/src/lib/compiler-container.tsx index d0b8f1aa4b..bb62d1c111 100644 --- a/libs/remix-ui/solidity-compiler/src/lib/compiler-container.tsx +++ b/libs/remix-ui/solidity-compiler/src/lib/compiler-container.tsx @@ -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(false) const [toggleExpander, setToggleExpander] = useState(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}`} >
+ {state.selectedVersion === build.path ? : null} {build.longVersion} - + {build.isDownloaded?:}
) : null @@ -844,6 +879,12 @@ export const CompilerContainer = (props: CompilerContainerProps) => { +
+ + +
{ cancelLabel: '', cancelFn: () => {}, handleHide: null - } + }, + compilersDownloaded: [] }) const [currentVersion, setCurrentVersion] = useState('') const [hideWarnings, setHideWarnings] = useState(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 && ( diff --git a/libs/remix-ui/solidity-compiler/src/lib/types/index.ts b/libs/remix-ui/solidity-compiler/src/lib/types/index.ts index 4b991c0f4c..f95d0116a4 100644 --- a/libs/remix-ui/solidity-compiler/src/lib/types/index.ts +++ b/libs/remix-ui/solidity-compiler/src/lib/types/index.ts @@ -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, diff --git a/yarn.lock b/yarn.lock index 0212e5a7d4..c6e801c48d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -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"