forked from x-motemen/ghq
/
remote_repository.go
117 lines (93 loc) · 2.39 KB
/
remote_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
108
109
110
111
112
113
114
115
116
117
package main
import (
"fmt"
"net/url"
"regexp"
"strings"
"github.com/motemen/ghq/utils"
)
// A RemoteRepository represents a remote repository.
type RemoteRepository interface {
// The repository URL.
URL() *url.URL
// Checks if the URL is valid.
IsValid() bool
// The VCS backend that hosts the repository.
VCS() *VCSBackend
}
// A GitHubRepository represents a GitHub repository. Impliments RemoteRepository.
type GitHubRepository struct {
url *url.URL
}
func (repo *GitHubRepository) URL() *url.URL {
return repo.url
}
func (repo *GitHubRepository) IsValid() bool {
if strings.HasPrefix(repo.url.Path, "/blog/") {
return false
}
// must be /{user}/{project}/?
pathComponents := strings.Split(strings.TrimRight(repo.url.Path, "/"), "/")
if len(pathComponents) != 3 {
return false
}
return true
}
func (repo *GitHubRepository) VCS() *VCSBackend {
return GitBackend
}
type GoogleCodeRepository struct {
url *url.URL
}
func (repo *GoogleCodeRepository) URL() *url.URL {
return repo.url
}
var validGoogleCodePathPattern = regexp.MustCompile(`^/p/[^/]+/?$`)
func (repo *GoogleCodeRepository) IsValid() bool {
return validGoogleCodePathPattern.MatchString(repo.url.Path)
}
func (repo *GoogleCodeRepository) VCS() *VCSBackend {
if utils.RunSilently("hg", "identify", repo.url.String()) == nil {
return MercurialBackend
} else if utils.RunSilently("git", "ls-remote", repo.url.String()) == nil {
return GitBackend
} else {
return nil
}
}
type OtherRepository struct {
url *url.URL
}
func (repo *OtherRepository) URL() *url.URL {
return repo.url
}
func (repo *OtherRepository) IsValid() bool {
return true
}
func (repo *OtherRepository) VCS() *VCSBackend {
if utils.RunSilently("hg", "identify", repo.url.String()) == nil {
return MercurialBackend
} else if utils.RunSilently("git", "ls-remote", repo.url.String()) == nil {
return GitBackend
} else {
return nil
}
}
func NewRemoteRepository(url *url.URL) (RemoteRepository, error) {
if url.Host == "github.com" {
return &GitHubRepository{url}, nil
}
if url.Host == "code.google.com" {
return &GoogleCodeRepository{url}, nil
}
gheHosts, err := GitConfigAll("ghq.ghe.host")
if err != nil {
return nil, fmt.Errorf("failed to retrieve GH:E hostname from .gitconfig: %s", err)
}
for _, host := range gheHosts {
if url.Host == host {
return &GitHubRepository{url}, nil
}
}
return &OtherRepository{url}, nil
}