You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
72 lines
1.7 KiB
Go
72 lines
1.7 KiB
Go
package gitutil
|
|
|
|
import (
|
|
"net/url"
|
|
"regexp"
|
|
"strings"
|
|
|
|
"github.com/moby/buildkit/util/sshutil"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
const (
|
|
HTTPProtocol string = "http"
|
|
HTTPSProtocol string = "https"
|
|
SSHProtocol string = "ssh"
|
|
GitProtocol string = "git"
|
|
)
|
|
|
|
var (
|
|
ErrUnknownProtocol = errors.New("unknown protocol")
|
|
ErrInvalidProtocol = errors.New("invalid protocol")
|
|
)
|
|
|
|
var supportedProtos = map[string]struct{}{
|
|
HTTPProtocol: {},
|
|
HTTPSProtocol: {},
|
|
SSHProtocol: {},
|
|
GitProtocol: {},
|
|
}
|
|
|
|
var protoRegexp = regexp.MustCompile(`^[a-zA-Z0-9]+://`)
|
|
|
|
// ParseURL parses a git URL and returns a parsed URL object.
|
|
//
|
|
// ParseURL understands implicit ssh URLs such as "git@host:repo", and
|
|
// returns the same response as if the URL were "ssh://git@host/repo".
|
|
func ParseURL(remote string) (*url.URL, error) {
|
|
if proto := protoRegexp.FindString(remote); proto != "" {
|
|
proto = strings.ToLower(strings.TrimSuffix(proto, "://"))
|
|
if _, ok := supportedProtos[proto]; !ok {
|
|
return nil, errors.Wrap(ErrInvalidProtocol, proto)
|
|
}
|
|
|
|
return url.Parse(remote)
|
|
}
|
|
|
|
if sshutil.IsImplicitSSHTransport(remote) {
|
|
remote, fragment, _ := strings.Cut(remote, "#")
|
|
remote, path, _ := strings.Cut(remote, ":")
|
|
user, host, _ := strings.Cut(remote, "@")
|
|
if !strings.HasPrefix(path, "/") {
|
|
path = "/" + path
|
|
}
|
|
return &url.URL{
|
|
Scheme: SSHProtocol,
|
|
User: url.User(user),
|
|
Host: host,
|
|
Path: path,
|
|
Fragment: fragment,
|
|
}, nil
|
|
}
|
|
|
|
return nil, ErrUnknownProtocol
|
|
}
|
|
|
|
// SplitGitFragments splits a git URL fragment into its respective git
|
|
// reference and subdirectory components.
|
|
func SplitGitFragment(fragment string) (ref string, subdir string) {
|
|
ref, subdir, _ = strings.Cut(fragment, ":")
|
|
return ref, subdir
|
|
}
|