Skip to content

Commit

Permalink
Merge pull request #5198 from iron-fish/staging
Browse files Browse the repository at this point in the history
Staging to master v2.5.0
  • Loading branch information
patnir committed Aug 1, 2024
2 parents d255420 + 66f7afe commit fc8d80e
Show file tree
Hide file tree
Showing 241 changed files with 10,569 additions and 6,357 deletions.
22 changes: 21 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ homepage = "https://ironfish.network/"
repository = "https://github.com/iron-fish/ironfish"

[profile.release]
debug = true
debug = true
1 change: 1 addition & 0 deletions config/eslint-config-ironfish/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ module.exports = {
rules: {
'ironfish/no-vague-imports': 'error',
'ironfish/no-buffer-cmp': 'error',
'ironfish/no-promise-race': 'error',

// Catches expressions that aren't assigned
'@typescript-eslint/no-unused-expressions': [
Expand Down
15 changes: 15 additions & 0 deletions config/eslint-plugin-ironfish/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,19 @@ module.exports.rules = {
};
},
},
"no-promise-race": {
create(context) {
return {
MemberExpression: function (node) {
if (node.object.name === 'Promise' && node.property.name === 'race') {
context.report({
node,
message:
"Promise.race leaks memory. You can work around it by using PromiseUtils.split to pass resolve/reject to other Promises. See https://github.com/nodejs/node/issues/17469#issuecomment-685216777 for more details.",
});
}
},
};
},
},
};
2 changes: 1 addition & 1 deletion ironfish-cli/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM node:20-bookworm as build
FROM node:20-bookworm AS build
ENV PATH="/root/.cargo/bin:${PATH}"

RUN \
Expand Down
14 changes: 14 additions & 0 deletions ironfish-cli/STYLE_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,20 @@ However, if prompting is required to complete a command, this means the user wil

## Output

When designing the output for a command, commands should output human readable output and not machine readable output. This means you should use components under the `ui` module such as `card`, `table`, or normal logs. It's fine if you only display a simplified version of the output. If the user needs the full data in machine readable format they can use the `--json` flag.

You can categorize commands in a few ways, and you will design their output differently depending on the purpose of the command. You have output commands (status, chain:blocks:info, wallet:transactions), operation commands (stop, wallet:rename).

### JSON Output

We want to support JSON output in all data commands. This will allow developers to use our CLI for basic automating purposes avoiding the need to set up an HTTP client.

If a command returns data it should have `static enableJsonFlag = true` and return an object with the JSON data in the command. The output JSON will automatically be colorized. See more here, https://oclif.io/docs/json/

It's OK to both return an object and use `log` even if JSON is not enabled. If you need custom logic and don't want to rely on returning the JSON, you can use `jsonEnabled()` and the `ui.json()` component to manually log colorized JSON.

This is not necessary for operation commands that perform actions and quit such as `wallet:rename`.

### Progress

Many commands need to run long running operations. The CLI should not look like it's unresponsive. For example, `ironfish wallet:post` posts a transaction and optionally sends it to the network:
Expand Down
5 changes: 1 addition & 4 deletions ironfish-cli/bin/run
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,4 @@ if (Number(process.versions.node.split('.')[0]) < MIN_NODE_VERSION) {
process.exit(1)
}

require('@oclif/core')
.run()
.then(require('@oclif/core/flush'))
.catch(require('@oclif/core/handle'))
require('@oclif/core').execute({ dir: __dirname })
31 changes: 21 additions & 10 deletions ironfish-cli/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ironfish",
"version": "2.4.1",
"version": "2.5.0",
"description": "CLI for running and interacting with an Iron Fish node",
"author": "Iron Fish <[email protected]> (https://ironfish.network)",
"main": "build/src/index.js",
Expand All @@ -23,8 +23,9 @@
"node": ">=18"
},
"devDependencies": {
"@oclif/test": "2.1.0",
"@oclif/test": "4.0.4",
"@types/blessed": "0.1.17",
"@types/cli-progress": "3.11.6",
"@types/inquirer": "8.2.5",
"@types/node": "18.11.16",
"@types/tar": "6.1.1",
Expand All @@ -34,7 +35,7 @@
"eslint-plugin-deprecation": "2.0.0",
"jest": "29.7.0",
"jest-jasmine2": "29.7.0",
"oclif": "3.7.2",
"oclif": "4.14.0",
"rimraf": "^3.0.2",
"ts-jest": "29.1.1",
"tsc-watch": "4.2.9",
Expand All @@ -58,15 +59,17 @@
"oclif:version": "oclif readme && git add README.md"
},
"dependencies": {
"@ironfish/rust-nodejs": "2.4.0",
"@ironfish/sdk": "2.4.1",
"@oclif/core": "3.27.0",
"@oclif/plugin-autocomplete": "1.3.10",
"@oclif/plugin-help": "5.1.12",
"@oclif/plugin-not-found": "2.3.1",
"@oclif/plugin-warn-if-update-available": "2.0.40",
"@ironfish/rust-nodejs": "2.5.0",
"@ironfish/sdk": "2.5.0",
"@ledgerhq/hw-transport-node-hid": "6.29.1",
"@oclif/core": "4.0.11",
"@oclif/plugin-autocomplete": "3.1.6",
"@oclif/plugin-help": "6.2.5",
"@oclif/plugin-not-found": "3.2.10",
"@oclif/plugin-warn-if-update-available": "3.1.8",
"@types/keccak": "3.0.4",
"@types/tar": "6.1.1",
"@zondax/ledger-ironfish": "0.1.2",
"axios": "1.7.2",
"bech32": "2.0.0",
"blessed": "0.1.81",
Expand All @@ -77,6 +80,8 @@
"inquirer": "8.2.5",
"json-colorizer": "2.2.2",
"keccak": "3.0.4",
"natural-orderby": "3.0.2",
"string-width": "4.2.3",
"supports-hyperlinks": "2.2.0",
"tar": "6.1.11",
"uuid": "8.3.2"
Expand All @@ -99,6 +104,12 @@
"topics": {
"wallet:scanning": {
"description": "Turn on or off scanning for accounts"
},
"chain:blocks": {
"description": "commands to look at blocks"
},
"chain:assets": {
"description": "commands to look at assets"
}
}
},
Expand Down
8 changes: 7 additions & 1 deletion ironfish-cli/scripts/build-docker.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,14 @@ set -euo pipefail
cd "$(dirname "$0")/../.."

