-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgosrcdir.go
118 lines (97 loc) · 2.41 KB
/
gosrcdir.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
package main
import (
"errors"
"fmt"
"go/build"
"net/url"
"os"
"path"
"strings"
)
// parseStandardURL parses a standard URI formatted git URL
func parseStandardURL(repo string) (pathParts []string, err error) {
parsedURL, err := url.Parse(repo)
if err != nil {
return
}
if parsedURL.Host == "" {
err = errors.New("Missing host part")
return
}
pathParts = append(pathParts, parsedURL.Host)
for _, pathPart := range strings.Split(parsedURL.Path, "/") {
if pathPart == "" {
continue
}
pathParts = append(pathParts, pathPart)
}
return
}
// parseWeirdGitURL tries to make sense of a user@host:path format git URL
func parseWeirdGitURL(repo string) (pathParts []string, err error) {
hostIndex := strings.Index(repo, "@") + 1
pathIndex := strings.Index(repo, ":") + 1
repoPath := strings.Split(string(repo[pathIndex:]), "/")
// If there is no : then this is wrong
if pathIndex == 0 || len(repoPath) == 0 {
err = errors.New("Missing path part")
return
}
// if index of @ is -1 then host is the first thing
// if @ is after : then it's part of the path
if hostIndex > pathIndex {
hostIndex = 0
}
host := string(repo[hostIndex : pathIndex-1])
pathParts = append(pathParts, host)
for _, pathPart := range repoPath {
if pathPart == "" {
err = fmt.Errorf("Blank path segment")
return
}
pathParts = append(pathParts, pathPart)
}
return
}
// calculateSourcePath works out the local filesystem path to directory above a given repo
func calculateSourcePath(goPath string, repo string) (repoPath string, err error) {
pathParts, err := parseStandardURL(repo)
if err != nil {
pathParts, err = parseWeirdGitURL(repo)
if err != nil {
return
}
}
if len(pathParts) < 2 {
err = errors.New("Host and path required")
return
}
pathParts = append([]string{goPath, "src"}, pathParts[:len(pathParts)-1]...)
repoPath = path.Join(pathParts...)
return
}
func getGoPath() string {
goPath := os.Getenv("GOPATH")
if goPath != "" {
return goPath
}
return build.Default.GOPATH
}
func main() {
args := os.Args[1:]
// Require at least one repo
if len(args) == 0 {
os.Exit(1)
}
// Work out where GOPATH really is
goPath := getGoPath()
// Calculate path for all repos
for _, repo := range args {
repoPath, err := calculateSourcePath(goPath, repo)
if err != nil {
fmt.Fprintf(os.Stderr, "Cannot parse repo URL %s: %s\n", repo, err)
os.Exit(1)
}
fmt.Println(repoPath)
}
}