-
Notifications
You must be signed in to change notification settings - Fork 3.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(cli): dynamically generate query CLI commands #11725
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking good. My main concern at the moment is the information that is lost or that would need to be added to the proto comments for the query messages. How do we auto-generate cli commands without losing the benefits of using cobra directly?
// CreateQueryMethodCommand creates a gRPC query command for the given service method. | ||
func (b *Builder) CreateQueryMethodCommand(descriptor protoreflect.MethodDescriptor) *cobra.Command { | ||
serviceDescriptor := descriptor.Parent().(protoreflect.ServiceDescriptor) | ||
docs := util.DescriptorDocs(descriptor) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think the proto comment will serve as an adequate Long
description. Many of the query commands we've implemented include more information than what is provided with the proto comment and the description is specific to the command. We also provide examples of how to use the command. If we were to use this as is, we would lose a lot of valuable information. How might custom Long
descriptions be added?
cmd := &cobra.Command{ | ||
Use: protoNameToCliName(descriptor.Name()), | ||
Long: docs, | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about Short
, Example
, and other cobra command properties? How might these be supported?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ryan, would you be OK with the tradeoff implied here?
eg: we lose cobra configurability
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should find a solution to support these options but we can address in follow-ups. We recently started using cobra/doc
in our application to generate documentation for each command and we are in the process of updating our commands to include such options as Example
so that we can provide better documentation.
@aaronc thank you, I think this is fantastic |
Love this, let's automate more <3 |
We can always add options to the proto files directly related to cli commands such as Usage and Short. Or that can be configured elsewhere. The benefit of storing it in the proto files is that it will allow a tool like lens to dynamically generate the CLI for any module even ones that have never been seen before. |
What about something like this: package cosmos.bank.v1beta1;
service Query {
// Balance queries the balance of a single coin for a single account.
rpc Balance(QueryBalanceRequest) returns (QueryBalanceResponse) {
option (cosmos.base.cli.v1.long) = "....";
}
...
}
message QueryBalanceRequest {
// address is the address to query balances for.
string address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
// denom is the coin denom to query balances for.
string denom = 2 [(cosmos.base.cli.v1.usage) = "...", (cosmos.base.cli.v1.shorthand) = "d"];
} For commands themselves we could have the following annotations: How does that sound? Either way, is it okay if we deal with this configurability in follow-ups? |
I'm currently not convinced we need both lens and this CLI v2. For me this code should go in lens, and whether lens gets the file/service descriptors by loading from memory (like in this PR) or from reflection over network, should be a simple lens-side config. Then, one day, the SDK simapp's CLI could do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Either way, is it okay if we deal with this configurability in follow-ups?
Yea, I think addressing this in follow-ups would be ok. This looks like the right direction and would be a really nice improvement. I just want to make sure we are providing good documentation both in the command interface itself and when auto-generating documentation using cobra/doc
, both of which are dependent on these configuration options.
cmd := &cobra.Command{ | ||
Use: protoNameToCliName(descriptor.Name()), | ||
Long: docs, | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should find a solution to support these options but we can address in follow-ups. We recently started using cobra/doc
in our application to generate documentation for each command and we are in the process of updating our commands to include such options as Example
so that we can provide better documentation.
I've heard talk of the lens code making it upstream into the SDK which I'd support. As far as I know there is no completely dynamic CLI generation in lens yet that fully uses regular CLI flags in a way that's similar to how we're currently using cobra. I've let the lens team know about this PR so hopefully we can align efforts. In the short term, the goal is for this to provide immediate value for people writing regular modules and hand-written CLI commands. The idea is for this to be a drop-in replacement for the hand-written CLI that can be used ASAP and obviate the need to write any of that tedious and hard to test code. |
@ryanchristo starting adding proto options in #11763 |
Re new proto options for CLI descriptions, I'm actually also not 100% in favor. I think it should be a separate config file. Let's maybe align on this tomorrow during our framework sync? Before Ryan puts too much work into it. |
Having options in the .proto files could make them more bloated. The advantage of the .proto files, however, is that they would get dynamically served up with gRPC reflection and make it easy to generate the client in a lens type context. We could also have a separate API to serve up these config files but that's another layer of complexity. Alternatively, dynamic clients like lens will just have less feature rich CLIs. |
In the Framework WG call today we agreed that this approach mostly makes sense but that we're not sure that .proto files are the right place for these options because of the risk of bloating those files. As a follow-up, we should probably look at a small PR showing annotations in .proto files and .yaml files side by side. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code LGTM. i think this code is superior than lens, as in it's more chain-agnostic (whereas lens still hardcodes stuff). This should be the direction a cross-chain CLI should go towards.
My concern is more ecosystem-wise: what's the CLI story in cosmos? My ideal long-term vision is that there will be one CLI for the whole ecosystem. Would love to see efforts aligned between this and lens.
A 3rd solution would be to add a new arg to |
Yep, let's figure out customization in follow-ups. I think it depends on how much a dynamic client like lens would want to generate these fully-fleshed cobra commands on the fly |
What is going on with CI? This doesn't touch any existing code so why is test-race failing? |
I force merged this because unrelated CI was failing but can someone please look into what's wrong with CI @AmauryM @alexanderbez @robert-zaremba @marbar3778 ? |
Is this consistently failing? Or just a timeout? If it's flakey, let's add it to the tracking issue for flakey tests. |
It seems like either it times out or some report isn't getting generating. Where is that tracking issue? |
#9010. This PR's failing test doesn't seem flaky though, but consistently failing. |
Description
This PR creates a new go.mod
client/v2
which starts out with functionality to dynamically generate query CLI commands based on a protobufQuery
service definitions.The intention is to completely (or almost completely) replace manually generated CLI commands with this.
All request fields are turned into flags and positional parameters aren't used at all in this initial version. I actually think this is preferable and that positional parameters are confusing, but customization around this could be added in the future.
Handling of flag types can be customized based on the protobuf message type and
cosmos_proto.scalar
annotations. Out of the box handling is provided for:int32
,string
,bool
, etc.)Timestamp
andDuration
cosmos.AddressString
scalarsPageRequest
In follow-up PRs, I plan to add:
Coin
andCoins
handlingclient.Context
(until we can fully replace it)Author Checklist
All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.
I have...
!
to the type prefix if API or client breaking changeCHANGELOG.md
Reviewers Checklist
All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items.
I have...
!
in the type prefix if API or client breaking change