1// Copyright 2015 The Gogs Authors. All rights reserved.
2// SPDX-License-Identifier: MIT
3
4package git
5
6import (
7 "context"
8 "errors"
9 "fmt"
10 "strings"
11
12 "forgejo.org/modules/util"
13)
14
15// ErrNotExist commit not exist error
16type ErrNotExist struct {
17 ID string
18 RelPath string
19}
20
21// IsErrNotExist if some error is ErrNotExist
22func IsErrNotExist(err error) bool {
23 _, ok := err.(ErrNotExist)
24 return ok
25}
26
27func (err ErrNotExist) Error() string {
28 return fmt.Sprintf("object does not exist [id: %s, rel_path: %s]", err.ID, err.RelPath)
29}
30
31func (err ErrNotExist) Unwrap() error {
32 return util.ErrNotExist
33}
34
35// ErrBadLink entry.FollowLink error
36type ErrBadLink struct {
37 Name string
38 Message string
39}
40
41func (err ErrBadLink) Error() string {
42 return fmt.Sprintf("%s: %s", err.Name, err.Message)
43}
44
45// IsErrBadLink if some error is ErrBadLink
46func IsErrBadLink(err error) bool {
47 _, ok := err.(ErrBadLink)
48 return ok
49}
50
51// ErrBranchNotExist represents a "BranchNotExist" kind of error.
52type ErrBranchNotExist struct {
53 Name string
54}
55
56// IsErrBranchNotExist checks if an error is a ErrBranchNotExist.
57func IsErrBranchNotExist(err error) bool {
58 _, ok := err.(ErrBranchNotExist)
59 return ok
60}
61
62func (err ErrBranchNotExist) Error() string {
63 return fmt.Sprintf("branch does not exist [name: %s]", err.Name)
64}
65
66func (err ErrBranchNotExist) Unwrap() error {
67 return util.ErrNotExist
68}
69
70// ErrPushOutOfDate represents an error if merging fails due to the base branch being updated
71type ErrPushOutOfDate struct {
72 StdOut string
73 StdErr string
74 Err error
75}
76
77// IsErrPushOutOfDate checks if an error is a ErrPushOutOfDate.
78func IsErrPushOutOfDate(err error) bool {
79 _, ok := err.(*ErrPushOutOfDate)
80 return ok
81}
82
83func (err *ErrPushOutOfDate) Error() string {
84 return fmt.Sprintf("PushOutOfDate Error: %v: %s\n%s", err.Err, err.StdErr, err.StdOut)
85}
86
87// Unwrap unwraps the underlying error
88func (err *ErrPushOutOfDate) Unwrap() error {
89 return fmt.Errorf("%w - %s", err.Err, err.StdErr)
90}
91
92// ErrPushRejected represents an error if merging fails due to rejection from a hook
93type ErrPushRejected struct {
94 Message string
95 StdOut string
96 StdErr string
97 Err error
98}
99
100// IsErrPushRejected checks if an error is a ErrPushRejected.
101func IsErrPushRejected(err error) bool {
102 _, ok := err.(*ErrPushRejected)
103 return ok
104}
105
106func (err *ErrPushRejected) Error() string {
107 return fmt.Sprintf("PushRejected Error: %v: %s\n%s", err.Err, err.StdErr, err.StdOut)
108}
109
110// Unwrap unwraps the underlying error
111func (err *ErrPushRejected) Unwrap() error {
112 return fmt.Errorf("%w - %s", err.Err, err.StdErr)
113}
114
115// GenerateMessage generates the remote message from the stderr
116func (err *ErrPushRejected) GenerateMessage() {
117 messageBuilder := &strings.Builder{}
118 i := strings.Index(err.StdErr, "remote: ")
119 if i < 0 {
120 err.Message = ""
121 return
122 }
123 for len(err.StdErr) > i+8 {
124 if err.StdErr[i:i+8] != "remote: " {
125 break
126 }
127 i += 8
128 nl := strings.IndexByte(err.StdErr[i:], '\n')
129 if nl >= 0 {
130 messageBuilder.WriteString(err.StdErr[i : i+nl+1])
131 i = i + nl + 1
132 } else {
133 messageBuilder.WriteString(err.StdErr[i:])
134 i = len(err.StdErr)
135 }
136 }
137 err.Message = strings.TrimSpace(messageBuilder.String())
138}
139
140// ErrMoreThanOne represents an error if pull request fails when there are more than one sources (branch, tag) with the same name
141type ErrMoreThanOne struct {
142 StdOut string
143 StdErr string
144 Err error
145}
146
147// IsErrMoreThanOne checks if an error is a ErrMoreThanOne
148func IsErrMoreThanOne(err error) bool {
149 _, ok := err.(*ErrMoreThanOne)
150 return ok
151}
152
153func (err *ErrMoreThanOne) Error() string {
154 return fmt.Sprintf("ErrMoreThanOne Error: %v: %s\n%s", err.Err, err.StdErr, err.StdOut)
155}
156
157func IsErrCanceledOrKilled(err error) bool {
158 // When "cancel()" a git command's context, the returned error of "Run()" could be one of them:
159 // - context.Canceled
160 // - *exec.ExitError: "signal: killed"
161 return err != nil && (errors.Is(err, context.Canceled) || err.Error() == "signal: killed")
162}