From 617b948f47ce8544d2b55d303f2de52e87ef0034 Mon Sep 17 00:00:00 2001 From: Lenin Mehedy Date: Wed, 10 Jan 2024 10:02:37 +1100 Subject: [PATCH] fix(cli): enable --dev flag for dev mode (#644) Signed-off-by: Lenin Mehedy --- .github/workflows/zxc-fsnetman-tests.yaml | 3 +- fullstack-network-manager/fsnetman.mjs | 8 ---- .../src/commands/flags.mjs | 10 +++++ .../src/commands/index.mjs | 3 +- .../src/commands/node.mjs | 24 ++++++++++-- .../src/core/config_manager.mjs | 3 ++ .../src/core/logging.mjs | 37 ++++++++++--------- .../src/core/shell_runner.mjs | 15 +++++++- fullstack-network-manager/src/index.mjs | 4 +- .../test/unit/core/shell_runner.test.mjs | 3 +- 10 files changed, 75 insertions(+), 35 deletions(-) diff --git a/.github/workflows/zxc-fsnetman-tests.yaml b/.github/workflows/zxc-fsnetman-tests.yaml index 1caeef9f6..9f2082f27 100644 --- a/.github/workflows/zxc-fsnetman-tests.yaml +++ b/.github/workflows/zxc-fsnetman-tests.yaml @@ -48,7 +48,7 @@ permissions: jobs: test: name: ${{ inputs.custom-job-label || 'fsnetman Test' }} - runs-on: [self-hosted, Linux, medium, ephemeral] + runs-on: [ self-hosted, Linux, medium, ephemeral ] steps: - name: Get related changed files id: changed-files @@ -125,7 +125,6 @@ jobs: working-directory: fullstack-network-manager if: ${{ steps.check-changed-files.outputs.run-tests && !cancelled() && !failure() }} run: | - export DEV_MODE=true npm i npm link fsnetman init -d ../charts diff --git a/fullstack-network-manager/fsnetman.mjs b/fullstack-network-manager/fsnetman.mjs index 2846af3ff..98c1e061a 100755 --- a/fullstack-network-manager/fsnetman.mjs +++ b/fullstack-network-manager/fsnetman.mjs @@ -1,12 +1,4 @@ #!/usr/bin/env node import * as fnm from './src/index.mjs' -// Check the value of the DEV_MODE environment variable, ignoring case -const devMode = process.env.DEV_MODE ? process.env.DEV_MODE.toLowerCase() === 'true' : false - -// Disable stack traces if DEV_MODE is false -if (!devMode) { - Error.stackTraceLimit = 0 -} - fnm.main(process.argv) diff --git a/fullstack-network-manager/src/commands/flags.mjs b/fullstack-network-manager/src/commands/flags.mjs index 0e1100236..1c76a6140 100644 --- a/fullstack-network-manager/src/commands/flags.mjs +++ b/fullstack-network-manager/src/commands/flags.mjs @@ -13,6 +13,15 @@ export function setCommandFlags (y, ...commandFlags) { }) } +export const devMode = { + name: 'dev', + definition: { + describe: 'Enable developer mode', + default: false, + type: 'boolean' + } +} + // list of common flags across commands. command specific flags are defined in the command's module. export const clusterName = { name: 'cluster-name', @@ -267,6 +276,7 @@ export const enableHederaExplorerTls = { } export const allFlags = [ + devMode, clusterName, namespace, deployMirrorNode, diff --git a/fullstack-network-manager/src/commands/index.mjs b/fullstack-network-manager/src/commands/index.mjs index fa96ee0fb..d3fa43108 100644 --- a/fullstack-network-manager/src/commands/index.mjs +++ b/fullstack-network-manager/src/commands/index.mjs @@ -3,6 +3,7 @@ import { InitCommand } from './init.mjs' import { ChartCommand } from './chart.mjs' import { NodeCommand } from './node.mjs' import { RelayCommand } from './relay.mjs' +import * as flags from './flags.mjs' /* * Return a list of Yargs command builder to be exposed through CLI @@ -25,4 +26,4 @@ function Initialize (opts) { } // Expose components from the command module -export { Initialize } +export { Initialize, flags } diff --git a/fullstack-network-manager/src/commands/node.mjs b/fullstack-network-manager/src/commands/node.mjs index d32f002e6..ceb5b66c2 100644 --- a/fullstack-network-manager/src/commands/node.mjs +++ b/fullstack-network-manager/src/commands/node.mjs @@ -118,8 +118,14 @@ export class NodeCommand extends BaseCommand { { title: 'Initialize', task: async (ctx, task) => { + const cachedConfig = await self.configManager.setupConfig(argv) + const namespace = self.configManager.flagValue(cachedConfig, flags.namespace) + + // get existing choices + const namespaces = await self.kubectl.getNamespace('--no-headers', '-o name') + const config = { - namespace: await prompts.promptNamespaceArg(task, argv.namespace), + namespace: await prompts.promptSelectNamespaceArg(task, namespace, namespaces), nodeIds: await prompts.promptNodeIdsArg(task, argv.nodeIds), releaseTag: await prompts.promptReleaseTag(task, argv.releaseTag), cacheDir: await prompts.promptCacheDir(task, argv.cacheDir), @@ -209,8 +215,14 @@ export class NodeCommand extends BaseCommand { { title: 'Initialize', task: async (ctx, task) => { + const cachedConfig = await self.configManager.setupConfig(argv) + const namespace = self.configManager.flagValue(cachedConfig, flags.namespace) + + // get existing choices + const namespaces = await self.kubectl.getNamespace('--no-headers', '-o name') + ctx.config = { - namespace: await prompts.promptNamespaceArg(task, argv.namespace), + namespace: await prompts.promptSelectNamespaceArg(task, namespace, namespaces), nodeIds: await prompts.promptNodeIdsArg(task, argv.nodeIds) } } @@ -282,8 +294,14 @@ export class NodeCommand extends BaseCommand { { title: 'Initialize', task: async (ctx, task) => { + const cachedConfig = await self.configManager.setupConfig(argv) + const namespace = self.configManager.flagValue(cachedConfig, flags.namespace) + + // get existing choices + const namespaces = await self.kubectl.getNamespace('--no-headers', '-o name') + ctx.config = { - namespace: await prompts.promptNamespaceArg(task, argv.namespace), + namespace: await prompts.promptSelectNamespaceArg(task, namespace, namespaces), nodeIds: await prompts.promptNodeIdsArg(task, argv.nodeIds) } } diff --git a/fullstack-network-manager/src/core/config_manager.mjs b/fullstack-network-manager/src/core/config_manager.mjs index e74b53872..29517a040 100644 --- a/fullstack-network-manager/src/core/config_manager.mjs +++ b/fullstack-network-manager/src/core/config_manager.mjs @@ -106,6 +106,9 @@ export class ConfigManager { config = JSON.parse(configJSON.toString()) } + this.logger.debug('Setup cached config', { cachedConfig: config }) + + this.logger.setDevMode(this.flagValue(config, flags.devMode)) return config } catch (e) { throw new FullstackTestingError(`failed to load config: ${e.message}`, e) diff --git a/fullstack-network-manager/src/core/logging.mjs b/fullstack-network-manager/src/core/logging.mjs index fbb73dfda..6869acc0e 100644 --- a/fullstack-network-manager/src/core/logging.mjs +++ b/fullstack-network-manager/src/core/logging.mjs @@ -41,20 +41,11 @@ export const Logger = class { /** * Create a new logger * @param level logging level as supported by winston library: - * { - * emerg: 0, - * alert: 1, - * crit: 2, - * error: 3, - * warning: 4, - * notice: 5, - * info: 6, - * debug: 7 - * } * @constructor */ - constructor (level) { + constructor (level = 'debug') { this.nextTraceId() + this.devMode = false this.winstonLogger = winston.createLogger({ level, @@ -76,6 +67,15 @@ export const Logger = class { }) } + setDevMode (devMode) { + this.debug(`setting dev mode: ${devMode}`) + this.devMode = devMode + } + + setLevel (level) { + this.winstonLogger.setLevel(level) + } + nextTraceId () { this.traceId = uuidv4() } @@ -94,24 +94,25 @@ export const Logger = class { } showUserError (err) { - this.error(err.message, err) - - console.log(chalk.red('ERROR: ')) - console.log(err.stack) - + const stack = [{ message: err.message, stacktrace: err.stack }] if (err.cause) { let depth = 0 let cause = err.cause while (cause !== undefined && depth < 10) { if (cause.stack) { - console.log(chalk.red('Caused by:')) - console.log(cause.stack) + stack.push({ message: cause.message, stacktrace: cause.stack }) } cause = cause.cause depth += 1 } } + + if (this.devMode) { + console.log(stack) + } + + this.error(err.message, { error: err.message, stacktrace: stack }) } error (msg, ...args) { diff --git a/fullstack-network-manager/src/core/shell_runner.mjs b/fullstack-network-manager/src/core/shell_runner.mjs index dab5276fd..a8ace9bd3 100644 --- a/fullstack-network-manager/src/core/shell_runner.mjs +++ b/fullstack-network-manager/src/core/shell_runner.mjs @@ -54,10 +54,23 @@ export class ShellRunner { errOutput.forEach(m => self.logger.showUser(chalk.red(m))) } + self.logger.error(`Error executing: '${cmd}'`, { + commandExitCode: code, + commandExitSignal: signal, + commandOutput: output, + errOutput, + error: { message: err.message, stack: err.stack } + }) + reject(err) } - self.logger.debug(`Finished executing: '${cmd}'`, { commandExitCode: code, commandExitSignal: signal, commandOutput: output }) + self.logger.debug(`Finished executing: '${cmd}'`, { + commandExitCode: code, + commandExitSignal: signal, + commandOutput: output, + errOutput + }) resolve(output) }) }) diff --git a/fullstack-network-manager/src/index.mjs b/fullstack-network-manager/src/index.mjs index f306c9e63..a66e302eb 100644 --- a/fullstack-network-manager/src/index.mjs +++ b/fullstack-network-manager/src/index.mjs @@ -1,12 +1,13 @@ import yargs from 'yargs' import { hideBin } from 'yargs/helpers' +import { flags } from './commands/index.mjs' import * as commands from './commands/index.mjs' import * as core from './core/index.mjs' import { ChartManager, ConfigManager, DependencyManager } from './core/index.mjs' import 'dotenv/config' export function main (argv) { - const logger = core.logging.NewLogger('debug') + const logger = core.logging.NewLogger() const kind = new core.Kind(logger) const helm = new core.Helm(logger) const kubectl = new core.Kubectl(logger) @@ -36,6 +37,7 @@ export function main (argv) { .alias('v', 'version') .command(commands.Initialize(opts)) .strict() + .option(flags.devMode.name, flags.devMode.definition) .wrap(120) .demand(1, 'Select a command') .parse() diff --git a/fullstack-network-manager/test/unit/core/shell_runner.test.mjs b/fullstack-network-manager/test/unit/core/shell_runner.test.mjs index 9e4ee0c81..5d2d34afe 100644 --- a/fullstack-network-manager/test/unit/core/shell_runner.test.mjs +++ b/fullstack-network-manager/test/unit/core/shell_runner.test.mjs @@ -17,7 +17,8 @@ describe('ShellRunner', () => { expect(loggerSpy).toHaveBeenNthCalledWith(2, 'Finished executing: \'ls -l\'', { commandExitCode: expect.any(Number), commandExitSignal: null, - commandOutput: expect.any(Array) + commandOutput: expect.any(Array), + errOutput: expect.any(Array) }) expect(readableSpy).toHaveBeenCalledWith('data', expect.anything()) expect(childProcessSpy).toHaveBeenCalledWith('exit', expect.anything())