From f56336220f6ac9b5647980953fe6df8bb53ae01e Mon Sep 17 00:00:00 2001 From: Jeremy Stribling Date: Fri, 8 Feb 2019 11:28:24 -0800 Subject: config: add a way to see if a "remote" URL is local or not This factors out some URL-parsing code from the transport layer so it can be used by config as well. Issue: #909 Signed-off-by: Jeremy Stribling --- config/config.go | 5 +++++ internal/url/url.go | 37 +++++++++++++++++++++++++++++++++++++ plumbing/transport/common.go | 22 ++++++++-------------- 3 files changed, 50 insertions(+), 14 deletions(-) create mode 100644 internal/url/url.go diff --git a/config/config.go b/config/config.go index a637f6d..2c3b8b9 100644 --- a/config/config.go +++ b/config/config.go @@ -8,6 +8,7 @@ import ( "sort" "strconv" + "gopkg.in/src-d/go-git.v4/internal/url" format "gopkg.in/src-d/go-git.v4/plumbing/format/config" ) @@ -399,3 +400,7 @@ func (c *RemoteConfig) marshal() *format.Subsection { return c.raw } + +func (c *RemoteConfig) IsFirstURLLocal() bool { + return url.IsLocalEndpoint(c.URLs[0]) +} diff --git a/internal/url/url.go b/internal/url/url.go new file mode 100644 index 0000000..0f0d709 --- /dev/null +++ b/internal/url/url.go @@ -0,0 +1,37 @@ +package url + +import ( + "regexp" +) + +var ( + isSchemeRegExp = regexp.MustCompile(`^[^:]+://`) + scpLikeUrlRegExp = regexp.MustCompile(`^(?:(?P[^@]+)@)?(?P[^:\s]+):(?:(?P[0-9]{1,5})/)?(?P[^\\].*)$`) +) + +// MatchesScheme returns true if the given string matches a URL-like +// format scheme. +func MatchesScheme(url string) bool { + return isSchemeRegExp.MatchString(url) +} + +// MatchesScpLike returns true if the given string matches an SCP-like +// format scheme. +func MatchesScpLike(url string) bool { + return scpLikeUrlRegExp.MatchString(url) +} + +// FindScpLikeComponents returns the user, host, port and path of the +// given SCP-like URL. +func FindScpLikeComponents(url string) (user, host, port, path string) { + m := scpLikeUrlRegExp.FindStringSubmatch(url) + return m[1], m[2], m[3], m[4] +} + +// IsLocalEndpoint returns true if the given URL string specifies a +// local file endpoint. For example, on a Linux machine, +// `/home/user/src/go-git` would match as a local endpoint, but +// `https://github.com/src-d/go-git` would not. +func IsLocalEndpoint(url string) bool { + return !MatchesScheme(url) && !MatchesScpLike(url) +} diff --git a/plumbing/transport/common.go b/plumbing/transport/common.go index f7b882b..dcf9391 100644 --- a/plumbing/transport/common.go +++ b/plumbing/transport/common.go @@ -19,10 +19,10 @@ import ( "fmt" "io" "net/url" - "regexp" "strconv" "strings" + giturl "gopkg.in/src-d/go-git.v4/internal/url" "gopkg.in/src-d/go-git.v4/plumbing" "gopkg.in/src-d/go-git.v4/plumbing/protocol/packp" "gopkg.in/src-d/go-git.v4/plumbing/protocol/packp/capability" @@ -224,34 +224,28 @@ func getPath(u *url.URL) string { return res } -var ( - isSchemeRegExp = regexp.MustCompile(`^[^:]+://`) - scpLikeUrlRegExp = regexp.MustCompile(`^(?:(?P[^@]+)@)?(?P[^:\s]+):(?:(?P[0-9]{1,5})/)?(?P[^\\].*)$`) -) - func parseSCPLike(endpoint string) (*Endpoint, bool) { - if isSchemeRegExp.MatchString(endpoint) || !scpLikeUrlRegExp.MatchString(endpoint) { + if giturl.MatchesScheme(endpoint) || !giturl.MatchesScpLike(endpoint) { return nil, false } - m := scpLikeUrlRegExp.FindStringSubmatch(endpoint) - - port, err := strconv.Atoi(m[3]) + user, host, portStr, path := giturl.FindScpLikeComponents(endpoint) + port, err := strconv.Atoi(portStr) if err != nil { port = 22 } return &Endpoint{ Protocol: "ssh", - User: m[1], - Host: m[2], + User: user, + Host: host, Port: port, - Path: m[4], + Path: path, }, true } func parseFile(endpoint string) (*Endpoint, bool) { - if isSchemeRegExp.MatchString(endpoint) { + if giturl.MatchesScheme(endpoint) { return nil, false } -- cgit