6
0
mirror of https://github.com/grdl/git-get.git synced 2026-02-10 23:39:14 +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 package pkg
import ( import (
"net/url" urlpkg "net/url"
"path" "path"
"regexp"
"strings" "strings"
"github.com/pkg/errors" "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) { func URLToPath(rawurl string) (string, error) {
parsed, err := url.Parse(rawurl) url, err := parseURL(rawurl)
if err != nil { 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 // remove trailing ".git" from repo name
//repoPath = strings.TrimSuffix(repoPath, ".git/") localPath := path.Join(repoHost, url.Path)
//repoPath = strings.TrimSuffix(repoPath, ".git")
localPath := path.Join(repoHost, repoPath)
localPath = strings.TrimSuffix(localPath, ".git") localPath = strings.TrimSuffix(localPath, ".git")
// remove tilde (~) char from username
localPath = strings.ReplaceAll(localPath, "~", "")
return localPath, nil 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 in string
want string want string
}{ }{
{"ssh://github.com/grdl/git-get.git", "github.com/grdl/git-get"}, {"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/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:grdl/git-get.git", "github.com/grdl/git-get"},
{"git@github.com:/~user/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"},
{"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"},
{"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"}, {"https://github.com/grdl/git-get.git", "github.com/grdl/git-get"},
{"http://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"}, {"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/////", "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"}, {"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"}, {"local/grdl/git-get/", "local/grdl/git-get"},
{"file://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 { 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)
}
}
}