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