Skip to content

Commit

Permalink
refactor: enhance kcl file generation with imports and JSON/YAML data
Browse files Browse the repository at this point in the history
Signed-off-by: peefy <[email protected]>
  • Loading branch information
Peefy committed Jan 15, 2024
1 parent b716114 commit 2e6a8f7
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 18 deletions.
3 changes: 1 addition & 2 deletions pkg/tools/gen/genkcl_jsonschema.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,10 @@ func (k *kclGenerator) genSchemaFromJsonSchema(w io.Writer, filename string, src
panic("result is not schema")
}
kclSch := kclFile{
Imports: []string{},
Schemas: []schema{result.schema},
}
for _, imp := range getSortedKeys(ctx.imports) {
kclSch.Imports = append(kclSch.Imports, imp)
kclSch.Imports = append(kclSch.Imports, kImport{PkgPath: imp})
}
for _, key := range getSortedKeys(ctx.resultMap) {
if ctx.resultMap[key].IsSchema {
Expand Down
6 changes: 3 additions & 3 deletions pkg/tools/gen/genkcl_terraform.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ package gen

import (
"encoding/json"
"github.com/iancoleman/strcase"
"io"
"kcl-lang.io/kcl-go/pkg/logger"
"reflect"
"sort"
"strconv"

"github.com/iancoleman/strcase"
"kcl-lang.io/kcl-go/pkg/logger"
)

type tfSchema struct {
Expand Down Expand Up @@ -74,7 +75,6 @@ func (k *kclGenerator) genSchemaFromTerraformSchema(w io.Writer, filename string

// generate kcl schema code
kclSch := kclFile{
Imports: []string{},
Schemas: result,
}
return k.genKcl(w, kclSch)
Expand Down
69 changes: 68 additions & 1 deletion pkg/tools/gen/genkcl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ package gen
import (
"bytes"
"fmt"
assert2 "github.com/stretchr/testify/assert"
"log"
"os"
"path/filepath"
"strings"
"testing"

assert2 "github.com/stretchr/testify/assert"
)

func TestGenKcl(t *testing.T) {
Expand Down Expand Up @@ -217,6 +219,71 @@ func TestGenKclFromYaml(t *testing.T) {
}
}

func TestGenKclFromJsonAndImports(t *testing.T) {
file := kclFile{}
g := &kclGenerator{}
b := bytes.NewBuffer(nil)
// Get a KCL config from JSON or YAML string
data, err := convertKclFromYamlString([]byte(`workload:
containers:
nginx:
image: nginx:v2
replicas: 2
`))
if err != nil {
t.Fatal(err)
}
// Add import statements
importStmt := kImport{
PkgPath: "models.schema.v1",
Alias: "ac",
}
file.Imports = append(file.Imports, importStmt)
configSchemaName := strings.Join([]string{importStmt.PkgName(), "AppConfiguration"}, ".")
// Add configurations
file.Config = append(file.Config, config{
Data: data,
IsUnion: true,
Var: "app1",
Name: configSchemaName,
})
file.Config = append(file.Config, config{
Data: data,
IsUnion: true,
Var: "app2",
Name: configSchemaName,
})
// Generate KCL code.
g.genKcl(b, file)
assert2.Equal(t, b.String(), `"""
This file was generated by the KCL auto-gen tool. DO NOT EDIT.
Editing this file might prove futile when you re-run the KCL auto-gen generate command.
"""
import models.schema.v1 as ac
app1: ac.AppConfiguration {
workload = {
containers = {
nginx = {
image = "nginx:v2"
}
}
replicas = 2
}
}
app2: ac.AppConfiguration {
workload = {
containers = {
nginx = {
image = "nginx:v2"
}
}
replicas = 2
}
}
`)
}

func readFileString(t testing.TB, p string) (content string) {
data, err := os.ReadFile(p)
if err != nil {
Expand Down
24 changes: 15 additions & 9 deletions pkg/tools/gen/genkcl_yaml.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,11 @@ func (k *kclGenerator) genKclFromYaml(w io.Writer, filename string, src interfac
if err != nil {
return err
}

code = bytes.ReplaceAll(code, []byte("\r\n"), []byte("\n"))

yamlData := &yaml.MapSlice{}
if err = yaml.UnmarshalWithOptions(code, yamlData, yaml.UseOrderedMap()); err != nil {
// convert yaml data to kcl
result, err := convertKclFromYamlString(code)
if err != nil {
return err
}

// convert yaml data to kcl
result := convertKclFromYaml(yamlData)

// generate kcl code
return k.genKcl(w, kclFile{Config: []config{
{Data: result},
Expand Down Expand Up @@ -59,3 +53,15 @@ func convertKclFromYaml(yamlData *yaml.MapSlice) []data {
}
return result
}

func convertKclFromYamlString(data []byte) ([]data, error) {
data = bytes.ReplaceAll(data, []byte("\r\n"), []byte("\n"))

yamlData := &yaml.MapSlice{}
if err := yaml.UnmarshalWithOptions(data, yamlData, yaml.UseOrderedMap()); err != nil {
return nil, err
}

// convert yaml data to kcl
return convertKclFromYaml(yamlData), nil
}
2 changes: 1 addition & 1 deletion pkg/tools/gen/templates/kcl/config.gotmpl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{{- if .Var }}{{ formatName .Var }}{{- if .IsUnion }}{{ " : " }}{{- else }}{{ " = " }}{{- end }}{{- end }}{{- if .Name }}{{ formatName .Name }}{{- end }}{{- if .Data }}{{- "{\n" }}
{{- if .Var }}{{ formatName .Var }}{{- if .IsUnion }}{{ ": " }}{{- else }}{{ " = " }}{{- end }}{{- end }}{{- if .Name }}{{ .Name }}{{ " " }}{{- end }}{{- if .Data }}{{- "{\n" }}
{{- range .Data -}}
{{- indentLines (include "data" .) " " }}
{{- end -}}
Expand Down
2 changes: 1 addition & 1 deletion pkg/tools/gen/templates/kcl/header.gotmpl
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ Editing this file might prove futile when you re-run the KCL auto-gen generate c

{{- if .Imports }}
{{- range .Imports }}
import {{ . }}
import {{ .PkgPath }}{{- if .Alias }}{{ " as " }}{{ .Alias }}{{- end }}
{{- end }}
{{- end -}}
20 changes: 19 additions & 1 deletion pkg/tools/gen/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ func getSortedFieldNames(fields map[string]*pb.KclType) []string {
// It contains all the imports, schemas and data in this file.
type kclFile struct {
// Import statements.
Imports []string
Imports []kImport
// Schema definitions.
Schemas []schema
// Top Level data definitions.
Expand All @@ -134,6 +134,23 @@ type kclFile struct {
Config []config
}

type kImport struct {
PkgPath string
Alias string
}

func (i *kImport) PkgName() string {
if len(i.Alias) > 0 {
return i.Alias
}
pkgNames := strings.Split(i.PkgPath, ".")
return pkgNames[len(pkgNames)-1]
}

func (i *kImport) Validate() bool {
return len(i.PkgPath) > 0
}

// schema is a kcl schema definition.
type schema struct {
Name string
Expand Down Expand Up @@ -166,6 +183,7 @@ type validation struct {
Regex *regexp.Regexp
MultiplyOf *int
Unique bool
AllOf []*validation
}

// indexSignature is a kcl schema index signature definition.
Expand Down

0 comments on commit 2e6a8f7

Please sign in to comment.