github.com/valorbit/go-ethereum@v1.9.11-rc4/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 "github.com/valorbit/go-ethereum/cmd/utils" 26 "github.com/valorbit/go-ethereum/internal/debug" 27 cli "gopkg.in/urfave/cli.v1" 28 ) 29 30 // AppHelpTemplate is the test template for the default, global app help topic. 31 var AppHelpTemplate = `NAME: 32 {{.App.Name}} - {{.App.Usage}} 33 34 Copyright 2013-2019 The go-ethereum Authors 35 36 USAGE: 37 {{.App.HelpName}} [options]{{if .App.Commands}} command [command options]{{end}} {{if .App.ArgsUsage}}{{.App.ArgsUsage}}{{else}}[arguments...]{{end}} 38 {{if .App.Version}} 39 VERSION: 40 {{.App.Version}} 41 {{end}}{{if len .App.Authors}} 42 AUTHOR(S): 43 {{range .App.Authors}}{{ . }}{{end}} 44 {{end}}{{if .App.Commands}} 45 COMMANDS: 46 {{range .App.Commands}}{{join .Names ", "}}{{ "\t" }}{{.Usage}} 47 {{end}}{{end}}{{if .FlagGroups}} 48 {{range .FlagGroups}}{{.Name}} OPTIONS: 49 {{range .Flags}}{{.}} 50 {{end}} 51 {{end}}{{end}}{{if .App.Copyright }} 52 COPYRIGHT: 53 {{.App.Copyright}} 54 {{end}} 55 ` 56 57 // flagGroup is a collection of flags belonging to a single topic. 58 type flagGroup struct { 59 Name string 60 Flags []cli.Flag 61 } 62 63 // AppHelpFlagGroups is the application flags, grouped by functionality. 64 var AppHelpFlagGroups = []flagGroup{ 65 { 66 Name: "ETHEREUM", 67 Flags: []cli.Flag{ 68 configFileFlag, 69 utils.DataDirFlag, 70 utils.AncientFlag, 71 utils.KeyStoreDirFlag, 72 utils.NoUSBFlag, 73 utils.SmartCardDaemonPathFlag, 74 utils.NetworkIdFlag, 75 utils.TestnetFlag, 76 utils.RinkebyFlag, 77 utils.GoerliFlag, 78 utils.ValorbitFlag, 79 utils.GranvilleFlag, 80 utils.SyncModeFlag, 81 utils.ExitWhenSyncedFlag, 82 utils.GCModeFlag, 83 utils.EthStatsURLFlag, 84 utils.IdentityFlag, 85 utils.LightKDFFlag, 86 utils.WhitelistFlag, 87 }, 88 }, 89 { 90 Name: "LIGHT CLIENT", 91 Flags: []cli.Flag{ 92 utils.LightServeFlag, 93 utils.LightIngressFlag, 94 utils.LightEgressFlag, 95 utils.LightMaxPeersFlag, 96 utils.UltraLightServersFlag, 97 utils.UltraLightFractionFlag, 98 utils.UltraLightOnlyAnnounceFlag, 99 }, 100 }, 101 { 102 Name: "DEVELOPER CHAIN", 103 Flags: []cli.Flag{ 104 utils.DeveloperFlag, 105 utils.DeveloperPeriodFlag, 106 }, 107 }, 108 { 109 Name: "ETHASH", 110 Flags: []cli.Flag{ 111 utils.EthashCacheDirFlag, 112 utils.EthashCachesInMemoryFlag, 113 utils.EthashCachesOnDiskFlag, 114 utils.EthashDatasetDirFlag, 115 utils.EthashDatasetsInMemoryFlag, 116 utils.EthashDatasetsOnDiskFlag, 117 }, 118 }, 119 { 120 Name: "TRANSACTION POOL", 121 Flags: []cli.Flag{ 122 utils.TxPoolLocalsFlag, 123 utils.TxPoolNoLocalsFlag, 124 utils.TxPoolJournalFlag, 125 utils.TxPoolRejournalFlag, 126 utils.TxPoolPriceLimitFlag, 127 utils.TxPoolPriceBumpFlag, 128 utils.TxPoolAccountSlotsFlag, 129 utils.TxPoolGlobalSlotsFlag, 130 utils.TxPoolAccountQueueFlag, 131 utils.TxPoolGlobalQueueFlag, 132 utils.TxPoolLifetimeFlag, 133 }, 134 }, 135 { 136 Name: "PERFORMANCE TUNING", 137 Flags: []cli.Flag{ 138 utils.CacheFlag, 139 utils.CacheDatabaseFlag, 140 utils.CacheTrieFlag, 141 utils.CacheGCFlag, 142 utils.CacheNoPrefetchFlag, 143 }, 144 }, 145 { 146 Name: "ACCOUNT", 147 Flags: []cli.Flag{ 148 utils.UnlockedAccountFlag, 149 utils.PasswordFileFlag, 150 utils.ExternalSignerFlag, 151 utils.InsecureUnlockAllowedFlag, 152 }, 153 }, 154 { 155 Name: "API AND CONSOLE", 156 Flags: []cli.Flag{ 157 utils.IPCDisabledFlag, 158 utils.IPCPathFlag, 159 utils.RPCEnabledFlag, 160 utils.RPCListenAddrFlag, 161 utils.RPCPortFlag, 162 utils.RPCApiFlag, 163 utils.RPCGlobalGasCap, 164 utils.RPCCORSDomainFlag, 165 utils.RPCVirtualHostsFlag, 166 utils.WSEnabledFlag, 167 utils.WSListenAddrFlag, 168 utils.WSPortFlag, 169 utils.WSApiFlag, 170 utils.WSAllowedOriginsFlag, 171 utils.GraphQLEnabledFlag, 172 utils.GraphQLListenAddrFlag, 173 utils.GraphQLPortFlag, 174 utils.GraphQLCORSDomainFlag, 175 utils.GraphQLVirtualHostsFlag, 176 utils.JSpathFlag, 177 utils.ExecFlag, 178 utils.PreloadJSFlag, 179 }, 180 }, 181 { 182 Name: "NETWORKING", 183 Flags: []cli.Flag{ 184 utils.BootnodesFlag, 185 utils.BootnodesV4Flag, 186 utils.BootnodesV5Flag, 187 utils.DNSDiscoveryFlag, 188 utils.ListenPortFlag, 189 utils.MaxPeersFlag, 190 utils.MaxPendingPeersFlag, 191 utils.NATFlag, 192 utils.NoDiscoverFlag, 193 utils.DiscoveryV5Flag, 194 utils.NetrestrictFlag, 195 utils.NodeKeyFileFlag, 196 utils.NodeKeyHexFlag, 197 }, 198 }, 199 { 200 Name: "MINER", 201 Flags: []cli.Flag{ 202 utils.MiningEnabledFlag, 203 utils.MinerThreadsFlag, 204 utils.MinerNotifyFlag, 205 utils.MinerGasPriceFlag, 206 utils.MinerGasTargetFlag, 207 utils.MinerGasLimitFlag, 208 utils.MinerEtherbaseFlag, 209 utils.MinerExtraDataFlag, 210 utils.MinerRecommitIntervalFlag, 211 utils.MinerNoVerfiyFlag, 212 }, 213 }, 214 { 215 Name: "GAS PRICE ORACLE", 216 Flags: []cli.Flag{ 217 utils.GpoBlocksFlag, 218 utils.GpoPercentileFlag, 219 }, 220 }, 221 { 222 Name: "VIRTUAL MACHINE", 223 Flags: []cli.Flag{ 224 utils.VMEnableDebugFlag, 225 utils.EVMInterpreterFlag, 226 utils.EWASMInterpreterFlag, 227 }, 228 }, 229 { 230 Name: "LOGGING AND DEBUGGING", 231 Flags: append([]cli.Flag{ 232 utils.FakePoWFlag, 233 utils.NoCompactionFlag, 234 }, debug.Flags...), 235 }, 236 { 237 Name: "METRICS AND STATS", 238 Flags: metricsFlags, 239 }, 240 { 241 Name: "WHISPER (EXPERIMENTAL)", 242 Flags: whisperFlags, 243 }, 244 { 245 Name: "DEPRECATED", 246 Flags: []cli.Flag{ 247 utils.LightLegacyServFlag, 248 utils.LightLegacyPeersFlag, 249 utils.MinerLegacyThreadsFlag, 250 utils.MinerLegacyGasTargetFlag, 251 utils.MinerLegacyGasPriceFlag, 252 utils.MinerLegacyEtherbaseFlag, 253 utils.MinerLegacyExtraDataFlag, 254 }, 255 }, 256 { 257 Name: "MISC", 258 }, 259 } 260 261 // byCategory sorts an array of flagGroup by Name in the order 262 // defined in AppHelpFlagGroups. 263 type byCategory []flagGroup 264 265 func (a byCategory) Len() int { return len(a) } 266 func (a byCategory) Swap(i, j int) { a[i], a[j] = a[j], a[i] } 267 func (a byCategory) Less(i, j int) bool { 268 iCat, jCat := a[i].Name, a[j].Name 269 iIdx, jIdx := len(AppHelpFlagGroups), len(AppHelpFlagGroups) // ensure non categorized flags come last 270 271 for i, group := range AppHelpFlagGroups { 272 if iCat == group.Name { 273 iIdx = i 274 } 275 if jCat == group.Name { 276 jIdx = i 277 } 278 } 279 280 return iIdx < jIdx 281 } 282 283 func flagCategory(flag cli.Flag) string { 284 for _, category := range AppHelpFlagGroups { 285 for _, flg := range category.Flags { 286 if flg.GetName() == flag.GetName() { 287 return category.Name 288 } 289 } 290 } 291 return "MISC" 292 } 293 294 func init() { 295 // Override the default app help template 296 cli.AppHelpTemplate = AppHelpTemplate 297 298 // Define a one shot struct to pass to the usage template 299 type helpData struct { 300 App interface{} 301 FlagGroups []flagGroup 302 } 303 304 // Override the default app help printer, but only for the global app help 305 originalHelpPrinter := cli.HelpPrinter 306 cli.HelpPrinter = func(w io.Writer, tmpl string, data interface{}) { 307 if tmpl == AppHelpTemplate { 308 // Iterate over all the flags and add any uncategorized ones 309 categorized := make(map[string]struct{}) 310 for _, group := range AppHelpFlagGroups { 311 for _, flag := range group.Flags { 312 categorized[flag.String()] = struct{}{} 313 } 314 } 315 var uncategorized []cli.Flag 316 for _, flag := range data.(*cli.App).Flags { 317 if _, ok := categorized[flag.String()]; !ok { 318 uncategorized = append(uncategorized, flag) 319 } 320 } 321 if len(uncategorized) > 0 { 322 // Append all ungategorized options to the misc group 323 miscs := len(AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags) 324 AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags = append(AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags, uncategorized...) 325 326 // Make sure they are removed afterwards 327 defer func() { 328 AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags = AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags[:miscs] 329 }() 330 } 331 // Render out custom usage screen 332 originalHelpPrinter(w, tmpl, helpData{data, AppHelpFlagGroups}) 333 } else if tmpl == utils.CommandHelpTemplate { 334 // Iterate over all command specific flags and categorize them 335 categorized := make(map[string][]cli.Flag) 336 for _, flag := range data.(cli.Command).Flags { 337 if _, ok := categorized[flag.String()]; !ok { 338 categorized[flagCategory(flag)] = append(categorized[flagCategory(flag)], flag) 339 } 340 } 341 342 // sort to get a stable ordering 343 sorted := make([]flagGroup, 0, len(categorized)) 344 for cat, flgs := range categorized { 345 sorted = append(sorted, flagGroup{cat, flgs}) 346 } 347 sort.Sort(byCategory(sorted)) 348 349 // add sorted array to data and render with default printer 350 originalHelpPrinter(w, tmpl, map[string]interface{}{ 351 "cmd": data, 352 "categorizedFlags": sorted, 353 }) 354 } else { 355 originalHelpPrinter(w, tmpl, data) 356 } 357 } 358 }