...
1 package git
2
3 import (
4 "fmt"
5 "net/url"
6 "strings"
7 )
8
9 func IsURL(u string) bool {
10 return strings.HasPrefix(u, "git@") || isSupportedProtocol(u)
11 }
12
13 func isSupportedProtocol(u string) bool {
14 return strings.HasPrefix(u, "ssh:") ||
15 strings.HasPrefix(u, "git+ssh:") ||
16 strings.HasPrefix(u, "git:") ||
17 strings.HasPrefix(u, "http:") ||
18 strings.HasPrefix(u, "git+https:") ||
19 strings.HasPrefix(u, "https:")
20 }
21
22 func isPossibleProtocol(u string) bool {
23 return isSupportedProtocol(u) ||
24 strings.HasPrefix(u, "ftp:") ||
25 strings.HasPrefix(u, "ftps:") ||
26 strings.HasPrefix(u, "file:")
27 }
28
29
30 func ParseURL(rawURL string) (u *url.URL, err error) {
31 if !isPossibleProtocol(rawURL) &&
32 strings.ContainsRune(rawURL, ':') &&
33
34 !strings.ContainsRune(rawURL, '\\') {
35
36 rawURL = "ssh://" + strings.Replace(rawURL, ":", "/", 1)
37 }
38
39 u, err = url.Parse(rawURL)
40 if err != nil {
41 return
42 }
43
44 if u.Scheme == "git+ssh" {
45 u.Scheme = "ssh"
46 }
47
48 if u.Scheme == "git+https" {
49 u.Scheme = "https"
50 }
51
52 if u.Scheme != "ssh" {
53 return
54 }
55
56 if strings.HasPrefix(u.Path, "//") {
57 u.Path = strings.TrimPrefix(u.Path, "/")
58 }
59
60 if idx := strings.Index(u.Host, ":"); idx >= 0 {
61 u.Host = u.Host[0:idx]
62 }
63
64 return
65 }
66
67
68 func RepoInfoFromURL(u *url.URL) (host string, owner string, name string, err error) {
69 if u.Hostname() == "" {
70 return "", "", "", fmt.Errorf("no hostname detected")
71 }
72
73 parts := strings.SplitN(strings.Trim(u.Path, "/"), "/", 3)
74 if len(parts) != 2 {
75 return "", "", "", fmt.Errorf("invalid path: %s", u.Path)
76 }
77
78 return normalizeHostname(u.Hostname()), parts[0], strings.TrimSuffix(parts[1], ".git"), nil
79 }
80
81 func normalizeHostname(h string) string {
82 return strings.ToLower(strings.TrimPrefix(h, "www."))
83 }
84
View as plain text