telemetry: Normalize git URLs
Normalize `https://github.com/dagger/dagger` and `git@github.com:dagger/dagger.git` to `github.com/dagger/dagger` Signed-off-by: Andrea Luzzardi <aluzzardi@gmail.com>
This commit is contained in:
parent
fead547df1
commit
f7628adee5
65
telemetry/git.go
Normal file
65
telemetry/git.go
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
package telemetry
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
urlSchemeRegExp = regexp.MustCompile(`^[^:]+://`)
|
||||||
|
scpLikeURLRegExp = regexp.MustCompile(`^(?:(?P<user>[^@]+)@)?(?P<host>[^:\s]+):(?:(?P<port>[0-9]{1,5})(?:\/|:))?(?P<path>[^\\].*\/[^\\].*)$`)
|
||||||
|
)
|
||||||
|
|
||||||
|
func parseGitURL(endpoint string) (string, error) {
|
||||||
|
if e, ok := parseSCPLike(endpoint); ok {
|
||||||
|
return e, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return parseURL(endpoint)
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseURL(endpoint string) (string, error) {
|
||||||
|
u, err := url.Parse(endpoint)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !u.IsAbs() {
|
||||||
|
return "", fmt.Errorf(
|
||||||
|
"invalid endpoint: %s", endpoint,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("%s%s", u.Hostname(), u.Path), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseSCPLike(endpoint string) (string, bool) {
|
||||||
|
if matchesURLScheme(endpoint) || !matchesScpLike(endpoint) {
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
|
||||||
|
_, host, _, path := findScpLikeComponents(endpoint)
|
||||||
|
|
||||||
|
return fmt.Sprintf("%s/%s", host, strings.TrimSuffix(path, ".git")), true
|
||||||
|
}
|
||||||
|
|
||||||
|
// matchesURLScheme returns true if the given string matches a URL-like
|
||||||
|
// format scheme.
|
||||||
|
func matchesURLScheme(url string) bool {
|
||||||
|
return urlSchemeRegExp.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]
|
||||||
|
}
|
22
telemetry/git_test.go
Normal file
22
telemetry/git_test.go
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package telemetry
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestParseGit(t *testing.T) {
|
||||||
|
var (
|
||||||
|
endpoint string
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
endpoint, err = parseGitURL("https://github.com/dagger/dagger")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, endpoint, "github.com/dagger/dagger")
|
||||||
|
|
||||||
|
endpoint, err = parseGitURL("git@github.com:dagger/dagger.git")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, endpoint, "github.com/dagger/dagger")
|
||||||
|
}
|
@ -50,7 +50,7 @@ func Track(ctx context.Context, eventName string, properties ...*Property) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
repo := gitRepoURL(".")
|
repo := gitRepoURL(ctx, ".")
|
||||||
|
|
||||||
// Base properties
|
// Base properties
|
||||||
props := map[string]interface{}{
|
props := map[string]interface{}{
|
||||||
@ -194,8 +194,8 @@ func hash(s string) string {
|
|||||||
return fmt.Sprintf("%x", sha256.Sum256([]byte(s)))
|
return fmt.Sprintf("%x", sha256.Sum256([]byte(s)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// // gitRepoURL returns the git repository remote, if any.
|
// gitRepoURL returns the git repository remote, if any.
|
||||||
func gitRepoURL(path string) string {
|
func gitRepoURL(ctx context.Context, path string) string {
|
||||||
repo, err := git.PlainOpenWithOptions(path, &git.PlainOpenOptions{
|
repo, err := git.PlainOpenWithOptions(path, &git.PlainOpenOptions{
|
||||||
DetectDotGit: true,
|
DetectDotGit: true,
|
||||||
})
|
})
|
||||||
@ -208,9 +208,16 @@ func gitRepoURL(path string) string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
if urls := origin.Config().URLs; len(urls) > 0 {
|
urls := origin.Config().URLs
|
||||||
return urls[0]
|
if len(urls) == 0 {
|
||||||
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
return ""
|
endpoint, err := parseGitURL(urls[0])
|
||||||
|
if err != nil {
|
||||||
|
log.Ctx(ctx).Debug().Err(err).Str("url", urls[0]).Msg("failed to parse git URL")
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return endpoint
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user