提交 8860670e 编写于 作者: M Mislav Marohnić

Resolve SSH host aliases by reading from `~/.ssh/config`

This allows someone to have something like this in their SSH config:

    Host gh
      HostName github.com

And then use git remote URLs such as:

    gh:myname/myrepo.git

Since git itself allows people to do this, we need to support it in hub.
上级 3e79a4eb
package git
import (
"fmt"
"bufio"
"net/url"
"os"
"path/filepath"
"regexp"
"strings"
)
var (
ProtocolRe = regexp.MustCompile("^[a-zA-Z_-]+://")
SshConfigFiles = []string{
filepath.Join(os.Getenv("HOME"), ".ssh/config"),
"/etc/ssh_config",
"/etc/ssh/ssh_config",
}
SshConfig map[string]string
)
func ParseURL(rawurl string) (u *url.URL, err error) {
sshGitRegexp := regexp.MustCompile(`(.+)@(.+):(.+)(\.git)?`)
if sshGitRegexp.MatchString(rawurl) {
match := sshGitRegexp.FindStringSubmatch(rawurl)
user := match[1]
host := match[2]
path := match[3]
ext := match[4]
rawurl = fmt.Sprintf("ssh://%s@%s/%s%s", user, host, path, ext)
if !ProtocolRe.MatchString(rawurl) && strings.Contains(rawurl, ":") {
rawurl = "ssh://" + strings.Replace(rawurl, ":", "/", 1)
}
u, err = url.Parse(rawurl)
if err == nil {
if SshConfig == nil {
SshConfig = readSshConfig()
}
if SshConfig[u.Host] != "" {
u.Host = SshConfig[u.Host]
}
}
return
}
func readSshConfig() map[string]string {
config := make(map[string]string)
hostRe := regexp.MustCompile("^[ \t]*(Host|HostName)[ \t]+(.+)$")
for _, filename := range SshConfigFiles {
file, err := os.Open(filename)
if err != nil {
continue
}
hosts := []string{"*"}
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
match := hostRe.FindStringSubmatch(line)
if match == nil {
continue
}
names := strings.Fields(match[2])
if match[1] == "Host" {
hosts = names
} else {
for _, host := range hosts {
for _, name := range names {
config[host] = name
}
}
}
}
file.Close()
}
return url.Parse(rawurl)
return config
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册