From c58af0bf38c785256e5cca9b4e8ac3f79102d5dc Mon Sep 17 00:00:00 2001
From: Christoph Witzko <github@christophwitzko.com>
Date: Mon, 30 May 2022 20:36:05 +0200
Subject: [PATCH] feat: add slug to plugin info

---
 pkg/plugin/plugin.go      | 28 ++++++++++++++++++++--------
 pkg/plugin/plugin_test.go | 20 ++++++++++++++++++++
 2 files changed, 40 insertions(+), 8 deletions(-)

diff --git a/pkg/plugin/plugin.go b/pkg/plugin/plugin.go
index aaa7641..750051d 100644
--- a/pkg/plugin/plugin.go
+++ b/pkg/plugin/plugin.go
@@ -20,6 +20,7 @@ type PluginInfo struct {
 	ShortNormalizedName string
 	Constraint          *semver.Constraints
 	Resolver            string
+	RepoSlug            string
 	PluginPath          string
 	BinPath             string
 }
@@ -42,14 +43,17 @@ func normalizedPluginType(t string) string {
 	return ""
 }
 
+var nameNormalizer = strings.NewReplacer(":", "-", "/", "-")
+
 func GetPluginInfo(pluginType, pluginName string) (*PluginInfo, error) {
 	nPluginType := normalizedPluginType(pluginType)
 	if nPluginType == "" {
 		return nil, fmt.Errorf("invalid plugin type: %s", pluginType)
 	}
 	resolver := "default"
+	repoSlug := ""
 	name := pluginName
-	normalizedName := fmt.Sprintf("%s-%s", nPluginType, pluginName)
+	normalizedName := nameNormalizer.Replace(fmt.Sprintf("%s-%s", nPluginType, pluginName))
 
 	if strings.Contains(name, ":") {
 		parts := strings.Split(name, ":")
@@ -58,16 +62,20 @@ func GetPluginInfo(pluginType, pluginName string) (*PluginInfo, error) {
 		}
 		resolver = parts[0]
 		name = parts[1]
-		normalizedName = strings.ReplaceAll(normalizedName, ":", "-")
 	}
 
 	if strings.Contains(name, "/") {
-		parts := strings.Split(name, "/")
-		if len(parts) != 2 {
-			return nil, fmt.Errorf("invalid plugin name format")
+		slashParts := strings.Split(name, "/")
+		pName := slashParts[len(slashParts)-1]
+		// remove version constraint from the slug
+		if strings.Contains(pName, "@") {
+			nameWithoutVersion, _, _ := strings.Cut(pName, "@")
+			repoSlug = strings.Join(slashParts[:len(slashParts)-1], "/") + "/" + nameWithoutVersion
+		} else {
+			repoSlug = name
 		}
-		name = parts[1]
-		normalizedName = strings.ReplaceAll(normalizedName, "/", "-")
+		// the last part is the plugin name
+		name = pName
 	}
 
 	var constraint *semver.Constraints
@@ -82,7 +90,10 @@ func GetPluginInfo(pluginType, pluginName string) (*PluginInfo, error) {
 		}
 		name = parts[0]
 		constraint = v
-		normalizedName, _, _ = strings.Cut(normalizedName, "@")
+
+		// remove version constraint from the normalized name
+		normalizedParts := strings.Split(normalizedName, "@")
+		normalizedName = strings.Join(normalizedParts[:len(normalizedParts)-1], "@")
 	}
 
 	return &PluginInfo{
@@ -92,5 +103,6 @@ func GetPluginInfo(pluginType, pluginName string) (*PluginInfo, error) {
 		ShortNormalizedName: fmt.Sprintf("%s-%s", nPluginType, name),
 		Constraint:          constraint,
 		Resolver:            resolver,
+		RepoSlug:            repoSlug,
 	}, nil
 }
diff --git a/pkg/plugin/plugin_test.go b/pkg/plugin/plugin_test.go
index 1b70a11..f591f88 100644
--- a/pkg/plugin/plugin_test.go
+++ b/pkg/plugin/plugin_test.go
@@ -32,6 +32,7 @@ func TestGetPluginInfo(t *testing.T) {
 			NormalizedName:      "provider-github-myorg-myplugin",
 			ShortNormalizedName: "provider-myplugin",
 			Resolver:            "github",
+			RepoSlug:            "myorg/myplugin",
 		}},
 		{"ci_condition", "github:myorg/myplugin", &PluginInfo{
 			Type:                "ci_condition",
@@ -39,6 +40,7 @@ func TestGetPluginInfo(t *testing.T) {
 			NormalizedName:      "condition-github-myorg-myplugin",
 			ShortNormalizedName: "condition-myplugin",
 			Resolver:            "github",
+			RepoSlug:            "myorg/myplugin",
 		}},
 		{"provider", "github:myorg/myplugin@^1.0.0", &PluginInfo{
 			Type:                "provider",
@@ -46,6 +48,7 @@ func TestGetPluginInfo(t *testing.T) {
 			NormalizedName:      "provider-github-myorg-myplugin",
 			ShortNormalizedName: "provider-myplugin",
 			Resolver:            "github",
+			RepoSlug:            "myorg/myplugin",
 			Constraint:          parseConstraint("^1.0.0"),
 		}},
 		{"provider", "git@2.0.0", &PluginInfo{
@@ -63,6 +66,23 @@ func TestGetPluginInfo(t *testing.T) {
 			ShortNormalizedName: "hooks-logger",
 			Resolver:            "registry",
 		}},
+		{"hooks", "myresolver:@myorg/myplugin", &PluginInfo{
+			Type:                "hooks",
+			Name:                "myplugin",
+			NormalizedName:      "hooks-myresolver-@myorg-myplugin",
+			ShortNormalizedName: "hooks-myplugin",
+			Resolver:            "myresolver",
+			RepoSlug:            "@myorg/myplugin",
+		}},
+		{"hooks", "myresolver:@myorg/myplugin@1.2.3", &PluginInfo{
+			Type:                "hooks",
+			Name:                "myplugin",
+			NormalizedName:      "hooks-myresolver-@myorg-myplugin",
+			ShortNormalizedName: "hooks-myplugin",
+			Resolver:            "myresolver",
+			RepoSlug:            "@myorg/myplugin",
+			Constraint:          parseConstraint("1.2.3"),
+		}},
 	}
 	for _, testCase := range testCases {
 		results, err := GetPluginInfo(testCase.t, testCase.input)
-- 
GitLab