github.com/TrueBlocks/trueblocks-core/src/apps/chifra@v0.0.0-20241022031540-b362680128f7/internal/globals/options.go (about) 1 // Copyright 2021 The TrueBlocks Authors. All rights reserved. 2 // Use of this source code is governed by a license that can 3 // be found in the LICENSE file. 4 5 package globals 6 7 import ( 8 "io" 9 "net/url" 10 "strings" 11 12 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/base" 13 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/caps" 14 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/colors" 15 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/config" 16 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/file" 17 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/logger" 18 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/output" 19 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/rpc" 20 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/tslib" 21 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/walk" 22 "github.com/spf13/cobra" 23 ) 24 25 type GlobalOptions struct { 26 Wei bool `json:"wei,omitempty"` 27 Ether bool `json:"ether,omitempty"` 28 Help bool `json:"help,omitempty"` 29 File string `json:"file,omitempty"` 30 Version bool `json:"version,omitempty"` 31 Noop bool `json:"noop,omitempty"` 32 NoColor bool `json:"noColor,omitempty"` 33 Cache bool `json:"cache,omitempty"` 34 Decache bool `json:"decache,omitempty"` 35 Caps caps.Capability `json:"-"` 36 output.OutputOptions 37 } 38 39 func (opts *GlobalOptions) TestLog() { 40 // Names is internal use only 41 cc := opts.Caps.Remove(caps.Names) 42 43 logger.TestLog(opts.Verbose, "Verbose: ", opts.Verbose) 44 logger.TestLog(opts.NoHeader, "NoHeader: ", opts.NoHeader) 45 logger.TestLog(len(opts.Chain) > 0 && opts.Chain != config.GetSettings().DefaultChain, "Chain: ", opts.Chain) 46 logger.TestLog(opts.Wei, "Wei: ", opts.Wei) 47 logger.TestLog(opts.Ether, "Ether: ", opts.Ether) 48 logger.TestLog(opts.Help, "Help: ", opts.Help) 49 logger.TestLog(len(opts.File) > 0, "File: ", opts.File) 50 logger.TestLog(opts.Version, "Version: ", opts.Version) 51 logger.TestLog(opts.Noop, "Noop: ", opts.Noop) 52 logger.TestLog(opts.NoColor, "NoColor: ", opts.NoColor) 53 logger.TestLog(len(opts.OutputFn) > 0, "OutputFn: ", opts.OutputFn) 54 logger.TestLog(opts.Append, "Append: ", opts.Append) 55 logger.TestLog(opts.Cache, "Cache: ", opts.Cache) 56 logger.TestLog(opts.Decache, "Decache: ", opts.Decache) 57 logger.TestLog(cc != caps.Default, "Caps: ", opts.Caps.Show()) 58 logger.TestLog(len(opts.Format) > 0, "Format: ", opts.Format) 59 // logger.TestLog(opts.TestMode, "TestMode: ", opts.TestMode) 60 } 61 62 func SetDefaults(opts *GlobalOptions) { 63 if len(opts.Chain) == 0 { 64 opts.Chain = config.GetSettings().DefaultChain 65 } 66 } 67 68 func (opts *GlobalOptions) ShouldLoadNames(force bool) bool { 69 return opts.Caps.Has(caps.Names) && (force || opts.Verbose) 70 } 71 72 // TODO: These options should be in a data file 73 func InitGlobals(whoAmI string, cmd *cobra.Command, opts *GlobalOptions, c caps.Capability) { 74 opts.TestMode = file.IsTestMode() 75 opts.Caps = c 76 77 if opts.Caps.Has(caps.Ether) { 78 cmd.Flags().BoolVarP(&opts.Ether, "ether", "H", false, "specify value in ether") 79 } 80 81 if opts.Caps.Has(caps.Wei) { 82 cmd.Flags().BoolVarP(&opts.Wei, "wei", "W", false, "specify value in wei (the default)") 83 } 84 _ = cmd.Flags().MarkHidden("wei") 85 86 if opts.Caps.Has(caps.Caching) { 87 if whoAmI != "monitors" { 88 cmd.Flags().BoolVarP(&opts.Cache, "cache", "o", false, "force the results of the query into the cache") 89 } 90 cmd.Flags().BoolVarP(&opts.Decache, "decache", "D", false, "removes related items from the cache") 91 } 92 93 if opts.Caps.Has(caps.Fmt) { 94 cmd.Flags().StringVarP(&opts.Format, "fmt", "x", "", "export format, one of [none|json*|txt|csv]") 95 } 96 97 if opts.Caps.Has(caps.Verbose) { 98 cmd.Flags().BoolVarP(&opts.Verbose, "verbose", "v", false, "enable verbose output") 99 } 100 101 cmd.Flags().BoolVarP(&opts.Help, "help", "h", false, "display this help screen") 102 103 if opts.Caps.Has(caps.Chain) { 104 cmd.Flags().StringVarP(&opts.Chain, "chain", "", "", "EVM compatible chain you're running against") 105 } 106 _ = cmd.Flags().MarkHidden("chain") 107 108 if opts.Caps.Has(caps.Version) { 109 cmd.Flags().BoolVarP(&opts.Version, "version", "", false, "display the current version of the tool") 110 } 111 _ = cmd.Flags().MarkHidden("version") 112 113 if opts.Caps.Has(caps.Noop) { 114 cmd.Flags().BoolVarP(&opts.Noop, "noop", "", false, "") 115 } 116 _ = cmd.Flags().MarkHidden("noop") 117 118 if opts.Caps.Has(caps.NoColor) { 119 cmd.Flags().BoolVarP(&opts.NoColor, "nocolor", "", false, "") 120 } 121 _ = cmd.Flags().MarkHidden("nocolor") 122 123 if opts.Caps.Has(caps.NoHeader) { 124 cmd.Flags().BoolVarP(&opts.NoHeader, "no_header", "", false, "supress export of header row for csv and txt exports") 125 } 126 _ = cmd.Flags().MarkHidden("no_header") 127 128 // if opts.Caps.Has(caps.File) { 129 cmd.Flags().StringVarP(&opts.File, "file", "", "", "specify multiple command line options in a file") 130 // } 131 _ = cmd.Flags().MarkHidden("file") 132 133 if opts.Caps.Has(caps.Output) { 134 cmd.Flags().StringVarP(&opts.OutputFn, "output", "", "", "redirect results from stdout to the given file, create if not present") 135 } 136 _ = cmd.Flags().MarkHidden("output") 137 138 if opts.Caps.Has(caps.Append) { 139 cmd.Flags().BoolVarP(&opts.Append, "append", "", false, "if true, open OutputFn for append (truncate otherwise)") 140 } 141 _ = cmd.Flags().MarkHidden("append") 142 143 SetDefaults(opts) 144 } 145 146 func (opts *GlobalOptions) FinishParseApi(w io.Writer, values url.Values, caches map[walk.CacheType]bool) *rpc.Connection { 147 opts.Writer = w 148 149 for key, value := range values { 150 switch key { 151 case "append": 152 opts.Append = true 153 case "cache": 154 opts.Cache = true 155 case "chain": 156 opts.Chain = value[0] 157 case "decache": 158 opts.Decache = true 159 case "ether": 160 opts.Ether = true 161 case "file": 162 opts.File = value[0] 163 case "fmt": 164 opts.Format = value[0] 165 case "nocolor": 166 opts.NoColor = true 167 case "noHeader": 168 opts.NoHeader = true 169 case "noop": 170 // do nothing 171 case "output": 172 opts.OutputFn = value[0] 173 case "verbose": 174 opts.Verbose = true 175 case "version": 176 opts.Version = true 177 case "wei": 178 opts.Wei = true 179 case "testRunner": 180 opts.TestMode = true 181 colors.ColorsOff() 182 } 183 } 184 185 if len(opts.Format) == 0 || opts.Format == "none" { 186 opts.Format = "json" 187 if len(opts.OutputFn) > 0 { 188 parts := strings.Split(opts.OutputFn, ".") 189 if len(parts) > 0 { 190 last := parts[len(parts)-1] 191 if last == "txt" || last == "csv" || last == "json" { 192 opts.Format = last 193 } 194 } 195 } 196 } 197 198 if len(opts.Chain) == 0 { 199 opts.Chain = config.GetSettings().DefaultChain 200 } 201 202 if config.IsChainConfigured(opts.Chain) { 203 conn := rpc.NewConnection(opts.Chain, opts.Cache, caches) 204 publisher, _ := conn.GetEnsAddress(config.GetPublisher("")) 205 publisherAddr := base.HexToAddress(publisher) 206 if err := tslib.EstablishTimestamps(opts.Chain, publisherAddr); err != nil { 207 logger.Warn(err) 208 } 209 return conn 210 } else { 211 // the error will be reported by the validator 212 return rpc.TempConnection(opts.Chain) 213 } 214 } 215 216 func (opts *GlobalOptions) FinishParse(args []string, caches map[walk.CacheType]bool) *rpc.Connection { 217 if (len(opts.Format) == 0 || opts.Format == "none") && len(opts.OutputFn) > 0 { 218 parts := strings.Split(opts.OutputFn, ".") 219 if len(parts) > 0 { 220 last := parts[len(parts)-1] 221 if last == "txt" || last == "csv" || last == "json" { 222 opts.Format = last 223 } 224 } 225 } 226 227 if len(opts.Chain) == 0 { 228 opts.Chain = config.GetSettings().DefaultChain 229 } 230 231 if config.IsChainConfigured(opts.Chain) { 232 conn := rpc.NewConnection(opts.Chain, opts.Cache, caches) 233 publisher, _ := conn.GetEnsAddress(config.GetPublisher("")) 234 publisherAddr := base.HexToAddress(publisher) 235 if err := tslib.EstablishTimestamps(opts.Chain, publisherAddr); err != nil { 236 logger.Warn(err) 237 } 238 return conn 239 } else { 240 // the error will be reported by the validator 241 return rpc.TempConnection(opts.Chain) 242 } 243 }