-
Notifications
You must be signed in to change notification settings - Fork 0
/
info_util.go
142 lines (117 loc) · 3.03 KB
/
info_util.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
package gitw
import (
"net/url"
"strings"
"github.com/gookit/gitw/gitutil"
"github.com/gookit/goutil/errorx"
"github.com/gookit/goutil/mathutil"
"github.com/gookit/goutil/strutil"
)
// ErrRemoteInfoNil error
var ErrRemoteInfoNil = errorx.Raw("the remote info data cannot be nil")
// ParseRemoteURL info to the RemoteInfo object.
func ParseRemoteURL(URL string, r *RemoteInfo) (err error) {
if r == nil {
return ErrRemoteInfoNil
}
var str string
hasSfx := strings.HasSuffix(URL, ".git")
// eg: "git@github.com:gookit/gitw.git"
if gitutil.IsSSHProto(URL) {
r.Proto = ProtoSSH
URL = strings.TrimPrefix(URL, "ssh://")
if hasSfx {
str = URL[4 : len(URL)-4]
} else {
str = URL[4:]
}
host, path, ok := strutil.Cut(str, ":")
if !ok {
return errorx.Rawf("invalid git URL: %s", URL)
}
var group, repo string
nodes := strings.Split(path, "/")
if len(nodes) < 2 {
return errorx.Rawf("invalid git URL path: %s", path)
}
// check first is port
if len(nodes) > 2 {
if strutil.IsNumeric(nodes[0]) {
r.Port = mathutil.SafeInt(nodes[0])
group = nodes[1]
repo = strings.Join(nodes[2:], "/")
}
} else {
group, repo, ok = strutil.Cut(path, "/")
if !ok {
return errorx.Rawf("invalid git URL path: %s", path)
}
}
r.Scheme = SchemeGIT
r.Host, r.Group, r.Repo = host, group, repo
return nil
}
// http protocol
str = URL
if hasSfx {
str = URL[0 : len(URL)-4]
}
// eg: "https://github.com/gookit/gitw.git"
info, err := url.Parse(str)
if err != nil {
return err
}
group, repo, ok := strutil.Cut(strings.Trim(info.Path, "/"), "/")
if !ok {
return errorx.Rawf("invalid http URL path: %s", info.Path)
}
r.Proto = ProtoHTTP
r.Scheme = info.Scheme
r.Host, r.Group, r.Repo = info.Host, group, repo
return nil
}
// ErrInvalidBrLine error
var ErrInvalidBrLine = errorx.Raw("invalid git branch line text")
// ParseBranchLine to BranchInfo data
//
// verbose:
//
// False - only branch name
// True - get by `git br -v --all`
// format: * BRANCH_NAME COMMIT_ID COMMIT_MSG
func ParseBranchLine(line string, verbose bool) (*BranchInfo, error) {
info := &BranchInfo{}
line = strings.TrimSpace(line)
if strings.HasPrefix(line, "*") {
info.Current = true
line = strings.Trim(line, "*\t ")
}
if line == "" {
return nil, ErrInvalidBrLine
}
// at tag head. eg: `* (头指针在 v0.2.3 分离) 3c08adf chore: update readme add branch info docs`
if strings.HasPrefix(line, "(") || strings.HasPrefix(line, "(") {
return nil, ErrInvalidBrLine
}
if !verbose {
info.SetName(line)
return info, nil
}
// parse name
nodes := strutil.SplitNTrimmed(line, " ", 2)
if len(nodes) != 2 {
return nil, ErrInvalidBrLine
}
info.SetName(nodes[0])
// parse hash and message
nodes = strutil.SplitNTrimmed(nodes[1], " ", 2)
if len(nodes) != 2 {
return nil, ErrInvalidBrLine
}
info.Hash, info.HashMsg = nodes[0], nodes[1]
return info, nil
}
func isVerboseBranchLine(line string) bool {
line = strings.Trim(line, " *\t\n\r\x0B")
return strings.ContainsRune(line, ' ')
}