fix `kratos new -r` not support scp styled git url.issue https://gith… (#2295)
* fix `kratos new -r` not support scp styled git url.issue https://github.com/go-kratos/kratos/issues/2294 * fix lint * fix lint * remove tail space and add test case Co-authored-by: czyt <czyt@w.cn> Co-authored-by: czyt <x-gopher@qq.com>pull/2312/head
parent
890bc21ac1
commit
20c2425c18
@ -0,0 +1,58 @@ |
|||||||
|
package base |
||||||
|
|
||||||
|
import ( |
||||||
|
"errors" |
||||||
|
"net/url" |
||||||
|
"regexp" |
||||||
|
"strings" |
||||||
|
) |
||||||
|
|
||||||
|
var ( |
||||||
|
scpSyntaxRe = regexp.MustCompile(`^([a-zA-Z0-9_]+)@([a-zA-Z0-9._-]+):(.*)$`) |
||||||
|
scheme = []string{"git", "https", "http", "git+ssh", "ssh", "file", "ftp", "ftps"} |
||||||
|
) |
||||||
|
|
||||||
|
// ParseVCSUrl ref https://github.com/golang/go/blob/master/src/cmd/go/internal/vcs/vcs.go
|
||||||
|
// see https://go-review.googlesource.com/c/go/+/12226/
|
||||||
|
// git url define https://git-scm.com/docs/git-clone#_git_urls
|
||||||
|
func ParseVCSUrl(repo string) (*url.URL, error) { |
||||||
|
var ( |
||||||
|
repoURL *url.URL |
||||||
|
err error |
||||||
|
) |
||||||
|
|
||||||
|
if m := scpSyntaxRe.FindStringSubmatch(repo); m != nil { |
||||||
|
// Match SCP-like syntax and convert it to a URL.
|
||||||
|
// Eg, "git@github.com:user/repo" becomes
|
||||||
|
// "ssh://git@github.com/user/repo".
|
||||||
|
repoURL = &url.URL{ |
||||||
|
Scheme: "ssh", |
||||||
|
User: url.User(m[1]), |
||||||
|
Host: m[2], |
||||||
|
Path: m[3], |
||||||
|
} |
||||||
|
} else { |
||||||
|
if !strings.Contains(repo, "//") { |
||||||
|
repo = "//" + repo |
||||||
|
} |
||||||
|
if strings.HasPrefix(repo, "//git@") { |
||||||
|
repo = "ssh:" + repo |
||||||
|
} else if strings.HasPrefix(repo, "//") { |
||||||
|
repo = "https:" + repo |
||||||
|
} |
||||||
|
repoURL, err = url.Parse(repo) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Iterate over insecure schemes too, because this function simply
|
||||||
|
// reports the state of the repo. If we can't see insecure schemes then
|
||||||
|
// we can't report the actual repo URL.
|
||||||
|
for _, s := range scheme { |
||||||
|
if repoURL.Scheme == s { |
||||||
|
return repoURL, nil |
||||||
|
} |
||||||
|
} |
||||||
|
return nil, errors.New("unable to parse repo url") |
||||||
|
} |
@ -0,0 +1,55 @@ |
|||||||
|
package base |
||||||
|
|
||||||
|
import ( |
||||||
|
"net" |
||||||
|
"strings" |
||||||
|
"testing" |
||||||
|
) |
||||||
|
|
||||||
|
func TestParseVCSUrl(t *testing.T) { |
||||||
|
repos := []string{ |
||||||
|
// ssh://[user@]host.xz[:port]/path/to/repo.git/
|
||||||
|
"ssh://git@github.com:7875/go-kratos/kratos.git", |
||||||
|
// git://host.xz[:port]/path/to/repo.git/
|
||||||
|
"git://github.com:7875/go-kratos/kratos.git", |
||||||
|
// http[s]://host.xz[:port]/path/to/repo.git/
|
||||||
|
"https://github.com:7875/go-kratos/kratos.git", |
||||||
|
// ftp[s]://host.xz[:port]/path/to/repo.git/
|
||||||
|
"ftps://github.com:7875/go-kratos/kratos.git", |
||||||
|
//[user@]host.xz:path/to/repo.git/
|
||||||
|
"git@github.com:go-kratos/kratos.git", |
||||||
|
// ssh://[user@]host.xz[:port]/~[user]/path/to/repo.git/
|
||||||
|
"ssh://git@github.com:7875/go-kratos/kratos.git", |
||||||
|
// git://host.xz[:port]/~[user]/path/to/repo.git/
|
||||||
|
"git://github.com:7875/go-kratos/kratos.git", |
||||||
|
//[user@]host.xz:/~[user]/path/to/repo.git/
|
||||||
|
"git@github.com:go-kratos/kratos.git", |
||||||
|
///path/to/repo.git/
|
||||||
|
"~/go-kratos/kratos.git", |
||||||
|
// file:///path/to/repo.git/
|
||||||
|
"file://~/go-kratos/kratos.git", |
||||||
|
} |
||||||
|
for _, repo := range repos { |
||||||
|
url, err := ParseVCSUrl(repo) |
||||||
|
if err != nil { |
||||||
|
t.Fatal(repo, err) |
||||||
|
} |
||||||
|
urlPath := strings.TrimLeft(url.Path, "/") |
||||||
|
if urlPath != "go-kratos/kratos.git" { |
||||||
|
t.Fatal(repo, "parse url failed", urlPath) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func TestParseSsh(t *testing.T) { |
||||||
|
repo := "ssh://git@github.com:7875/go-kratos/kratos.git" |
||||||
|
url, err := ParseVCSUrl(repo) |
||||||
|
if err != nil { |
||||||
|
t.Fatal(err) |
||||||
|
} |
||||||
|
host, _, err := net.SplitHostPort(url.Host) |
||||||
|
if err != nil { |
||||||
|
host = url.Host |
||||||
|
} |
||||||
|
t.Log(host, url.Path) |
||||||
|
} |
Loading…
Reference in new issue