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  }