github.com/janotchain/janota@v0.0.0-20220824112012-93ea4c5dee78/cmd/gmc/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 janetad command usage template and generator. 18 19 package main 20 21 import ( 22 "io" 23 "sort" 24 25 "github.com/ethereum/go-ethereum/cmd/utils" 26 "github.com/ethereum/go-ethereum/internal/debug" 27 "gopkg.in/urfave/cli.v1" 28 "strings" 29 ) 30 31 // AppHelpTemplate is the test template for the default, global app help topic. 32 var AppHelpTemplate = `NAME: 33 {{.App.Name}} - {{.App.Usage}} 34 35 Copyright 2013-2017 The Go-Ethereum Authors 36 Copyright 2016-2017 The Go-Janetacoin 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.EthStatsURLFlag, 79 utils.IdentityFlag, 80 utils.LightServFlag, 81 utils.LightPeersFlag, 82 utils.LightKDFFlag, 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: "DASHBOARD", 104 // Flags: []cli.Flag{ 105 // utils.DashboardEnabledFlag, 106 // utils.DashboardAddrFlag, 107 // utils.DashboardPortFlag, 108 // utils.DashboardRefreshFlag, 109 // utils.DashboardAssetsFlag, 110 // }, 111 //}, 112 { 113 Name: "TRANSACTION POOL", 114 Flags: []cli.Flag{ 115 utils.TxPoolNoLocalsFlag, 116 utils.TxPoolJournalFlag, 117 utils.TxPoolRejournalFlag, 118 utils.TxPoolPriceLimitFlag, 119 utils.TxPoolPriceBumpFlag, 120 utils.TxPoolAccountSlotsFlag, 121 utils.TxPoolGlobalSlotsFlag, 122 utils.TxPoolAccountQueueFlag, 123 utils.TxPoolGlobalQueueFlag, 124 utils.TxPoolLifetimeFlag, 125 }, 126 }, 127 { 128 Name: "PERFORMANCE TUNING", 129 Flags: []cli.Flag{ 130 utils.CacheFlag, 131 utils.TrieCacheGenFlag, 132 }, 133 }, 134 { 135 Name: "ACCOUNT", 136 Flags: []cli.Flag{ 137 utils.UnlockedAccountFlag, 138 utils.PasswordFileFlag, 139 }, 140 }, 141 { 142 Name: "API AND CONSOLE", 143 Flags: []cli.Flag{ 144 utils.RPCEnabledFlag, 145 utils.RPCListenAddrFlag, 146 utils.RPCPortFlag, 147 utils.RPCApiFlag, 148 utils.WSEnabledFlag, 149 utils.WSListenAddrFlag, 150 utils.WSPortFlag, 151 utils.WSApiFlag, 152 utils.WSAllowedOriginsFlag, 153 utils.IPCDisabledFlag, 154 utils.IPCPathFlag, 155 utils.RPCCORSDomainFlag, 156 utils.JSpathFlag, 157 utils.ExecFlag, 158 utils.PreloadJSFlag, 159 }, 160 }, 161 { 162 Name: "NETWORKING", 163 Flags: []cli.Flag{ 164 utils.BootnodesFlag, 165 utils.BootnodesV4Flag, 166 utils.BootnodesV5Flag, 167 utils.ListenPortFlag, 168 utils.MaxPeersFlag, 169 utils.MaxPendingPeersFlag, 170 utils.NATFlag, 171 utils.NoDiscoverFlag, 172 utils.DiscoveryV5Flag, 173 utils.NetrestrictFlag, 174 utils.NodeKeyFileFlag, 175 utils.NodeKeyHexFlag, 176 }, 177 }, 178 { 179 Name: "MINER", 180 Flags: []cli.Flag{ 181 utils.MiningEnabledFlag, 182 utils.MinerThreadsFlag, 183 utils.EtherbaseFlag, 184 utils.TargetGasLimitFlag, 185 utils.GasPriceFlag, 186 utils.ExtraDataFlag, 187 }, 188 }, 189 { 190 Name: "GAS PRICE ORACLE", 191 Flags: []cli.Flag{ 192 utils.GpoBlocksFlag, 193 utils.GpoPercentileFlag, 194 }, 195 }, 196 { 197 Name: "VIRTUAL MACHINE", 198 Flags: []cli.Flag{ 199 utils.VMEnableDebugFlag, 200 }, 201 }, 202 { 203 Name: "LOGGING AND DEBUGGING", 204 Flags: append([]cli.Flag{ 205 utils.MetricsEnabledFlag, 206 utils.FakePoWFlag, 207 utils.NoCompactionFlag, 208 }, debug.Flags...), 209 }, 210 { 211 Name: "WHISPER (EXPERIMENTAL)", 212 Flags: whisperFlags, 213 }, 214 { 215 Name: "DEPRECATED", 216 Flags: []cli.Flag{ 217 utils.FastSyncFlag, 218 utils.LightModeFlag, 219 }, 220 }, 221 { 222 Name: "MISC", 223 }, 224 } 225 226 // byCategory sorts an array of flagGroup by Name in the order 227 // defined in AppHelpFlagGroups. 228 type byCategory []flagGroup 229 230 func (a byCategory) Len() int { return len(a) } 231 func (a byCategory) Swap(i, j int) { a[i], a[j] = a[j], a[i] } 232 func (a byCategory) Less(i, j int) bool { 233 iCat, jCat := a[i].Name, a[j].Name 234 iIdx, jIdx := len(AppHelpFlagGroups), len(AppHelpFlagGroups) // ensure non categorized flags come last 235 236 for i, group := range AppHelpFlagGroups { 237 if iCat == group.Name { 238 iIdx = i 239 } 240 if jCat == group.Name { 241 jIdx = i 242 } 243 } 244 245 return iIdx < jIdx 246 } 247 248 func flagCategory(flag cli.Flag) string { 249 for _, category := range AppHelpFlagGroups { 250 for _, flg := range category.Flags { 251 if flg.GetName() == flag.GetName() { 252 return category.Name 253 } 254 } 255 } 256 return "MISC" 257 } 258 259 func init() { 260 // Override the default app help template 261 cli.AppHelpTemplate = AppHelpTemplate 262 263 // Define a one shot struct to pass to the usage template 264 type helpData struct { 265 App interface{} 266 FlagGroups []flagGroup 267 } 268 269 // Override the default app help printer, but only for the global app help 270 originalHelpPrinter := cli.HelpPrinter 271 cli.HelpPrinter = func(w io.Writer, tmpl string, data interface{}) { 272 if tmpl == AppHelpTemplate { 273 // Iterate over all the flags and add any uncategorized ones 274 categorized := make(map[string]struct{}) 275 for _, group := range AppHelpFlagGroups { 276 for _, flag := range group.Flags { 277 categorized[flag.String()] = struct{}{} 278 } 279 } 280 uncategorized := []cli.Flag{} 281 for _, flag := range data.(*cli.App).Flags { 282 if _, ok := categorized[flag.String()]; !ok { 283 if strings.HasPrefix(flag.GetName(), "dashboard") { 284 continue 285 } 286 uncategorized = append(uncategorized, flag) 287 } 288 } 289 if len(uncategorized) > 0 { 290 // Append all ungategorized options to the misc group 291 miscs := len(AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags) 292 AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags = append(AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags, uncategorized...) 293 294 // Make sure they are removed afterwards 295 defer func() { 296 AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags = AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags[:miscs] 297 }() 298 } 299 // Render out custom usage screen 300 originalHelpPrinter(w, tmpl, helpData{data, AppHelpFlagGroups}) 301 } else if tmpl == utils.CommandHelpTemplate { 302 // Iterate over all command specific flags and categorize them 303 categorized := make(map[string][]cli.Flag) 304 for _, flag := range data.(cli.Command).Flags { 305 if _, ok := categorized[flag.String()]; !ok { 306 categorized[flagCategory(flag)] = append(categorized[flagCategory(flag)], flag) 307 } 308 } 309 310 // sort to get a stable ordering 311 sorted := make([]flagGroup, 0, len(categorized)) 312 for cat, flgs := range categorized { 313 sorted = append(sorted, flagGroup{cat, flgs}) 314 } 315 sort.Sort(byCategory(sorted)) 316 317 // add sorted array to data and render with default printer 318 originalHelpPrinter(w, tmpl, map[string]interface{}{ 319 "cmd": data, 320 "categorizedFlags": sorted, 321 }) 322 } else { 323 originalHelpPrinter(w, tmpl, data) 324 } 325 } 326 }