diff --git a/pkg/url.go b/pkg/url.go new file mode 100644 index 0000000..fce8980 --- /dev/null +++ b/pkg/url.go @@ -0,0 +1,28 @@ +package pkg + +import ( + "net/url" + "path" + "strings" + + "github.com/pkg/errors" +) + +// TODO: maybe use https://github.com/whilp/git-urls? + +func URLToPath(rawurl string) (string, error) { + parsed, err := url.Parse(rawurl) + if err != nil { + return "", errors.Wrap(err, "Failed parsing URL") + } + + repoHost := strings.Split(parsed.Host, ":")[0] + + repoPath := parsed.Path + //repoPath = strings.TrimSuffix(repoPath, ".git/") + //repoPath = strings.TrimSuffix(repoPath, ".git") + + localPath := path.Join(repoHost, repoPath) + localPath = strings.TrimSuffix(localPath, ".git") + return localPath, nil +} diff --git a/pkg/url_test.go b/pkg/url_test.go new file mode 100644 index 0000000..a283cb0 --- /dev/null +++ b/pkg/url_test.go @@ -0,0 +1,63 @@ +package pkg + +import "testing" + +// Following URLs are considered valid according to https://git-scm.com/docs/git-clone#_git_urls: +// ssh://[user@]host.xz[:port]/path/to/repo.git +// ssh://[user@]host.xz[:port]/~[user]/path/to/repo.git/ +// [user@]host.xz:path/to/repo.git/ +// [user@]host.xz:/~[user]/path/to/repo.git/ +// git://host.xz[:port]/path/to/repo.git/ +// git://host.xz[:port]/~[user]/path/to/repo.git/ +// http[s]://host.xz[:port]/path/to/repo.git/ +// ftp[s]://host.xz[:port]/path/to/repo.git/ +// /path/to/repo.git/ +// file:///path/to/repo.git/ + +func TestURLParse(t *testing.T) { + tests := []struct { + 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? + {"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"}, + + {"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"}, + {"https://github.com/git-get.git", "github.com/git-get"}, + {"https://github.com/git-get", "github.com/git-get"}, + {"https://github.com/grdl/sub/path/git-get.git", "github.com/grdl/sub/path/git-get"}, + {"https://github.com:1234/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/", "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"}, + + {"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 { + got, err := URLToPath(test.in) + if err != nil { + t.Errorf("Error parsing URL: %+v", err) + } + + if got != test.want { + t.Errorf("Wrong result of parsing URL: %s, got: %s; want: %s", test.in, got, test.want) + } + } +}