-
Notifications
You must be signed in to change notification settings - Fork 2
/
repository.go
107 lines (85 loc) · 2.55 KB
/
repository.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
package utils
import (
"path"
"strings"
"errors"
)
var (
//ErrInvalidCharacters occurs when one of "%><$." is found in either Owner or repo
ErrInvalidCharacters = errors.New("repository name contains invalid characters")
)
// OwnerRepo returns the owner and repository parts of a github full repository
// name. It returns an error if there are issues.
func OwnerRepo(repoName string) (string, string, error) {
parts := strings.Split(repoName, "/")
if len(parts) != 2 {
return "", "", errors.New("parsing repository name: invalid number of parts")
}
for _, part := range parts {
if len(part) == 0 {
return "", "", errors.New("repository name part is empty")
}
if strings.HasPrefix(part, ".") || strings.HasSuffix(part, ".") {
return "", "", ErrInvalidCharacters
}
if strings.Contains(part, ">") || strings.Contains(part, "<") {
return "", "", ErrInvalidCharacters
}
if strings.Contains(part, "&") || strings.Contains(part, "%") {
return "", "", ErrInvalidCharacters
}
}
return parts[0], parts[1], nil
}
// IsOwnerRepo is a predicate to determine whether or not a github repo name is
// valid.
func IsOwnerRepo(repoName string) bool {
_, _, err := OwnerRepo(repoName)
return err == nil
}
// IsSHA detects if the string looks like a real SHA1 digest or not.
func IsSHA(sha string) bool {
sha = strings.TrimSpace(sha)
if len(sha) != 40 {
return false
}
for _, c := range strings.ToLower(sha) {
if c < '0' || c > 'f' {
return false
}
}
return true
}
// QualifyBranch corrects branch data to reflect our internal ref-type/ref-name
// strategy for tracking branches. It returns an error when it can't figure it out.
func QualifyBranch(branch string) (string, error) {
if IsSHA(branch) {
return branch, errors.New("is not a branch; is a sha")
}
if strings.HasPrefix(branch, "/") {
return "", errors.New("invalid branch name")
}
branch = strings.TrimSpace(branch)
branch = strings.TrimPrefix(branch, "refs/heads/")
paths := strings.Split(branch, "/")
if len(paths) == 0 {
return "", errors.New("invalid branch name")
}
cleanedPaths := []string{}
for _, p := range paths {
p = strings.TrimSpace(p)
if p != "" && p != "." && p != ".." { // guard against relative dir shit
cleanedPaths = append(cleanedPaths, p)
}
}
if len(cleanedPaths) == 0 {
return "", errors.New("paths were invalid")
}
if cleanedPaths[0] == "heads" {
if len(cleanedPaths) > 1 {
return path.Join(cleanedPaths...), nil
}
return "", errors.New("paths were invalid")
}
return path.Join("heads", path.Join(cleanedPaths...)), nil
}