github.com/munnerz/test-infra@v0.0.0-20190108210205-ce3d181dc989/prow/plugins/shrug/shrug.go (about) 1 /* 2 Copyright 2017 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 shrug 18 19 import ( 20 "fmt" 21 "regexp" 22 23 "github.com/sirupsen/logrus" 24 25 "k8s.io/test-infra/prow/github" 26 "k8s.io/test-infra/prow/labels" 27 "k8s.io/test-infra/prow/pluginhelp" 28 "k8s.io/test-infra/prow/plugins" 29 ) 30 31 const pluginName = "shrug" 32 33 var ( 34 shrugRe = regexp.MustCompile(`(?mi)^/shrug\s*$`) 35 unshrugRe = regexp.MustCompile(`(?mi)^/unshrug\s*$`) 36 ) 37 38 type event struct { 39 org string 40 repo string 41 number int 42 prAuthor string 43 commentAuthor string 44 body string 45 assignees []github.User 46 hasLabel func(label string) (bool, error) 47 htmlurl string 48 } 49 50 func init() { 51 plugins.RegisterGenericCommentHandler(pluginName, handleGenericComment, helpProvider) 52 } 53 54 func helpProvider(config *plugins.Configuration, enabledRepos []string) (*pluginhelp.PluginHelp, error) { 55 // The Config field is omitted because this plugin is not configurable. 56 pluginHelp := &pluginhelp.PluginHelp{ 57 Description: labels.Shrug, 58 } 59 pluginHelp.AddCommand(pluginhelp.Command{ 60 Usage: "/[un]shrug", 61 Description: labels.Shrug, 62 Featured: false, 63 WhoCanUse: "Anyone, " + labels.Shrug, 64 Examples: []string{"/shrug", "/unshrug"}, 65 }) 66 return pluginHelp, nil 67 } 68 69 type githubClient interface { 70 AddLabel(owner, repo string, number int, label string) error 71 CreateComment(owner, repo string, number int, comment string) error 72 RemoveLabel(owner, repo string, number int, label string) error 73 GetIssueLabels(org, repo string, number int) ([]github.Label, error) 74 } 75 76 func handleGenericComment(pc plugins.Agent, e github.GenericCommentEvent) error { 77 return handle(pc.GitHubClient, pc.Logger, &e) 78 } 79 80 func handle(gc githubClient, log *logrus.Entry, e *github.GenericCommentEvent) error { 81 if e.Action != github.GenericCommentActionCreated { 82 return nil 83 } 84 85 wantShrug := false 86 if shrugRe.MatchString(e.Body) { 87 wantShrug = true 88 } else if unshrugRe.MatchString(e.Body) { 89 wantShrug = false 90 } else { 91 return nil 92 } 93 94 org := e.Repo.Owner.Login 95 repo := e.Repo.Name 96 97 // Only add the label if it doesn't have it yet. 98 hasShrug := false 99 issueLabels, err := gc.GetIssueLabels(org, repo, e.Number) 100 if err != nil { 101 log.WithError(err).Errorf("Failed to get the labels on %s/%s#%d.", org, repo, e.Number) 102 } 103 for _, candidate := range issueLabels { 104 if candidate.Name == labels.Shrug { 105 hasShrug = true 106 break 107 } 108 } 109 if hasShrug && !wantShrug { 110 log.Info("Removing Shrug label.") 111 resp := "¯\\\\\\_(ツ)\\_/¯" 112 log.Infof("Commenting with \"%s\".", resp) 113 if err := gc.CreateComment(org, repo, e.Number, plugins.FormatResponseRaw(e.Body, e.HTMLURL, e.User.Login, resp)); err != nil { 114 return fmt.Errorf("failed to comment on %s/%s#%d: %v", org, repo, e.Number, err) 115 } 116 return gc.RemoveLabel(org, repo, e.Number, labels.Shrug) 117 } else if !hasShrug && wantShrug { 118 log.Info("Adding Shrug label.") 119 return gc.AddLabel(org, repo, e.Number, labels.Shrug) 120 } 121 return nil 122 }