Skip to content

Commit

Permalink
Add a slightly more readable API for editing reflected schemas
Browse files Browse the repository at this point in the history
  • Loading branch information
MacroPower committed Jan 9, 2025
1 parent f7e36d3 commit 7049d22
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 133 deletions.
185 changes: 68 additions & 117 deletions pkg/helmmodels/chartmodule/chart.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,68 +46,43 @@ func (c *ChartConfig) GenerateKCL(w io.Writer) error {
return fmt.Errorf("failed to create schema reflector: %w", err)
}
js := r.Reflect(reflect.TypeOf(ChartConfig{}))
if cv, ok := js.Properties.Get("chart"); ok {
cv.Default = c.ChartBase.Chart
}
if cv, ok := js.Properties.Get("repoURL"); ok {
cv.Default = c.ChartBase.RepoURL
}
if cv, ok := js.Properties.Get("targetRevision"); ok {
cv.Default = c.ChartBase.TargetRevision
}
if cv, ok := js.Properties.Get("namespace"); ok {
if c.Namespace != "" {
cv.Default = c.ChartBase.Namespace
} else {
js.Properties.Delete("namespace")
}
}
if cv, ok := js.Properties.Get("releaseName"); ok {
if c.ReleaseName != "" {
cv.Default = c.ChartBase.ReleaseName
} else {
js.Properties.Delete("releaseName")
}
}
if cv, ok := js.Properties.Get("skipCRDs"); ok {
if c.SkipCRDs {
cv.Default = c.ChartBase.SkipCRDs
} else {
js.Properties.Delete("skipCRDs")
}
}
if cv, ok := js.Properties.Get("passCredentials"); ok {
if c.PassCredentials {
cv.Default = c.ChartBase.PassCredentials
} else {
js.Properties.Delete("passCredentials")
}
}
if cv, ok := js.Properties.Get("schemaValidator"); ok {
if c.ChartBase.SchemaValidator != jsonschema.DefaultValidatorType {
cv.Default = c.ChartBase.SchemaValidator
cv.Enum = jsonschema.ValidatorTypeEnum
} else {
js.Properties.Delete("schemaValidator")
}
}
if cv, ok := js.Properties.Get("schemaPath"); ok {
if c.HelmChartConfig.SchemaPath != "" {
cv.Default = c.HelmChartConfig.SchemaPath
} else {
js.Properties.Delete("schemaPath")
}
}
if cv, ok := js.Properties.Get("schemaGenerator"); ok {
if c.HelmChartConfig.SchemaGenerator != jsonschema.DefaultGeneratorType {
cv.Default = c.HelmChartConfig.SchemaGenerator
cv.Enum = jsonschema.GeneratorTypeEnum
} else {
js.Properties.Delete("schemaGenerator")
}
}

err = jsonschema.ReflectedSchemaToKCL(js, w)
js.SetProperty("chart", jsonschema.WithDefault(c.ChartBase.Chart))
js.SetProperty("repoURL", jsonschema.WithDefault(c.ChartBase.RepoURL))
js.SetProperty("targetRevision", jsonschema.WithDefault(c.ChartBase.TargetRevision))

js.SetOrRemoveProperty(
"namespace", c.ChartBase.Namespace != "",
jsonschema.WithDefault(c.ChartBase.Namespace),
)
js.SetOrRemoveProperty(
"releaseName", c.ChartBase.ReleaseName != "",
jsonschema.WithDefault(c.ChartBase.ReleaseName),
)
js.SetOrRemoveProperty(
"skipCRDs", c.ChartBase.SkipCRDs,
jsonschema.WithDefault(c.ChartBase.SkipCRDs),
)
js.SetOrRemoveProperty(
"passCredentials", c.ChartBase.PassCredentials,
jsonschema.WithDefault(c.ChartBase.PassCredentials),
)
js.SetOrRemoveProperty(
"schemaPath", c.HelmChartConfig.SchemaPath != "",
jsonschema.WithDefault(c.HelmChartConfig.SchemaPath),
)
js.SetOrRemoveProperty(
"schemaValidator", c.ChartBase.SchemaValidator != jsonschema.DefaultValidatorType,
jsonschema.WithDefault(c.ChartBase.SchemaValidator),
jsonschema.WithEnum(jsonschema.ValidatorTypeEnum),
)
js.SetOrRemoveProperty(
"schemaGenerator", c.HelmChartConfig.SchemaGenerator != jsonschema.DefaultGeneratorType,
jsonschema.WithDefault(c.HelmChartConfig.SchemaGenerator),
jsonschema.WithEnum(jsonschema.GeneratorTypeEnum),
)

