github.com/zppinho/prow@v0.0.0-20240510014325-1738badeb017/pkg/pjutil/help.go (about) 1 /* 2 Copyright 2021 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 pjutil 18 19 import ( 20 "fmt" 21 "regexp" 22 "strings" 23 24 "k8s.io/apimachinery/pkg/util/sets" 25 ) 26 27 var ( 28 TestHelpRe = regexp.MustCompile(`(?m)^/test[ \t]*\?\s*$`) 29 EmptyTestRe = regexp.MustCompile(`(?m)^/test\s*$`) 30 RetestWithTargetRe = regexp.MustCompile(`(?m)^/retest[ \t]+\S+`) 31 TestWithAnyTargetRe = regexp.MustCompile(`(?m)^/test[ \t]+\S+`) 32 33 TestWithoutTargetNote = "The `/test` command needs one or more targets.\n" 34 RetestWithTargetNote = "The `/retest` command does not accept any targets.\n" 35 TargetNotFoundNote = "The specified target(s) for `/test` were not found.\n" 36 ThereAreNoTestAllJobsNote = "No jobs can be run with `/test all`.\n" 37 ) 38 39 func MayNeedHelpComment(body string) bool { 40 return EmptyTestRe.MatchString(body) || 41 RetestWithTargetRe.MatchString(body) || 42 TestWithAnyTargetRe.MatchString(body) || 43 TestHelpRe.MatchString(body) 44 } 45 46 func ShouldRespondWithHelp(body string, toRunOrSkip int) (bool, string) { 47 switch { 48 case TestHelpRe.MatchString(body): 49 return true, "" 50 case EmptyTestRe.MatchString(body): 51 return true, TestWithoutTargetNote 52 case RetestWithTargetRe.MatchString(body): 53 return true, RetestWithTargetNote 54 case toRunOrSkip == 0 && TestAllRe.MatchString(body): 55 return true, ThereAreNoTestAllJobsNote 56 case toRunOrSkip == 0 && TestWithAnyTargetRe.MatchString(body): 57 return true, TargetNotFoundNote 58 default: 59 return false, "" 60 } 61 } 62 63 // HelpMessage returns a user friendly help message with the 64 // 65 // available /test commands that can be triggered 66 func HelpMessage(org, repo, branch, note string, testAllNames, optionalTestCommands, requiredTestCommands sets.Set[string]) string { 67 var resp string 68 if testAllNames.Len()+optionalTestCommands.Len()+requiredTestCommands.Len() == 0 { 69 return fmt.Sprintf("No presubmit jobs available for %s/%s@%s", org, repo, branch) 70 } 71 72 listBuilder := func(names sets.Set[string]) string { 73 var list strings.Builder 74 for _, name := range sets.List(names) { 75 list.WriteString(fmt.Sprintf("\n* `%s`", name)) 76 } 77 return list.String() 78 } 79 80 resp = note 81 if requiredTestCommands.Len() > 0 { 82 resp += fmt.Sprintf("The following commands are available to trigger required jobs:%s\n\n", listBuilder(requiredTestCommands)) 83 } 84 if optionalTestCommands.Len() > 0 { 85 resp += fmt.Sprintf("The following commands are available to trigger optional jobs:%s\n\n", listBuilder(optionalTestCommands)) 86 } 87 88 var testAllNote string 89 if testAllNames.Len() == optionalTestCommands.Len()+requiredTestCommands.Len() { 90 testAllNote = "Use `/test all` to run all jobs.\n" 91 } else if testAllNames.Len() > 0 { 92 testAllNote = fmt.Sprintf("Use `/test all` to run the following jobs that were automatically triggered:%s\n\n", listBuilder(testAllNames)) 93 } 94 resp += testAllNote 95 96 return resp 97 }