cat .gitignore - > .dockerignore <<EOF
# do not send the .git directory to the Docker daemon to make builds faster
# Do not send all the files from the .git directory to the Docker daemon to
# make builds faster. Send only the strictly necessary files/directories to
# make git know the hash of the HEAD.
.git
!.git/HEAD
!.git/refs
!.git/objects
.git/objects/*
EOF

echo "Building Docker Image"
Expand Down
42 changes: 33 additions & 9 deletions ironfish-cli/src/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@ import {
InternalOptions,
IronfishSdk,
Logger,
RpcClient,
RpcConnectionError,
} from '@ironfish/sdk'
import { Command, Config } from '@oclif/core'
import { CLIError, ExitError } from '@oclif/core/lib/errors'
import { Command, Config, ux } from '@oclif/core'
import { CLIError, ExitError } from '@oclif/core/errors'
import {
ConfigFlag,
ConfigFlagKey,
DataDirFlag,
DataDirFlagKey,
RpcAuthFlagKey,
RpcHttpHostFlagKey,
Expand All @@ -33,6 +36,7 @@ import {
VerboseFlagKey,
} from './flags'
import { IronfishCliPKG } from './package'
import * as ui from './ui'
import { hasUserResponseError } from './utils'

export type SIGNALS = 'SIGTERM' | 'SIGINT' | 'SIGUSR2'
Expand Down Expand Up @@ -68,16 +72,24 @@ export abstract class IronfishCommand extends Command {
*/
closing = false

client: RpcClient | null = null

public static baseFlags = {
[VerboseFlagKey]: VerboseFlag,
[ConfigFlagKey]: ConfigFlag,
[DataDirFlagKey]: DataDirFlag,
}

constructor(argv: string[], config: Config) {
super(argv, config)
this.logger = createRootLogger().withTag(this.ctor.id)
}

abstract start(): Promise<void> | void
abstract start(): Promise<unknown> | void

async run(): Promise<void> {
async run(): Promise<unknown> {
try {
await this.start()
return await this.start()
} catch (error: unknown) {
if (hasUserResponseError(error)) {
this.log(error.codeMessage)
Expand All @@ -103,16 +115,15 @@ export abstract class IronfishCommand extends Command {
} else {
throw error
}
} finally {
this.client?.close()
}

this.exit(0)
}

async init(): Promise<void> {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any
const commandClass = this.constructor as any
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
const { flags } = await this.parse(commandClass)
const { flags } = await this.parse(this.ctor)

// Get the flags from the flag object which is unknown
const dataDirFlag = getFlag(flags, DataDirFlagKey)
Expand Down Expand Up @@ -220,6 +231,19 @@ export abstract class IronfishCommand extends Command {
closeFromSignal(signal: NodeJS.Signals): Promise<unknown> {
throw new Error(`Not implemented closeFromSignal: ${signal}`)
}

// Override the built-in logJson method to implement our own colorizer that
// works with default terminal colors instead of requiring a theme to be
// configured.
logJson(json: unknown): void {
ux.stdout(ui.json(json))
}

async connectRpc(forceLocal = false, forceRemote = false): Promise<RpcClient> {
const client = await this.sdk.connectRpc(forceLocal, forceRemote)
this.client = client
return client
}
}

function getFlag(flags: unknown, flag: FLAGS): unknown {
Expand Down
31 changes: 0 additions & 31 deletions ironfish-cli/src/commands/blocks/show.ts

This file was deleted.

3 changes: 0 additions & 3 deletions ironfish-cli/src/commands/browse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,12 @@
import { Platform } from '@ironfish/sdk'
import { Flags } from '@oclif/core'
import { IronfishCommand } from '../command'
import { ConfigFlag, ConfigFlagKey, DataDirFlag, DataDirFlagKey } from '../flags'
import { PlatformUtils } from '../utils'

export class BrowseCommand extends IronfishCommand {
static description = `Browse to your data directory`

static flags = {
[ConfigFlagKey]: ConfigFlag,
[DataDirFlagKey]: DataDirFlag,
cd: Flags.boolean({
default: false,
description: 'print the directory where the data directory is',
Expand Down
38 changes: 0 additions & 38 deletions ironfish-cli/src/commands/chain/asset.ts

This file was deleted.

Loading

0 comments on commit fc8d80e

Please sign in to comment.