github.com/luckypickle/go-ethereum-vet@v1.14.2/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/luckypickle/go-ethereum-vet/cmd/utils" 26 "github.com/luckypickle/go-ethereum-vet/internal/debug" 27 "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-2018 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.KeyStoreDirFlag, 71 utils.NoUSBFlag, 72 utils.NetworkIdFlag, 73 utils.TestnetFlag, 74 utils.RinkebyFlag, 75 utils.SyncModeFlag, 76 utils.GCModeFlag, 77 utils.EthStatsURLFlag, 78 utils.IdentityFlag, 79 utils.LightServFlag, 80 utils.LightPeersFlag, 81 utils.LightKDFFlag, 82 }, 83 }, 84 { 85 Name: "DEVELOPER CHAIN", 86 Flags: []cli.Flag{ 87 utils.DeveloperFlag, 88 utils.DeveloperPeriodFlag, 89 }, 90 }, 91 { 92 Name: "ETHASH", 93 Flags: []cli.Flag{ 94 utils.EthashCacheDirFlag, 95 utils.EthashCachesInMemoryFlag, 96 utils.EthashCachesOnDiskFlag, 97 utils.EthashDatasetDirFlag, 98 utils.EthashDatasetsInMemoryFlag, 99 utils.EthashDatasetsOnDiskFlag, 100 }, 101 }, 102 { 103 Name: "TRANSACTION POOL", 104 Flags: []cli.Flag{ 105 utils.TxPoolLocalsFlag, 106 utils.TxPoolNoLocalsFlag, 107 utils.TxPoolJournalFlag, 108 utils.TxPoolRejournalFlag, 109 utils.TxPoolPriceLimitFlag, 110 utils.TxPoolPriceBumpFlag, 111 utils.TxPoolAccountSlotsFlag, 112 utils.TxPoolGlobalSlotsFlag, 113 utils.TxPoolAccountQueueFlag, 114 utils.TxPoolGlobalQueueFlag, 115 utils.TxPoolLifetimeFlag, 116 }, 117 }, 118 { 119 Name: "PERFORMANCE TUNING", 120 Flags: []cli.Flag{ 121 utils.CacheFlag, 122 utils.CacheDatabaseFlag, 123 utils.CacheGCFlag, 124 utils.TrieCacheGenFlag, 125 }, 126 }, 127 { 128 Name: "ACCOUNT", 129 Flags: []cli.Flag{ 130 utils.UnlockedAccountFlag, 131 utils.PasswordFileFlag, 132 }, 133 }, 134 { 135 Name: "API AND CONSOLE", 136 Flags: []cli.Flag{ 137 utils.RPCEnabledFlag, 138 utils.RPCListenAddrFlag, 139 utils.RPCPortFlag, 140 utils.RPCApiFlag, 141 utils.WSEnabledFlag, 142 utils.WSListenAddrFlag, 143 utils.WSPortFlag, 144 utils.WSApiFlag, 145 utils.WSAllowedOriginsFlag, 146 utils.IPCDisabledFlag, 147 utils.IPCPathFlag, 148 utils.RPCCORSDomainFlag, 149 utils.RPCVirtualHostsFlag, 150 utils.JSpathFlag, 151 utils.ExecFlag, 152 utils.PreloadJSFlag, 153 }, 154 }, 155 { 156 Name: "NETWORKING", 157 Flags: []cli.Flag{ 158 utils.BootnodesFlag, 159 utils.BootnodesV4Flag, 160 utils.BootnodesV5Flag, 161 utils.ListenPortFlag, 162 utils.MaxPeersFlag, 163 utils.MaxPendingPeersFlag, 164 utils.NATFlag, 165 utils.NoDiscoverFlag, 166 utils.DiscoveryV5Flag, 167 utils.NetrestrictFlag, 168 utils.NodeKeyFileFlag, 169 utils.NodeKeyHexFlag, 170 }, 171 }, 172 { 173 Name: "MINER", 174 Flags: []cli.Flag{ 175 utils.MiningEnabledFlag, 176 utils.MinerThreadsFlag, 177 utils.MinerNotifyFlag, 178 utils.MinerGasPriceFlag, 179 utils.MinerGasTargetFlag, 180 utils.MinerEtherbaseFlag, 181 utils.MinerExtraDataFlag, 182 utils.MinerRecommitIntervalFlag, 183 }, 184 }, 185 { 186 Name: "GAS PRICE ORACLE", 187 Flags: []cli.Flag{ 188 utils.GpoBlocksFlag, 189 utils.GpoPercentileFlag, 190 }, 191 }, 192 { 193 Name: "VIRTUAL MACHINE", 194 Flags: []cli.Flag{ 195 utils.VMEnableDebugFlag, 196 }, 197 }, 198 { 199 Name: "LOGGING AND DEBUGGING", 200 Flags: append([]cli.Flag{ 201 utils.FakePoWFlag, 202 utils.NoCompactionFlag, 203 }, debug.Flags...), 204 }, 205 { 206 Name: "METRICS AND STATS", 207 Flags: []cli.Flag{ 208 utils.MetricsEnabledFlag, 209 utils.MetricsEnableInfluxDBFlag, 210 utils.MetricsInfluxDBEndpointFlag, 211 utils.MetricsInfluxDBDatabaseFlag, 212 utils.MetricsInfluxDBUsernameFlag, 213 utils.MetricsInfluxDBPasswordFlag, 214 utils.MetricsInfluxDBHostTagFlag, 215 }, 216 }, 217 { 218 Name: "WHISPER (EXPERIMENTAL)", 219 Flags: whisperFlags, 220 }, 221 { 222 Name: "DEPRECATED", 223 Flags: []cli.Flag{ 224 utils.MinerLegacyThreadsFlag, 225 utils.MinerLegacyGasTargetFlag, 226 utils.MinerLegacyGasPriceFlag, 227 utils.MinerLegacyEtherbaseFlag, 228 utils.MinerLegacyExtraDataFlag, 229 }, 230 }, 231 { 232 Name: "MISC", 233 }, 234 } 235 236 // byCategory sorts an array of flagGroup by Name in the order 237 // defined in AppHelpFlagGroups. 238 type byCategory []flagGroup 239 240 func (a byCategory) Len() int { return len(a) } 241 func (a byCategory) Swap(i, j int) { a[i], a[j] = a[j], a[i] } 242 func (a byCategory) Less(i, j int) bool { 243 iCat, jCat := a[i].Name, a[j].Name 244 iIdx, jIdx := len(AppHelpFlagGroups), len(AppHelpFlagGroups) // ensure non categorized flags come last 245 246 for i, group := range AppHelpFlagGroups { 247 if iCat == group.Name { 248 iIdx = i 249 } 250 if jCat == group.Name { 251 jIdx = i 252 } 253 } 254 255 return iIdx < jIdx 256 } 257 258 func flagCategory(flag cli.Flag) string { 259 for _, category := range AppHelpFlagGroups { 260 for _, flg := range category.Flags { 261 if flg.GetName() == flag.GetName() { 262 return category.Name 263 } 264 } 265 } 266 return "MISC" 267 } 268 269 func init() { 270 // Override the default app help template 271 cli.AppHelpTemplate = AppHelpTemplate 272 273 // Define a one shot struct to pass to the usage template 274 type helpData struct { 275 App interface{} 276 FlagGroups []flagGroup 277 } 278 279 // Override the default app help printer, but only for the global app help 280 originalHelpPrinter := cli.HelpPrinter 281 cli.HelpPrinter = func(w io.Writer, tmpl string, data interface{}) { 282 if tmpl == AppHelpTemplate { 283 // Iterate over all the flags and add any uncategorized ones 284 categorized := make(map[string]struct{}) 285 for _, group := range AppHelpFlagGroups { 286 for _, flag := range group.Flags { 287 categorized[flag.String()] = struct{}{} 288 } 289 } 290 uncategorized := []cli.Flag{} 291 for _, flag := range data.(*cli.App).Flags { 292 if _, ok := categorized[flag.String()]; !ok { 293 uncategorized = append(uncategorized, flag) 294 } 295 } 296 if len(uncategorized) > 0 { 297 // Append all ungategorized options to the misc group 298 miscs := len(AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags) 299 AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags = append(AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags, uncategorized...) 300 301 // Make sure they are removed afterwards 302 defer func() { 303 AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags = AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags[:miscs] 304 }() 305 } 306 // Render out custom usage screen 307 originalHelpPrinter(w, tmpl, helpData{data, AppHelpFlagGroups}) 308 } else if tmpl == utils.CommandHelpTemplate { 309 // Iterate over all command specific flags and categorize them 310 categorized := make(map[string][]cli.Flag) 311 for _, flag := range data.(cli.Command).Flags { 312 if _, ok := categorized[flag.String()]; !ok { 313 categorized[flagCategory(flag)] = append(categorized[flagCategory(flag)], flag) 314 } 315 } 316 317 // sort to get a stable ordering 318 sorted := make([]flagGroup, 0, len(categorized)) 319 for cat, flgs := range categorized { 320 sorted = append(sorted, flagGroup{cat, flgs}) 321 } 322 sort.Sort(byCategory(sorted)) 323 324 // add sorted array to data and render with default printer 325 originalHelpPrinter(w, tmpl, map[string]interface{}{ 326 "cmd": data, 327 "categorizedFlags": sorted, 328 }) 329 } else { 330 originalHelpPrinter(w, tmpl, data) 331 } 332 } 333 }