mirror of https://github.com/go-gitea/gitea.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
78 lines
1.9 KiB
78 lines
1.9 KiB
// Copyright 2026 The Gitea Authors. All rights reserved. |
|
// SPDX-License-Identifier: MIT |
|
|
|
package gitcmd |
|
|
|
import ( |
|
"context" |
|
"errors" |
|
"fmt" |
|
"os/exec" |
|
"strings" |
|
) |
|
|
|
type RunStdError interface { |
|
error |
|
Unwrap() error |
|
Stderr() string |
|
} |
|
|
|
type runStdError struct { |
|
err error // usually the low-level error like `*exec.ExitError` |
|
stderr string // git command's stderr output |
|
errMsg string // the cached error message for Error() method |
|
} |
|
|
|
func (r *runStdError) Error() string { |
|
// FIXME: GIT-CMD-STDERR: it is a bad design, the stderr should not be put in the error message |
|
// But a lot of code only checks `strings.Contains(err.Error(), "git error")` |
|
if r.errMsg == "" { |
|
r.errMsg = fmt.Sprintf("%s - %s", r.err.Error(), strings.TrimSpace(r.stderr)) |
|
} |
|
return r.errMsg |
|
} |
|
|
|
func (r *runStdError) Unwrap() error { |
|
return r.err |
|
} |
|
|
|
func (r *runStdError) Stderr() string { |
|
return r.stderr |
|
} |
|
|
|
func ErrorAsStderr(err error) (string, bool) { |
|
var runErr RunStdError |
|
if errors.As(err, &runErr) { |
|
return runErr.Stderr(), true |
|
} |
|
return "", false |
|
} |
|
|
|
func StderrHasPrefix(err error, prefix string) bool { |
|
stderr, ok := ErrorAsStderr(err) |
|
if !ok { |
|
return false |
|
} |
|
return strings.HasPrefix(stderr, prefix) |
|
} |
|
|
|
func IsErrorExitCode(err error, code int) bool { |
|
var exitError *exec.ExitError |
|
if errors.As(err, &exitError) { |
|
return exitError.ExitCode() == code |
|
} |
|
return false |
|
} |
|
|
|
func IsErrorSignalKilled(err error) bool { |
|
var exitError *exec.ExitError |
|
return errors.As(err, &exitError) && exitError.String() == "signal: killed" |
|
} |
|
|
|
func IsErrorCanceledOrKilled(err error) bool { |
|
// When "cancel()" a git command's context, the returned error of "Run()" could be one of them: |
|
// - context.Canceled |
|
// - *exec.ExitError: "signal: killed" |
|
// TODO: in the future, we need to use unified error type from gitcmd.Run to check whether it is manually canceled |
|
return errors.Is(err, context.Canceled) || IsErrorSignalKilled(err) |
|
}
|
|
|