github.com/SamarSidharth/kpt@v0.0.0-20231122062228-c7d747ae3ace/internal/errors/resolver/git.go (about) 1 // Copyright 2021 The kpt Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package resolver 16 17 import ( 18 goerrors "errors" 19 "fmt" 20 "strings" 21 22 "github.com/GoogleContainerTools/kpt/internal/gitutil" 23 ) 24 25 //nolint:gochecknoinits 26 func init() { 27 AddErrorResolver(&gitExecErrorResolver{}) 28 } 29 30 // gitExecErrorResolver is an implementation of the ErrorResolver interface 31 // that can produce error messages for errors of the gitutil.GitExecError type. 32 type gitExecErrorResolver struct{} 33 34 func (*gitExecErrorResolver) Resolve(err error) (ResolvedResult, bool) { 35 var gitExecErr *gitutil.GitExecError 36 if !goerrors.As(err, &gitExecErr) { 37 return ResolvedResult{}, false 38 } 39 fullCommand := fmt.Sprintf("git %s %s", gitExecErr.Command, 40 strings.Join(gitExecErr.Args, " ")) 41 42 var msg string 43 switch gitExecErr.Type { 44 case gitutil.UnknownReference: 45 msg = fmt.Sprintf("Error: Unknown ref %q. Please verify that the reference exists in upstream repo %q.", gitExecErr.Ref, gitExecErr.Repo) 46 msg = msg + "\n" + BuildOutputDetails(gitExecErr.StdOut, gitExecErr.StdErr) 47 48 case gitutil.GitExecutableNotFound: 49 msg = "Error: No git executable found. kpt requires git to be installed and available in the path." 50 msg = msg + "\n" + BuildOutputDetails(gitExecErr.StdOut, gitExecErr.StdErr) 51 52 case gitutil.HTTPSAuthRequired: 53 msg = fmt.Sprintf("Error: Repository %q requires authentication.", gitExecErr.Repo) 54 msg += " kpt does not support this for the 'https' protocol." 55 msg += " Please use the 'git' protocol instead." 56 msg = msg + "\n" + BuildOutputDetails(gitExecErr.StdOut, gitExecErr.StdErr) 57 58 case gitutil.RepositoryUnavailable: 59 msg = fmt.Sprintf("Error: Unable to access repository %q.", gitExecErr.Repo) 60 msg = msg + "\n" + BuildOutputDetails(gitExecErr.StdOut, gitExecErr.StdErr) 61 62 case gitutil.RepositoryNotFound: 63 msg = fmt.Sprintf("Error: Repository %q not found.", gitExecErr.Repo) 64 msg = msg + "\n" + BuildOutputDetails(gitExecErr.StdOut, gitExecErr.StdErr) 65 default: 66 msg = fmt.Sprintf("Error: Failed to execute git command %q", fullCommand) 67 if gitExecErr.Repo != "" { 68 msg += fmt.Sprintf(" against repo %q", gitExecErr.Repo) 69 } 70 if gitExecErr.Ref != "" { 71 msg += fmt.Sprintf(" for reference %q", gitExecErr.Ref) 72 } 73 msg = msg + "\n" + BuildOutputDetails(gitExecErr.StdOut, gitExecErr.StdErr) 74 } 75 return ResolvedResult{ 76 Message: msg, 77 }, true 78 } 79 80 func BuildOutputDetails(stdout string, stderr string) string { 81 var sb strings.Builder 82 if len(stdout) > 0 || len(stderr) > 0 { 83 sb.WriteString("\nDetails:\n") 84 } 85 if len(stdout) > 0 { 86 sb.WriteString(stdout) 87 } 88 if len(stderr) > 0 { 89 sb.WriteString(stderr) 90 } 91 return sb.String() 92 }