err = js.GenerateKCL(w)
if err != nil {
return fmt.Errorf("failed to convert JSON Schema to KCL Schema: %w", err)
}
Expand All @@ -131,64 +106,40 @@ func (c *Chart) GenerateKCL(w io.Writer) error {
return fmt.Errorf("failed to create schema reflector: %w", err)
}
js := r.Reflect(reflect.TypeOf(Chart{}))
js.Description = "All possible chart configuration, inheriting from `helm.Chart(helm.ChartBase)`."
if cv, ok := js.Properties.Get("chart"); ok {
cv.Default = c.ChartBase.Chart
}
if cv, ok := js.Properties.Get("repoURL"); ok {
cv.Default = c.ChartBase.RepoURL
}
if cv, ok := js.Properties.Get("targetRevision"); ok {
cv.Default = c.ChartBase.TargetRevision
}
if cv, ok := js.Properties.Get("namespace"); ok {
if c.Namespace != "" {
cv.Default = c.ChartBase.Namespace
} else {
js.Properties.Delete("namespace")
}
}
if cv, ok := js.Properties.Get("releaseName"); ok {
if c.ReleaseName != "" {
cv.Default = c.ChartBase.ReleaseName
} else {
js.Properties.Delete("releaseName")
}
}
if cv, ok := js.Properties.Get("skipCRDs"); ok {
if c.SkipCRDs {
cv.Default = c.ChartBase.SkipCRDs
} else {
js.Properties.Delete("skipCRDs")
}
}
if cv, ok := js.Properties.Get("passCredentials"); ok {
if c.PassCredentials {
cv.Default = c.ChartBase.PassCredentials
} else {
js.Properties.Delete("passCredentials")
}
}
if cv, ok := js.Properties.Get("schemaValidator"); ok {
if c.ChartBase.SchemaValidator != jsonschema.DefaultValidatorType {
cv.Default = c.ChartBase.SchemaValidator
cv.Enum = jsonschema.ValidatorTypeEnum
} else {
js.Properties.Delete("schemaValidator")
}
}
if cv, ok := js.Properties.Get("values"); ok {
cv.Type = "null"
}
if _, ok := js.Properties.Get("valueFiles"); ok {
js.Properties.Delete("valueFiles")
}
if _, ok := js.Properties.Get("postRenderer"); ok {
js.Properties.Delete("postRenderer")
}
js.Schema.Description = "All possible chart configuration, inheriting from `helm.Chart(helm.ChartBase)`."

js.SetProperty("chart", jsonschema.WithDefault(c.ChartBase.Chart))
js.SetProperty("repoURL", jsonschema.WithDefault(c.ChartBase.RepoURL))
js.SetProperty("targetRevision", jsonschema.WithDefault(c.ChartBase.TargetRevision))
js.SetProperty("values", jsonschema.WithType("null"))

js.SetOrRemoveProperty(
"namespace", c.ChartBase.Namespace != "",
jsonschema.WithDefault(c.ChartBase.Namespace),
)
js.SetOrRemoveProperty(
"releaseName", c.ChartBase.ReleaseName != "",
jsonschema.WithDefault(c.ChartBase.ReleaseName),
)
js.SetOrRemoveProperty(
"skipCRDs", c.ChartBase.SkipCRDs,
jsonschema.WithDefault(c.ChartBase.SkipCRDs),
)
js.SetOrRemoveProperty(
"passCredentials", c.ChartBase.PassCredentials,
jsonschema.WithDefault(c.ChartBase.PassCredentials),
)
js.SetOrRemoveProperty(
"schemaValidator", c.ChartBase.SchemaValidator != jsonschema.DefaultValidatorType,
jsonschema.WithDefault(c.ChartBase.SchemaValidator),
jsonschema.WithEnum(jsonschema.ValidatorTypeEnum),
)

js.RemoveProperty("valueFiles")
js.RemoveProperty("postRenderer")

b := &bytes.Buffer{}
err = jsonschema.ReflectedSchemaToKCL(js, b)
err = js.GenerateKCL(b)
if err != nil {
return fmt.Errorf("failed to convert JSON Schema to KCL Schema: %w", err)
}
Expand Down
21 changes: 9 additions & 12 deletions pkg/helmmodels/pluginmodule/chart.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,10 @@ func (c *ChartBase) GenerateKCL(w io.Writer) error {
return fmt.Errorf("failed to create schema reflector: %w", err)
}
js := r.Reflect(reflect.TypeOf(ChartBase{}))
if cv, ok := js.Properties.Get("schemaValidator"); ok {
cv.Enum = jsonschema.ValidatorTypeEnum
}

