forked from solana-labs/solana
-
Notifications
You must be signed in to change notification settings - Fork 271
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
[clap-v3-utils] Add functions to directly parse from SignerSource
#1062
Merged
samkim-crypto
merged 4 commits into
anza-xyz:master
from
samkim-crypto:clap-v3-utils/direct-parse
May 2, 2024
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Is there value in returning
Result<Option<T>>
for all of these?ie. is there meaningful difference, from the user's perspective, between an Err and Ok(None)?
All our original clap parsers return
Option<T>
, and the new ones (likekeypair_from_source
) returnResult<T>
. Can/should we coerce these combiner functions into one or the other of those patterns?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.
Yeah this is the return type of
try_get_one::<T>(arg)
function in clap-v3... the main difference is detailed in solana-labs#33184:Err
means that the function was asked on an unknown/undefined argument:MatchesError::UnknownArgument
means that the arg is unknownMatchesError::Downcast
means that the arg is known, but is asked on an incorrect typeOk(None)
means that the argument is known and of correct type, but was not provided by the userIn clap-v2, the
value_of(arg)
function did not distinguish between the two cases and always returnNone
, which was why our original parsers returnedOption<T>
.The unfortunate thing is that the function
value_of(arg)
(now deprecated) changed its behavior in clap-v3. It now panics in Case 1 and returnsNone
in Case 2. All our original parsers (e.g.pubkey_of
), which usedvalue_of
have inherited the same panicking behavior and this has been the source of many headaches when upgrading clap-v2 --> clap-v3. To cope with this, thetry_
versions of these (e.g.try_pubkey_of
) were added, which prevented panics, but since the original parsing functions expect to parse args asString
as opposed toSignerSource
, they are incompatible withSignerSourceParserBuilder
(and hence this PR).Given this, I think it does make sense that these combiner functions follow the clap-v3 syntax of
try_get_one::<T>(arg)
since it is what it relies on to parse the arguments.Functions like
{signer, keypair, pubkey}_from_source
are not really arg parsers (though it does takeArgMatches
...), but more like functions to extractsigner
,keypair
, orpubkey
from aSignerSource
after the signer source is parsed from user args. Here, I think it makes sense to return just aResult<T>
as in the{signer, keypair, pubkey}_from_path
fucntions.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.
Thanks for the thorough response. I did see that
try_get_one
andtry_get_many
have that return type, but afaict, the two Error cases would only get thrown if we mess up the code in our library (ie. at the call sites oftry_get_one
/try_get_many
). If the user inputs the an arg that doesn't exist or supplies the wrong input type to an argument, they will receive a clap runtime error and not make it to these methods. PlaygroundSo it doesn't seem like there are really any distinct cases being communicated by
Err
vsOk(None)
for these uses oftry_get_one
/try_get_many
. Am I missing something there?That said, I guess our v1 clap signer parsers return
Result<Option<T>>
, so remaining consistent with those is probably the best argument for persisting this return type. I do wish we had handled those better in the first place, though...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.
Ah yes, that is a good point. There is also
try_get_matches
, but it also returns a different error type thanMatchesError
.I may be misunderstanding your point, but it does seem like the one case not considered in the playground example is when the user does provide the correct arguments as specified in the clap app, but the internal logic looks for an unknown or wrong type argument playground This was what I encountered when I was upgrading the token-cli. For example, the argument
--signer
was not defined in theTransfer
command, but it was queried bysigner_from_path
on pubkey inputs causing a panic.So in the context of this PR, it does seem like the downstream code can call
SignerSource::try_get_keypair
on an unknown argument that was not defined in the clap-app (independent of whether the user provided the correct inputs or not), which would produce aMatchesError
. It would be nice if clap catches this on compile time, but it doesn't seem to do so. Does this sound right to you? or am I confusing myself 🥲?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 are saying the same thing. 😅 But I think it is largely incumbent on us to ensure our internal logic is correct (ie. to ensure that clap Arg apis that might be called reflect things in the actual App). Your example is not really all that different than having a fn that calls
matches.value_of("misspelled_arg")
in clap v1, except that the old clap will just fail silently. I do acknowledge that ensuring our internal logic is correct is more difficult given the layers of clap utils.But anyway, since I already conceded there are other reasons to keep the return type, go forth and do good :)
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.
Ah yes, I see your point. Thanks a lot for the clarification!