github.com/abayer/test-infra@v0.0.5/mungegithub/mungers/mungerutil/util.go (about) 1 /* 2 Copyright 2016 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package mungerutil 18 19 import ( 20 "fmt" 21 "io/ioutil" 22 "net/http" 23 "strings" 24 "time" 25 26 "k8s.io/apimachinery/pkg/util/sets" 27 28 "github.com/google/go-github/github" 29 ) 30 31 // UserSet is a set a of users 32 type UserSet sets.String 33 34 // GetUsers returns a UserSet 35 func GetUsers(users ...*github.User) UserSet { 36 allUsers := sets.String{} 37 38 for _, user := range users { 39 if !IsValidUser(user) { 40 continue 41 } 42 allUsers.Insert(*user.Login) 43 } 44 45 return UserSet(allUsers) 46 } 47 48 // Has tells you if the users can be found in the set 49 func (u UserSet) Has(user ...*github.User) bool { 50 return len(u.intersection(GetUsers(user...))) != 0 51 } 52 53 // Mention adds @ to user in the list who don't have it yet 54 func (u UserSet) Mention() UserSet { 55 mentionedUsers := sets.NewString() 56 57 for _, user := range u.List() { 58 if !strings.HasPrefix(user, "@") { 59 mentionedUsers.Insert("@" + user) 60 } else { 61 mentionedUsers.Insert(user) 62 } 63 } 64 65 return UserSet(mentionedUsers) 66 } 67 68 // List makes a list from the set 69 func (u UserSet) List() []string { 70 return sets.String(u).List() 71 } 72 73 // Join joins each users into a single string 74 func (u UserSet) Join() string { 75 return strings.Join(u.List(), " ") 76 } 77 78 func (u UserSet) union(o UserSet) UserSet { 79 return UserSet(sets.String(u).Union(sets.String(o))) 80 } 81 82 func (u UserSet) intersection(o UserSet) UserSet { 83 return UserSet(sets.String(u).Intersection(sets.String(o))) 84 } 85 86 // IssueUsers tracks Users involved in a github Issue 87 type IssueUsers struct { 88 Assignees UserSet 89 Author UserSet // This will usually be one or zero 90 } 91 92 // GetIssueUsers creates a new IssueUsers object from an issue's fields 93 func GetIssueUsers(issue *github.Issue) *IssueUsers { 94 return &IssueUsers{ 95 Assignees: GetUsers(issue.Assignees...).union(GetUsers(issue.Assignee)), 96 Author: GetUsers(issue.User), 97 } 98 } 99 100 // AllUsers return a list of unique users (both assignees and author) 101 func (u *IssueUsers) AllUsers() UserSet { 102 return u.Assignees.union(u.Author) 103 } 104 105 // IsValidUser returns true only if given user has valid github username. 106 func IsValidUser(u *github.User) bool { 107 return u != nil && u.Login != nil 108 } 109 110 // ReadHTTP fetches file contents from a URL with retries. 111 func ReadHTTP(url string) ([]byte, error) { 112 var err error 113 retryDelay := time.Duration(2) * time.Second 114 for retryCount := 0; retryCount < 5; retryCount++ { 115 if retryCount > 0 { 116 time.Sleep(retryDelay) 117 retryDelay *= time.Duration(2) 118 } 119 120 resp, err := http.Get(url) 121 if resp != nil && resp.StatusCode >= 500 { 122 // Retry on this type of error. 123 continue 124 } 125 if err != nil { 126 return nil, err 127 } 128 defer resp.Body.Close() 129 130 body, err := ioutil.ReadAll(resp.Body) 131 if err != nil { 132 continue 133 } 134 return body, nil 135 } 136 return nil, fmt.Errorf("ran out of retries reading from '%s'. Last error was %v", url, err) 137 }