Skip to content

Commit

Permalink
feat: generate property documentation for resources
Browse files Browse the repository at this point in the history
  • Loading branch information
ekristen committed Apr 14, 2024
1 parent 0ebff99 commit c1c6eff
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 0 deletions.
75 changes: 75 additions & 0 deletions pkg/docs/generate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package docs

import (
"fmt"
"reflect"
"strings"
)

func GeneratePropertiesMap(data interface{}) map[string]string {
properties := map[string]string{}

v := reflect.ValueOf(data)
if v.Kind() == reflect.Ptr {
v = v.Elem()
}
t := v.Type()

for i := 0; i < t.NumField(); i++ {
field := t.Field(i)

if !field.IsExported() {
continue
}

propertyTag := field.Tag.Get("property")
options := strings.Split(propertyTag, ",")
name := field.Name
prefix := ""

if options[0] == "-" {
continue
}

for _, option := range options {
parts := strings.Split(option, "=")
if len(parts) != 2 {
continue
}
switch parts[0] {
case "name":
name = parts[1]
case "prefix":
prefix = parts[1]
}
}

if prefix != "" && name != "Tags" {
name = fmt.Sprintf("%s:%s", prefix, name)
}

descriptionTag := field.Tag.Get("description")

if name == "Tags" {
originalName := name
name = "tag:<key>:"
tagPrefix := "tag:"
if prefix != "" {
tagPrefix = fmt.Sprintf("tag:%s:", prefix)
}

descriptionTag = fmt.Sprintf(
"This resource has tags with property `%s`. These are key/value pairs that are\n\t"+
"added as their own property with the prefix of `%s` (e.g. [%sexample: \"value\"]) ",
originalName, tagPrefix, tagPrefix)

if prefix != "" {
name = fmt.Sprintf("tag:%s:<key>:", prefix)
}
}

properties[name] = fmt.Sprintf("%s", descriptionTag)

Check failure on line 71 in pkg/docs/generate.go

View workflow job for this annotation

GitHub Actions / lint

redundantSprint: descriptionTag is already string (gocritic)
}

return properties
}
57 changes: 57 additions & 0 deletions pkg/docs/generate_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package docs

import (
"github.com/stretchr/testify/assert"

Check failure on line 4 in pkg/docs/generate_test.go

View workflow job for this annotation

GitHub Actions / lint

File is not `goimports`-ed (goimports)
"testing"
)

func TestGenerateProperties(t *testing.T) {
type TestResource1 struct {
Name string `description:"The name of the resource"`
Region *string `description:"The region in which the resource resides"`
VpcID string `description:"The VPC ID of the resource" property:"prefix=vpc"`
Tags map[string]string `description:"The tags associated with the resource"`
}

type TestResource2 struct {
Name string `description:"The name of the resource"`
Region *string `description:"The region in which the resource resides"`
Tags map[string]string `description:"The tags associated with the resource" property:"prefix=ee"`
}

cases := []struct {
name string
in interface{}
want map[string]string
}{
{
name: "TestResource1",
in: TestResource1{},
want: map[string]string{
"Name": "The name of the resource",
"Region": "The region in which the resource resides",
"vpc:VpcID": "The VPC ID of the resource",
"tag:<key>:": "This resource has tags with property `Tags`. These are key/value pairs that are\n\t" +
"added as their own property with the prefix of `tag:` (e.g. [tag:example: \"value\"]) ",
},
},
{
name: "TestResource2",
in: TestResource2{},
want: map[string]string{
"Name": "The name of the resource",
"Region": "The region in which the resource resides",
"tag:ee:<key>:": "This resource has tags with property `Tags`. These are key/value pairs that are\n\t" +
"added as their own property with the prefix of `tag:ee:" +
"` (e.g. [tag:ee:example: \"value\"]) ",
},
},
}

for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
have := GeneratePropertiesMap(c.in)
assert.Equal(t, c.want, have)
})
}
}
6 changes: 6 additions & 0 deletions pkg/registry/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ type Registration struct {
// different levels, whereas AWS has simply Account level.
Scope Scope

// Resource is the resource type that the lister is going to list. This is a struct that implements the Resource
// interface. This is primarily used to generate documentation by parsing the structs properties and generating
// markdown documentation.
// Note: it is a interface{} because we are going to inspect it, we do not need to actually call any methods on it.
Resource interface{}

// Lister is the lister for the resource type, it is a struct with a method called List that returns a slice
// of resources. The lister is responsible for filtering out any resources that should not be deleted because they
// are ineligible for deletion. For example, built in resources that cannot be deleted.
Expand Down

0 comments on commit c1c6eff

Please sign in to comment.