err = jsonschema.ReflectedSchemaToKCL(js, w)
js.SetProperty("schemaValidator", jsonschema.WithEnum(jsonschema.ValidatorTypeEnum))

err = js.GenerateKCL(w)
if err != nil {
return fmt.Errorf("failed to convert JSON Schema to KCL Schema: %w", err)
}
Expand Down Expand Up @@ -71,15 +70,13 @@ func (c *Chart) GenerateKCL(w io.Writer) error {
return fmt.Errorf("failed to create schema reflector: %w", err)
}
js := r.Reflect(reflect.TypeOf(Chart{}))
// if cv, ok := js.Properties.Get("values"); ok {
// cv.Default = struct{}{}
// }

b := &bytes.Buffer{}
err = jsonschema.ReflectedSchemaToKCL(js, b)
err = js.GenerateKCL(b)
if err != nil {
return fmt.Errorf("failed to convert JSON Schema to KCL Schema: %w", err)
}

nb := &bytes.Buffer{}
scanner := bufio.NewScanner(b)
for scanner.Scan() {
Expand Down Expand Up @@ -115,15 +112,15 @@ func (c *ChartConfig) GenerateKCL(w io.Writer) error {
return fmt.Errorf("failed to create schema reflector: %w", err)
}
js := r.Reflect(reflect.TypeOf(ChartConfig{}))
if cv, ok := js.Properties.Get("schemaGenerator"); ok {
cv.Enum = jsonschema.GeneratorTypeEnum
}

js.SetProperty("schemaGenerator", jsonschema.WithEnum(jsonschema.GeneratorTypeEnum))

b := &bytes.Buffer{}
err = jsonschema.ReflectedSchemaToKCL(js, b)
err = js.GenerateKCL(b)
if err != nil {
return fmt.Errorf("failed to convert JSON Schema to KCL Schema: %w", err)
}

nb := &bytes.Buffer{}
scanner := bufio.NewScanner(b)
for scanner.Scan() {
Expand Down
58 changes: 54 additions & 4 deletions pkg/jsonschema/reflector.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,16 @@ func (r *Reflector) AddGoComments(pkg, path string) error {
return nil
}

func (r *Reflector) Reflect(t reflect.Type) *invopopjsonschema.Schema {
return r.Reflector.ReflectFromType(t)
func (r *Reflector) Reflect(t reflect.Type) *Reflected {
return &Reflected{Schema: r.Reflector.ReflectFromType(t)}
}

func ReflectedSchemaToKCL(r *invopopjsonschema.Schema, w io.Writer) error {
jsBytes, err := r.MarshalJSON()
type Reflected struct {
Schema *invopopjsonschema.Schema
}

func (r *Reflected) GenerateKCL(w io.Writer) error {
jsBytes, err := r.Schema.MarshalJSON()
if err != nil {
return fmt.Errorf("failed to marshal json schema: %w", err)
}
Expand All @@ -51,3 +55,49 @@ func ReflectedSchemaToKCL(r *invopopjsonschema.Schema, w io.Writer) error {

return nil
}

func (r *Reflected) SetProperty(key string, opts ...PropertyOpt) {
if cv, ok := r.Schema.Properties.Get(key); ok {
for _, opt := range opts {
opt(cv)
}
}
}

func (r *Reflected) SetOrRemoveProperty(key string, setProperty bool, opts ...PropertyOpt) {
if cv, ok := r.Schema.Properties.Get(key); ok {
if setProperty {
for _, opt := range opts {
opt(cv)
}
} else {
r.Schema.Properties.Delete(key)
}
}
}

func (r *Reflected) RemoveProperty(key string) {
if _, ok := r.Schema.Properties.Get(key); ok {
r.Schema.Properties.Delete(key)
}
}

type PropertyOpt func(*invopopjsonschema.Schema)

func WithEnum(enum []interface{}) PropertyOpt {
return func(s *invopopjsonschema.Schema) {
s.Enum = enum
}
}

func WithDefault(defaultValue interface{}) PropertyOpt {
return func(s *invopopjsonschema.Schema) {
s.Default = defaultValue
}
}

func WithType(t string) PropertyOpt {
return func(s *invopopjsonschema.Schema) {
s.Type = t
}
}

0 comments on commit 7049d22

Please sign in to comment.