github.com/jenkins-x/jx/v2@v2.1.155/pkg/gits/credentialhelper/git_credential.go (about) 1 package credentialhelper 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "net/url" 7 "reflect" 8 "strings" 9 10 "github.com/jenkins-x/jx/v2/pkg/util" 11 "github.com/pkg/errors" 12 ) 13 14 // GitCredential represents the different parts of a git credential URL 15 // See also https://git-scm.com/docs/git-credential 16 type GitCredential struct { 17 Protocol string 18 Host string 19 Path string 20 Username string 21 Password string 22 } 23 24 // CreateGitCredential creates a CreateGitCredential instance from a slice of strings where each element is a key/value pair 25 // separated by '='. 26 func CreateGitCredential(lines []string) (GitCredential, error) { 27 var credential GitCredential 28 29 if lines == nil { 30 return credential, errors.New("no data lines provided") 31 } 32 33 fieldMap, err := util.ExtractKeyValuePairs(lines, "=") 34 if err != nil { 35 return credential, errors.Wrap(err, "unable to extract git credential parameters") 36 } 37 38 data, err := json.Marshal(fieldMap) 39 if err != nil { 40 return GitCredential{}, errors.Wrapf(err, "unable to marshal git credential data") 41 } 42 43 err = json.Unmarshal(data, &credential) 44 if err != nil { 45 return GitCredential{}, errors.Wrapf(err, "unable unmarshal git credential data") 46 } 47 48 return credential, nil 49 } 50 51 // CreateGitCredentialFromURL creates a CreateGitCredential instance from a URL and optional username and password. 52 func CreateGitCredentialFromURL(gitURL string, username string, password string) (GitCredential, error) { 53 var credential GitCredential 54 55 if gitURL == "" { 56 return credential, errors.New("url cannot be empty") 57 } 58 59 u, err := url.Parse(gitURL) 60 if err != nil { 61 return credential, errors.Wrapf(err, "unable to parse URL %s", gitURL) 62 } 63 64 credential.Protocol = u.Scheme 65 credential.Host = u.Host 66 credential.Path = u.Path 67 if username != "" { 68 credential.Username = username 69 } 70 71 if password != "" { 72 credential.Password = password 73 } 74 75 return credential, nil 76 } 77 78 // String returns a string representation of this instance according to the expected format of git credential helpers. 79 // See also https://git-scm.com/docs/git-credential 80 func (g *GitCredential) String() string { 81 answer := "" 82 83 value := reflect.ValueOf(g).Elem() 84 typeOfT := value.Type() 85 86 for i := 0; i < value.NumField(); i++ { 87 field := value.Field(i) 88 answer = answer + fmt.Sprintf("%s=%v\n", strings.ToLower(typeOfT.Field(i).Name), field.Interface()) 89 } 90 91 answer = answer + "\n" 92 93 return answer 94 } 95 96 // Clone clones this GitCredential instance 97 func (g *GitCredential) Clone() GitCredential { 98 clone := GitCredential{} 99 100 value := reflect.ValueOf(g).Elem() 101 typeOfT := value.Type() 102 for i := 0; i < value.NumField(); i++ { 103 field := value.Field(i) 104 value := field.String() 105 v := reflect.ValueOf(&clone).Elem().FieldByName(typeOfT.Field(i).Name) 106 v.SetString(value) 107 } 108 109 return clone 110 } 111 112 // URL returns a URL from the data of this instance. If not enough information exist an error is returned 113 func (g *GitCredential) URL() (url.URL, error) { 114 urlAsString := g.Protocol + "://" + g.Host 115 if g.Path != "" { 116 urlAsString = urlAsString + "/" + g.Path 117 } 118 u, err := url.Parse(urlAsString) 119 if err != nil { 120 return url.URL{}, errors.Wrap(err, "unable to construct URL") 121 } 122 123 u.User = url.UserPassword(g.Username, g.Password) 124 return *u, nil 125 }