github.com/blend/go-sdk@v1.20240719.1/cmd/ask/main.go (about) 1 /* 2 3 Copyright (c) 2024 - Present. Blend Labs, Inc. All rights reserved 4 Use of this source code is governed by a MIT license that can be found in the LICENSE file. 5 6 */ 7 8 package main 9 10 import ( 11 "bytes" 12 "flag" 13 "fmt" 14 "os" 15 "strings" 16 17 "gopkg.in/yaml.v3" 18 19 "github.com/blend/go-sdk/sh" 20 ) 21 22 type configVar struct { 23 Field string 24 Default string 25 Value string 26 } 27 28 func (cv *configVar) Set(value string) error { 29 cv.Value = value 30 return nil 31 } 32 33 type configVarSet []configVar 34 35 func (cvs configVarSet) String() string { 36 return "Fields to prompt for in the form fieldname=default" 37 } 38 39 func (cvs configVarSet) Union(other configVarSet) configVarSet { 40 return append(cvs, other...) 41 } 42 43 func (cvs *configVarSet) Set(flagValue string) error { 44 parts := strings.SplitN(flagValue, "=", 2) 45 if len(parts) > 1 { 46 *cvs = append(*cvs, configVar{ 47 Field: parts[0], 48 Default: parts[1], 49 }) 50 } else if len(parts) > 0 { 51 *cvs = append(*cvs, configVar{ 52 Field: parts[0], 53 }) 54 } else { 55 return fmt.Errorf("invalid config var: %s", flagValue) 56 } 57 return nil 58 } 59 60 func (cvs configVarSet) MarshalYAML() (interface{}, error) { 61 output := make(map[string]interface{}) 62 for _, cv := range cvs { 63 if cv.Value != "" { 64 output[cv.Field] = cv.Value 65 } else { 66 output[cv.Field] = cv.Default 67 } 68 } 69 return output, nil 70 } 71 72 func main() { 73 fields := configVarSet{} 74 secureFields := configVarSet{} 75 output := flag.String("o", "", "The output file") 76 flag.Var(&fields, "field", "Fields to prompt for, can be multiple") 77 flag.Var(&secureFields, "secure", "Secure Fields to prompt for, can be multiple, will hide input") 78 flag.Parse() 79 80 if len(fields) == 0 && len(secureFields) == 0 { 81 fmt.Fprintf(os.Stderr, "please provide at least (1) field or a secure field\n") 82 flag.Usage() 83 } 84 85 for index := range fields { 86 prompt(&fields[index]) 87 } 88 89 for index := range secureFields { 90 secure(&secureFields[index]) 91 } 92 93 all := fields.Union(secureFields) 94 buffer := new(bytes.Buffer) 95 if err := yaml.NewEncoder(buffer).Encode(all); err != nil { 96 fmt.Fprintf(os.Stderr, "%v", err) 97 os.Exit(1) 98 } 99 100 if *output != "" { 101 if err := os.WriteFile(*output, buffer.Bytes(), 0644); err != nil { 102 fmt.Fprintf(os.Stderr, "%v", err) 103 os.Exit(1) 104 } 105 } else { 106 fmt.Fprint(os.Stderr, buffer.String()) 107 } 108 } 109 110 func prompt(cv *configVar) { 111 if len(cv.Default) > 0 { 112 cv.Value = sh.Promptf("%s[%s]: ", cv.Field, cv.Default) 113 } else { 114 cv.Value = sh.Promptf("%s: ", cv.Field) 115 } 116 } 117 118 func secure(cv *configVar) { 119 var prompt string 120 if len(cv.Default) > 0 { 121 prompt = fmt.Sprintf("%s[%s]: ", cv.Field, cv.Default) 122 } else { 123 prompt = fmt.Sprintf("%s: ", cv.Field) 124 } 125 output := sh.MustPassword(prompt) 126 cv.Value = output 127 }