From e1c80f69580193df1d4a5603dab9bfb8eef4bd8c Mon Sep 17 00:00:00 2001 From: Mohamed Ismail Date: Wed, 29 May 2024 11:29:35 +0200 Subject: [PATCH] feat(kadena-cli): improve config show command to include all command paths and counts of wallets, accounts, networks, templates (#2167) * feat(kadena-cli): improve config show command to include all command paths and number of files * test: add tests for config show command * test: cleanup verbose option from tests * chore: review feedback * chore: prettier format * test: update tests after transfer create template changes --- .changeset/early-apples-jog.md | 6 + .../src/account/tests/accountDetails.test.ts | 1 - .../src/account/tests/accountFund.test.ts | 1 - .../src/config/commands/configPath.ts | 27 ----- .../src/config/commands/configShow.ts | 104 ++++++++++++++++++ packages/tools/kadena-cli/src/config/index.ts | 4 +- .../src/config/tests/configPath.test.ts | 16 --- .../src/config/tests/configShow.test.ts | 72 ++++++++++++ .../src/networks/tests/networkDelete.test.ts | 1 - .../src/networks/tests/networkManage.test.ts | 2 - 10 files changed, 184 insertions(+), 50 deletions(-) create mode 100644 .changeset/early-apples-jog.md delete mode 100644 packages/tools/kadena-cli/src/config/commands/configPath.ts create mode 100644 packages/tools/kadena-cli/src/config/commands/configShow.ts delete mode 100644 packages/tools/kadena-cli/src/config/tests/configPath.test.ts create mode 100644 packages/tools/kadena-cli/src/config/tests/configShow.test.ts diff --git a/.changeset/early-apples-jog.md b/.changeset/early-apples-jog.md new file mode 100644 index 0000000000..2829c2db28 --- /dev/null +++ b/.changeset/early-apples-jog.md @@ -0,0 +1,6 @@ +--- +"@kadena/kadena-cli": minor +--- + +Rename config path command to config show command +Config show command to include all commands directory paths and counts of different resources like wallets, accounts, networks etc. diff --git a/packages/tools/kadena-cli/src/account/tests/accountDetails.test.ts b/packages/tools/kadena-cli/src/account/tests/accountDetails.test.ts index e7293732a1..c66226d598 100644 --- a/packages/tools/kadena-cli/src/account/tests/accountDetails.test.ts +++ b/packages/tools/kadena-cli/src/account/tests/accountDetails.test.ts @@ -56,7 +56,6 @@ describe('account details', () => { 'Enter a ChainId (0-19) (comma or hyphen separated e.g 0,1,2 or 1-5 or all):': '0', }, - verbose: true, }); const res = await runCommandJson('account details'); expect(res).toEqual(accountDetailsSuccessData.result.data); diff --git a/packages/tools/kadena-cli/src/account/tests/accountFund.test.ts b/packages/tools/kadena-cli/src/account/tests/accountFund.test.ts index b4217a4ce4..5e2d510f27 100644 --- a/packages/tools/kadena-cli/src/account/tests/accountFund.test.ts +++ b/packages/tools/kadena-cli/src/account/tests/accountFund.test.ts @@ -91,7 +91,6 @@ describe('account fund', () => { '1', 'Enter an amount:': '5', }, - verbose: true, }); const res = await runCommand('account fund'); diff --git a/packages/tools/kadena-cli/src/config/commands/configPath.ts b/packages/tools/kadena-cli/src/config/commands/configPath.ts deleted file mode 100644 index 4f07f1690d..0000000000 --- a/packages/tools/kadena-cli/src/config/commands/configPath.ts +++ /dev/null @@ -1,27 +0,0 @@ -import type { Command } from 'commander'; -import { services } from '../../services/index.js'; -import { KadenaError } from '../../services/service-error.js'; -import { createCommand } from '../../utils/createCommand.js'; -import { log } from '../../utils/logger.js'; - -export const createConfigPathCommand: ( - program: Command, - version: string, -) => void = createCommand( - 'path', - 'Print the currently used config location', - [], - async () => { - log.debug('config path'); - - const kadenaDir = services.config.getDirectory(); - if (kadenaDir === null) { - throw new KadenaError('no_kadena_directory'); - } - - log.info(log.color.green('Currently using kadena config directory in:')); - log.output(kadenaDir, { - directory: kadenaDir, - }); - }, -); diff --git a/packages/tools/kadena-cli/src/config/commands/configShow.ts b/packages/tools/kadena-cli/src/config/commands/configShow.ts new file mode 100644 index 0000000000..8bca29924c --- /dev/null +++ b/packages/tools/kadena-cli/src/config/commands/configShow.ts @@ -0,0 +1,104 @@ +import type { Table } from 'cli-table3'; +import type { Command } from 'commander'; +import path from 'node:path'; +import { + ACCOUNT_DIR, + NETWORKS_DIR, + TX_TEMPLATE_FOLDER, + WALLET_DIR, +} from '../../constants/config.js'; +import { services } from '../../services/index.js'; +import { KadenaError } from '../../services/service-error.js'; +import { createCommand } from '../../utils/createCommand.js'; +import { getDefaultNetworkName } from '../../utils/helpers.js'; +import { log } from '../../utils/logger.js'; +import { createTable } from '../../utils/table.js'; + +const getConfigPaths = (kadenaDir: string): Record => ({ + configDirectory: kadenaDir, + walletDirectory: path.join(kadenaDir, WALLET_DIR), + defaultTemplateDirectory: path.join(kadenaDir, TX_TEMPLATE_FOLDER), + networkDirectory: path.join(kadenaDir, NETWORKS_DIR), + accountDirectory: path.join(kadenaDir, ACCOUNT_DIR), +}); + +const getNumberOfFiles = async (directory: string): Promise => { + return (await services.filesystem.readDir(directory).catch(() => [])).length; +}; + +const calculateDirectoryFileCounts = async ( + config: Record, +): Promise> => { + const [ + numberOfWallets, + numberOfTemplates, + numberOfNetworks, + numberOfAccounts, + ] = await Promise.all([ + getNumberOfFiles(config.walletDirectory), + getNumberOfFiles(config.defaultTemplateDirectory), + getNumberOfFiles(config.networkDirectory), + getNumberOfFiles(config.accountDirectory), + ]); + + return { + numberOfWallets, + numberOfTemplates, + numberOfNetworks, + numberOfAccounts, + }; +}; + +const generateTabularData = async ( + config: Record, +): Promise => { + const table = createTable({}); + table.push( + { [log.color.green('Config path')]: config.configDirectory }, + { [log.color.green('Wallet path')]: config.walletDirectory }, + { [log.color.green('Number of wallets')]: config.numberOfWallets }, + { + [log.color.green('Default template path')]: + config.defaultTemplateDirectory, + }, + { [log.color.green('Number of templates')]: config.numberOfTemplates }, + { [log.color.green('Network path')]: config.networkDirectory }, + { [log.color.green('Number of networks')]: config.numberOfNetworks }, + { [log.color.green('Default network')]: config.defaultNetwork }, + { [log.color.green('Account path')]: config.accountDirectory }, + { [log.color.green('Number of accounts')]: config.numberOfAccounts }, + ); + + return table; +}; + +export const createConfigShowCommand: ( + program: Command, + version: string, +) => void = createCommand( + 'show', + 'Displays the current config location and counts of different resources like wallets, templates, networks, accounts and etc.)', + [], + async () => { + log.debug('config show'); + + const kadenaDir = services.config.getDirectory(); + if (kadenaDir === null) { + throw new KadenaError('no_kadena_directory'); + } + + log.info(log.color.green('Currently using the following config:')); + const configPaths = getConfigPaths(kadenaDir); + const directoryFileCounts = await calculateDirectoryFileCounts(configPaths); + const defaultNetwork = (await getDefaultNetworkName()) ?? 'N/A'; + + const config = { + ...configPaths, + ...directoryFileCounts, + defaultNetwork, + }; + const table = await generateTabularData(config); + + log.output(table.toString(), config); + }, +); diff --git a/packages/tools/kadena-cli/src/config/index.ts b/packages/tools/kadena-cli/src/config/index.ts index 1beb97c721..65cc71083c 100644 --- a/packages/tools/kadena-cli/src/config/index.ts +++ b/packages/tools/kadena-cli/src/config/index.ts @@ -1,7 +1,7 @@ import { createConfigInitCommand } from './commands/configInit.js'; import type { Command } from 'commander'; -import { createConfigPathCommand } from './commands/configPath.js'; +import { createConfigShowCommand } from './commands/configShow.js'; /** * Represents the root command for the configuration CLI. @@ -26,5 +26,5 @@ export function configCommandFactory(program: Command, version: string): void { all projects bootstrap comes from this configuration */ createConfigInitCommand(configProgram, version); - createConfigPathCommand(configProgram, version); + createConfigShowCommand(configProgram, version); } diff --git a/packages/tools/kadena-cli/src/config/tests/configPath.test.ts b/packages/tools/kadena-cli/src/config/tests/configPath.test.ts deleted file mode 100644 index b7a8003d08..0000000000 --- a/packages/tools/kadena-cli/src/config/tests/configPath.test.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { describe, expect, it } from 'vitest'; -import { CWD_KADENA_DIR, HOME_KADENA_DIR } from '../../constants/config.js'; -import { runCommand, runCommandJson } from '../../utils/test.util.js'; - -describe('config path', () => { - it('should show path used', async () => { - const { stdout } = await runCommand('config path'); - expect(stdout).toEqual(CWD_KADENA_DIR); - }); - - it('should switch to home dir if it exists', async () => { - await runCommandJson('config init -g --quiet -c=false'); - const output = await runCommandJson('config path'); - expect(output.directory).toEqual(HOME_KADENA_DIR); - }); -}); diff --git a/packages/tools/kadena-cli/src/config/tests/configShow.test.ts b/packages/tools/kadena-cli/src/config/tests/configShow.test.ts new file mode 100644 index 0000000000..397ed90ce1 --- /dev/null +++ b/packages/tools/kadena-cli/src/config/tests/configShow.test.ts @@ -0,0 +1,72 @@ +import path from 'node:path'; +import { describe, expect, it, vi } from 'vitest'; +import { + ACCOUNT_DIR, + NETWORKS_DIR, + TX_TEMPLATE_FOLDER, + WALLET_DIR, +} from '../../constants/config.js'; +import { services } from '../../services/index.js'; +import { runCommand, runCommandJson } from '../../utils/test.util.js'; + +describe('config show', () => { + const configDirectory = process.env.KADENA_DIR!; + it('should return the default config paths and values based on test setup', async () => { + // as part of test setup, we have already created the default config + // with 2 templates and 3 networks + const output = await runCommandJson('config show'); + expect(output).toEqual({ + configDirectory, + walletDirectory: path.join(configDirectory, WALLET_DIR), + defaultTemplateDirectory: path.join(configDirectory, TX_TEMPLATE_FOLDER), + networkDirectory: path.join(configDirectory, NETWORKS_DIR), + accountDirectory: path.join(configDirectory, ACCOUNT_DIR), + numberOfWallets: 0, + numberOfTemplates: 3, + numberOfNetworks: 3, + numberOfAccounts: 0, + defaultNetwork: 'N/A', + }); + }); + + it('should return wallets and accounts count after creating a wallet and account', async () => { + // creating a wallet + await runCommandJson('wallet add -w test --quiet', { + stdin: '12345678', + }); + // creating an account + await runCommand( + 'account add --from=key --account-alias=account-one --account-name=k:55e10019549e047e68efaa18489ed785eca271642e2d0ce41d56ced2a30ccb84 --fungible=coin --network=testnet --chain-id=1 --public-keys=55e10019549e047e68efaa18489ed785eca271642e2d0ce41d56ced2a30ccb84 --quiet', + ); + const output = await runCommandJson('config show'); + expect(output).toEqual({ + configDirectory, + walletDirectory: path.join(configDirectory, WALLET_DIR), + defaultTemplateDirectory: path.join(configDirectory, TX_TEMPLATE_FOLDER), + networkDirectory: path.join(configDirectory, NETWORKS_DIR), + accountDirectory: path.join(configDirectory, ACCOUNT_DIR), + numberOfWallets: 1, + numberOfTemplates: 3, + numberOfNetworks: 3, + numberOfAccounts: 1, + defaultNetwork: 'N/A', + }); + }); + + it('should return the default network name when it exists', async () => { + // setting the default network + await runCommand('network set-default --network=testnet --confirm --quiet'); + const output = await runCommandJson('config show'); + expect(output.defaultNetwork).toEqual('testnet'); + }); + + it('should return warning message to run "kadena config init" command when there is no configDirectory', async () => { + const mockGetDirectory = vi.fn().mockReturnValue(null); + services.config.getDirectory = mockGetDirectory; + const { stderr } = await runCommand('config show'); + expect(stderr).toContain( + 'No kadena directory found. Run the following command to create one:', + ); + expect(stderr).toContain('kadena config init'); + }); +}); diff --git a/packages/tools/kadena-cli/src/networks/tests/networkDelete.test.ts b/packages/tools/kadena-cli/src/networks/tests/networkDelete.test.ts index 2c19acb9fd..83de5cf55d 100644 --- a/packages/tools/kadena-cli/src/networks/tests/networkDelete.test.ts +++ b/packages/tools/kadena-cli/src/networks/tests/networkDelete.test.ts @@ -27,7 +27,6 @@ describe('network delete command', () => { 'Are you sure you want to delete the configuration for network "devnet"?\n type "yes" to confirm or "no" to cancel and press enter.': 'yes', }, - verbose: true, }); await runCommand('network delete'); diff --git a/packages/tools/kadena-cli/src/networks/tests/networkManage.test.ts b/packages/tools/kadena-cli/src/networks/tests/networkManage.test.ts index 58272f1fc2..253bbf4e1a 100644 --- a/packages/tools/kadena-cli/src/networks/tests/networkManage.test.ts +++ b/packages/tools/kadena-cli/src/networks/tests/networkManage.test.ts @@ -32,7 +32,6 @@ describe('network update command', () => { 'Enter Kadena network explorer URL (e.g. "https://explorer.chainweb.com/mainnet/tx/"):': '', }, - verbose: true, }); await runCommand('network update'); const content = await services.filesystem.readFile(networkFilePath); @@ -82,7 +81,6 @@ describe('network update command', () => { 'Enter Kadena network explorer URL (e.g. "https://explorer.chainweb.com/mainnet/tx/"):': '', }, - verbose: true, }); await runCommand('network update'); expect(await services.filesystem.fileExists(networkFilePath)).toBe(false);