Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions generators/artifacthub/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,21 @@ func (pkg AhPackage) GenerateComponents(group string) ([]_component.ComponentDef
}
comp.Model.Metadata.AdditionalProperties["source_uri"] = pkg.ChartUrl
comp.Model.Version = pkg.Version
comp.Model.Name = pkg.Name

// Derive model from the CRD's API group when available; otherwise, fallback to package name
group := component.ExtractGroupFromAPIVersion(comp.Component.Version)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

It would be beneficial to add a comment explaining the purpose of extracting the group from the API version here. This will improve the code's readability and maintainability.

modelName, displayName := component.GroupToModel(group, pkg.Name)
if strings.TrimSpace(modelName) == "" {
modelName = pkg.Name
}
if strings.TrimSpace(displayName) == "" {
displayName = manifests.FormatToReadableString(modelName)
}
comp.Model.Name = modelName
comp.Model.Category = category.CategoryDefinition{
Name: "",
}
comp.Model.DisplayName = manifests.FormatToReadableString(comp.Model.Name)
comp.Model.DisplayName = displayName
components = append(components, comp)
}
return components, nil
Expand Down
16 changes: 14 additions & 2 deletions generators/github/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package github
import (
"bytes"
"os"
"strings"

"github.com/meshery/meshkit/utils"
"github.com/meshery/meshkit/utils/component"
Expand Down Expand Up @@ -81,11 +82,22 @@ func (gp GitHubPackage) GenerateComponents(group string) ([]_component.Component

comp.Model.Metadata.AdditionalProperties["source_uri"] = gp.SourceURL
comp.Model.Version = gp.version
comp.Model.Name = gp.Name

// Derive model from the CRD's API group when available; otherwise, fallback to package name
group := component.ExtractGroupFromAPIVersion(comp.Component.Version)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

It would be beneficial to add a comment explaining the purpose of extracting the group from the API version here. This will improve the code's readability and maintainability.

modelName, displayName := component.GroupToModel(group, gp.Name)
// Avoid empty names
if strings.TrimSpace(modelName) == "" {
modelName = gp.Name
}
if strings.TrimSpace(displayName) == "" {
displayName = manifests.FormatToReadableString(modelName)
}
comp.Model.Name = modelName
comp.Model.Category = category.CategoryDefinition{
Name: "",
}
comp.Model.DisplayName = manifests.FormatToReadableString(comp.Model.Name)
comp.Model.DisplayName = displayName
components = append(components, comp)
}

Expand Down
34 changes: 34 additions & 0 deletions utils/component/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/json"
"errors"
"fmt"
"strings"

"cuelang.org/go/cue"
"github.com/meshery/meshkit/utils"
Expand Down Expand Up @@ -58,6 +59,39 @@ var OpenAPISpecPathConfig = CuePathConfig{

var Configs = []CuePathConfig{DefaultPathConfig, DefaultPathConfig2}

// GroupToModel determines the model name and display name from a CRD/OpenAPI group value.
// - If group is non-empty, model name is the exact group (e.g., "monitor.azure.com").
// Display name is a title-cased, dot-separated host converted to words (e.g., "Monitor Azure Com").
// - If group is empty, fallbackName and its formatted variant are used.
func GroupToModel(group, fallbackName string) (modelName, displayName string) {
if strings.TrimSpace(group) != "" {
// Title case each dot-separated part and join with space for display name
parts := strings.Split(group, ".")
for i := range parts {
if parts[i] == "" {
continue
}
parts[i] = strings.ToUpper(parts[i][:1]) + strings.ToLower(parts[i][1:])
}
return group, strings.Join(parts, " ")
}
// Fallback: format and ensure leading character is capitalized for display
display := manifests.FormatToReadableString(fallbackName)
if display != "" {
display = strings.ToUpper(display[:1]) + display[1:]
}
return fallbackName, display
}

// ExtractGroupFromAPIVersion returns the API group from a k8s apiVersion string like "group/version".
// If apiVersion does not contain '/', it returns an empty string.
func ExtractGroupFromAPIVersion(apiVersion string) string {
if strings.Contains(apiVersion, "/") {
return strings.SplitN(apiVersion, "/", 2)[0]
}
return ""
}

func IncludeComponentBasedOnGroup(resource string, groupFilter string) (bool, error) {
if groupFilter == "" {
return true, nil
Expand Down
45 changes: 45 additions & 0 deletions utils/component/generator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,3 +155,48 @@ func TestGenerate(t *testing.T) {
})
}
}

func TestGroupToModel(t *testing.T) {
cases := []struct {
name string
group string
fallback string
expectName string
expectDisplay string
}{
{
name: "with group",
group: "monitor.azure.com",
fallback: "ignored",
expectName: "monitor.azure.com",
expectDisplay: "Monitor Azure Com",
},
{
name: "empty group uses fallback",
group: "",
fallback: "fooBarBaz",
expectName: "fooBarBaz",
expectDisplay: "Foo Bar Baz",
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
name, display := GroupToModel(tc.group, tc.fallback)
if name != tc.expectName {
t.Fatalf("expected model name '%s', got '%s'", tc.expectName, name)
}
if display != tc.expectDisplay {
t.Fatalf("expected display name '%s', got '%s'", tc.expectDisplay, display)
}
})
}
}

func TestExtractGroupFromAPIVersion(t *testing.T) {
if g := ExtractGroupFromAPIVersion("apps/v1"); g != "apps" {
t.Fatalf("expected 'apps', got '%s'", g)
}
if g := ExtractGroupFromAPIVersion("v1"); g != "" {
t.Fatalf("expected '', got '%s'", g)
}
}
11 changes: 9 additions & 2 deletions utils/component/openapi_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,13 @@ func GenerateFromOpenAPI(resource string, pkg models.Package) ([]component.Compo
}
}

// Decide model name/display based on group when present
modelName := pkg.GetName()
displayModelName := manifests.FormatToReadableString(pkg.GetName())
if g, _ := groupCue.String(); g != "" {
modelName, displayModelName = GroupToModel(g, pkg.GetName())
}

c := component.ComponentDefinition{
SchemaVersion: v1beta1.ComponentSchemaVersion,
Format: component.JSON,
Expand All @@ -138,8 +145,8 @@ func GenerateFromOpenAPI(resource string, pkg models.Package) ([]component.Compo
Model: model.Model{
Version: pkg.GetVersion(),
},
Name: pkg.GetName(),
DisplayName: manifests.FormatToReadableString(pkg.GetName()),
Name: modelName,
DisplayName: displayModelName,
Metadata: &model.ModelDefinition_Metadata{
AdditionalProperties: map[string]interface{}{
"source_uri": pkg.GetSourceURL(),
Expand Down