Skip to content
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

Update to Cobra CLI #64

Merged
merged 13 commits into from
Apr 21, 2017
Merged

Update to Cobra CLI #64

merged 13 commits into from
Apr 21, 2017

Conversation

rigelrozanski
Copy link
Contributor

@rigelrozanski rigelrozanski commented Apr 2, 2017

Closes #62, Closes #61, Closes #46
In conjunction with Basecoin-Examples PR tendermint/basecoin-examples#8

Updated CLI, new "simplified" basecoin, and all associated documentation/tutorials

@ethanfrey
Copy link
Contributor

Modified init to be more robust when an existing validator key is there but no genesis file.

Also, do we really want to print "%+v" for the error all the time. For debugging, the stack trace can be nice, but when using it and I type in an empty account, I just want the message, not the stack dump.

Maybe a separate flag "--verbose" / "--debug" so it will print this info, and just "%v" otherwise? You would just have to extract this idiom: cmn.Exit(fmt.Sprintf("%+v\n", err)) into a basecoin local helper, which checks the verbose flag itself.

@rigelrozanski
Copy link
Contributor Author

rigelrozanski commented Apr 3, 2017

hmm okay, yeah I agree that it would be nice to not have the stack dump when we're not debugging... Even easier just reference a string variable that can be either "v%" or "v+%" depending on if --debug is used. @ebuchman thoughts too?

@ethanfrey
Copy link
Contributor

How about a new function in the cmd/commands directory:

func dieOnError(err error) {
  if err != nil {
    form := "%v"
    if viper.GetBool("debug") {
      form = "%+v"
    }
    cmn.Exit(fmt.Sprintf(form, err))
  }
}

Note the first check, so it does nothing if err is nil, and you can safely call it without checking..

err := foo()
dieOnError(err)

@ethanfrey
Copy link
Contributor

You do use viper? Or not? Otherwise change the viper.GetBool to whatever makes sense to you. Or see how I register all the flags on viper in go-keys

@rigelrozanski
Copy link
Contributor Author

Okay cool. Yeah viper is not used yet. Going to update tendermint and basecoin to use viper this week. @ebuchman and I have had a few discussions on using functions to check errors as opposed to checking them in place, the resolution is that we've decided to check errors in place to maintain portability... However I wonder if there is a way to do both... such as check the error in place first, but also if the debug flag is on, do a stack trace print and exit, an alternative util function might look something like this (which would be called after checking for the error in place)

func debug(err error) {
   if viper.GetBool("debug") && err != nil {
      cmn.Exit(fmt.Sprintf(%+v, err))
   }
}

@ethanfrey
Copy link
Contributor

Let @ebuchman decide and please write the prefered mechanism in the style-guide

@rigelrozanski
Copy link
Contributor Author

@ethanfrey Okay sounds good

@ebuchman
Copy link
Member

--debug seems fine. The stack trace doesn't buy us much in most cases. Though in some sense it balances exiting in these functions. My personal preference is to return errors all the way to the top and exiting in one place only. Errors can include a stack trace when its useful

@rigelrozanski
Copy link
Contributor Author

@ebuchman --debug has been added as well as returning errors all the way up

Copy link
Member

@ebuchman ebuchman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work!

// register flags
registerFlags := []Flag2Register{
{&ibcChainIDFlag, "ibc_chain_id", "", "ChainID for the new blockchain"},
{&ibcGenesisFlag, "genesis", "", "Genesis file for the new blockchain"},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe for consistency all these flags should have ibc_. that could also avoid breaking changes later

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually leave this for now and we can discuss as a team after some QA testing. fine to have this on develop before a final decision

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

leaving for now

}
)

// setupFile aborts on error... or should we return it??
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like it always returns now

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed

