github.com/intfoundation/intchain@v0.0.0-20220727031208-4316ad31ca73/cmd/intchain/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 intchain command usage template and generator. 18 19 package main 20 21 import ( 22 "io" 23 "sort" 24 25 "github.com/intfoundation/intchain/cmd/utils" 26 "github.com/intfoundation/intchain/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 2017-2021 The INT Chain 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: "INTCHAIN", 67 Flags: []cli.Flag{ 68 configFileFlag, 69 utils.DataDirFlag, 70 utils.KeyStoreDirFlag, 71 utils.NoUSBFlag, 72 utils.NetworkIdFlag, 73 utils.TestnetFlag, 74 utils.SyncModeFlag, 75 utils.GCModeFlag, 76 utils.EthStatsURLFlag, 77 utils.IdentityFlag, 78 }, 79 }, 80 { 81 Name: "TRANSACTION POOL", 82 Flags: []cli.Flag{ 83 utils.TxPoolNoLocalsFlag, 84 utils.TxPoolJournalFlag, 85 utils.TxPoolRejournalFlag, 86 utils.TxPoolPriceLimitFlag, 87 utils.TxPoolPriceBumpFlag, 88 utils.TxPoolAccountSlotsFlag, 89 utils.TxPoolGlobalSlotsFlag, 90 utils.TxPoolAccountQueueFlag, 91 utils.TxPoolGlobalQueueFlag, 92 utils.TxPoolLifetimeFlag, 93 }, 94 }, 95 { 96 Name: "PERFORMANCE TUNING", 97 Flags: []cli.Flag{ 98 utils.CacheFlag, 99 utils.CacheDatabaseFlag, 100 utils.CacheTrieFlag, 101 utils.CacheGCFlag, 102 }, 103 }, 104 { 105 Name: "ACCOUNT", 106 Flags: []cli.Flag{ 107 utils.UnlockedAccountFlag, 108 utils.PasswordFileFlag, 109 }, 110 }, 111 { 112 Name: "API AND CONSOLE", 113 Flags: []cli.Flag{ 114 utils.RPCEnabledFlag, 115 utils.RPCListenAddrFlag, 116 utils.RPCPortFlag, 117 utils.RPCApiFlag, 118 utils.WSEnabledFlag, 119 utils.WSListenAddrFlag, 120 utils.WSPortFlag, 121 utils.WSApiFlag, 122 utils.WSAllowedOriginsFlag, 123 utils.IPCDisabledFlag, 124 utils.IPCPathFlag, 125 utils.RPCCORSDomainFlag, 126 utils.RPCVirtualHostsFlag, 127 utils.JSpathFlag, 128 utils.ExecFlag, 129 utils.PreloadJSFlag, 130 }, 131 }, 132 { 133 Name: "NETWORKING", 134 Flags: []cli.Flag{ 135 utils.BootnodesFlag, 136 utils.BootnodesV4Flag, 137 utils.BootnodesV5Flag, 138 utils.ListenPortFlag, 139 utils.MaxPeersFlag, 140 utils.MaxPendingPeersFlag, 141 utils.NATFlag, 142 utils.NoDiscoverFlag, 143 utils.DiscoveryV5Flag, 144 utils.NetrestrictFlag, 145 utils.NodeKeyFileFlag, 146 utils.NodeKeyHexFlag, 147 }, 148 }, 149 { 150 Name: "MINER", 151 Flags: []cli.Flag{ 152 utils.MiningEnabledFlag, 153 utils.MinerThreadsFlag, 154 utils.MinerGasPriceFlag, 155 utils.MinerGasTargetFlag, 156 utils.MinerGasLimitFlag, 157 utils.MinerCoinbaseFlag, 158 utils.ExtraDataFlag, 159 }, 160 }, 161 { 162 Name: "GAS PRICE ORACLE", 163 Flags: []cli.Flag{ 164 utils.GpoBlocksFlag, 165 utils.GpoPercentileFlag, 166 }, 167 }, 168 { 169 Name: "VIRTUAL MACHINE", 170 Flags: []cli.Flag{ 171 utils.VMEnableDebugFlag, 172 }, 173 }, 174 { 175 Name: "LOGGING AND DEBUGGING", 176 Flags: append([]cli.Flag{ 177 utils.MetricsEnabledFlag, 178 utils.NoCompactionFlag, 179 }, debug.Flags...), 180 }, 181 { 182 Name: "DEPRECATED", 183 Flags: []cli.Flag{ 184 utils.FastSyncFlag, 185 }, 186 }, 187 } 188 189 // byCategory sorts an array of flagGroup by Name in the order 190 // defined in AppHelpFlagGroups. 191 type byCategory []flagGroup 192 193 func (a byCategory) Len() int { return len(a) } 194 func (a byCategory) Swap(i, j int) { a[i], a[j] = a[j], a[i] } 195 func (a byCategory) Less(i, j int) bool { 196 iCat, jCat := a[i].Name, a[j].Name 197 iIdx, jIdx := len(AppHelpFlagGroups), len(AppHelpFlagGroups) // ensure non categorized flags come last 198 199 for i, group := range AppHelpFlagGroups { 200 if iCat == group.Name { 201 iIdx = i 202 } 203 if jCat == group.Name { 204 jIdx = i 205 } 206 } 207 208 return iIdx < jIdx 209 } 210 211 func flagCategory(flag cli.Flag) string { 212 for _, category := range AppHelpFlagGroups { 213 for _, flg := range category.Flags { 214 if flg.GetName() == flag.GetName() { 215 return category.Name 216 } 217 } 218 } 219 return "MISC" 220 } 221 222 func init() { 223 // Override the default app help template 224 cli.AppHelpTemplate = AppHelpTemplate 225 226 // Define a one shot struct to pass to the usage template 227 type helpData struct { 228 App interface{} 229 FlagGroups []flagGroup 230 } 231 232 // Override the default app help printer, but only for the global app help 233 originalHelpPrinter := cli.HelpPrinter 234 cli.HelpPrinter = func(w io.Writer, tmpl string, data interface{}) { 235 if tmpl == AppHelpTemplate { 236 // Iterate over all the flags and add any uncategorized ones 237 categorized := make(map[string]struct{}) 238 for _, group := range AppHelpFlagGroups { 239 for _, flag := range group.Flags { 240 categorized[flag.String()] = struct{}{} 241 } 242 } 243 uncategorized := []cli.Flag{} 244 for _, flag := range data.(*cli.App).Flags { 245 if _, ok := categorized[flag.String()]; !ok { 246 uncategorized = append(uncategorized, flag) 247 } 248 } 249 if len(uncategorized) > 0 { 250 // Append all ungategorized options to the misc group 251 miscs := len(AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags) 252 AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags = append(AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags, uncategorized...) 253 254 // Make sure they are removed afterwards 255 defer func() { 256 AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags = AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags[:miscs] 257 }() 258 } 259 // Render out custom usage screen 260 originalHelpPrinter(w, tmpl, helpData{data, AppHelpFlagGroups}) 261 } else if tmpl == utils.CommandHelpTemplate { 262 // Iterate over all command specific flags and categorize them 263 categorized := make(map[string][]cli.Flag) 264 for _, flag := range data.(cli.Command).Flags { 265 if _, ok := categorized[flag.String()]; !ok { 266 categorized[flagCategory(flag)] = append(categorized[flagCategory(flag)], flag) 267 } 268 } 269 270 // sort to get a stable ordering 271 sorted := make([]flagGroup, 0, len(categorized)) 272 for cat, flgs := range categorized { 273 sorted = append(sorted, flagGroup{cat, flgs}) 274 } 275 sort.Sort(byCategory(sorted)) 276 277 // add sorted array to data and render with default printer 278 originalHelpPrinter(w, tmpl, map[string]interface{}{ 279 "cmd": data, 280 "categorizedFlags": sorted, 281 }) 282 } else { 283 originalHelpPrinter(w, tmpl, data) 284 } 285 } 286 }