diff --git a/.circleci/config.yml b/.circleci/config.yml index 11c6ede82b..d865907c91 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -30,16 +30,16 @@ jobs: - restore_cache: keys: - v1-deps-{{ checksum "package-lock.json" }} - - run: npm install + - run: yarn install - save_cache: key: v1-deps-{{ checksum "package-lock.json" }} paths: - node_modules - - run: npm run downloadsolc_assets + - run: yarn run downloadsolc_assets - run: npx nx build remix-ide - run: npx nx build remix-ide-e2e-src-local-plugin - - run: npm run build:libs + - run: yarn run build:libs - run: mkdir persist && zip -r persist/dist.zip dist - persist_to_workspace: root: . @@ -65,7 +65,7 @@ jobs: - restore_cache: keys: - v1-deps-{{ checksum "package-lock.json" }} - - run: npm install + - run: yarn install - run: name: Remix Libs Linting command: ./apps/remix-ide/ci/lint.sh @@ -92,9 +92,9 @@ jobs: - restore_cache: keys: - v1-deps-{{ checksum "package-lock.json" }} - - run: npm i - - run: cd dist/libs/remix-tests && npm install - - run: npm run test:libs + - run: yarn install + - run: cd dist/libs/remix-tests && yarn install + - run: yarn run test:libs remix-ide-chrome: docker: @@ -128,7 +128,7 @@ jobs: - restore_cache: keys: - v1-deps-{{ checksum "package-lock.json" }} - - run: npm install + - run: yarn install - run: name: Start Selenium command: java -jar /usr/local/bin/selenium.jar @@ -171,7 +171,7 @@ jobs: - restore_cache: keys: - v1-deps-{{ checksum "package-lock.json" }} - - run: npm install + - run: yarn install - run: name: Start Selenium command: java -jar /usr/local/bin/selenium.jar @@ -214,7 +214,7 @@ jobs: - restore_cache: keys: - v1-deps-{{ checksum "package-lock.json" }} - - run: npm install + - run: yarn install - run: name: Start Selenium command: java -jar /usr/local/bin/selenium.jar @@ -256,7 +256,7 @@ jobs: - restore_cache: keys: - v1-deps-{{ checksum "package-lock.json" }} - - run: npm install + - run: yarn install - run: name: Start Selenium command: java -jar /usr/local/bin/selenium.jar @@ -299,7 +299,7 @@ jobs: - restore_cache: keys: - v1-deps-{{ checksum "package-lock.json" }} - - run: npm install + - run: yarn install - run: name: Start Selenium command: java -jar /usr/local/bin/selenium.jar @@ -328,9 +328,9 @@ jobs: steps: - checkout - - run: npm install - - run: npm run downloadsolc_assets - - run: npm run build:production + - run: yarn install + - run: yarn run downloadsolc_assets + - run: yarn run build:production - run: name: Deploy command: | @@ -357,9 +357,9 @@ jobs: steps: - checkout - - run: npm install - - run: npm run downloadsolc_assets - - run: npm run build:production + - run: yarn install + - run: yarn run downloadsolc_assets + - run: yarn run build:production - run: name: Deploy command: | @@ -385,10 +385,10 @@ jobs: steps: - checkout - - run: npm install - - run: npm run build:libs - - run: npm run downloadsolc_assets - - run: npm run build:production + - run: yarn install + - run: yarn run build:libs + - run: yarn run downloadsolc_assets + - run: yarn run build:production - run: name: Deploy command: | diff --git a/.github/workflows/publish-action.yml b/.github/workflows/publish-action.yml index b023c4ffcc..3fb3a3031f 100644 --- a/.github/workflows/publish-action.yml +++ b/.github/workflows/publish-action.yml @@ -9,11 +9,11 @@ jobs: steps: - name: Checkout uses: actions/checkout@v2 - - run: npm install + - run: yarn install - run: ls - run: pwd - - run: npm run downloadsolc_assets - - run: npm run build:production + - run: yarn run downloadsolc_assets + - run: yarn run build:production - run: echo "action_state=$('./apps/remix-ide/ci/publishIpfs')" >> $GITHUB_ENV - uses: mshick/add-pr-comment@v1 with: diff --git a/README.md b/README.md index a96b99c249..aea4299352 100644 --- a/README.md +++ b/README.md @@ -8,18 +8,23 @@ [![Twitter Follow](https://img.shields.io/twitter/follow/ethereumremix?style=social)](https://twitter.com/ethereumremix) # Remix Project +**Remix Project** is a rich toolset including Remix IDE, a comprehensive smart contract development tool. The Remix Project also includes Remix Plugin Engine and Remix Libraries which are low-level tools for wider use. -**Remix Project** is a platform for development tools that use a plugin architecture. It encompasses sub-projects including Remix Plugin Engine, Remix Libraries, and of course Remix IDE. +## Remix IDE +**Remix IDE** is used for the entire journey of contract development by users of any knowledge level. It fosters a fast development cycle and has a rich set of plugins with intuitive GUIs. The IDE comes in 2 flavors and a VSCode extension: -**Remix IDE** is an open source web and desktop application. It fosters a fast development cycle and has a rich set of plugins with intuitive GUIs. Remix is used for the **entire journey of contract development with [Solidity language](https://soliditylang.org/)** as well as a playground for learning and teaching [Ethereum](https://ethereum.org/). +**Remix Online IDE**, see: [https://remix.ethereum.org](https://remix.ethereum.org) -Start developing using Remix on browser, visit: [https://remix.ethereum.org](https://remix.ethereum.org) +:point_right: Supported browsers: Firefox v100.0.1 & Chrome v101.0.4951.64. No support for Remix's use on tablets or smartphones or telephones. -For desktop version, see releases: [https://github.com/ethereum/remix-desktop/releases](https://github.com/ethereum/remix-desktop/releases) +**Remix Desktop IDE**, see releases: [https://github.com/ethereum/remix-desktop/releases](https://github.com/ethereum/remix-desktop/releases) -![Remix screenshot](https://github.com/ethereum/remix-project/raw/master/apps/remix-ide/remix_screenshot.png) +![Remix screenshot](https://github.com/ethereum/remix-project/raw/master/apps/remix-ide/remix-screenshot-400h.png) -:point_right: **Remix libraries** work as a core of native plugins of Remix IDE. Read more about libraries [here](libs/README.md) +**VSCode extension**, see: [Ethereum-Remix](https://marketplace.visualstudio.com/items?itemName=RemixProject.ethereum-remix) + +## Remix libraries +Remix libraries are essential for Remix IDE's native plugins. Read more about libraries [here](libs/README.md) ## Offline Usage @@ -30,7 +35,7 @@ Note: It contains the latest supported version of Solidity available at the time ## Setup -* Install **NPM** and **Node.js**. See [Guide](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm)
+* Install **Yarn** and **Node.js**. See [Guide for NodeJs](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) and [Yarn install](https://classic.yarnpkg.com/lang/en/docs/install)
*Supported versions:* ```bash "engines": { @@ -40,7 +45,7 @@ Note: It contains the latest supported version of Solidity available at the time ``` * Install [Nx CLI](https://nx.dev/react/cli/overview) globally to enable running **nx executable commands**. ```bash -npm install -g @nrwl/cli +yarn global add @nrwl/cli ``` * Clone the github repository (`wget` need to be installed first): @@ -50,8 +55,8 @@ git clone https://github.com/ethereum/remix-project.git * Build `remix-project`: ```bash cd remix-project -npm install -npm run build:libs // Build remix libs +yarn install +yarn run build:libs // Build remix libs nx build nx serve ``` @@ -63,12 +68,12 @@ Go to your `text editor` and start developing. Browser will automatically refres ## Production Build To generate react production builds for remix-project. ```bash -npm run build:production +yarn run build:production ``` Build can be found in `remix-project/dist/apps/remix-ide` directory. ```bash -npm run serve:production +yarn run serve:production ``` Production build will be served by default to `http://localhost:8080/` or `http://127.0.0.1:8080/` @@ -133,17 +138,17 @@ For example, to run unit tests of `remix-analyzer`, use `nx test remix-analyzer` To run the Selenium tests via Nightwatch: - - Install Selenium for first time: `npm run selenium-install` - - Run a selenium server: `npm run selenium` + - Install Selenium for first time: `yarn run selenium-install` + - Run a selenium server: `yarn run selenium` - Build & Serve Remix: `nx serve` - Run all the end-to-end tests: - for Firefox: `npm run nightwatch_local_firefox`, or + for Firefox: `yarn run nightwatch_local_firefox`, or - for Google Chrome: `npm run nightwatch_local_chrome` + for Google Chrome: `yarn run nightwatch_local_chrome` - Run a specific test case instead, use a command like this: - - npm run nightwatch_local_ballot + - yarn run nightwatch_local_ballot The package.json file contains a list of all the tests you can run. @@ -163,7 +168,7 @@ To run the Selenium tests via Nightwatch: There is a script to allow selecting the browser and a specific test to run: ``` -npm run select_test +yarn run select_test ``` You need to have @@ -209,13 +214,13 @@ module.exports = { - change package json to locally run all group tests: ``` - "nightwatch_local_debugger": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/debugger_*.spec.js --env=chrome", + "nightwatch_local_debugger": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/debugger_*.spec.js --env=chrome", ``` - run the build script to build the test files if you want to run the locally ``` -npm run build:e2e +yarn run build:e2e ``` ### Locally testing group tests @@ -229,12 +234,12 @@ You can tag any test with a groupname, for example, #group10 and easily run the This script will give you an option menu, just select the test you want ``` -npm run select_test +yarn run select_test ``` #### method 2 ``` -npm run group_test --test=debugger --group=10 --env=chromeDesktop +yarn run group_test --test=debugger --group=10 --env=chromeDesktop ``` - specify chromeDesktop to see the browser action, use 'chrome' to run it headless diff --git a/apps/remix-ide-e2e/src/select_tests.sh b/apps/remix-ide-e2e/src/select_tests.sh index 65fa5c1656..ee1c4e38be 100644 --- a/apps/remix-ide-e2e/src/select_tests.sh +++ b/apps/remix-ide-e2e/src/select_tests.sh @@ -24,7 +24,7 @@ do *) echo "invalid option $REPLY";; esac done -npm run build:e2e +yarn run build:e2e PS3='Select a test or command: ' TESTFILES=( $(grep -IRiL "\'@disabled\': \?true" "dist/apps/remix-ide-e2e/src/tests" | grep "\.spec\|\.test\|plugin_api" | sort ) ) @@ -42,6 +42,6 @@ do done else # run the selected test - npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js $opt --env=$BROWSER + yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js $opt --env=$BROWSER fi done diff --git a/apps/remix-ide-e2e/src/tests/compiler_api.test.ts b/apps/remix-ide-e2e/src/tests/compiler_api.test.ts index 8a6ca27cd3..2adc5a4c62 100644 --- a/apps/remix-ide-e2e/src/tests/compiler_api.test.ts +++ b/apps/remix-ide-e2e/src/tests/compiler_api.test.ts @@ -46,7 +46,7 @@ module.exports = { browser .addFile('test_updateConfiguration.js', { content: updateConfiguration }) .executeScript('remix.exeCurrent()') - .pause(5000) + .pause(15000) .addFile('test_updateConfiguration.sol', { content: simpleContract }) .verifyContracts(['StorageTestUpdateConfiguration'], { wait: 5000, version: '0.6.8+commit.0bbfe453' }) }, diff --git a/apps/remix-ide-e2e/src/tests/fileManager_api.test.ts b/apps/remix-ide-e2e/src/tests/fileManager_api.test.ts index 78e4ee8f1a..32da1f4828 100644 --- a/apps/remix-ide-e2e/src/tests/fileManager_api.test.ts +++ b/apps/remix-ide-e2e/src/tests/fileManager_api.test.ts @@ -71,7 +71,7 @@ module.exports = { .addFile('mkdirFile.js', { content: executeMkdir }) .executeScript('remix.exeCurrent()') .pause(2000) - .waitForElementPresent('[data-id="treeViewLitreeViewItemTest_Folder"]', 60000) + .waitForElementPresent('[data-id="treeViewLitreeViewItemTest_Folder"]', 80000) }, 'Should execute `readdir` api from file manager external api #group3': function (browser: NightwatchBrowser) { diff --git a/apps/remix-ide-e2e/src/tests/plugin_api.ts b/apps/remix-ide-e2e/src/tests/plugin_api.ts index d0cdfacf13..cf696f2bec 100644 --- a/apps/remix-ide-e2e/src/tests/plugin_api.ts +++ b/apps/remix-ide-e2e/src/tests/plugin_api.ts @@ -230,7 +230,13 @@ module.exports = { }, 'Should get current files #group7': async function (browser: NightwatchBrowser) { - await clickAndCheckLog(browser, 'fileManager:readdir', { contracts: { isDirectory: true }, scripts: { isDirectory: true }, tests: { isDirectory: true }, 'README.txt': { isDirectory: false } }, null, '/') + await clickAndCheckLog(browser, 'fileManager:readdir', { + 'compiler_config.json': { isDirectory: false }, + contracts: { isDirectory: true }, + scripts: { isDirectory: true }, + tests: { isDirectory: true }, + 'README.txt': { isDirectory: false } + }, null, '/') }, 'Should throw error on current file #group7': async function (browser: NightwatchBrowser) { await clickAndCheckLog(browser, 'fileManager:getCurrentFile', 'Error from IDE : Error: No such file or directory No file selected', null, null) @@ -280,12 +286,20 @@ module.exports = { 'Should create empty workspace #group2': async function (browser: NightwatchBrowser) { await clickAndCheckLog(browser, 'filePanel:createWorkspace', null, null, ['emptyworkspace', true]) await clickAndCheckLog(browser, 'filePanel:getCurrentWorkspace', { name: 'emptyworkspace', isLocalhost: false, absolutePath: '.workspaces/emptyworkspace' }, null, null) - await clickAndCheckLog(browser, 'fileManager:readdir', {}, null, '/') + await clickAndCheckLog(browser, 'fileManager:readdir', { + 'compiler_config.json': { isDirectory: false } + }, null, '/') }, 'Should create workspace #group2': async function (browser: NightwatchBrowser) { await clickAndCheckLog(browser, 'filePanel:createWorkspace', null, null, 'testspace') await clickAndCheckLog(browser, 'filePanel:getCurrentWorkspace', { name: 'testspace', isLocalhost: false, absolutePath: '.workspaces/testspace' }, null, null) - await clickAndCheckLog(browser, 'fileManager:readdir', { contracts: { isDirectory: true }, scripts: { isDirectory: true }, tests: { isDirectory: true }, 'README.txt': { isDirectory: false } }, null, null) + await clickAndCheckLog(browser, 'fileManager:readdir', { + 'compiler_config.json': { isDirectory: false }, + contracts: { isDirectory: true }, + scripts: { isDirectory: true }, + tests: { isDirectory: true }, + 'README.txt': { isDirectory: false } + }, null, null) }, 'Should get all workspaces #group2': async function (browser: NightwatchBrowser) { await clickAndCheckLog(browser, 'filePanel:getWorkspaces', ['default_workspace', 'emptyworkspace', 'testspace'], null, null) @@ -409,7 +423,7 @@ module.exports = { .addFile('test_modal.js', { content: testModalToasterApi }) .executeScript('remix.execute(\'test_modal.js\')') .useCss() - .waitForElementVisible('*[data-id="test_id_1_ModalDialogModalBody-react"]') + .waitForElementVisible('*[data-id="test_id_1_ModalDialogModalBody-react"]', 60000) .assert.containsText('*[data-id="test_id_1_ModalDialogModalBody-react"]', 'message 1') .modalFooterOKClick('test_id_1_') // check the script runner notifications diff --git a/apps/remix-ide-e2e/src/tests/recorder.test.ts b/apps/remix-ide-e2e/src/tests/recorder.test.ts index fc77f0ef0f..7e1c0859a7 100644 --- a/apps/remix-ide-e2e/src/tests/recorder.test.ts +++ b/apps/remix-ide-e2e/src/tests/recorder.test.ts @@ -17,7 +17,7 @@ module.exports = { .pause(5000) .clickLaunchIcon('udapp') .selectAccount('0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c') // this account will be used for this test suite - .click('[data-id="udapp_arrow"]') + .click('[data-id="udappRecorderTitleExpander"]') .click('[data-id="runtransaction"]') .clickInstance(0) .clickInstance(1) diff --git a/apps/remix-ide-e2e/src/tests/url.test.ts b/apps/remix-ide-e2e/src/tests/url.test.ts index e6233ae2e7..a201b4ea36 100644 --- a/apps/remix-ide-e2e/src/tests/url.test.ts +++ b/apps/remix-ide-e2e/src/tests/url.test.ts @@ -81,6 +81,7 @@ module.exports = { .refresh() .pause(5000) .clickLaunchIcon('solidity') + .click('*[data-id="scConfigExpander"]') .assert.containsText('#versionSelector option[data-id="selected"]', '0.7.4+commit.3f05b770') .assert.containsText('#evmVersionSelector option[data-id="selected"]', 'istanbul') .assert.containsText('#compilierLanguageSelector option[data-id="selected"]', 'Yul') @@ -96,6 +97,7 @@ module.exports = { .pause(5000) .clickLaunchIcon('solidity') .pause(5000) + .click('*[data-id="scConfigExpander"]') .assert.containsText('#versionSelector option[data-id="selected"]', 'custom') // default values .assert.containsText('#evmVersionSelector option[data-id="selected"]', 'default') diff --git a/apps/remix-ide-e2e/src/tests/workspace.test.ts b/apps/remix-ide-e2e/src/tests/workspace.test.ts index e8bde35140..f5fea02e36 100644 --- a/apps/remix-ide-e2e/src/tests/workspace.test.ts +++ b/apps/remix-ide-e2e/src/tests/workspace.test.ts @@ -50,11 +50,42 @@ module.exports = { .assert.elementPresent('*[data-id="treeViewLitreeViewItemcontracts/3_Ballot.sol"]') .assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts"]') .assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/deploy_with_web3.ts"]') + // check js and ts files are not transformed + .click('*[data-id="treeViewLitreeViewItemscripts/deploy_with_web3.ts"]') + + .getEditorValue((content) => { + browser.assert.ok(content.indexOf(`import { deploy } from './web3-lib'`) !== -1, + 'Incorrect content') + }) .assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/deploy_with_ethers.ts"]') + .click('*[data-id="treeViewLitreeViewItemscripts/deploy_with_ethers.ts"]') + .pause(100) + .getEditorValue((content) => { + browser.assert.ok(content.indexOf(`import { deploy } from './ethers-lib'`) !== -1, + 'Incorrect content') + }) .assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/web3-lib.ts"]') + .click('*[data-id="treeViewLitreeViewItemscripts/web3-lib.ts"]') + .pause(2000) + .getEditorValue((content) => { + browser.assert.ok(content.indexOf(`export const deploy = async (contractName: string, args: Array, from?: string, gas?: number): Promise => {`) !== -1, + 'Incorrect content') + }) .assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/ethers-lib.ts"]') + .click('*[data-id="treeViewLitreeViewItemscripts/ethers-lib.ts"]') + .pause(100) + .getEditorValue((content) => { + browser.assert.ok(content.indexOf(`export const deploy = async (contractName: string, args: Array, from?: string): Promise => { `) !== -1, + 'Incorrect content') + }) .assert.elementPresent('*[data-id="treeViewLitreeViewItemtests"]') .assert.elementPresent('*[data-id="treeViewLitreeViewItemtests/storage.test.js"]') + .click('*[data-id="treeViewLitreeViewItemtests/storage.test.js"]') + .pause(100) + .getEditorValue((content) => { + browser.assert.ok(content.indexOf(`const { expect } = require("chai");`) !== -1, + 'Incorrect content') + }) .assert.elementPresent('*[data-id="treeViewLitreeViewItemtests/Ballot_test.sol"]') .assert.elementPresent('*[data-id="treeViewLitreeViewItemREADME.txt"]') }, @@ -70,14 +101,14 @@ module.exports = { .click('select[id="wstemplate"] option[value=blank]') .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') .execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() }) - .pause(1000) + .pause(100) .assert.elementPresent('*[data-id="treeViewUltreeViewMenu"]') .execute(function () { const fileList = document.querySelector('*[data-id="treeViewUltreeViewMenu"]') return fileList.getElementsByTagName('li').length; }, [], function(result){ - // check there are no files in FE - browser.assert.equal(result.value, 0, 'Incorrect number of files'); + // check there are no files in FE except config file + browser.assert.equal(result.value, 1, 'Incorrect number of files'); }); }, @@ -92,18 +123,91 @@ module.exports = { .click('select[id="wstemplate"] option[value=ozerc20]') .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') .execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() }) - .pause(1000) + .pause(100) .assert.elementPresent('*[data-id="treeViewLitreeViewItemcontracts"]') .assert.elementPresent('*[data-id="treeViewLitreeViewItemcontracts/SampleERC20.sol"]') .assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts"]') .assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/deploy_with_web3.ts"]') + // check js and ts files are not transformed + .click('*[data-id="treeViewLitreeViewItemscripts/deploy_with_web3.ts"]') + + .getEditorValue((content) => { + browser.assert.ok(content.indexOf(`import { deploy } from './web3-lib'`) !== -1, + 'Incorrect content') + }) .assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/deploy_with_ethers.ts"]') + .click('*[data-id="treeViewLitreeViewItemscripts/deploy_with_ethers.ts"]') + .pause(100) + .getEditorValue((content) => { + browser.assert.ok(content.indexOf(`import { deploy } from './ethers-lib'`) !== -1, + 'Incorrect content') + }) .assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/web3-lib.ts"]') + .click('*[data-id="treeViewLitreeViewItemscripts/web3-lib.ts"]') + .pause(100) + .getEditorValue((content) => { + browser.assert.ok(content.indexOf(`export const deploy = async (contractName: string, args: Array, from?: string, gas?: number): Promise => {`) !== -1, + 'Incorrect content') + }) .assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/ethers-lib.ts"]') + .click('*[data-id="treeViewLitreeViewItemscripts/ethers-lib.ts"]') + .pause(100) + .getEditorValue((content) => { + browser.assert.ok(content.indexOf(`export const deploy = async (contractName: string, args: Array, from?: string): Promise => { `) !== -1, + 'Incorrect content') + }) .assert.elementPresent('*[data-id="treeViewLitreeViewItemtests"]') .assert.elementPresent('*[data-id="treeViewLitreeViewItemtests/SampleERC20_test.sol"]') }, + 'Should create ERC721 workspace with files': function (browser: NightwatchBrowser) { + browser + .click('*[data-id="workspaceCreate"]') + .waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]') + .waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > span') + // eslint-disable-next-line dot-notation + .execute(function () { document.querySelector('*[data-id="modalDialogCustomPromptTextCreate"]')['value'] = 'workspace_erc721' }) + .click('select[id="wstemplate"]') + .click('select[id="wstemplate"] option[value=ozerc721]') + .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') + .execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() }) + .pause(100) + .assert.elementPresent('*[data-id="treeViewLitreeViewItemcontracts"]') + .assert.elementPresent('*[data-id="treeViewLitreeViewItemcontracts/SampleERC721.sol"]') + .assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts"]') + .assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/deploy_with_web3.ts"]') + // check js and ts files are not transformed + .click('*[data-id="treeViewLitreeViewItemscripts/deploy_with_web3.ts"]') + + .getEditorValue((content) => { + browser.assert.ok(content.indexOf(`import { deploy } from './web3-lib'`) !== -1, + 'Incorrect content') + }) + .assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/deploy_with_ethers.ts"]') + .click('*[data-id="treeViewLitreeViewItemscripts/deploy_with_ethers.ts"]') + .pause(100) + .getEditorValue((content) => { + browser.assert.ok(content.indexOf(`import { deploy } from './ethers-lib'`) !== -1, + 'Incorrect content') + }) + .assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/web3-lib.ts"]') + .click('*[data-id="treeViewLitreeViewItemscripts/web3-lib.ts"]') + .pause(100) + .getEditorValue((content) => { + browser.assert.ok(content.indexOf(`export const deploy = async (contractName: string, args: Array, from?: string, gas?: number): Promise => {`) !== -1, + 'Incorrect content') + }) + .assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/ethers-lib.ts"]') + .click('*[data-id="treeViewLitreeViewItemscripts/ethers-lib.ts"]') + .pause(100) + .getEditorValue((content) => { + browser.assert.ok(content.indexOf(`export const deploy = async (contractName: string, args: Array, from?: string): Promise => { `) !== -1, + 'Incorrect content') + }) + .assert.elementPresent('*[data-id="treeViewLitreeViewItemtests"]') + .assert.elementPresent('*[data-id="treeViewLitreeViewItemtests/SampleERC721_test.sol"]') + }, + // WORKSPACE TEMPLATES E2E END 'Should create two workspace and switch to the first one': function (browser: NightwatchBrowser) { diff --git a/apps/remix-ide/.travis.yml b/apps/remix-ide/.travis.yml index ef1c5da85e..c8790fa6b8 100644 --- a/apps/remix-ide/.travis.yml +++ b/apps/remix-ide/.travis.yml @@ -9,8 +9,8 @@ branches: - master - remix_live script: - - npm install - - npm run lint && npm run test && npm run make-mock-compiler && npm run build + - yarn install + - yarn run lint && yarn run test && yarn run make-mock-compiler && yarn run build - wget http://selenium-release.storage.googleapis.com/3.5/selenium-server-standalone-3.5.3.jar - wget http://chromedriver.storage.googleapis.com/2.30/chromedriver_linux64.zip - unzip chromedriver_linux64.zip diff --git a/apps/remix-ide/README.md b/apps/remix-ide/README.md index 77535515cb..8f84d6771f 100644 --- a/apps/remix-ide/README.md +++ b/apps/remix-ide/README.md @@ -26,7 +26,7 @@ Install **npm** and **node.js** (see https://docs.npmjs.com/getting-started/inst Remix-ide has been published as an npm module: ```bash -npm install remix-ide -g +yarn global add remix-ide remix-ide ``` Or if you want to clone the github repository (`wget` need to be installed first) : @@ -36,12 +36,12 @@ git clone https://github.com/ethereum/remix-ide.git git clone https://github.com/ethereum/remix.git # only if you plan to link remix and remix-ide repositories and develop on it. cd remix # only if you plan to link remix and remix-ide repositories and develop on it. -npm install # only if you plan to link remix and remix-ide repositories and develop on it. -npm run bootstrap # only if you plan to link remix and remix-ide repositories and develop on it. +yarn install # only if you plan to link remix and remix-ide repositories and develop on it. +yarn run bootstrap # only if you plan to link remix and remix-ide repositories and develop on it. cd remix-ide -npm install -npm run setupremix # only if you plan to link remix and remix-ide repositories and develop on it. +yarn install +yarn run setupremix # only if you plan to link remix and remix-ide repositories and develop on it. npm start ``` @@ -112,40 +112,40 @@ nvm --version Register new unit test files in `test/index.js`. The tests are written using [tape](https://www.npmjs.com/package/tape). -Run the unit tests via: `npm test` +Run the unit tests via: `yarn test` -For local headless browser tests run `npm run test-browser` -(requires Selenium to be installed - can be done with `npm run selenium-install`) +For local headless browser tests run `yarn run test-browser` +(requires Selenium to be installed - can be done with `yarn run selenium-install`) -Running unit tests via `npm test` requires at least node v7.0.0 +Running unit tests via `yarn test` requires at least node v7.0.0 ## Browser Testing To run the Selenium tests via Nightwatch: - - Build Remix IDE and serve it: `npm run build && npm run serve` # starts web server at localhost:8080 - - Make sure Selenium is installed `npm run selenium-install` # don't need to repeat - - Run a selenium server `npm run selenium` - - Run all the tests `npm run nightwatch_local_firefox` or `npm run nightwatch_local_chrome` + - Build Remix IDE and serve it: `yarn run build && yarn run serve` # starts web server at localhost:8080 + - Make sure Selenium is installed `yarn run selenium-install` # don't need to repeat + - Run a selenium server `yarn run selenium` + - Run all the tests `yarn run nightwatch_local_firefox` or `yarn run nightwatch_local_chrome` - Or run a specific test case: - - npm run nightwatch_local_ballot + - yarn run nightwatch_local_ballot - - npm run nightwatch_local_libraryDeployment + - yarn run nightwatch_local_libraryDeployment - - npm run nightwatch_local_solidityImport + - yarn run nightwatch_local_solidityImport - - npm run nightwatch_local_recorder + - yarn run nightwatch_local_recorder - - npm run nightwatch_local_transactionExecution + - yarn run nightwatch_local_transactionExecution - - npm run nightwatch_local_staticAnalysis + - yarn run nightwatch_local_staticAnalysis - - npm run nightwatch_local_signingMessage + - yarn run nightwatch_local_signingMessage - - npm run nightwatch_local_console + - yarn run nightwatch_local_console - - npm run nightwatch_local_remixd # remixd needs to be run + - yarn run nightwatch_local_remixd # remixd needs to be run **NOTE:** - **the `ballot` tests suite** requires to run `ganache-cli` locally. diff --git a/apps/remix-ide/ci/browser_test.sh b/apps/remix-ide/ci/browser_test.sh index f9385198b5..7a9b536f0c 100755 --- a/apps/remix-ide/ci/browser_test.sh +++ b/apps/remix-ide/ci/browser_test.sh @@ -6,14 +6,14 @@ BUILD_ID=${CIRCLE_BUILD_NUM:-${TRAVIS_JOB_NUMBER}} echo "$BUILD_ID" TEST_EXITCODE=0 -npm run ganache-cli & -npm run serve:production & +yarn run ganache-cli & +yarn run serve:production & echo 'sharing folder: ' $PWD '/apps/remix-ide/contracts' & -npm run remixd & +yarn run remixd & sleep 5 -npm run build:e2e +yarn run build:e2e TESTFILES=$(grep -IRiL "\'@disabled\': \?true" "dist/apps/remix-ide-e2e/src/tests" | grep "\.spec\|\.test" | sort | circleci tests split ) for TESTFILE in $TESTFILES; do diff --git a/apps/remix-ide/ci/browser_tests.sh b/apps/remix-ide/ci/browser_tests.sh index 4a093f6b5d..3070563e52 100755 --- a/apps/remix-ide/ci/browser_tests.sh +++ b/apps/remix-ide/ci/browser_tests.sh @@ -15,13 +15,13 @@ BUILD_ID=${CIRCLE_BUILD_NUM:-${TRAVIS_JOB_NUMBER}} echo "$BUILD_ID" TEST_EXITCODE=0 -npm run ganache-cli & -npm run serve & +yarn run ganache-cli & +yarn run serve & setupRemixd sleep 5 -npm run nightwatch_parallel || TEST_EXITCODE=1 +yarn run nightwatch_parallel || TEST_EXITCODE=1 TESTFILES=$(circleci tests glob "./apps/remix-ide/test-browser/tests/**/*.test.js" | circleci tests split ) for TESTFILE in $TESTFILES; do ./node_modules/.bin/nightwatch --config ./apps/remix-ide/nightwatch.js --env chrome $TESTFILE || TEST_EXITCODE=1 diff --git a/apps/remix-ide/ci/browser_tests_plugin_api.sh b/apps/remix-ide/ci/browser_tests_plugin_api.sh index ab94f74a31..a955297d12 100755 --- a/apps/remix-ide/ci/browser_tests_plugin_api.sh +++ b/apps/remix-ide/ci/browser_tests_plugin_api.sh @@ -6,13 +6,13 @@ BUILD_ID=${CIRCLE_BUILD_NUM:-${TRAVIS_JOB_NUMBER}} echo "$BUILD_ID" TEST_EXITCODE=0 -npm run ganache-cli & -npm run serve:production & +yarn run ganache-cli & +yarn run serve:production & npx nx serve remix-ide-e2e-src-local-plugin & sleep 5 -npm run build:e2e +yarn run build:e2e TESTFILES=$(grep -IRiL "\'@disabled\': \?true" "dist/apps/remix-ide-e2e/src/tests" | grep "plugin_api" | sort | circleci tests split ) for TESTFILE in $TESTFILES; do diff --git a/apps/remix-ide/ci/flaky.sh b/apps/remix-ide/ci/flaky.sh index 8a2dac3e73..41e6c69528 100755 --- a/apps/remix-ide/ci/flaky.sh +++ b/apps/remix-ide/ci/flaky.sh @@ -2,7 +2,7 @@ set -e -npm run build:e2e +yarn run build:e2e TESTFILES=$(grep -IRiL "\'@disabled\': \?true" "dist/apps/remix-ide-e2e/src/tests" | grep "\.flaky" | sort ) # count test files @@ -18,10 +18,10 @@ BUILD_ID=${CIRCLE_BUILD_NUM:-${TRAVIS_JOB_NUMBER}} echo "$BUILD_ID" TEST_EXITCODE=0 -npm run ganache-cli & -npm run serve:production & +yarn run ganache-cli & +yarn run serve:production & echo 'sharing folder: ' $PWD '/apps/remix-ide/contracts' & -npm run remixd & +yarn run remixd & npx nx serve remix-ide-e2e-src-local-plugin & sleep 5 diff --git a/apps/remix-ide/ci/lint.sh b/apps/remix-ide/ci/lint.sh index f0d0345391..fcedab9655 100755 --- a/apps/remix-ide/ci/lint.sh +++ b/apps/remix-ide/ci/lint.sh @@ -13,7 +13,7 @@ KEYS=$(jq -r '.projects | keys' workspace.json | tr -d '[],"') then echo ${row} fi -done) | circleci tests split | { while read i;do npm run lint $i; done } +done) | circleci tests split | { while read i;do yarn run lint $i; done } echo "$TEST_EXITCODE" if [ "$TEST_EXITCODE" -eq 1 ] diff --git a/apps/remix-ide/docs/locations.md b/apps/remix-ide/docs/locations.md index e193139619..d9550ac799 100644 --- a/apps/remix-ide/docs/locations.md +++ b/apps/remix-ide/docs/locations.md @@ -5,6 +5,6 @@ So if you've found the documentation to Remix but don't know where to find Remix - An online version is available at [https://remix.ethereum.org](https://remix.ethereum.org). This version is stable and is updated at almost every release. - An alpha online version is available at [https://remix-alpha.ethereum.org](https://remix-alpha.ethereum.org). This is not a stable version. -- npm `remix-ide` package `npm install remix-ide -g`. `remix-ide` create a new instance of `Remix IDE` available at [http://127.0.0.1:8080](http://127.0.0.1:8080) and make the current folder available to Remix IDE by automatically starting `remixd`. +- npm `remix-ide` package `yarn global add remix-ide`. `remix-ide` create a new instance of `Remix IDE` available at [http://127.0.0.1:8080](http://127.0.0.1:8080) and make the current folder available to Remix IDE by automatically starting `remixd`. see [Connection to `remixd`](https://remix-ide.readthedocs.io/en/latest/remixd.html) for more information about sharing local file with `Remix IDE`. -- Github release: [https://github.com/ethereum/remix-ide/releases](https://github.com/ethereum/remix-ide/releases) . The source code is packaged at every release but still need to be built using `npm run build`. +- Github release: [https://github.com/ethereum/remix-ide/releases](https://github.com/ethereum/remix-ide/releases) . The source code is packaged at every release but still need to be built using `yarn run build`. diff --git a/apps/remix-ide/docs/remixd.md b/apps/remix-ide/docs/remixd.md index 45e2d2062c..3fc7b1bdb3 100644 --- a/apps/remix-ide/docs/remixd.md +++ b/apps/remix-ide/docs/remixd.md @@ -8,10 +8,7 @@ The code of `remixd` is [here](https://github.com/ethereum/remixd) . `remixd` can be globally installed using the following command: -`npm install -g remixd` - -Or just install it in the directory of your choice by removing the -g flag: -`npm install remixd` +`yarn global add @remix-project/remixd` Then from the terminal, the command `remixd -s --remix-ide ` will start `remixd` and will share the given folder with remix-ide. diff --git a/apps/remix-ide/release-process.md b/apps/remix-ide/release-process.md index 45842919b0..511c8ad74e 100644 --- a/apps/remix-ide/release-process.md +++ b/apps/remix-ide/release-process.md @@ -9,7 +9,6 @@ This document includes: - git checkout origin/master - git checkout -b bumpVersion - update package.json version - - remove package-lock.json version and generate a new one with `npm install` - merge PR - git fetch origin master - git checkout origin/master @@ -18,9 +17,9 @@ This document includes: - github-changes -o ethereum -r remix-ide -a --only-pulls --use-commit-body --only-merges --between-tags previous_version...next_version - publish a release in github using the changelog - rm -rf node_modules - - npm install + - yarn install - remove all soljson.js files in root folder - - npm run build + - yarn run build - npm publish - after remix_live is updated, drop the zip (from https://github.com/ethereum/remix-live/) to the release. @@ -29,7 +28,6 @@ This document includes: - git checkout origin/master - git checkout -b bumpVersion - update package.json version to the new version "vx.x.x-beta.1" - - remove package-lock/json version and generate a new one with `npm install` - merge PR - git fetch origin master - git checkout origin/master diff --git a/apps/remix-ide/remix-screenshot-400h.png b/apps/remix-ide/remix-screenshot-400h.png new file mode 100644 index 0000000000..74ac1e57dc Binary files /dev/null and b/apps/remix-ide/remix-screenshot-400h.png differ diff --git a/apps/remix-ide/remix_screenshot.png b/apps/remix-ide/remix_screenshot.png deleted file mode 100644 index 76df964d6d..0000000000 Binary files a/apps/remix-ide/remix_screenshot.png and /dev/null differ diff --git a/apps/remix-ide/src/app/panels/tab-proxy.js b/apps/remix-ide/src/app/panels/tab-proxy.js index ec8026c517..645b30ecce 100644 --- a/apps/remix-ide/src/app/panels/tab-proxy.js +++ b/apps/remix-ide/src/app/panels/tab-proxy.js @@ -24,7 +24,7 @@ export class TabProxy extends Plugin { this.themeQuality = 'dark' } - onActivation () { + async onActivation () { this.on('theme', 'themeChanged', (theme) => { this.themeQuality = theme.quality // update invert for all icons @@ -169,6 +169,13 @@ export class TabProxy extends Plugin { this.on('manager', 'pluginDeactivated', (profile) => { this.removeTab(profile.name) }) + + try { + this.themeQuality = (await this.call('theme', 'currentTheme') ).quality + } catch (e) { + console.log('theme plugin has an issue: ', e) + } + this.renderComponent() } focus (name) { @@ -208,6 +215,7 @@ export class TabProxy extends Plugin { } renameTab (oldName, newName) { + // The new tab is being added by FileManager this.removeTab(oldName) } @@ -292,7 +300,15 @@ export class TabProxy extends Plugin { } updateComponent(state) { - return + return } renderComponent () { diff --git a/apps/remix-ide/src/app/plugins/config.ts b/apps/remix-ide/src/app/plugins/config.ts index 3102d555df..b65f1ddfa7 100644 --- a/apps/remix-ide/src/app/plugins/config.ts +++ b/apps/remix-ide/src/app/plugins/config.ts @@ -18,7 +18,7 @@ export class ConfigPlugin extends Plugin { const queryParams = new QueryParams() const params = queryParams.get() const config = Registry.getInstance().get('config').api - let param = params[name] || config.get(name) || config.get('settings/' + name) + const param = params[name] || config.get(name) || config.get('settings/' + name) if (param === 'true') return true if (param === 'false') return false return param diff --git a/apps/remix-ide/src/app/tabs/ganache-provider.tsx b/apps/remix-ide/src/app/tabs/ganache-provider.tsx index b73cb18786..002e31a3a2 100644 --- a/apps/remix-ide/src/app/tabs/ganache-provider.tsx +++ b/apps/remix-ide/src/app/tabs/ganache-provider.tsx @@ -23,7 +23,7 @@ export class GanacheProvider extends AbstractProvider { body (): JSX.Element { return (
Note: To run Ganache on your system, run -
npm install -g ganache
+
yarn global add ganache
ganache
For more info, visit: Ganache Documentation
Ganache JSON-RPC Endpoint:
diff --git a/apps/remix-ide/src/remixAppManager.js b/apps/remix-ide/src/remixAppManager.js index 96d79aba39..0868ef8689 100644 --- a/apps/remix-ide/src/remixAppManager.js +++ b/apps/remix-ide/src/remixAppManager.js @@ -7,7 +7,7 @@ const _paq = window._paq = window._paq || [] const requiredModules = [ // services + layout views + system views 'manager', 'config', 'compilerArtefacts', 'compilerMetadata', 'contextualListener', 'editor', 'offsetToLineColumnConverter', 'network', 'theme', 'fileManager', 'contentImport', 'blockchain', 'web3Provider', 'scriptRunner', 'fetchAndCompile', 'mainPanel', 'hiddenPanel', 'sidePanel', 'menuicons', - 'filePanel', 'terminal', 'settings', 'pluginManager', 'tabs', 'udapp', 'dGitProvider', 'solidity-logic', 'gistHandler', 'layout', + 'filePanel', 'terminal', 'settings', 'pluginManager', 'tabs', 'udapp', 'dGitProvider', 'solidity', 'solidity-logic', 'gistHandler', 'layout', 'notification', 'permissionhandler', 'walkthrough', 'storage', 'restorebackupzip', 'link-libraries', 'deploy-libraries', 'openzeppelin-proxy', 'hardhat-provider', 'compileAndRun', 'search'] const dependentModules = ['git', 'hardhat', 'truffle', 'slither'] // module which shouldn't be manually activated (e.g git is activated by remixd) @@ -19,7 +19,8 @@ const sensitiveCalls = { } export function isNative(name) { - const nativePlugins = ['vyper', 'workshops', 'debugger', 'remixd', 'menuicons', 'solidity', 'hardhat-provider', 'solidityStaticAnalysis', 'solidityUnitTesting', 'layout', 'notification', 'hardhat-provider', 'ganache-provider'] + const nativePlugins = ['vyper', 'workshops', 'debugger', 'remixd', 'menuicons', 'solidity', 'solidity-logic', + 'hardhat-provider', 'solidityStaticAnalysis', 'solidityUnitTesting', 'layout', 'notification', 'hardhat-provider', 'ganache-provider'] return nativePlugins.includes(name) || requiredModules.includes(name) } diff --git a/apps/solidity-compiler/src/app/compiler-api.ts b/apps/solidity-compiler/src/app/compiler-api.ts index 8ad3db0da0..06c0b993e2 100644 --- a/apps/solidity-compiler/src/app/compiler-api.ts +++ b/apps/solidity-compiler/src/app/compiler-api.ts @@ -18,7 +18,7 @@ export const CompilerApiMixin = (Base) => class extends Base { onCurrentFileChanged: (fileName: string) => void // onResetResults: () => void - onSetWorkspace: (workspace: any) => void + onSetWorkspace: (isLocalhost: boolean, workspaceName: string) => void onNoFileSelected: () => void onCompilationFinished: (compilationDetails: { contractMap: { file: string } | Record, contractsDetails: Record }) => void onSessionSwitched: () => void @@ -237,12 +237,12 @@ export const CompilerApiMixin = (Base) => class extends Base { this.on('filePanel', 'setWorkspace', (workspace) => { this.resetResults() - if (this.onSetWorkspace) this.onSetWorkspace(workspace.isLocalhost) + if (this.onSetWorkspace) this.onSetWorkspace(workspace.isLocalhost, workspace.name) }) this.on('remixd', 'rootFolderChanged', () => { this.resetResults() - if (this.onSetWorkspace) this.onSetWorkspace(true) + if (this.onSetWorkspace) this.onSetWorkspace(true, 'localhost') }) this.on('editor', 'sessionSwitched', () => { diff --git a/apps/solidity-compiler/src/app/compiler.ts b/apps/solidity-compiler/src/app/compiler.ts index a58ff585a2..df64855ab9 100644 --- a/apps/solidity-compiler/src/app/compiler.ts +++ b/apps/solidity-compiler/src/app/compiler.ts @@ -6,31 +6,14 @@ import { CompilerApiMixin } from './compiler-api' import { ICompilerApi } from '@remix-project/remix-lib-ts' import { CompileTabLogic } from '@remix-ui/solidity-compiler' -const profile = { - name: 'solidity', - displayName: 'Solidity compiler', - icon: 'assets/img/solidity.webp', - description: 'Compile solidity contracts', - kind: 'compiler', - permission: true, - location: 'sidePanel', - documentation: 'https://remix-ide.readthedocs.io/en/latest/solidity_editor.html', - version: '0.0.1', - methods: ['getCompilationResult', 'compile', 'compileWithParameters', 'setCompilerConfig', 'compileFile', 'getCompilerState'] -} - -const defaultAppParameters = { - hideWarnings: false, - autoCompile: false, - includeNightlies: false -} - const defaultCompilerParameters = { runs: '200', optimize: false, version: 'soljson-v0.8.7+commit.e28d00a7', evmVersion: null, // compiler default - language: 'Solidity' + language: 'Solidity', + useFileConfiguration: false, + configFilePath: "compiler_config.json" } export class CompilerClientApi extends CompilerApiMixin(PluginClient) implements ICompilerApi { constructor () { @@ -48,7 +31,9 @@ export class CompilerClientApi extends CompilerApiMixin(PluginClient) implements optimize: localStorage.getItem('optimize') === 'true', version: localStorage.getItem('version') || defaultCompilerParameters.version, evmVersion: localStorage.getItem('evmVersion') || defaultCompilerParameters.evmVersion, // default - language: localStorage.getItem('language') || defaultCompilerParameters.language + language: localStorage.getItem('language') || defaultCompilerParameters.language, + useFileConfiguration: localStorage.getItem('useFileConfiguration') === 'true', + configFilePath: localStorage.getItem('configFilePath') || defaultCompilerParameters.configFilePath } return params } diff --git a/libs/remix-analyzer/README.md b/libs/remix-analyzer/README.md index d81b93b787..a2cc46d6bd 100644 --- a/libs/remix-analyzer/README.md +++ b/libs/remix-analyzer/README.md @@ -10,7 +10,7 @@ ### Installation `@remix-project/remix-analyzer` is an NPM package and can be installed using NPM as: -`npm install @remix-project/remix-analyzer` +`yarn add @remix-project/remix-analyzer` ### How to use diff --git a/libs/remix-astwalker/README.md b/libs/remix-astwalker/README.md index cc6416b8b0..6b03957968 100644 --- a/libs/remix-astwalker/README.md +++ b/libs/remix-astwalker/README.md @@ -10,7 +10,7 @@ ### Installation `@remix-project/remix-astwalker` is an NPM package and can be installed using NPM as: -`npm install @remix-project/remix-astwalker` +`yarn add @remix-project/remix-astwalker` ### How to use diff --git a/libs/remix-debug/README.md b/libs/remix-debug/README.md index c8ea008043..e512499d36 100644 --- a/libs/remix-debug/README.md +++ b/libs/remix-debug/README.md @@ -10,7 +10,7 @@ ### Installation `@remix-project/remix-debug` is an NPM package and can be installed using NPM as: -`npm install @remix-project/remix-debug` +`yarn add @remix-project/remix-debug` ### How to use diff --git a/libs/remix-lib/README.md b/libs/remix-lib/README.md index 31075ad154..64a6706ef3 100644 --- a/libs/remix-lib/README.md +++ b/libs/remix-lib/README.md @@ -10,7 +10,7 @@ ### Installation `@remix-project/remix-lib` is an NPM package and can be installed using NPM as: -`npm install @remix-project/remix-lib` +`yarn add @remix-project/remix-lib` ### How to use diff --git a/libs/remix-lib/src/types/ICompilerApi.ts b/libs/remix-lib/src/types/ICompilerApi.ts index 8e43892fa0..f34d20f420 100644 --- a/libs/remix-lib/src/types/ICompilerApi.ts +++ b/libs/remix-lib/src/types/ICompilerApi.ts @@ -24,7 +24,7 @@ export interface ICompilerApi { onCurrentFileChanged: (fileName: string) => void // onResetResults: () => void, - onSetWorkspace: (workspace: any) => void + onSetWorkspace: (isLocalhost: boolean, workspaceName: string) => void onNoFileSelected: () => void onCompilationFinished: (contractsDetails: any, contractMap: any) => void onSessionSwitched: () => void diff --git a/libs/remix-simulator/README.md b/libs/remix-simulator/README.md index ebd7b31aff..bf1b0c675a 100644 --- a/libs/remix-simulator/README.md +++ b/libs/remix-simulator/README.md @@ -10,7 +10,7 @@ ### Installation `@remix-project/remix-simulator` is an NPM package and can be installed using NPM as: -`npm install @remix-project/remix-simulator` +`yarn add @remix-project/remix-simulator` ### How to use diff --git a/libs/remix-solidity/README.md b/libs/remix-solidity/README.md index 2e448074fc..45f0cda698 100644 --- a/libs/remix-solidity/README.md +++ b/libs/remix-solidity/README.md @@ -12,7 +12,7 @@ `@remix-project/remix-solidity` is an NPM package and can be installed using NPM as: -`npm install @remix-project/remix-solidity` +`yarn add @remix-project/remix-solidity` ### How to use diff --git a/libs/remix-solidity/src/compiler/compiler-input.ts b/libs/remix-solidity/src/compiler/compiler-input.ts index 7f8f05594e..92934e5649 100644 --- a/libs/remix-solidity/src/compiler/compiler-input.ts +++ b/libs/remix-solidity/src/compiler/compiler-input.ts @@ -50,3 +50,9 @@ export function getValidLanguage (val: string): Language { } return null } + +export function compilerInputForConfigFile(sources: Source, opts) +{ + opts.sources = sources + return JSON.stringify(opts) +} diff --git a/libs/remix-solidity/src/compiler/compiler.ts b/libs/remix-solidity/src/compiler/compiler.ts index 931279a04e..36b7981493 100644 --- a/libs/remix-solidity/src/compiler/compiler.ts +++ b/libs/remix-solidity/src/compiler/compiler.ts @@ -2,7 +2,7 @@ import { update } from 'solc/abi' import * as webworkify from 'webworkify-webpack' -import compilerInput from './compiler-input' +import compilerInput, { compilerInputForConfigFile } from './compiler-input' import EventManager from '../lib/eventManager' import txHelper from './helper' import { @@ -31,6 +31,8 @@ export class Compiler { language: 'Solidity', compilationStartTime: null, target: null, + useFileConfiguration: false, + configFileContent: '', lastCompilationResult: { data: null, source: null @@ -111,11 +113,17 @@ export class Compiler { return { error: 'Deferred import' } } let result: CompilationResult = {} - let input + let input = "" try { if (source && source.sources) { - const { optimize, runs, evmVersion, language } = this.state - input = compilerInput(source.sources, { optimize, runs, evmVersion, language }) + const { optimize, runs, evmVersion, language, useFileConfiguration, configFileContent } = this.state + + if (useFileConfiguration) { + input = compilerInputForConfigFile(source.sources, JSON.parse(configFileContent)) + } else { + input = compilerInput(source.sources, { optimize, runs, evmVersion, language }) + } + result = JSON.parse(compiler.compile(input, { import: missingInputsCallback })) } } catch (exception) { @@ -184,11 +192,17 @@ export class Compiler { return { error: 'Deferred import' } } let result: CompilationResult = {} - let input: string + let input = "" try { if (source && source.sources) { - const { optimize, runs, evmVersion, language } = this.state - input = compilerInput(source.sources, { optimize, runs, evmVersion, language }) + const { optimize, runs, evmVersion, language, useFileConfiguration, configFileContent } = this.state + + if (useFileConfiguration) { + input = compilerInputForConfigFile(source.sources, JSON.parse(configFileContent)) + } else { + input = compilerInput(source.sources, { optimize, runs, evmVersion, language }) + } + result = JSON.parse(remoteCompiler.compile(input, { import: missingInputsCallback })) } } catch (exception) { @@ -290,12 +304,26 @@ export class Compiler { this.state.compileJSON = (source: SourceWithTarget) => { if (source && source.sources) { - const { optimize, runs, evmVersion, language } = this.state + const { optimize, runs, evmVersion, language, useFileConfiguration, configFileContent } = this.state jobs.push({ sources: source }) + let input = "" + + try { + if (useFileConfiguration) { + input = compilerInputForConfigFile(source.sources, JSON.parse(configFileContent)) + } else { + input = compilerInput(source.sources, { optimize, runs, evmVersion, language }) + } + } catch (exception) { + this.onCompilationFinished({ error: { formattedMessage: exception.message } }, [], source, "", this.state.currentVersion) + return + } + + this.state.worker.postMessage({ cmd: 'compile', job: jobs.length - 1, - input: compilerInput(source.sources, { optimize, runs, evmVersion, language }) + input: input }) } } diff --git a/libs/remix-solidity/src/compiler/types.ts b/libs/remix-solidity/src/compiler/types.ts index 0e96a21618..ae3a60fe96 100644 --- a/libs/remix-solidity/src/compiler/types.ts +++ b/libs/remix-solidity/src/compiler/types.ts @@ -165,6 +165,8 @@ export interface CompilerState { language: Language, compilationStartTime: number| null, target: string | null, + useFileConfiguration: boolean, + configFileContent: string, lastCompilationResult: { data: CompilationResult | null, source: SourceWithTarget | null | undefined diff --git a/libs/remix-tests/README.md b/libs/remix-tests/README.md index f08ca19985..81a3bc6aaf 100644 --- a/libs/remix-tests/README.md +++ b/libs/remix-tests/README.md @@ -12,11 +12,11 @@ To know more about Remix IDE `Solidity Unit Testing Plugin`, visit [Remix IDE of ### Installation * As a dev dependency: -`npm install --save-dev @remix-project/remix-tests` +`yarn add --dev @remix-project/remix-tests` * As a global NPM module to use as CLI: -`npm -g install @remix-project/remix-tests` +`yarn global add @remix-project/remix-tests` To confirm installation, run: ``` diff --git a/libs/remix-tests/tests/testRunner.cli.spec.ts b/libs/remix-tests/tests/testRunner.cli.spec.ts index 496f6f4936..65bea514da 100644 --- a/libs/remix-tests/tests/testRunner.cli.spec.ts +++ b/libs/remix-tests/tests/testRunner.cli.spec.ts @@ -11,7 +11,7 @@ describe('testRunner: remix-tests CLI', () => { const dirContent = result.stdout.toString() // Install dependencies if 'node_modules' is not already present if(!dirContent.includes('node_modules')) { - execSync('npm install', { cwd: resolve(__dirname + '/../../../dist/libs/remix-tests') }) + execSync('yarn install', { cwd: resolve(__dirname + '/../../../dist/libs/remix-tests') }) } } diff --git a/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx b/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx index ace02c70f7..614daf14ff 100644 --- a/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx +++ b/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx @@ -83,6 +83,25 @@ export interface EditorUIProps { export const EditorUI = (props: EditorUIProps) => { const [, setCurrentBreakpoints] = useState({}) + const defaultEditorValue = ` + \t\t\t\t\t\t\t ____ _____ __ __ ___ __ __ ___ ____ _____ + \t\t\t\t\t\t\t| _ \\ | ____| | \\/ | |_ _| \\ \\/ / |_ _| | _ \\ | ____| + \t\t\t\t\t\t\t| |_) | | _| | |\\/| | | | \\ / | | | | | | | _| + \t\t\t\t\t\t\t| _ < | |___ | | | | | | / \\ | | | |_| | | |___ + \t\t\t\t\t\t\t|_| \\_\\ |_____| |_| |_| |___| /_/\\_\\ |___| |____/ |_____|\n\n + \t\t\t\t\t\t\tKeyboard Shortcuts:\n + \t\t\t\t\t\t\t\tCTRL + S: Compile the current contract\n + \t\t\t\t\t\t\t\tCtrl + Shift + F : Open the File Explorer\n + \t\t\t\t\t\t\t\tCtrl + Shift + A : Open the Plugin Manager\n + \t\t\t\t\t\t\t\tCTRL + SHIFT + S: Compile the current contract & Run an associated script\n\n + \t\t\t\t\t\t\tImportant Links:\n + \t\t\t\t\t\t\t\tOfficial website about the Remix Project: https://remix-project.org/\n + \t\t\t\t\t\t\t\tOfficial documentation: https://remix-ide.readthedocs.io/en/latest/\n + \t\t\t\t\t\t\t\tGithub: https://github.com/ethereum/remix-project\n + \t\t\t\t\t\t\t\tGitter: https://gitter.im/ethereum/remix\n + \t\t\t\t\t\t\t\tMedium: https://medium.com/remix-ide\n + \t\t\t\t\t\t\t\tTwitter: https://twitter.com/ethereumremix\n + ` const editorRef = useRef(null) const monacoRef = useRef(null) const currentFileRef = useRef('') @@ -453,7 +472,8 @@ export const EditorUI = (props: EditorUIProps) => { language={editorModelsState[props.currentFile] ? editorModelsState[props.currentFile].language : 'text'} onMount={handleEditorDidMount} beforeMount={handleEditorWillMount} - options={{ glyphMargin: true }} + options={{ glyphMargin: true, readOnly: true}} + defaultValue={defaultEditorValue} />
-
+
+ { instanceList.length > 0 ?
{ props.instances.instanceList.map((instance, index) => { return { - return ( -
{}}> -
-
{title}
-
-
-
{recorderCount}
-
-
-
-
-
-
-
- ) - } - + const [toggleExpander, setToggleExpander] = useState(false) const triggerRecordButton = () => { props.storeScenario(props.scenarioPrompt) } @@ -30,24 +12,35 @@ export function RecorderUI (props: RecorderProps) { props.runCurrentScenario(props.gasEstimationPrompt, props.passphrasePrompt, props.mainnetPrompt, props.logBuilder) } + const toggleClass = () => { + setToggleExpander(!toggleExpander) + } + return ( -
- - -
-
- All transactions (deployed contracts and function executions) in this environment can be saved and replayed in - another environment. e.g Transactions created in Javascript VM can be replayed in the Injected Web3. -
-
- - -
-
-
-
+
+
+
+ +
{props.count}
+
+
+ + + +
+
+
+
+ All transactions (deployed contracts and function executions) can be saved and replayed in + another environment. e.g Transactions created in Javascript VM can be replayed in the Injected Web3. +
+
+ + +
+
) } diff --git a/libs/remix-ui/run-tab/src/lib/css/card.css b/libs/remix-ui/run-tab/src/lib/css/card.css index 1decf7c720..65cba95c60 100644 --- a/libs/remix-ui/run-tab/src/lib/css/card.css +++ b/libs/remix-ui/run-tab/src/lib/css/card.css @@ -2,11 +2,4 @@ padding : 0 24px 16px; margin : 0; background : none; -} -.udapp_arrow { - font-weight : bold; - cursor : pointer; - font-size : 14px; -} -.udapp_arrow:hover { } \ No newline at end of file diff --git a/libs/remix-ui/run-tab/src/lib/css/run-tab.css b/libs/remix-ui/run-tab/src/lib/css/run-tab.css index f5ec6c2e65..5ad8e6774c 100644 --- a/libs/remix-ui/run-tab/src/lib/css/run-tab.css +++ b/libs/remix-ui/run-tab/src/lib/css/run-tab.css @@ -60,6 +60,9 @@ text-align: center; padding: 0 14px 16px; } +.udapp_deployedContracts { + font-size: 1rem; +} .udapp_pendingTxsContainer { display: flex; flex-direction: column; @@ -70,9 +73,6 @@ .udapp_container { padding: 0 24px 16px; } -.udapp_recorderDescription { - margin: 0 15px 15px 0; - } .udapp_contractNames { width: 100%; border: 1px solid @@ -121,7 +121,14 @@ .udapp_ataddressinput { padding: .25rem; } -.udapp_create { +.udapp_recorderSection:hover { + cursor: pointer; +}.udapp_recorderSectionLabel:hover { + cursor: pointer; +} +.udapp_recorderSectionLabel { + cursor: pointer; + font-size: 1rem; } .udapp_input { font-size: 10px !important; diff --git a/libs/remix-ui/run-tab/src/lib/types/index.ts b/libs/remix-ui/run-tab/src/lib/types/index.ts index b3ac8ca28c..5f1d2fb496 100644 --- a/libs/remix-ui/run-tab/src/lib/types/index.ts +++ b/libs/remix-ui/run-tab/src/lib/types/index.ts @@ -227,7 +227,8 @@ export interface ContractGUIProps { clickCallBack: (inputs: { name: string, type: string }[], input: string) => void, widthClass?: string, evmBC: any, - lookupOnly: boolean + lookupOnly: boolean, + disabled?: boolean } export interface MainnetProps { network: Network, 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 cf2121190b..d5d3ff9f5b 100644 --- a/libs/remix-ui/solidity-compiler/src/lib/compiler-container.tsx +++ b/libs/remix-ui/solidity-compiler/src/lib/compiler-container.tsx @@ -9,6 +9,7 @@ import { resetEditorMode, listenToEvents } from './actions/compiler' import { OverlayTrigger, Tooltip } from 'react-bootstrap' // eslint-disable-line import { getValidLanguage } from '@remix-project/remix-solidity' import { CopyToClipboard } from '@remix-ui/clipboard' +import { configFileContent } from './compilerConfiguration' import './css/style.css' @@ -21,10 +22,12 @@ 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, isTruffleProject } = props // eslint-disable-line + const { api, compileTabLogic, tooltip, modal, compiledFileName, updateCurrentVersion, configurationSettings, isHardhatProject, isTruffleProject, workspaceName } = props // eslint-disable-line const [state, setState] = useState({ hideWarnings: false, autoCompile: false, + configFilePath: "compiler_config.json", + useFileConfiguration: false, matomoAutocompileOnce: true, optimize: false, compileTimeout: null, @@ -39,13 +42,43 @@ export const CompilerContainer = (props: CompilerContainerProps) => { language: 'Solidity', evmVersion: '' }) + const [showFilePathInput, setShowFilePathInput] = useState(false) + const [toggleExpander, setToggleExpander] = useState(false) const [disableCompileButton, setDisableCompileButton] = useState(false) const compileIcon = useRef(null) const promptMessageInput = useRef(null) + const configFilePathInput = useRef(null) const [hhCompilation, sethhCompilation] = useState(false) const [truffleCompilation, setTruffleCompilation] = useState(false) const [compilerContainer, dispatch] = useReducer(compilerReducer, compilerInitialState) + useEffect(() => { + api.setAppParameter('configFilePath', "/compiler_config.json") + api.fileExists("/compiler_config.json").then((exists) => { + if (!exists) createNewConfigFile() + else { + // what to do? discuss + } + }) + api.setAppParameter('configFilePath', "/compiler_config.json") + setShowFilePathInput(false) + }, [workspaceName]) + + useEffect(() => { + const listener = (event) => { + if (configFilePathInput.current !== event.target) { + setShowFilePathInput(false) + return; + } + }; + document.addEventListener("mousedown", listener); + document.addEventListener("touchstart", listener); + return () => { + document.removeEventListener("mousedown", listener); + document.removeEventListener("touchstart", listener); + } + }) + useEffect(() => { fetchAllVersion((allversions, selectedVersion, isURL) => { setState(prevState => { @@ -72,6 +105,10 @@ export const CompilerContainer = (props: CompilerContainerProps) => { const autocompile = await api.getAppParameter('autoCompile') as boolean || false const hideWarnings = await api.getAppParameter('hideWarnings') as boolean || false const includeNightlies = await api.getAppParameter('includeNightlies') as boolean || false + const useFileConfiguration = await api.getAppParameter('useFileConfiguration') as boolean || false + let configFilePath = await api.getAppParameter('configFilePath') + if (!configFilePath || configFilePath == '') configFilePath = "/compiler_config.json" + setState(prevState => { const params = api.getCompilerParameters() const optimize = params.optimize @@ -84,6 +121,8 @@ export const CompilerContainer = (props: CompilerContainerProps) => { hideWarnings: hideWarnings, autoCompile: autocompile, includeNightlies: includeNightlies, + useFileConfiguration: useFileConfiguration, + configFilePath: configFilePath, optimize: optimize, runs: runs, evmVersion: (evmVersion !== null) && (evmVersion !== 'null') && (evmVersion !== undefined) && (evmVersion !== 'undefined') ? evmVersion : 'default', @@ -140,12 +179,67 @@ export const CompilerContainer = (props: CompilerContainerProps) => { } }, [compilerContainer.editor.mode]) + useEffect(() => { + compileTabLogic.setUseFileConfiguration(state.useFileConfiguration) + if (state.useFileConfiguration) compileTabLogic.setConfigFilePath(state.configFilePath) + }, [state.useFileConfiguration]) + useEffect(() => { if (configurationSettings) { setConfiguration(configurationSettings) } }, [configurationSettings]) + const toggleConfigType = () => { + setState(prevState => { + api.setAppParameter('useFileConfiguration', !state.useFileConfiguration) + return { ...prevState, useFileConfiguration: !state.useFileConfiguration } + }) + } + + const openFile = async () => { + api.open(state.configFilePath) + } + + const createNewConfigFile = async () => { + let filePath = configFilePathInput.current && configFilePathInput.current.value !== '' ? configFilePathInput.current.value : state.configFilePath + if (!filePath.endsWith('.json')) filePath = filePath + '.json' + + await api.writeFile(filePath, configFileContent) + api.setAppParameter('configFilePath', filePath) + setState(prevState => { + return { ...prevState, configFilePath: filePath } + }) + compileTabLogic.setConfigFilePath(filePath) + setShowFilePathInput(false) + } + + const handleConfigPathChange = async () => { + if (configFilePathInput.current.value !== '') { + if (!configFilePathInput.current.value.endsWith('.json')) configFilePathInput.current.value += '.json' + + if (await api.fileExists(configFilePathInput.current.value)) { + api.setAppParameter('configFilePath', configFilePathInput.current.value) + setState(prevState => { + return { ...prevState, configFilePath: configFilePathInput.current.value } + }) + compileTabLogic.setConfigFilePath(configFilePathInput.current.value) + + setShowFilePathInput(false) + } else { + modal( + 'New configuration file', `The file "${configFilePathInput.current.value}" you entered does not exist. Do you want to create a new one?`, + 'Create', + async () => await createNewConfigFile(), + 'Cancel', + () => { + setShowFilePathInput(false) + } + ) + } + } + } + const _retrieveVersion = (version?) => { if (!version) version = state.selectedVersion if (version === 'builtin') version = state.defaultVersion @@ -538,14 +632,18 @@ export const CompilerContainer = (props: CompilerContainerProps) => { onChangeRuns(settings.runs) } + const toggleConfigurations = () => { + setToggleExpander(!toggleExpander) + } + return (
-
-
+
+
-
+
-
- - +
+ +
-
- - -
-
-

Compiler Configuration

-
- - -
-
-
- { handleOptimizeChange(e.target.checked) }} className="custom-control-input" id="optimize" type="checkbox" checked={state.optimize} /> - - onChangeRuns(e.target.value)} - disabled={!state.optimize} - /> -
-
-
- - -
+
+ +
{ isHardhatProject && @@ -636,7 +701,81 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
} +
+
+
+ +
+ + + +
+
+
+
+ + +
+
+
+ + +
+
+ + +
+
+
+ { handleOptimizeChange(e.target.checked) }} disabled={state.useFileConfiguration} className="custom-control-input" id="optimize" type="checkbox" checked={state.optimize} /> + + onChangeRuns(e.target.value)} + disabled={!state.optimize || state.useFileConfiguration} + /> +
+
+
+
+ + +
+
+ { (!showFilePathInput && state.useFileConfiguration) && {state.configFilePath} } + { (!showFilePathInput&& !state.useFileConfiguration) && {state.configFilePath} } + { + if (event.key === 'Enter') { + handleConfigPathChange() + } + }} + /> + { !showFilePathInput && } +
+
+
-
-
Choose the script to execute right after compilation by adding the `dev-run-script` natspec tag, as in:
-
-                      
-                      /**
- * @title ContractName
- * @dev ContractDescription
- * @custom:dev-run-script file_path
- */
- contract ContractName {'{}'}
-
-
- Click to know more -
- - }> - -
- '@custom:dev-run-script file_path'} direction='top'> - - -
-
-
+ +
+
Choose the script to execute right after compilation by adding the `dev-run-script` natspec tag, as in:
+
+                  
+                  /**
+ * @title ContractName
+ * @dev ContractDescription
+ * @custom:dev-run-script file_path
+ */
+ contract ContractName {'{}'}
+
+
+ Click to know more +
+
+ }> + + + '@custom:dev-run-script file_path'} direction='top'> + + +
+
) diff --git a/libs/remix-ui/solidity-compiler/src/lib/compilerConfiguration.tsx b/libs/remix-ui/solidity-compiler/src/lib/compilerConfiguration.tsx new file mode 100644 index 0000000000..d05e1ab21c --- /dev/null +++ b/libs/remix-ui/solidity-compiler/src/lib/compilerConfiguration.tsx @@ -0,0 +1,18 @@ +export const configFileContent = ` +{ + "language": "Solidity", + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "": ["ast"], + "*": ["abi", "metadata", "devdoc", "userdoc", "storageLayout", "evm.legacyAssembly", "evm.bytecode", "evm.deployedBytecode", "evm.methodIdentifiers", "evm.gasEstimates", "evm.assembly"] + } + }, + "evmVersion": "byzantium" + } +} +` \ No newline at end of file diff --git a/libs/remix-ui/solidity-compiler/src/lib/css/style.css b/libs/remix-ui/solidity-compiler/src/lib/css/style.css index 9bc492311d..892dc26e0b 100644 --- a/libs/remix-ui/solidity-compiler/src/lib/css/style.css +++ b/libs/remix-ui/solidity-compiler/src/lib/css/style.css @@ -72,6 +72,15 @@ .remixui_compilerSection { padding: 12px 24px 16px; } +.remixui_compilerConfigSection:hover { + cursor: pointer; +} +.remixui_compilerConfigSection { + font-size: 1rem; +} +.remixui_compilerConfigPath { + cursor: pointer; +} .remixui_compilerLabel { margin-bottom: 2px; font-size: 11px; diff --git a/libs/remix-ui/solidity-compiler/src/lib/logic/compileTabLogic.ts b/libs/remix-ui/solidity-compiler/src/lib/logic/compileTabLogic.ts index 05e47fcd17..e84f73a76c 100644 --- a/libs/remix-ui/solidity-compiler/src/lib/logic/compileTabLogic.ts +++ b/libs/remix-ui/solidity-compiler/src/lib/logic/compileTabLogic.ts @@ -18,6 +18,8 @@ export class CompileTabLogic { public compilerImport public event public evmVersions: Array + public useFileConfiguration: boolean + public configFilePath: string constructor (public api: ICompilerApi, public contentImport) { this.event = new EventEmitter() @@ -52,12 +54,21 @@ export class CompileTabLogic { } } - setOptimize (newOptimizeValue) { + setOptimize (newOptimizeValue: boolean) { this.optimize = newOptimizeValue this.api.setCompilerParameters({ optimize: this.optimize }) this.compiler.set('optimize', this.optimize) } + setUseFileConfiguration (useFileConfiguration: boolean) { + this.useFileConfiguration = useFileConfiguration + this.compiler.set('useFileConfiguration', useFileConfiguration) + } + + setConfigFilePath (path) { + this.configFilePath = path + } + setRuns (runs) { this.runs = runs this.api.setCompilerParameters({ runs: this.runs }) @@ -95,6 +106,9 @@ export class CompileTabLogic { const sources = { [target]: { content } } this.event.emit('removeAnnotations') this.event.emit('startingCompilation') + this.api.readFile(this.configFilePath).then( contentConfig => { + this.compiler.set('configFileContent', contentConfig) + }) // setTimeout fix the animation on chrome... (animation triggered by 'staringCompilation') setTimeout(() => { this.compiler.compile(sources, target); resolve(true) }, 100) }).catch((error) => { diff --git a/libs/remix-ui/solidity-compiler/src/lib/solidity-compiler.tsx b/libs/remix-ui/solidity-compiler/src/lib/solidity-compiler.tsx index 328e830113..33d56f3175 100644 --- a/libs/remix-ui/solidity-compiler/src/lib/solidity-compiler.tsx +++ b/libs/remix-ui/solidity-compiler/src/lib/solidity-compiler.tsx @@ -13,6 +13,7 @@ export const SolidityCompiler = (props: SolidityCompilerProps) => { const [state, setState] = useState({ isHardhatProject: false, isTruffleProject: false, + workspaceName: '', currentFile, loading: false, compileTabLogic: null, @@ -63,11 +64,11 @@ export const SolidityCompiler = (props: SolidityCompilerProps) => { }) } - api.onSetWorkspace = async (isLocalhost: boolean) => { + api.onSetWorkspace = async (isLocalhost: boolean, workspaceName: string) => { const isHardhat = isLocalhost && await compileTabLogic.isHardhatProject() const isTruffle = await compileTabLogic.isTruffleProject() setState(prevState => { - return { ...prevState, currentFile, isHardhatProject: isHardhat, isTruffleProject: isTruffle } + return { ...prevState, currentFile, isHardhatProject: isHardhat, workspaceName: workspaceName, isTruffleProject: isTruffle } }) } @@ -150,7 +151,18 @@ export const SolidityCompiler = (props: SolidityCompilerProps) => { return ( <>
- + { contractsFile[currentFile] && contractsFile[currentFile].contractsDetails && } { compileErrors[currentFile] &&
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 d9c5635ba9..37cffd4289 100644 --- a/libs/remix-ui/solidity-compiler/src/lib/types/index.ts +++ b/libs/remix-ui/solidity-compiler/src/lib/types/index.ts @@ -11,6 +11,7 @@ export interface CompilerContainerProps { compileTabLogic: CompileTabLogic, isHardhatProject: boolean, isTruffleProject: boolean, + workspaceName: string, tooltip: (message: string | JSX.Element) => void, modal: (title: string, message: string | JSX.Element, okLabel: string, okFn: () => void, cancelLabel?: string, cancelFn?: () => void) => void, compiledFileName: string, @@ -45,4 +46,3 @@ export interface CompilationDetails { export interface ContractsFile { [currentFile: string]: CompilationDetails } - diff --git a/libs/remix-ui/solidity-compiler/tsconfig.json b/libs/remix-ui/solidity-compiler/tsconfig.json index d52e31ad74..3375d6822b 100644 --- a/libs/remix-ui/solidity-compiler/tsconfig.json +++ b/libs/remix-ui/solidity-compiler/tsconfig.json @@ -4,7 +4,7 @@ "jsx": "react", "allowJs": true, "esModuleInterop": true, - "allowSyntheticDefaultImports": true + "allowSyntheticDefaultImports": true, }, "files": [], "include": [], diff --git a/libs/remix-ui/tabs/src/lib/remix-ui-tabs.tsx b/libs/remix-ui/tabs/src/lib/remix-ui-tabs.tsx index b762b78dde..cf4eaca964 100644 --- a/libs/remix-ui/tabs/src/lib/remix-ui-tabs.tsx +++ b/libs/remix-ui/tabs/src/lib/remix-ui-tabs.tsx @@ -10,7 +10,7 @@ export interface TabsUIProps { onZoomOut: () => void onZoomIn: () => void onReady: (api: any) => void - themeQuality: "dark" + themeQuality: string } export interface TabsUIApi { diff --git a/libs/remix-ui/tree-view/src/lib/remix-ui-tree-view.tsx b/libs/remix-ui/tree-view/src/lib/remix-ui-tree-view.tsx index 37f9c49dad..4f47c123c4 100644 --- a/libs/remix-ui/tree-view/src/lib/remix-ui-tree-view.tsx +++ b/libs/remix-ui/tree-view/src/lib/remix-ui-tree-view.tsx @@ -7,7 +7,7 @@ export const TreeView = (props: TreeViewProps) => { const { children, id, ...otherProps } = props return ( -
    +
      { children }
    ) diff --git a/libs/remix-ui/workspace/src/lib/components/file-label.tsx b/libs/remix-ui/workspace/src/lib/components/file-label.tsx index ed5b75e628..e4bbbee19b 100644 --- a/libs/remix-ui/workspace/src/lib/components/file-label.tsx +++ b/libs/remix-ui/workspace/src/lib/components/file-label.tsx @@ -57,7 +57,7 @@ export const FileLabel = (props: FileLabelProps) => { > { file.name } diff --git a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx index 70551c701f..9e0b0a0f04 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -134,6 +134,8 @@ export function Workspace () { + + ) @@ -191,7 +193,7 @@ export function Workspace () { title='Delete'>