Skip to content

Commit

Permalink
Updated model naming.
Browse files Browse the repository at this point in the history
* Removed root prefixes from model and column names.
* Root prefix is used for the model name instead of `vehicle`.
* file names are updated to match the model name.
* table name matches the root prefix.
  • Loading branch information
KevinJoiner committed Mar 6, 2024
1 parent bd66b46 commit 75ca67d
Show file tree
Hide file tree
Showing 31 changed files with 2,998 additions and 790 deletions.
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/internal/codegen/cmd",
"program": "${workspaceFolder}/cmd/codegen",
"args": [
"-output=${workspaceFolder}/pkg/vss",
"-spec=${workspaceFolder}/schema/vss_rel_4.2-DIMO.csv",
Expand Down
51 changes: 0 additions & 51 deletions clickhouse-migrations/20240304143248_init.sql

This file was deleted.

13 changes: 5 additions & 8 deletions cmd/codegen/codegen.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,27 +25,24 @@ func main() {
log.Fatal(err)
}

signals, err := codegen.GetDefinedSignals(*vspecPath, *definitionPath)
tmplData, err := codegen.GetDefinedSignals(*vspecPath, *definitionPath)
if err != nil {
log.Fatal(err)
}

tmplData := codegen.TemplateData{
PackageName: *packageName,
Signals: signals,
}
tmplData.PackageName = *packageName

err = model.Generate(&tmplData, *outputDir)
err = model.Generate(tmplData, *outputDir)
if err != nil {
log.Fatalf("failed to generate model: %v", err)
}

err = clickhouse.Generate(&tmplData, *outputDir)
err = clickhouse.Generate(tmplData, *outputDir)
if err != nil {
log.Fatalf("failed to generate ClickHouse file: %v", err)
}

err = convert.Generate(&tmplData, *outputDir, *withTest)
err = convert.Generate(tmplData, *outputDir, *withTest)
if err != nil {
log.Fatalf("failed to generate convert file: %v", err)
}
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.22.0
require (
github.com/stretchr/testify v1.9.0
github.com/tidwall/gjson v1.17.1
golang.org/x/text v0.14.0
golang.org/x/tools v0.18.0
)

Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8=
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ=
golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
Expand Down
48 changes: 46 additions & 2 deletions internal/codegen/clickhouse/clickhouse.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
package clickhouse

import (
"bytes"
_ "embed"
"fmt"
"os"
Expand All @@ -12,19 +13,29 @@ import (
"github.com/KevinJoiner/model-garage/internal/codegen"
)

//go:embed vssTable.tmpl
// clickhouseFileName is the name of the ClickHouse table file that will be generated.
var clickhouseFileName = "%s-table.sql"

var embeddedClickhouseFileName = "%s-table.go"

//go:embed table.tmpl
var clickhouseTableTemplate string

//go:embed embeddedTable.tmpl
var embeddedClickhouseTableTemplate string

// Generate creates a new ClickHouse table file.
func Generate(tmplData *codegen.TemplateData, outputDir string) error {
setFileNamesFrom(tmplData.ModelName)

// create a new ClickHouse table template.
clickhouseTableTmpl, err := createClickHouseTableTemplate()
if err != nil {
return err
}

// execute the ClickHouse table template directly to a file.
tablePath := filepath.Clean((filepath.Join(outputDir, codegen.ClickhouseFileName)))
tablePath := filepath.Clean((filepath.Join(outputDir, clickhouseFileName)))
clickhouseTableOutputFile, err := os.Create(tablePath)
if err != nil {
return fmt.Errorf("error creating ClickHouse table output file: %w", err)
Expand All @@ -39,15 +50,48 @@ func Generate(tmplData *codegen.TemplateData, outputDir string) error {
if err != nil {
return fmt.Errorf("error executing ClickHouse table template: %w", err)
}

// create a new embedded ClickHouse table template.
embeddedClickhouseTableTmpl, err := createEmbeddedClickHouseTableTemplate()
if err != nil {
return err
}
var outBuf bytes.Buffer
if err = embeddedClickhouseTableTmpl.Execute(&outBuf, &tmplData); err != nil {
return fmt.Errorf("error executing embedded ClickHouse table template: %w", err)
}
filePath := filepath.Clean(filepath.Join(outputDir, embeddedClickhouseFileName))
err = codegen.FormatAndWriteToFile(outBuf.Bytes(), filePath)
if err != nil {
return fmt.Errorf("error writing file: %w", err)
}

return nil
}

func setFileNamesFrom(modelName string) {
lowerName := strings.ToLower(modelName)
clickhouseFileName = fmt.Sprintf(clickhouseFileName, lowerName)
embeddedClickhouseFileName = fmt.Sprintf(embeddedClickhouseFileName, lowerName)
}

func createClickHouseTableTemplate() (*template.Template, error) {
tmpl, err := template.New("clickhouseTableTemplate").Funcs(template.FuncMap{
"escapeDesc": func(desc string) string { return strings.ReplaceAll(desc, `'`, `\'`) },
"lower": strings.ToLower,
}).Parse(clickhouseTableTemplate)
if err != nil {
return nil, fmt.Errorf("error parsing ClickHouse table template: %w", err)
}
return tmpl, nil
}

func createEmbeddedClickHouseTableTemplate() (*template.Template, error) {
tmpl, err := template.New("embeddedClickhouseTableTemplate").Funcs(template.FuncMap{
"sqlFileName": func() string { return clickhouseFileName },
}).Parse(embeddedClickhouseTableTemplate)
if err != nil {
return nil, fmt.Errorf("error parsing ClickHouse table template: %w", err)
}
return tmpl, nil
}
11 changes: 11 additions & 0 deletions internal/codegen/clickhouse/embeddedTable.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Code generated by "model-garage" DO NOT EDIT.
package {{ .PackageName }}

import (
_ "embed"
)

// VSSTableCreateQuery is the SQL query to create a clickhouse table for the {{ .ModelName }} model.
//
//go:embed {{ sqlFileName }}
var VSSTableCreateQuery string
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
CREATE TABLE IF NOT EXISTS vss (
CREATE TABLE IF NOT EXISTS {{ lower .ModelName }} (
{{- range .Signals }}
{{ .CHName }} {{ .CHType }} COMMENT '{{ escapeDesc .Desc }}',
{{- end }}
Expand Down
38 changes: 20 additions & 18 deletions internal/codegen/codegen.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,24 @@ import (
"fmt"
"os"
"path/filepath"
"strings"

"golang.org/x/text/cases"
"golang.org/x/text/language"
"golang.org/x/tools/imports"
)

const (
// ClickhouseFileName is the name of the ClickHouse table file that will be generated.
ClickhouseFileName = "vss-table.sql"

// StructFileName is the name of the Go file that will contain the vehicle struct.
StructFileName = "vss-structs.go"

// ConvertFileName is the name of the Go file that will convert JSON data to the vehicle struct.
ConvertFileName = "vss-convert.go"

// ConvertFuncFileName is the name of the Go file that will contain the conversion functions.
ConvertFuncFileName = "vss-convert-funcs.go"

readAll = 0o755
)
const readAll = 0o755

// TemplateData contains the data to be used during template execution.
type TemplateData struct {
PackageName string
ModelName string
Signals []*SignalInfo
}

// GetDefinedSignals reads the signals and definitions files and merges them.
func GetDefinedSignals(specFile, definitionFile string) ([]*SignalInfo, error) {
func GetDefinedSignals(specFile, definitionFile string) (*TemplateData, error) {
signals, err := loadSignalsCSV(specFile)
if err != nil {
return nil, fmt.Errorf("error reading signals: %w", err)
Expand All @@ -42,9 +32,21 @@ func GetDefinedSignals(specFile, definitionFile string) ([]*SignalInfo, error) {
if err != nil {
return nil, fmt.Errorf("error reading definition file: %w", err)
}
signals = definitions.DefinedSignal(signals)
modelName := "Model"
if len(signals) > 0 {
idx := strings.IndexByte(signals[0].Name, '.')
if idx > 0 {
modelName = signals[0].Name[:idx]
modelName = cases.Title(language.English).String(modelName)
}
}
tmplData := &TemplateData{
Signals: signals,
ModelName: modelName,
}

definedSignals := definitions.DefinedSignal(signals)
return definedSignals, nil
return tmplData, nil
}

// EnsureDir ensures the output directory exists.
Expand Down
38 changes: 27 additions & 11 deletions internal/codegen/convert/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@ import (
"github.com/KevinJoiner/model-garage/internal/codegen"
)

var (
// convertFileName is the name of the Go file that will convert JSON data to the vehicle struct.
convertFileName = "%s-convert.go"
// convertFuncFileName is the name of the Go file that will contain the conversion functions.
convertFuncFileName = "%s-convert-funcs.go"
// convertTestFuncFileName is the name of the Go file that will contain the conversion test functions.
convertTestFuncFileName = "%s-convert-funcs_test.go"
)

//go:embed convert.tmpl
var convertTemplateStr string

Expand All @@ -27,7 +36,7 @@ var convertTestsFuncTemplateStr string

const header = `package %s
// This file is automatically populated with conversion functions for each field of a vehicle struct.
// This file is automatically populated with conversion functions for each field of the model struct.
// any conversion functions already defined in this package will not be generated.
// Code generated by model-garage.
`
Expand All @@ -37,9 +46,11 @@ type funcTmplData struct {
PackageName string
}

// Generate creates a conversion functions for each field of a vehicle struct.
// as well as the entire vehicle struct.
// Generate creates a conversion functions for each field of a model struct.
// as well as the entire model struct.
func Generate(tmplData *codegen.TemplateData, outputDir string, withTest bool) (err error) {
setFileNamesFrom(tmplData.ModelName)

err = createStructConversion(tmplData, outputDir)
if err != nil {
return err
Expand Down Expand Up @@ -67,6 +78,13 @@ func Generate(tmplData *codegen.TemplateData, outputDir string, withTest bool) (
return nil
}

func setFileNamesFrom(modelName string) {
lowerModelName := strings.ToLower(modelName)
convertFileName = fmt.Sprintf(convertFileName, lowerModelName)
convertFuncFileName = fmt.Sprintf(convertFuncFileName, lowerModelName)
convertTestFuncFileName = fmt.Sprintf(convertTestFuncFileName, lowerModelName)
}

func createConvertFuncs(tmplData *codegen.TemplateData, outputDir string, needsConvertFunc []*codegen.SignalInfo) error {
convertFuncTemplate, err := createConvertFuncTemplate()
if err != nil {
Expand All @@ -75,7 +93,7 @@ func createConvertFuncs(tmplData *codegen.TemplateData, outputDir string, needsC
if len(needsConvertFunc) == 0 {
return nil
}
filePath := filepath.Join(outputDir, codegen.ConvertFuncFileName)
filePath := filepath.Join(outputDir, convertFuncFileName)
err = writeConvertFuncs(needsConvertFunc, convertFuncTemplate, filePath, tmplData.PackageName)
if err != nil {
return err
Expand Down Expand Up @@ -112,10 +130,7 @@ func createConvertTestFunc(tmplData *codegen.TemplateData, outputDir string, nee
return nil
}

ext := filepath.Ext(codegen.ConvertFuncFileName)
//nolint:gocritic // we want to trim the extension
testFileName := strings.TrimSuffix(codegen.ConvertFuncFileName, ext) + "_test.go"
filePath := filepath.Join(outputDir, testFileName)
filePath := filepath.Join(outputDir, convertTestFuncFileName)
packageName := tmplData.PackageName + "_test"
err = writeConvertFuncs(needsConvertTestFunc, convertTestFuncTemplate, filePath, packageName)
if err != nil {
Expand All @@ -124,7 +139,7 @@ func createConvertTestFunc(tmplData *codegen.TemplateData, outputDir string, nee
return nil
}

// createStructConversion creates the conversion function for converting JSON data to a vehicle struct.
// createStructConversion creates the conversion function for converting JSON data to a model struct.
func createStructConversion(tmplData *codegen.TemplateData, outputDir string) error {
basConversionTemplate, err := createGoTemplate()
if err != nil {
Expand All @@ -135,7 +150,7 @@ func createStructConversion(tmplData *codegen.TemplateData, outputDir string) er
return fmt.Errorf("error executing template: %w", err)
}

goOutputPath := filepath.Join(outputDir, codegen.ConvertFileName)
goOutputPath := filepath.Join(outputDir, convertFileName)
// format and write the go file.
err = codegen.FormatAndWriteToFile(outBuf.Bytes(), goOutputPath)
if err != nil {
Expand All @@ -147,6 +162,7 @@ func createStructConversion(tmplData *codegen.TemplateData, outputDir string) er
func createGoTemplate() (*template.Template, error) {
tmpl, err := template.New("convertTemplate").Funcs(template.FuncMap{
"convertName": convertName,
"lower": strings.ToLower,
}).Parse(convertTemplateStr)
if err != nil {
return nil, fmt.Errorf("error parsing go struct template: %w", err)
Expand Down Expand Up @@ -229,7 +245,7 @@ func ensureFuncFile(convertFuncPath string, packageName string) error {
return nil
}
if !os.IsNotExist(err) {
return fmt.Errorf("error checking for %s file: %w", codegen.ConvertFuncFileName, err)
return fmt.Errorf("error checking for %s file: %w", convertFuncPath, err)
}
// create the convertFunc file
funcFile, err := os.Create(filepath.Clean(convertFuncPath))
Expand Down
Loading

0 comments on commit 75ca67d

Please sign in to comment.