96 lines
4.6 KiB
Markdown
96 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
|