github.com/cobalt77/jfrog-client-go@v0.14.5/artifactory/services/utils/properties.go (about) 1 package utils 2 3 import ( 4 "encoding/base64" 5 "errors" 6 "fmt" 7 "net/url" 8 "strings" 9 10 "github.com/cobalt77/jfrog-client-go/utils/errorutils" 11 ) 12 13 type PropertyParseOptions int 14 15 const ( 16 // Parsing properties 17 SplitCommas PropertyParseOptions = iota 18 JoinCommas 19 ) 20 21 type Properties struct { 22 Properties []Property 23 } 24 25 type Property struct { 26 Key string 27 Value string 28 } 29 30 // Parsing properties string to Properties struct. 31 func ParseProperties(propStr string, option PropertyParseOptions) (*Properties, error) { 32 props := &Properties{} 33 propList := strings.Split(propStr, ";") 34 for _, prop := range propList { 35 if prop == "" { 36 continue 37 } 38 39 key, values, err := splitProp(prop) 40 if err != nil { 41 return props, err 42 } 43 44 switch option { 45 case SplitCommas: 46 splitedValues := strings.Split(values, ",") 47 for i, val := range splitedValues { 48 // If "\" is found, then it means that the original string contains the "\," which indicate this "," is part of the value 49 // and not a sperator 50 if strings.HasSuffix(val, "\\") && i+1 < len(splitedValues) { 51 splitedValues[i+1] = val[:len(val)-1] + "," + splitedValues[i+1] 52 } else { 53 props.Properties = append(props.Properties, Property{key, val}) 54 } 55 } 56 case JoinCommas: 57 props.Properties = append(props.Properties, Property{key, values}) 58 } 59 } 60 return props, nil 61 } 62 63 func (props *Properties) ToEncodedString() string { 64 encodedProps := "" 65 for _, v := range props.Properties { 66 jointProp := fmt.Sprintf("%s=%s", url.QueryEscape(v.Key), url.QueryEscape(v.Value)) 67 encodedProps = fmt.Sprintf("%s;%s", encodedProps, jointProp) 68 } 69 // Remove leading semicolon 70 if strings.HasPrefix(encodedProps, ";") { 71 return encodedProps[1:] 72 } 73 return encodedProps 74 } 75 76 func (props *Properties) ToHeadersMap() map[string]string { 77 headers := map[string]string{} 78 for _, v := range props.Properties { 79 headers[v.Key] = base64.StdEncoding.EncodeToString([]byte(v.Value)) 80 } 81 return headers 82 } 83 84 // Convert properties from Slice to map that build promotion REST API requires 85 func (props *Properties) ToBuildPromoteMap() map[string][]string { 86 buildPromote := map[string][]string{} 87 for _, prop := range props.Properties { 88 buildPromote[prop.Key] = []string{prop.Value} 89 } 90 return buildPromote 91 } 92 93 // Split properties string of format key=value to key value strings 94 func splitProp(prop string) (string, string, error) { 95 splitIndex := strings.Index(prop, "=") 96 if splitIndex < 1 || len(prop[splitIndex+1:]) < 1 { 97 err := errorutils.CheckError(errors.New("Invalid property: " + prop)) 98 return "", "", err 99 } 100 return prop[:splitIndex], prop[splitIndex+1:], nil 101 }