101 lines
1.9 KiB
Go
101 lines
1.9 KiB
Go
package github
|
|
|
|
import (
|
|
"fmt"
|
|
"net/url"
|
|
"regexp"
|
|
"strings"
|
|
|
|
"github.com/github/gh-cli/git"
|
|
)
|
|
|
|
var (
|
|
OriginNamesInLookupOrder = []string{"upstream", "github", "origin"}
|
|
)
|
|
|
|
type Remote struct {
|
|
Name string
|
|
URL *url.URL
|
|
PushURL *url.URL
|
|
}
|
|
|
|
func (remote *Remote) String() string {
|
|
return remote.Name
|
|
}
|
|
|
|
func (remote *Remote) Project() (*Project, error) {
|
|
p, err := NewProjectFromURL(remote.URL)
|
|
if _, ok := err.(*GithubHostError); ok {
|
|
return NewProjectFromURL(remote.PushURL)
|
|
}
|
|
return p, err
|
|
}
|
|
|
|
func Remotes() (remotes []Remote, err error) {
|
|
re := regexp.MustCompile(`(.+)\s+(.+)\s+\((push|fetch)\)`)
|
|
|
|
rs, err := git.Remotes()
|
|
if err != nil {
|
|
err = fmt.Errorf("Can't load git remote")
|
|
return
|
|
}
|
|
|
|
// build the remotes map
|
|
remotesMap := make(map[string]map[string]string)
|
|
for _, r := range rs {
|
|
if re.MatchString(r) {
|
|
match := re.FindStringSubmatch(r)
|
|
name := strings.TrimSpace(match[1])
|
|
url := strings.TrimSpace(match[2])
|
|
urlType := strings.TrimSpace(match[3])
|
|
utm, ok := remotesMap[name]
|
|
if !ok {
|
|
utm = make(map[string]string)
|
|
remotesMap[name] = utm
|
|
}
|
|
utm[urlType] = url
|
|
}
|
|
}
|
|
|
|
// construct remotes in priority order
|
|
names := OriginNamesInLookupOrder
|
|
for _, name := range names {
|
|
if u, ok := remotesMap[name]; ok {
|
|
r, err := newRemote(name, u)
|
|
if err == nil {
|
|
remotes = append(remotes, r)
|
|
delete(remotesMap, name)
|
|
}
|
|
}
|
|
}
|
|
|
|
// the rest of the remotes
|
|
for n, u := range remotesMap {
|
|
r, err := newRemote(n, u)
|
|
if err == nil {
|
|
remotes = append(remotes, r)
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func newRemote(name string, urlMap map[string]string) (Remote, error) {
|
|
r := Remote{}
|
|
|
|
fetchURL, ferr := git.ParseURL(urlMap["fetch"])
|
|
pushURL, perr := git.ParseURL(urlMap["push"])
|
|
if ferr != nil && perr != nil {
|
|
return r, fmt.Errorf("No valid remote URLs")
|
|
}
|
|
|
|
r.Name = name
|
|
if ferr == nil {
|
|
r.URL = fetchURL
|
|
}
|
|
if perr == nil {
|
|
r.PushURL = pushURL
|
|
}
|
|
|
|
return r, nil
|
|
}
|