Some checks failed
Build SimApp / build (amd64) (push) Waiting to run
Build SimApp / build (arm64) (push) Waiting to run
CodeQL / Analyze (push) Waiting to run
Build & Push / build (push) Waiting to run
Run Gosec / Gosec (push) Waiting to run
Lint / golangci-lint (push) Waiting to run
Checks dependencies and mocks generation / Check go mod tidy (push) Waiting to run
Checks dependencies and mocks generation / Check up to date mocks (push) Waiting to run
System Tests / setup (push) Waiting to run
System Tests / test-system (push) Blocked by required conditions
System Tests / test-system-legacy (push) Blocked by required conditions
Tests / Code Coverage / split-test-files (push) Waiting to run
Tests / Code Coverage / tests (00) (push) Blocked by required conditions
Tests / Code Coverage / tests (01) (push) Blocked by required conditions
Tests / Code Coverage / tests (02) (push) Blocked by required conditions
Tests / Code Coverage / tests (03) (push) Blocked by required conditions
Tests / Code Coverage / test-integration (push) Waiting to run
Tests / Code Coverage / test-e2e (push) Waiting to run
Tests / Code Coverage / repo-analysis (push) Blocked by required conditions
Tests / Code Coverage / test-sim-nondeterminism (push) Waiting to run
Tests / Code Coverage / test-clientv2 (push) Waiting to run
Tests / Code Coverage / test-core (push) Waiting to run
Tests / Code Coverage / test-depinject (push) Waiting to run
Tests / Code Coverage / test-errors (push) Waiting to run
Tests / Code Coverage / test-math (push) Waiting to run
Tests / Code Coverage / test-schema (push) Waiting to run
Tests / Code Coverage / test-collections (push) Waiting to run
Tests / Code Coverage / test-cosmovisor (push) Waiting to run
Tests / Code Coverage / test-confix (push) Waiting to run
Tests / Code Coverage / test-store (push) Waiting to run
Tests / Code Coverage / test-log (push) Waiting to run
Tests / Code Coverage / test-x-tx (push) Waiting to run
Tests / Code Coverage / test-x-nft (push) Waiting to run
Tests / Code Coverage / test-x-circuit (push) Waiting to run
Tests / Code Coverage / test-x-feegrant (push) Waiting to run
Tests / Code Coverage / test-x-evidence (push) Waiting to run
Tests / Code Coverage / test-x-upgrade (push) Waiting to run
Tests / Code Coverage / test-tools-benchmark (push) Waiting to run
Build & Push SDK Proto Builder / build (push) Has been cancelled
98 lines
4.6 KiB
Markdown
98 lines
4.6 KiB
Markdown
# ADR 058: Auto-Generated CLI
|
|
|
|
## Changelog
|
|
|
|
* 2022-05-04: Initial Draft
|
|
|
|
## Status
|
|
|
|
ACCEPTED Partially Implemented
|
|
|
|
## Abstract
|
|
|
|
In order to make it easier for developers to write Cosmos SDK modules, we provide infrastructure which automatically
|
|
generates CLI commands based on protobuf definitions.
|
|
|
|
## Context
|
|
|
|
Current Cosmos SDK modules generally implement a CLI command for every transaction and every query supported by the
|
|
module. These are handwritten for each command and essentially amount to providing some CLI flags or positional
|
|
arguments for specific fields in protobuf messages.
|
|
|
|
In order to make sure CLI commands are correctly implemented as well as to make sure that the application works
|
|
in end-to-end scenarios, we do integration tests using CLI commands. While these tests are valuable on some-level,
|
|
they can be hard to write and maintain, and run slowly. [Some teams have contemplated](https://github.com/regen-network/regen-ledger/issues/1041)
|
|
moving away from CLI-style integration tests (which are really end-to-end tests) towards narrower integration tests
|
|
which exercise `MsgClient` and `QueryClient` directly. This might involve replacing the current end-to-end CLI
|
|
tests with unit tests as there still needs to be some way to test these CLI commands for full quality assurance.
|
|
|
|
## Decision
|
|
|
|
To make module development simpler, we provide infrastructure - in the new [`client/v2`](https://github.com/cosmos/cosmos-sdk/tree/main/client/v2)
|
|
go module - for automatically generating CLI commands based on protobuf definitions to either replace or complement
|
|
handwritten CLI commands. This will mean that when developing a module, it will be possible to skip both writing and
|
|
testing CLI commands as that can all be taken care of by the framework.
|
|
|
|
The basic design for automatically generating CLI commands is to:
|
|
|
|
* create one CLI command for each `rpc` method in a protobuf `Query` or `Msg` service
|
|
* create a CLI flag for each field in the `rpc` request type
|
|
* for `query` commands call gRPC and print the response as protobuf JSON or YAML (via the `-o`/`--output` flag)
|
|
* for `tx` commands, create a transaction and apply common transaction flags
|
|
|
|
In order to make the auto-generated CLI as easy to use (or easier) than handwritten CLI, we need to do custom handling
|
|
of specific protobuf field types so that the input format is easy for humans:
|
|
|
|
* `Coin`, `Coins`, `DecCoin`, and `DecCoins` should be input using the existing format (i.e. `1000uatom`)
|
|
* it should be possible to specify an address using either the bech32 address string or a named key in the keyring
|
|
* `Timestamp` and `Duration` should accept strings like `2001-01-01T00:00:00Z` and `1h3m` respectively
|
|
* pagination should be handled with flags like `--page-limit`, `--page-offset`, etc.
|
|
* it should be possible to customize any other protobuf type either via its message name or a `cosmos_proto.scalar` annotation
|
|
|
|
At a basic level it should be possible to generate a command for a single `rpc` method as well as all the commands for
|
|
a whole protobuf `service` definition. It should be possible to mix and match auto-generated and handwritten commands.
|
|
|
|
## Consequences
|
|
|
|
### Backwards Compatibility
|
|
|
|
Existing modules can mix and match auto-generated and handwritten CLI commands so it is up to them as to whether they
|
|
make breaking changes by replacing handwritten commands with slightly different auto-generated ones.
|
|
|
|
For now the SDK will maintain the existing set of CLI commands for backwards compatibility but new commands will use
|
|
this functionality.
|
|
|
|
### Positive
|
|
|
|
* module developers will not need to write CLI commands
|
|
* module developers will not need to test CLI commands
|
|
* [lens](https://github.com/strangelove-ventures/lens) may benefit from this
|
|
|
|
### Negative
|
|
|
|
### Neutral
|
|
|
|
## Further Discussions
|
|
|
|
We would like to be able to customize:
|
|
|
|
* short and long usage strings for commands
|
|
* aliases for flags (ex. `-a` for `--amount`)
|
|
* which fields are positional parameters rather than flags
|
|
|
|
It is an [open discussion](https://github.com/cosmos/cosmos-sdk/pull/11725#issuecomment-1108676129)
|
|
as to whether these customizations options should line in:
|
|
|
|
* the .proto files themselves,
|
|
* separate config files (ex. YAML), or
|
|
* directly in code
|
|
|
|
Providing the options in .proto files would allow a dynamic client to automatically generate
|
|
CLI commands on the fly. However, that may pollute the .proto files themselves with information that is only relevant
|
|
for a small subset of users.
|
|
|
|
## References
|
|
|
|
* https://github.com/regen-network/regen-ledger/issues/1041
|
|
* https://github.com/cosmos/cosmos-sdk/tree/main/client/v2
|
|
* https://github.com/cosmos/cosmos-sdk/pull/11725#issuecomment-1108676129
|