sigs.k8s.io/prow@v0.0.0-20240503223140-c5e374dc7eb1/pkg/clonerefs/parse.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 clonerefs 18 19 import ( 20 "fmt" 21 "strconv" 22 "strings" 23 24 prowapi "sigs.k8s.io/prow/pkg/apis/prowjobs/v1" 25 ) 26 27 // ParseRefs parses a human-provided string into the repo 28 // that should be cloned and the refs that need to be 29 // checked out once it is. The format is: 30 // 31 // org,repo=base-ref[:base-sha][,pull-id[:pull-sha[:pull-ref]]]... 32 // 33 // For the base ref and pull IDs, a SHA may optionally be 34 // provided or may be omitted for the latest available SHA. 35 // Examples: 36 // 37 // kubernetes,test-infra=master 38 // kubernetes,test-infra=master:abcde12 39 // kubernetes,test-infra=master:abcde12,34 40 // kubernetes,test-infra=master:abcde12,34:fghij56 41 // kubernetes,test-infra=master,34:fghij56 42 // kubernetes,test-infra=master:abcde12,34:fghij56,78 43 // gerrit,test-infra=master:abcde12,34:fghij56:refs/changes/00/123/1 44 func ParseRefs(value string) (*prowapi.Refs, error) { 45 gitRef := &prowapi.Refs{} 46 values := strings.SplitN(value, "=", 2) 47 if len(values) != 2 { 48 return gitRef, fmt.Errorf("refspec %s invalid: does not contain '='", value) 49 } 50 info := values[0] 51 allRefs := values[1] 52 53 infoValues := strings.SplitN(info, ",", 2) 54 if len(infoValues) != 2 { 55 return gitRef, fmt.Errorf("refspec %s invalid: does not contain 'org,repo' as prefix", value) 56 } 57 gitRef.Org = infoValues[0] 58 gitRef.Repo = infoValues[1] 59 60 refValues := strings.Split(allRefs, ",") 61 if len(refValues) == 1 && refValues[0] == "" { 62 return gitRef, fmt.Errorf("refspec %s invalid: does not contain any refs", value) 63 } 64 baseRefParts := strings.Split(refValues[0], ":") 65 if len(baseRefParts) != 1 && len(baseRefParts) != 2 { 66 return gitRef, fmt.Errorf("refspec %s invalid: malformed base ref", refValues[0]) 67 } 68 gitRef.BaseRef = baseRefParts[0] 69 if len(baseRefParts) == 2 { 70 gitRef.BaseSHA = baseRefParts[1] 71 } 72 for _, refValue := range refValues[1:] { 73 refParts := strings.Split(refValue, ":") 74 if len(refParts) == 0 || len(refParts) > 3 { 75 return gitRef, fmt.Errorf("refspec %s invalid: malformed pull ref", refValue) 76 } 77 pullNumber, err := strconv.Atoi(refParts[0]) 78 if err != nil { 79 return gitRef, fmt.Errorf("refspec %s invalid: pull request identifier not a number: %w", refValue, err) 80 } 81 pullRef := prowapi.Pull{ 82 Number: pullNumber, 83 } 84 if len(refParts) > 1 { 85 pullRef.SHA = refParts[1] 86 } 87 if len(refParts) > 2 { 88 pullRef.Ref = refParts[2] 89 } 90 gitRef.Pulls = append(gitRef.Pulls, pullRef) 91 } 92 93 return gitRef, nil 94 }