OSDN Git Service

Merge pull request #839 from Bytom/dev-bytomcli
[bytom/bytom.git] / cmd / bytomcli / commands / bytomcli.go
1 package commands
2
3 import (
4         "fmt"
5         "os"
6         "regexp"
7
8         "github.com/spf13/cobra"
9
10         "github.com/bytom/util"
11 )
12
13 // bytomcli usage template
14 var usageTemplate = `Usage:{{if .Runnable}}
15   {{.UseLine}}{{end}}{{if .HasAvailableSubCommands}}
16   {{.CommandPath}} [command]{{end}}{{if gt (len .Aliases) 0}}
17
18 Aliases:
19   {{.NameAndAliases}}{{end}}{{if .HasExample}}
20
21 Examples:
22 {{.Example}}{{end}}{{if .HasAvailableSubCommands}}
23
24 Available Commands:
25     {{range .Commands}}{{if (and .IsAvailableCommand (.Name | WalletDisable))}}
26     {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}
27
28   available with wallet enable:
29     {{range .Commands}}{{if (and .IsAvailableCommand (.Name | WalletEnable))}}
30     {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableLocalFlags}}
31
32 Flags:
33 {{.LocalFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasAvailableInheritedFlags}}
34
35 Global Flags:
36 {{.InheritedFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasHelpSubCommands}}
37
38 Additional help topics:{{range .Commands}}{{if .IsAdditionalHelpTopicCommand}}
39   {{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableSubCommands}}
40
41 Use "{{.CommandPath}} [command] --help" for more information about a command.{{end}}
42 `
43
44 // commandError is an error used to signal different error situations in command handling.
45 type commandError struct {
46         s         string
47         userError bool
48 }
49
50 func (c commandError) Error() string {
51         return c.s
52 }
53
54 func (c commandError) isUserError() bool {
55         return c.userError
56 }
57
58 func newUserError(a ...interface{}) commandError {
59         return commandError{s: fmt.Sprintln(a...), userError: true}
60 }
61
62 func newSystemError(a ...interface{}) commandError {
63         return commandError{s: fmt.Sprintln(a...), userError: false}
64 }
65
66 func newSystemErrorF(format string, a ...interface{}) commandError {
67         return commandError{s: fmt.Sprintf(format, a...), userError: false}
68 }
69
70 // Catch some of the obvious user errors from Cobra.
71 // We don't want to show the usage message for every error.
72 // The below may be to generic. Time will show.
73 var userErrorRegexp = regexp.MustCompile("argument|flag|shorthand")
74
75 func isUserError(err error) bool {
76         if cErr, ok := err.(commandError); ok && cErr.isUserError() {
77                 return true
78         }
79
80         return userErrorRegexp.MatchString(err.Error())
81 }
82
83 // BytomcliCmd is Bytomcli's root command.
84 // Every other command attached to BytomcliCmd is a child command to it.
85 var BytomcliCmd = &cobra.Command{
86         Use:   "bytomcli",
87         Short: "Bytomcli is a commond line client for bytom core (a.k.a. bytomd)",
88         Run: func(cmd *cobra.Command, args []string) {
89                 if len(args) < 1 {
90                         cmd.SetUsageTemplate(usageTemplate)
91                         cmd.Usage()
92                 }
93         },
94 }
95
96 // Execute adds all child commands to the root command BytomcliCmd and sets flags appropriately.
97 func Execute() {
98
99         AddCommands()
100         AddTemplateFunc()
101
102         if _, err := BytomcliCmd.ExecuteC(); err != nil {
103                 os.Exit(util.ErrLocalExe)
104         }
105 }
106
107 // AddCommands adds child commands to the root command BytomcliCmd.
108 func AddCommands() {
109         BytomcliCmd.AddCommand(createAccessTokenCmd)
110         BytomcliCmd.AddCommand(listAccessTokenCmd)
111         BytomcliCmd.AddCommand(deleteAccessTokenCmd)
112         BytomcliCmd.AddCommand(checkAccessTokenCmd)
113
114         BytomcliCmd.AddCommand(createAccountCmd)
115         BytomcliCmd.AddCommand(deleteAccountCmd)
116         BytomcliCmd.AddCommand(listAccountsCmd)
117         BytomcliCmd.AddCommand(createAccountReceiverCmd)
118         BytomcliCmd.AddCommand(listAddressesCmd)
119         BytomcliCmd.AddCommand(validateAddressCmd)
120
121         BytomcliCmd.AddCommand(createAssetCmd)
122         BytomcliCmd.AddCommand(getAssetCmd)
123         BytomcliCmd.AddCommand(listAssetsCmd)
124         BytomcliCmd.AddCommand(updateAssetAliasCmd)
125
126         BytomcliCmd.AddCommand(getTransactionCmd)
127         BytomcliCmd.AddCommand(listTransactionsCmd)
128
129         BytomcliCmd.AddCommand(getUnconfirmedTransactionCmd)
130         BytomcliCmd.AddCommand(listUnconfirmedTransactionsCmd)
131
132         BytomcliCmd.AddCommand(listUnspentOutputsCmd)
133         BytomcliCmd.AddCommand(listBalancesCmd)
134
135         BytomcliCmd.AddCommand(buildTransactionCmd)
136         BytomcliCmd.AddCommand(signTransactionCmd)
137         BytomcliCmd.AddCommand(submitTransactionCmd)
138         BytomcliCmd.AddCommand(estimateTransactionGasCmd)
139
140         BytomcliCmd.AddCommand(getBlockCountCmd)
141         BytomcliCmd.AddCommand(getBlockHashCmd)
142         BytomcliCmd.AddCommand(getBlockCmd)
143         BytomcliCmd.AddCommand(getBlockHeaderCmd)
144
145         BytomcliCmd.AddCommand(createKeyCmd)
146         BytomcliCmd.AddCommand(deleteKeyCmd)
147         BytomcliCmd.AddCommand(listKeysCmd)
148         BytomcliCmd.AddCommand(resetKeyPwdCmd)
149
150         BytomcliCmd.AddCommand(createTransactionFeedCmd)
151         BytomcliCmd.AddCommand(listTransactionFeedsCmd)
152         BytomcliCmd.AddCommand(deleteTransactionFeedCmd)
153         BytomcliCmd.AddCommand(getTransactionFeedCmd)
154         BytomcliCmd.AddCommand(updateTransactionFeedCmd)
155
156         BytomcliCmd.AddCommand(isMiningCmd)
157         BytomcliCmd.AddCommand(setMiningCmd)
158
159         BytomcliCmd.AddCommand(netInfoCmd)
160         BytomcliCmd.AddCommand(gasRateCmd)
161
162         BytomcliCmd.AddCommand(versionCmd)
163 }
164
165 // AddTemplateFunc adds usage template to the root command BytomcliCmd.
166 func AddTemplateFunc() {
167         walletEnableCmd := []string{
168                 createAccountCmd.Name(),
169                 listAccountsCmd.Name(),
170                 deleteAccountCmd.Name(),
171                 createAccountReceiverCmd.Name(),
172                 listAddressesCmd.Name(),
173                 validateAddressCmd.Name(),
174
175                 createAssetCmd.Name(),
176                 getAssetCmd.Name(),
177                 listAssetsCmd.Name(),
178                 updateAssetAliasCmd.Name(),
179
180                 createKeyCmd.Name(),
181                 deleteKeyCmd.Name(),
182                 listKeysCmd.Name(),
183                 resetKeyPwdCmd.Name(),
184
185                 buildTransactionCmd.Name(),
186                 signTransactionCmd.Name(),
187                 submitTransactionCmd.Name(),
188                 estimateTransactionGasCmd.Name(),
189
190                 getTransactionCmd.Name(),
191                 listTransactionsCmd.Name(),
192                 listUnspentOutputsCmd.Name(),
193                 listBalancesCmd.Name(),
194         }
195
196         cobra.AddTemplateFunc("WalletEnable", func(cmdName string) bool {
197                 for _, name := range walletEnableCmd {
198                         if name == cmdName {
199                                 return true
200                         }
201                 }
202                 return false
203         })
204
205         cobra.AddTemplateFunc("WalletDisable", func(cmdName string) bool {
206                 for _, name := range walletEnableCmd {
207                         if name == cmdName {
208                                 return false
209                         }
210                 }
211                 return true
212         })
213 }