github.com/gobitfly/go-ethereum@v1.8.12/cmd/geth/usage.go (about) 1 // Copyright 2015 The go-ethereum Authors 2 // This file is part of go-ethereum. 3 // 4 // go-ethereum is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // go-ethereum is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with go-ethereum. If not, see <http://www.gnu.org/licenses/>. 16 17 // Contains the geth command usage template and generator. 18 19 package main 20 21 import ( 22 "io" 23 "sort" 24 25 "strings" 26 27 "github.com/ethereum/go-ethereum/cmd/utils" 28 "github.com/ethereum/go-ethereum/internal/debug" 29 "gopkg.in/urfave/cli.v1" 30 ) 31 32 // AppHelpTemplate is the test template for the default, global app help topic. 33 var AppHelpTemplate = `NAME: 34 {{.App.Name}} - {{.App.Usage}} 35 36 Copyright 2013-2018 The go-ethereum Authors 37 38 USAGE: 39 {{.App.HelpName}} [options]{{if .App.Commands}} command [command options]{{end}} {{if .App.ArgsUsage}}{{.App.ArgsUsage}}{{else}}[arguments...]{{end}} 40 {{if .App.Version}} 41 VERSION: 42 {{.App.Version}} 43 {{end}}{{if len .App.Authors}} 44 AUTHOR(S): 45 {{range .App.Authors}}{{ . }}{{end}} 46 {{end}}{{if .App.Commands}} 47 COMMANDS: 48 {{range .App.Commands}}{{join .Names ", "}}{{ "\t" }}{{.Usage}} 49 {{end}}{{end}}{{if .FlagGroups}} 50 {{range .FlagGroups}}{{.Name}} OPTIONS: 51 {{range .Flags}}{{.}} 52 {{end}} 53 {{end}}{{end}}{{if .App.Copyright }} 54 COPYRIGHT: 55 {{.App.Copyright}} 56 {{end}} 57 ` 58 59 // flagGroup is a collection of flags belonging to a single topic. 60 type flagGroup struct { 61 Name string 62 Flags []cli.Flag 63 } 64 65 // AppHelpFlagGroups is the application flags, grouped by functionality. 66 var AppHelpFlagGroups = []flagGroup{ 67 { 68 Name: "ETHEREUM", 69 Flags: []cli.Flag{ 70 configFileFlag, 71 utils.DataDirFlag, 72 utils.KeyStoreDirFlag, 73 utils.NoUSBFlag, 74 utils.NetworkIdFlag, 75 utils.TestnetFlag, 76 utils.RinkebyFlag, 77 utils.SyncModeFlag, 78 utils.GCModeFlag, 79 utils.EthStatsURLFlag, 80 utils.IdentityFlag, 81 utils.LightServFlag, 82 utils.LightPeersFlag, 83 utils.LightKDFFlag, 84 }, 85 }, 86 {Name: "DEVELOPER CHAIN", 87 Flags: []cli.Flag{ 88 utils.DeveloperFlag, 89 utils.DeveloperPeriodFlag, 90 }, 91 }, 92 { 93 Name: "ETHASH", 94 Flags: []cli.Flag{ 95 utils.EthashCacheDirFlag, 96 utils.EthashCachesInMemoryFlag, 97 utils.EthashCachesOnDiskFlag, 98 utils.EthashDatasetDirFlag, 99 utils.EthashDatasetsInMemoryFlag, 100 utils.EthashDatasetsOnDiskFlag, 101 }, 102 }, 103 //{ 104 // Name: "DASHBOARD", 105 // Flags: []cli.Flag{ 106 // utils.DashboardEnabledFlag, 107 // utils.DashboardAddrFlag, 108 // utils.DashboardPortFlag, 109 // utils.DashboardRefreshFlag, 110 // utils.DashboardAssetsFlag, 111 // }, 112 //}, 113 { 114 Name: "TRANSACTION POOL", 115 Flags: []cli.Flag{ 116 utils.TxPoolNoLocalsFlag, 117 utils.TxPoolJournalFlag, 118 utils.TxPoolRejournalFlag, 119 utils.TxPoolPriceLimitFlag, 120 utils.TxPoolPriceBumpFlag, 121 utils.TxPoolAccountSlotsFlag, 122 utils.TxPoolGlobalSlotsFlag, 123 utils.TxPoolAccountQueueFlag, 124 utils.TxPoolGlobalQueueFlag, 125 utils.TxPoolLifetimeFlag, 126 }, 127 }, 128 { 129 Name: "PERFORMANCE TUNING", 130 Flags: []cli.Flag{ 131 utils.CacheFlag, 132 utils.CacheDatabaseFlag, 133 utils.CacheGCFlag, 134 utils.TrieCacheGenFlag, 135 }, 136 }, 137 { 138 Name: "ACCOUNT", 139 Flags: []cli.Flag{ 140 utils.UnlockedAccountFlag, 141 utils.PasswordFileFlag, 142 }, 143 }, 144 { 145 Name: "API AND CONSOLE", 146 Flags: []cli.Flag{ 147 utils.RPCEnabledFlag, 148 utils.RPCListenAddrFlag, 149 utils.RPCPortFlag, 150 utils.RPCApiFlag, 151 utils.WSEnabledFlag, 152 utils.WSListenAddrFlag, 153 utils.WSPortFlag, 154 utils.WSApiFlag, 155 utils.WSAllowedOriginsFlag, 156 utils.IPCDisabledFlag, 157 utils.IPCPathFlag, 158 utils.RPCCORSDomainFlag, 159 utils.RPCVirtualHostsFlag, 160 utils.JSpathFlag, 161 utils.ExecFlag, 162 utils.PreloadJSFlag, 163 }, 164 }, 165 { 166 Name: "NETWORKING", 167 Flags: []cli.Flag{ 168 utils.BootnodesFlag, 169 utils.BootnodesV4Flag, 170 utils.BootnodesV5Flag, 171 utils.ListenPortFlag, 172 utils.MaxPeersFlag, 173 utils.MaxPendingPeersFlag, 174 utils.NATFlag, 175 utils.NoDiscoverFlag, 176 utils.DiscoveryV5Flag, 177 utils.NetrestrictFlag, 178 utils.NodeKeyFileFlag, 179 utils.NodeKeyHexFlag, 180 }, 181 }, 182 { 183 Name: "MINER", 184 Flags: []cli.Flag{ 185 utils.MiningEnabledFlag, 186 utils.MinerThreadsFlag, 187 utils.EtherbaseFlag, 188 utils.TargetGasLimitFlag, 189 utils.GasPriceFlag, 190 utils.ExtraDataFlag, 191 }, 192 }, 193 { 194 Name: "GAS PRICE ORACLE", 195 Flags: []cli.Flag{ 196 utils.GpoBlocksFlag, 197 utils.GpoPercentileFlag, 198 }, 199 }, 200 { 201 Name: "VIRTUAL MACHINE", 202 Flags: []cli.Flag{ 203 utils.VMEnableDebugFlag, 204 }, 205 }, 206 { 207 Name: "LOGGING AND DEBUGGING", 208 Flags: append([]cli.Flag{ 209 utils.FakePoWFlag, 210 utils.NoCompactionFlag, 211 }, debug.Flags...), 212 }, 213 { 214 Name: "METRICS AND STATS", 215 Flags: []cli.Flag{ 216 utils.MetricsEnabledFlag, 217 utils.MetricsEnableInfluxDBFlag, 218 utils.MetricsInfluxDBEndpointFlag, 219 utils.MetricsInfluxDBDatabaseFlag, 220 utils.MetricsInfluxDBUsernameFlag, 221 utils.MetricsInfluxDBPasswordFlag, 222 utils.MetricsInfluxDBHostTagFlag, 223 }, 224 }, 225 { 226 Name: "WHISPER (EXPERIMENTAL)", 227 Flags: whisperFlags, 228 }, 229 { 230 Name: "DEPRECATED", 231 Flags: []cli.Flag{ 232 utils.FastSyncFlag, 233 utils.LightModeFlag, 234 }, 235 }, 236 { 237 Name: "MISC", 238 }, 239 } 240 241 // byCategory sorts an array of flagGroup by Name in the order 242 // defined in AppHelpFlagGroups. 243 type byCategory []flagGroup 244 245 func (a byCategory) Len() int { return len(a) } 246 func (a byCategory) Swap(i, j int) { a[i], a[j] = a[j], a[i] } 247 func (a byCategory) Less(i, j int) bool { 248 iCat, jCat := a[i].Name, a[j].Name 249 iIdx, jIdx := len(AppHelpFlagGroups), len(AppHelpFlagGroups) // ensure non categorized flags come last 250 251 for i, group := range AppHelpFlagGroups { 252 if iCat == group.Name { 253 iIdx = i 254 } 255 if jCat == group.Name { 256 jIdx = i 257 } 258 } 259 260 return iIdx < jIdx 261 } 262 263 func flagCategory(flag cli.Flag) string { 264 for _, category := range AppHelpFlagGroups { 265 for _, flg := range category.Flags { 266 if flg.GetName() == flag.GetName() { 267 return category.Name 268 } 269 } 270 } 271 return "MISC" 272 } 273 274 func init() { 275 // Override the default app help template 276 cli.AppHelpTemplate = AppHelpTemplate 277 278 // Define a one shot struct to pass to the usage template 279 type helpData struct { 280 App interface{} 281 FlagGroups []flagGroup 282 } 283 284 // Override the default app help printer, but only for the global app help 285 originalHelpPrinter := cli.HelpPrinter 286 cli.HelpPrinter = func(w io.Writer, tmpl string, data interface{}) { 287 if tmpl == AppHelpTemplate { 288 // Iterate over all the flags and add any uncategorized ones 289 categorized := make(map[string]struct{}) 290 for _, group := range AppHelpFlagGroups { 291 for _, flag := range group.Flags { 292 categorized[flag.String()] = struct{}{} 293 } 294 } 295 uncategorized := []cli.Flag{} 296 for _, flag := range data.(*cli.App).Flags { 297 if _, ok := categorized[flag.String()]; !ok { 298 if strings.HasPrefix(flag.GetName(), "dashboard") { 299 continue 300 } 301 uncategorized = append(uncategorized, flag) 302 } 303 } 304 if len(uncategorized) > 0 { 305 // Append all ungategorized options to the misc group 306 miscs := len(AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags) 307 AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags = append(AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags, uncategorized...) 308 309 // Make sure they are removed afterwards 310 defer func() { 311 AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags = AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags[:miscs] 312 }() 313 } 314 // Render out custom usage screen 315 originalHelpPrinter(w, tmpl, helpData{data, AppHelpFlagGroups}) 316 } else if tmpl == utils.CommandHelpTemplate { 317 // Iterate over all command specific flags and categorize them 318 categorized := make(map[string][]cli.Flag) 319 for _, flag := range data.(cli.Command).Flags { 320 if _, ok := categorized[flag.String()]; !ok { 321 categorized[flagCategory(flag)] = append(categorized[flagCategory(flag)], flag) 322 } 323 } 324 325 // sort to get a stable ordering 326 sorted := make([]flagGroup, 0, len(categorized)) 327 for cat, flgs := range categorized { 328 sorted = append(sorted, flagGroup{cat, flgs}) 329 } 330 sort.Sort(byCategory(sorted)) 331 332 // add sorted array to data and render with default printer 333 originalHelpPrinter(w, tmpl, map[string]interface{}{ 334 "cmd": data, 335 "categorizedFlags": sorted, 336 }) 337 } else { 338 originalHelpPrinter(w, tmpl, data) 339 } 340 } 341 }