github.com/TrueBlocks/trueblocks-core/src/apps/chifra@v0.0.0-20241022031540-b362680128f7/internal/status/options.go (about) 1 // Copyright 2016, 2024 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 * Parts of this file were auto generated. Edit only those parts of 6 * the code inside of 'EXISTING_CODE' tags. 7 */ 8 9 package statusPkg 10 11 import ( 12 // EXISTING_CODE 13 "encoding/json" 14 "io" 15 "net/http" 16 "net/url" 17 "strings" 18 19 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/internal/globals" 20 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/base" 21 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/caps" 22 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/logger" 23 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/rpc" 24 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/validate" 25 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/walk" 26 // EXISTING_CODE 27 ) 28 29 // StatusOptions provides all command options for the chifra status command. 30 type StatusOptions struct { 31 Modes []string `json:"modes,omitempty"` // The (optional) name of the binary cache to report on, terse otherwise 32 Diagnose bool `json:"diagnose,omitempty"` // Same as the default but with additional diagnostics 33 FirstRecord uint64 `json:"firstRecord,omitempty"` // The first record to process 34 MaxRecords uint64 `json:"maxRecords,omitempty"` // The maximum number of records to process 35 Chains bool `json:"chains,omitempty"` // Include a list of chain configurations in the output 36 Healthcheck bool `json:"healthcheck,omitempty"` // An alias for the diagnose endpoint 37 Globals globals.GlobalOptions `json:"globals,omitempty"` // The global options 38 Conn *rpc.Connection `json:"conn,omitempty"` // The connection to the RPC server 39 BadFlag error `json:"badFlag,omitempty"` // An error flag if needed 40 // EXISTING_CODE 41 ModeTypes []walk.CacheType `json:"-"` 42 // EXISTING_CODE 43 } 44 45 var defaultStatusOptions = StatusOptions{ 46 MaxRecords: 10000, 47 } 48 49 // testLog is used only during testing to export the options for this test case. 50 func (opts *StatusOptions) testLog() { 51 logger.TestLog(len(opts.Modes) > 0, "Modes: ", opts.Modes) 52 logger.TestLog(opts.Diagnose, "Diagnose: ", opts.Diagnose) 53 logger.TestLog(opts.FirstRecord != 0, "FirstRecord: ", opts.FirstRecord) 54 logger.TestLog(opts.MaxRecords != 10000, "MaxRecords: ", opts.MaxRecords) 55 logger.TestLog(opts.Chains, "Chains: ", opts.Chains) 56 logger.TestLog(opts.Healthcheck, "Healthcheck: ", opts.Healthcheck) 57 opts.Conn.TestLog(opts.getCaches()) 58 opts.Globals.TestLog() 59 } 60 61 // String implements the Stringer interface 62 func (opts *StatusOptions) String() string { 63 b, _ := json.MarshalIndent(opts, "", " ") 64 return string(b) 65 } 66 67 // statusFinishParseApi finishes the parsing for server invocations. Returns a new StatusOptions. 68 func statusFinishParseApi(w http.ResponseWriter, r *http.Request) *StatusOptions { 69 values := r.URL.Query() 70 if r.Header.Get("User-Agent") == "testRunner" { 71 values.Set("testRunner", "true") 72 } 73 return StatusFinishParseInternal(w, values) 74 } 75 76 func StatusFinishParseInternal(w io.Writer, values url.Values) *StatusOptions { 77 copy := defaultStatusOptions 78 copy.Globals.Caps = getCaps() 79 opts := © 80 opts.MaxRecords = 10000 81 for key, value := range values { 82 switch key { 83 case "modes": 84 for _, val := range value { 85 s := strings.Split(val, " ") // may contain space separated items 86 opts.Modes = append(opts.Modes, s...) 87 } 88 case "diagnose": 89 opts.Diagnose = true 90 case "firstRecord": 91 opts.FirstRecord = base.MustParseUint64(value[0]) 92 case "maxRecords": 93 opts.MaxRecords = base.MustParseUint64(value[0]) 94 case "chains": 95 opts.Chains = true 96 case "healthcheck": 97 opts.Healthcheck = true 98 default: 99 if !copy.Globals.Caps.HasKey(key) { 100 err := validate.Usage("Invalid key ({0}) in {1} route.", key, "status") 101 if opts.BadFlag == nil || opts.BadFlag.Error() > err.Error() { 102 opts.BadFlag = err 103 } 104 } 105 } 106 } 107 opts.Conn = opts.Globals.FinishParseApi(w, values, opts.getCaches()) 108 109 // EXISTING_CODE 110 if len(opts.Modes) == 0 && opts.Globals.Verbose { 111 opts.Modes = append(opts.Modes, "some") 112 } 113 opts.ModeTypes = walk.CacheTypesFromStringSlice(opts.Modes) 114 // EXISTING_CODE 115 if !opts.Diagnose { 116 opts.Diagnose = opts.Healthcheck // alias 117 opts.Healthcheck = false 118 } 119 120 return opts 121 } 122 123 // statusFinishParse finishes the parsing for command line invocations. Returns a new StatusOptions. 124 func statusFinishParse(args []string) *StatusOptions { 125 // remove duplicates from args if any (not needed in api mode because the server does it). 126 dedup := map[string]int{} 127 if len(args) > 0 { 128 tmp := []string{} 129 for _, arg := range args { 130 if value := dedup[arg]; value == 0 { 131 tmp = append(tmp, arg) 132 } 133 dedup[arg]++ 134 } 135 args = tmp 136 } 137 138 defFmt := "txt" 139 opts := GetOptions() 140 opts.Conn = opts.Globals.FinishParse(args, opts.getCaches()) 141 142 // EXISTING_CODE 143 opts.Modes = append(opts.Modes, args...) 144 if len(opts.Modes) == 0 && opts.Globals.Verbose { 145 opts.Modes = append(opts.Modes, "some") 146 } 147 opts.ModeTypes = walk.CacheTypesFromStringSlice(opts.Modes) 148 if len(opts.Modes) > 0 { 149 defFmt = "json" 150 } 151 // EXISTING_CODE 152 if !opts.Diagnose { 153 opts.Diagnose = opts.Healthcheck // alias 154 opts.Healthcheck = false 155 } 156 if len(opts.Globals.Format) == 0 || opts.Globals.Format == "none" { 157 opts.Globals.Format = defFmt 158 } 159 160 return opts 161 } 162 163 func GetOptions() *StatusOptions { 164 // EXISTING_CODE 165 // EXISTING_CODE 166 return &defaultStatusOptions 167 } 168 169 func getCaps() caps.Capability { 170 var capabilities caps.Capability // capabilities for chifra status 171 capabilities = capabilities.Add(caps.Default) 172 // EXISTING_CODE 173 // EXISTING_CODE 174 return capabilities 175 } 176 177 func ResetOptions(testMode bool) { 178 // We want to keep writer between command file calls 179 w := GetOptions().Globals.Writer 180 opts := StatusOptions{} 181 globals.SetDefaults(&opts.Globals) 182 opts.Globals.TestMode = testMode 183 opts.Globals.Writer = w 184 opts.Globals.Caps = getCaps() 185 opts.MaxRecords = 10000 186 defaultStatusOptions = opts 187 } 188 189 func (opts *StatusOptions) getCaches() (caches map[walk.CacheType]bool) { 190 // EXISTING_CODE 191 // EXISTING_CODE 192 return 193 } 194 195 // EXISTING_CODE 196 // EXISTING_CODE