diff --git a/.github/workflows/PrettierAndTSLint.yml b/.github/workflows/PrettierAndTSLint.yml deleted file mode 100644 index 571092e..0000000 --- a/.github/workflows/PrettierAndTSLint.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: Prettier and TSLint - -on: - push: - pull_request: - workflow_dispatch: - -jobs: - Lint: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: NPM Clean Install - run: npm ci - - name: Run Prettier - run: npx prettier --write src/ - - name: Run TS Linter - run: npm run lint:fix \ No newline at end of file diff --git a/.github/workflows/prettier.yml b/.github/workflows/prettier.yml new file mode 100644 index 0000000..b3cd6da --- /dev/null +++ b/.github/workflows/prettier.yml @@ -0,0 +1,20 @@ +name: Prettier + +on: + pull_request: + workflow_dispatch: + +jobs: + prettier: + runs-on: ubuntu-latest + + steps: + - name: Checkout + - uses: actions/checkout@v2with: + ref: ${{ github.head_ref }} + fetch-depth: 0 + - name: Prettify code + uses: creyD/prettier_action@v4.2 + with: + prettier_options: --write src/ + only_changed: True \ No newline at end of file diff --git a/.github/workflows/tslint.yml b/.github/workflows/tslint.yml new file mode 100644 index 0000000..ca0f9ed --- /dev/null +++ b/.github/workflows/tslint.yml @@ -0,0 +1,22 @@ +name: TSLint + +on: + pull_request: + workflow_dispatch: + +jobs: + tslint: + runs-on: ubuntu-latest + timeout-minutes: 2 + steps: + - name: Checkout + - uses: actions/checkout@v2with: + ref: ${{ github.head_ref }} + fetch-depth: 0 + - name: NPM Clean Install + run: npm ci + - name: TSLint + uses: mooyoul/tslint-actions@v1.1.1 + with: + token: ${{ secrets.GITHUB_TOKEN }} + pattern: 'src/*.ts' \ No newline at end of file diff --git a/README.md b/README.md index a0778d6..1a4e3c1 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ [![license](https://img.shields.io/github/license/jamesisaac/react-native-background-task.svg)](https://opensource.org/licenses/MIT) -# hardhat-awesome-cli +# 👷 hardhat-awesome-cli Hardhat made awesome with a flexible CLI to help run test, deploy and more. # This package is not yet published on npmjs, for now @@ -38,15 +38,22 @@ or inside hardhat.config.ts import hardhatAwesomeCli from 'hardhat-awesome-cli' ``` -## Done +## 💪 Done - Run test on all or sigle test file (from all your file in test/) - Run scripts on all or sigle scripts file (from all your file in scripts/) -- Setting: +- Settings: - Activate/Disable chain to show on test/scripts options + - Build .env file with rpc url and private key (or mnemonic) +- More settings + - Exclude files from, tests and scripts selection (useful for config and share helper file) - Create Mock contracts (ERC20, ERC721, ERC1155 + Upgradeable version) -## To do: -- Settings: - - Build .env file with rpc url and private key (inject both chain and .env info in hardhat.config) - - Select or exclude file from the test&script directory (to generate a list of different test&scripts to be run and not show these files) -- Add tool to log all contracts deploy on each chain (1 unique contractName/chain + full log) \ No newline at end of file +## 🏗️ To do: +- Inject chain settings, rpc and accounts in hardhat.config +- Offer to generate deployment script and test script for Mock contract created +- Deployment contract generator +- More Settings: + - Create github workflows file to run test and coverage test + - Setup slack API or email report to receive a copy of test result and contracts list deployed +- Add tool to log all contracts deploy on each chain (1 unique contractName/chain + full log) +- Add option to create Admin Proxy and Transparent proxy w/ appropriate deployment scripts \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 2538079..019b806 100644 --- a/src/index.ts +++ b/src/index.ts @@ -146,7 +146,7 @@ const buildActivatedChainList = async () => { return chainList } -const buildTestsList = async () => { +const buildAllTestsList = async () => { const testList = [] if (fs.existsSync('test')) { testList.push({ @@ -171,7 +171,7 @@ const buildTestsList = async () => { return testList } -const buildScriptsList = async () => { +const buildAllScriptsList = async () => { const testList = [] if (fs.existsSync('scripts')) { const files = fs.readdirSync('scripts') @@ -192,6 +192,44 @@ const buildScriptsList = async () => { return testList } +const buildTestsList = async () => { + let allTestList = await buildAllTestsList() + let excludedFiles = await buildExcludedFile() + if (excludedFiles && excludedFiles.length > 0) { + excludedFiles = excludedFiles.filter((test) => test.directory === 'test') + if (excludedFiles && excludedFiles.length > 0) { + excludedFiles = excludedFiles.map((file) => { + return file.filePath + }) + allTestList = allTestList.filter((script) => { + return !excludedFiles.includes(script.filePath) + }) + return allTestList + } + } else { + return allTestList + } +} + +const buildScriptsList = async () => { + let allScriptList = await buildAllScriptsList() + let excludedFiles = await buildExcludedFile() + if (excludedFiles && excludedFiles.length > 0) { + excludedFiles = excludedFiles.filter((test) => test.directory === 'scripts') + if (excludedFiles && excludedFiles.length > 0) { + excludedFiles = excludedFiles.map((file) => { + return file.filePath + }) + allScriptList = allScriptList.filter((script) => { + return !excludedFiles.includes(script.filePath) + }) + return allScriptList + } + } else { + return allScriptList + } +} + const buildMockContract = async (contractName) => { const packageRootPath = path.join(path.dirname(require.main.filename), '../../../hardhat-easy-cli/src/mockContracts') if (fs.existsSync('scripts')) { @@ -214,6 +252,18 @@ const buildMockContract = async (contractName) => { } } +const buildExcludedFile = async () => { + let fileSetting: any = [] + if (fs.existsSync(fileHardhatAwesomeCLI)) { + const rawdata: any = fs.readFileSync(fileHardhatAwesomeCLI) + fileSetting = JSON.parse(rawdata) + if (fileSetting && fileSetting.excludedFiles) { + return fileSetting.excludedFiles + } + } + return [] +} + const addChain = async (chainName, chainToAdd) => { let fileSetting: any = [] if (fs.existsSync(fileHardhatAwesomeCLI)) { @@ -221,6 +271,7 @@ const addChain = async (chainName, chainToAdd) => { fileSetting = JSON.parse(rawdata) if (fileSetting && !fileSetting.activatedChain) { fileSetting = { + ...fileSetting, activatedChain: [] } } @@ -294,6 +345,80 @@ const addCustomChain = async (chainDetails) => { } } +const addExcludedFiles = async (directory, filePath) => { + let fileSetting: any = [] + const fileToAdd = { + directory, + filePath + } + if (fs.existsSync(fileHardhatAwesomeCLI)) { + const rawdata: any = fs.readFileSync(fileHardhatAwesomeCLI) + fileSetting = JSON.parse(rawdata) + if (fileSetting && !fileSetting.excludedFiles) { + fileSetting = { + ...fileSetting, + excludedFiles: [] + } + } + } else { + fileSetting = { + excludedFiles: [] + } + } + if (fileSetting && fileSetting.excludedFiles) { + if (fileSetting.excludedFiles.length > 0) { + if (!fileSetting.excludedFiles.find((file) => file.directory === directory && file.filePath === filePath)) { + fileSetting.excludedFiles.push(fileToAdd) + } + } else { + fileSetting.excludedFiles.push(fileToAdd) + } + } else { + fileSetting.push({ + excludedFiles: [fileToAdd] + }) + } + try { + fs.writeFileSync(fileHardhatAwesomeCLI, JSON.stringify(fileSetting, null, 2)) + } catch { + console.log(chalk.red('Error adding file: ' + directory + '/' + filePath + ' to your excluded files settings!')) + } +} + +const removeExcludedFiles = async (directory, filePath) => { + let allFiles: any = [] + const excludedFiles: any = [] + if (directory === 'test') { + allFiles = (await buildAllTestsList()) + .filter((test) => test.type === 'file') + .map((file) => { + return file.filePath + }) + } else if (directory === 'script') { + allFiles = (await buildAllScriptsList()) + .filter((script) => script.type === 'file') + .map((file) => { + return file.filePath + }) + } + const fileToRemove = allFiles.find((file) => file.directory === directory && file.filePath === filePath) + let fileSetting: any = [] + if (fs.existsSync(fileHardhatAwesomeCLI)) { + const rawdata: any = fs.readFileSync(fileHardhatAwesomeCLI) + fileSetting = JSON.parse(rawdata) + if (fileSetting && fileSetting.excludedFiles) { + if (fileSetting.excludedFiles.length > 0) { + fileSetting.excludedFiles + .filter((file) => file.directory === directory && file.filePath === filePath) + .forEach(() => { + fileSetting.excludedFiles.pop(fileToRemove) + fs.writeFileSync(fileHardhatAwesomeCLI, JSON.stringify(fileSetting, null, 2)) + }) + } + } + } +} + const getEnvValue = async (envName) => { if (fs.existsSync(fileEnvHardhatAwesomeCLI)) { const allEnv = require('dotenv').config({ path: fileEnvHardhatAwesomeCLI }) @@ -588,7 +713,70 @@ const serveSettingSelector = async (env) => { }) } -const serveMoreSettingSelector = async () => {} +const serveExcludeFileSelector = async (option) => { + let allFiles: any = [] + let excludedFiles: any = await buildExcludedFile() + if (option === 'test') { + allFiles = await buildAllTestsList() + } else if (option === 'scripts') { + allFiles = await buildAllScriptsList() + } + if (allFiles && allFiles.length > 0) { + allFiles = allFiles + .filter((test) => test.type === 'file') + .map((file) => { + return file.filePath + }) + } + if (excludedFiles && excludedFiles.length > 0) { + excludedFiles = excludedFiles.filter((test) => test.directory === option) + if (excludedFiles && excludedFiles.length > 0) { + excludedFiles = excludedFiles.map((file) => { + return file.filePath + }) + } + } + await inquirer + .prompt([ + { + type: 'checkbox', + name: 'allFiles', + message: 'Select the files you want to exclude', + choices: allFiles, + default: excludedFiles + } + ]) + .then(async (activateFilesSelected) => { + allFiles.map(async (file: any) => { + if (activateFilesSelected.allFiles.includes(file)) { + await addExcludedFiles(option, file) + } else { + await removeExcludedFiles(option, file) + } + }) + console.log(chalk.green('Settings updated!')) + }) +} + +const serveMoreSettingSelector = async () => { + await inquirer + .prompt([ + { + type: 'list', + name: 'moreSettings', + message: 'Select a mock contract', + choices: ['Exclude test file from the tests selection list', 'Exclude script file from the scripts selection list'] + } + ]) + .then(async (moreSettingsSelected) => { + if (moreSettingsSelected.moreSettings === 'Exclude test file from the tests selection list') { + await serveExcludeFileSelector('test') + } + if (moreSettingsSelected.moreSettings === 'Exclude script file from the scripts selection list') { + await serveExcludeFileSelector('scripts') + } + }) +} const serveMockContractCreatorSelector = async () => { if (MockContractsList) {