6
0
mirror of https://github.com/grdl/git-get.git synced 2026-02-04 17:24:49 +00:00

Handle scp-like syntax in URL parsing, add more tests

This commit is contained in:
Grzegorz Dlugoszewski
2020-05-22 08:52:08 +02:00
parent bb3a243829
commit 02e32a5543
2 changed files with 65 additions and 23 deletions

View File

@@ -1,28 +1,57 @@
package pkg
import (
"net/url"
urlpkg "net/url"
"path"
"regexp"
"strings"
"github.com/pkg/errors"
)
// TODO: maybe use https://github.com/whilp/git-urls?
// scpSyntax matches the SCP-like addresses used by the ssh procotol (eg, [user@]host.xz:path/to/repo.git/).
// See: https://golang.org/src/cmd/go/internal/get/vcs.go
var scpSyntax = regexp.MustCompile(`^([a-zA-Z0-9_]+)@([a-zA-Z0-9._-]+):(.*)$`)
func URLToPath(rawurl string) (string, error) {
parsed, err := url.Parse(rawurl)
url, err := parseURL(rawurl)
if err != nil {
return "", errors.Wrap(err, "Failed parsing URL")
return "", err
}
repoHost := strings.Split(parsed.Host, ":")[0]
// remove port numbers from host
repoHost := strings.Split(url.Host, ":")[0]
repoPath := parsed.Path
//repoPath = strings.TrimSuffix(repoPath, ".git/")
//repoPath = strings.TrimSuffix(repoPath, ".git")
localPath := path.Join(repoHost, repoPath)
// remove trailing ".git" from repo name
localPath := path.Join(repoHost, url.Path)
localPath = strings.TrimSuffix(localPath, ".git")
// remove tilde (~) char from username
localPath = strings.ReplaceAll(localPath, "~", "")
return localPath, nil
}
func parseURL(rawurl string) (url *urlpkg.URL, err error) {
// If rawurl matches SCP-like syntax, convert it into a URL.
// eg, "git@github.com:user/repo" becomes "ssh://git@github.com/user/repo".
if m := scpSyntax.FindStringSubmatch(rawurl); m != nil {
url = &urlpkg.URL{
Scheme: "ssh",
User: urlpkg.User(m[1]),
Host: m[2],
Path: m[3],
}
} else {
url, err = urlpkg.Parse(rawurl)
if err != nil {
return nil, errors.Wrap(err, "Failed parsing URL")
}
}
if url.Host == "" && url.Path == "" {
return nil, errors.New("Parsed URL is empty")
}
return url, nil
}

View File

@@ -19,18 +19,15 @@ func TestURLParse(t *testing.T) {
in string
want string
}{
{"ssh://github.com/grdl/git-get.git", "github.com/grdl/git-get"},
{"ssh://user@github.com/grdl/git-get.git", "github.com/grdl/git-get"},
{"ssh://user@github.com/~user/grdl/git-get.git", "github.com/~user/grdl/git-get"}, // TODO: is this what we want or should the result be github.com/grdl/git-get?
{"ssh://user@github.com:1234/grdl/git-get.git", "github.com/grdl/git-get"},
{"ssh://user@github.com/~user/grdl/git-get.git", "github.com/user/grdl/git-get"},
{"git+ssh://github.com/grdl/git-get.git", "github.com/grdl/git-get"},
{"git@github.com:grdl/git-get.git", "github.com/grdl/git-get"},
{"git@github.com:/~user/grdl/git-get.git", "github.com/grdl/git-get"},
{"https://github.com/grdl/git-get.git", "github.com/grdl/git-get"},
{"https://github.com/grdl/git-get.git", "github.com/grdl/git-get"},
{"https://github.com/grdl/git-get.git", "github.com/grdl/git-get"},
{"https://github.com/grdl/git-get.git", "github.com/grdl/git-get"},
{"git@github.com:/~user/grdl/git-get.git", "github.com/user/grdl/git-get"},
{"git://github.com/grdl/git-get.git", "github.com/grdl/git-get"},
{"git://github.com/~user/grdl/git-get.git", "github.com/user/grdl/git-get"},
{"https://github.com/grdl/git-get.git", "github.com/grdl/git-get"},
{"http://github.com/grdl/git-get.git", "github.com/grdl/git-get"},
{"https://github.com/grdl/git-get", "github.com/grdl/git-get"},
@@ -42,12 +39,11 @@ func TestURLParse(t *testing.T) {
{"https://github.com/grdl/git-get/", "github.com/grdl/git-get"},
{"https://github.com/grdl/git-get/////", "github.com/grdl/git-get"},
{"https://github.com/grdl/git-get.git/////", "github.com/grdl/git-get"},
{"ftp://github.com/grdl/git-get.git", "github.com/grdl/git-get"},
{"ftps://github.com/grdl/git-get.git", "github.com/grdl/git-get"},
{"rsync://github.com/grdl/git-get.git", "github.com/grdl/git-get"},
{"local/grdl/git-get/", "local/grdl/git-get"},
{"file://local/grdl/git-get", "local/grdl/git-get"},
{"https://github.com/grdl/git-get/////", "github.com/grdl/git-get"},
{"https://github.com/grdl/git-get/////", "github.com/grdl/git-get"},
{"https://github.com/grdl/git-get/////", "github.com/grdl/git-get"},
}
for _, test := range tests {
@@ -61,3 +57,20 @@ func TestURLParse(t *testing.T) {
}
}
}
func TestInvalidURLParse(t *testing.T) {
invalidURLs := []string{
"",
//TODO: This URL is technically a correct scp-like syntax. Not sure how to handle it
"github.com:grdl/git-git.get.git",
"git@github.com:1234:grdl/git-get.git",
}
for _, url := range invalidURLs {
got, err := URLToPath(url)
if err == nil {
t.Errorf("Wrong result of parsing invalid URL: %s, got: %s, want: error", url, got)
}
}
}