// returns 1 iff it set a file, otherwise 0 (so we can add them)
func setupFile(path, data string, perm os.FileMode) (int, error) {
_, err := os.Stat(path)
if !os.IsNotExist(err) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldnt this just be os.IsExist ?

Copy link
Contributor Author

@rigelrozanski rigelrozanski Apr 18, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

causes a permission denied error if we use os.IsExist, this check is the same as in tendermint core, leaving (will add a comment)

key := genKey()
keyJSON, err := json.MarshalIndent(key, "", "\t")
fmt.Println(&key)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

if err != nil {
return errors.New(cmn.Fmt("Proof (%v) is invalid hex: %v", c.String("proof"), err))
}
proofBytes, err := hex.DecodeString(StripHex(proofFlag))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check this error

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whoops. done

{&amountFlag, "amount", "", "Coins to send in transaction of the format <amt><coin>,<amt2><coin2>,... (eg: 1btc,2gold,5silver},"},
{&gasFlag, "gas", 0, "The amount of gas for the transaction"},
{&feeFlag, "fee", "", "Coins for the transaction fee of the format <amt><coin>"},
{&seqFlag, "sequence", -1, "Sequence number for the account (-1 to autocalculate},"},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

again, } should be )

@@ -21,16 +23,87 @@ import (
tmtypes "github.com/tendermint/tendermint/types"
)

//This variable can be overwritten by plugin applications
// if they require a different working directory
var DefaultHome = "basecoin"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.basecoin

func BasecoinRoot(rootDir string) string {
if rootDir == "" {
rootDir = os.Getenv("BCHOME")
}
if rootDir == "" {
rootDir = os.Getenv("HOME") + "/.basecoin"
rootDir = os.Getenv("HOME") + "/." + DefaultHome
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

path.Join(os.Getenv("HOME"), DefaultHome)

var debug bool
RootCmd.PersistentFlags().BoolVar(&debug, "debug", false, "enables stack trace error messages")

//note that Execute() prints the error if encountered, so no need to reprint the error,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is bad, because it also prints the help menu, which may be totally irrelevant.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

solved with cmd.SilenceUsage but update the comment.

}
}

type Flag2Register struct {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

neat. a comment would be helpful

// returns 1 iff it set a file, otherwise 0 (so we can add them)
func setupFile(path, data string, perm os.FileMode) (int, error) {
_, err := os.Stat(path)
if !os.IsNotExist(err) {
if !os.IsNotExist(err) { //permission errors generated if use os.IsExist
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Investigate

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See this gist for a pretty informative description as to what is going on, looks like os.IsExist is not appropriate here https://gist.github.com/mastef/05f46d3ab2f5ed6a6787#file-isexist_vs_isnotexist-go-L35-L43

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can just check the err == nil. But fine.

@@ -198,6 +198,9 @@ func verifyCmd(cmd *cobra.Command, args []string) error {
}

proofBytes, err := hex.DecodeString(StripHex(proofFlag))
if err != nil {
return errors.Errorf("Proof (%v) is invalid hex: %v\n", proofBytes, err)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be proofFlag here, the bytes will be nil if there's an err

@@ -25,14 +26,14 @@ import (

//This variable can be overwritten by plugin applications
// if they require a different working directory
var DefaultHome = "basecoin"
var DefaultHome = ".basecoin"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually we should probably just put the whole path here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This variable exists because it is changed by each basecoin plugin which may require a modified genesis (and the original space should not be overwritten). Only if we choose not to enforce use of the home directory for default basecoin-plugin working spaces should be we change this. If we choose to enforce using the home directory (which I had assumed we would) then it does not make sense to modify this to include the full path as it would mean that each plugin would be duplicating the code os.Getenv("Home").. Just considering

@ebuchman
Copy link
Member

I'll handle my comments and the rebase tmrw.

@rigelrozanski
Copy link
Contributor Author

Okay made minor fixes/left rebase and decision/code changes on your issues based on my comment - to you

@ebuchman ebuchman merged commit 488f3e1 into develop Apr 21, 2017
@ethanfrey ethanfrey deleted the cli_cobra branch May 29, 2017 15:38
liamsi pushed a commit to liamsi/cosmos-sdk that referenced this pull request Jun 26, 2018
wimel added a commit to wimel/cosmos-sdk that referenced this pull request Oct 9, 2020
wimel added a commit to wimel/cosmos-sdk that referenced this pull request Oct 9, 2020
mergify bot pushed a commit that referenced this pull request Oct 9, 2020
* Fix ISSUE #64 on cosmosdevs/stargate

* Fix ISSUE #64 on cosmosdevs/stargate

* Update x/upgrade/client/cli/tx.go

Co-authored-by: Aleksandr Bezobchuk <alexanderbez@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants