From e6756de4f2a836fc63d1aaf3030479cec72d53ae Mon Sep 17 00:00:00 2001 From: Kevin Joiner <10265309+KevinJoiner@users.noreply.github.com> Date: Wed, 17 Apr 2024 12:35:34 -0400 Subject: [PATCH] Adds config objects for generators - GQL generator now takes in a template to execute. --- cmd/codegen/codegen.go | 19 +++++++++++-- internal/codegen/convert/convert.go | 9 +++++-- internal/codegen/graphql/gql.tmpl | 41 ----------------------------- internal/codegen/graphql/graphql.go | 38 ++++++++++++++------------ pkg/runner/runner.go | 23 ++++++++++------ 5 files changed, 60 insertions(+), 70 deletions(-) delete mode 100644 internal/codegen/graphql/gql.tmpl diff --git a/cmd/codegen/codegen.go b/cmd/codegen/codegen.go index 58f6d0a..fedb529 100644 --- a/cmd/codegen/codegen.go +++ b/cmd/codegen/codegen.go @@ -10,6 +10,8 @@ import ( "path/filepath" "strings" + "github.com/DIMO-Network/model-garage/internal/codegen/convert" + "github.com/DIMO-Network/model-garage/internal/codegen/graphql" "github.com/DIMO-Network/model-garage/pkg/runner" "github.com/DIMO-Network/model-garage/schema" ) @@ -24,7 +26,8 @@ func main() { // Convert flags withTest := flag.Bool("convert.with-test", true, "Generate test functions for conversion functions. Default is true.") // GQL flags - gqlModelname := flag.String("graphql.model-name", "", "Name of the model to generate the graphql table if empty, the model name will be infered.") + gqlOutFile := flag.String("graphql.output-file", "", "Path of the generate gql file that is appened to the outputDir.") + gqlTemplateFile := flag.String("graphql.template-file", "", "Path to the template file. Which is executed with codegen.TemplateData data.") flag.Parse() var vspecReader io.Reader @@ -53,7 +56,19 @@ func main() { } gens := strings.Split(*generators, ",") - err := runner.Execute(*outputDir, *packageName, vspecReader, definitionReader, *withTest, *gqlModelname, gens) + cfg := runner.Config{ + PackageName: *packageName, + OutputDir: *outputDir, + GraphQL: graphql.Config{ + OutputFile: *gqlOutFile, + TemplateFile: *gqlTemplateFile, + }, + Convert: convert.Config{ + WithTest: *withTest, + }, + } + + err := runner.Execute(vspecReader, definitionReader, gens, cfg) if err != nil { log.Fatal(err) } diff --git a/internal/codegen/convert/convert.go b/internal/codegen/convert/convert.go index 30f834b..ee73066 100644 --- a/internal/codegen/convert/convert.go +++ b/internal/codegen/convert/convert.go @@ -54,9 +54,14 @@ type funcTmplData struct { Conversion *codegen.ConversionInfo } +type Config struct { + // WithTest determines if test functions should be generated. + WithTest bool +} + // 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) { +func Generate(tmplData *codegen.TemplateData, outputDir string, cfg Config) (err error) { setFileNamesFrom(tmplData.ModelName) err = createStructConversion(tmplData, outputDir) @@ -76,7 +81,7 @@ func Generate(tmplData *codegen.TemplateData, outputDir string, withTest bool) ( return err } - if withTest { + if cfg.WithTest { err = createConvertTestFunc(tmplData, outputDir, needsConvertTestFunc) if err != nil { return err diff --git a/internal/codegen/graphql/gql.tmpl b/internal/codegen/graphql/gql.tmpl deleted file mode 100644 index f784e87..0000000 --- a/internal/codegen/graphql/gql.tmpl +++ /dev/null @@ -1,41 +0,0 @@ -# Code generated by "model-garage" DO NOT EDIT. -extend type {{ GQLModelName }} { - {{- range .Signals }} - """ - {{ .Desc }} - Required Privlieges: {{ .Privileges }} - """ - {{ .JSONName }}( - {{- if eq .GQLType "Float" }} - agg: FloatAggregation - ): [SignalFloat!] - {{- else }} - agg: StringAggregation - ): [SignalString!] - {{- end }} @requiresPrivilege(privileges: {{ .Privileges }}) - {{ end }} -} - -type SignalFloat { - """ - timestamp of when this data was colllected - """ - timestamp: Time - - """ - value of the signal - """ - value: Float -} - -type SignalString { - """ - timestamp of when this data was colllected - """ - timestamp: Time - - """ - value of the signal - """ - value: String -} \ No newline at end of file diff --git a/internal/codegen/graphql/graphql.go b/internal/codegen/graphql/graphql.go index 775176c..b7af4f8 100644 --- a/internal/codegen/graphql/graphql.go +++ b/internal/codegen/graphql/graphql.go @@ -5,6 +5,7 @@ import ( _ "embed" "fmt" "os" + "path" "path/filepath" "strings" "text/template" @@ -12,28 +13,35 @@ import ( "github.com/DIMO-Network/model-garage/internal/codegen" ) -// graphqlFileName is the name of the Graphql table file that will be generated. -var graphqlFileName = "%s-gql.graphqls" +var graphqlFileFormat = "%s.graphqls" //go:embed gql.tmpl var graphqlTableTemplate string +type Config struct { + // OutputFile is the name of the model to generate the graphql table. + OutputFile string + + // TemplateFile is the path to the template file. + TemplateFile string +} + // Generate creates a new Graphql table file. -func Generate(tmplData *codegen.TemplateData, outputDir, gqlModelName string) error { - if gqlModelName == "" { - gqlModelName = tmplData.ModelName +func Generate(tmplData *codegen.TemplateData, outputDir string, cfg Config) error { + outFile := cfg.OutputFile + if outFile == "" { + lowerName := strings.ToLower(tmplData.ModelName) + outFile = fmt.Sprintf(graphqlFileFormat, lowerName) } - setFileNamesFrom(gqlModelName) - // create a new Graphql table template. - graphqlTableTmpl, err := createGraphqlTableTemplate(gqlModelName) + graphqlTableTmpl, err := createGraphqlTableTemplate(outFile, cfg.TemplateFile) if err != nil { return err } // execute the Graphql table template directly to a file. - tablePath := filepath.Clean((filepath.Join(outputDir, graphqlFileName))) + tablePath := filepath.Clean((filepath.Join(outputDir, outFile))) graphqlTableOutputFile, err := os.Create(tablePath) if err != nil { return fmt.Errorf("error creating Graphql table output file: %w", err) @@ -52,15 +60,11 @@ func Generate(tmplData *codegen.TemplateData, outputDir, gqlModelName string) er return nil } -func setFileNamesFrom(modelName string) { - lowerName := strings.ToLower(modelName) - graphqlFileName = fmt.Sprintf(graphqlFileName, lowerName) -} - -func createGraphqlTableTemplate(gqlmodelName string) (*template.Template, error) { - tmpl, err := template.New("graphqlTableTemplate").Funcs(template.FuncMap{ +func createGraphqlTableTemplate(gqlmodelName, templateFile string) (*template.Template, error) { + tmplName := path.Base(templateFile) + tmpl, err := template.New(tmplName).Funcs(template.FuncMap{ "GQLModelName": func() string { return gqlmodelName }, - }).Parse(graphqlTableTemplate) + }).ParseFiles(templateFile) if err != nil { return nil, fmt.Errorf("error parsing Graphql table template: %w", err) } diff --git a/pkg/runner/runner.go b/pkg/runner/runner.go index 65718e4..cc5baa0 100644 --- a/pkg/runner/runner.go +++ b/pkg/runner/runner.go @@ -28,8 +28,15 @@ const ( MigrationGenerator = "migration" ) +type Config struct { + PackageName string + OutputDir string + GraphQL graphql.Config + Convert convert.Config +} + // Execute runs the code generation tool. -func Execute(outputDir, packageName string, vspecReader, definitionsReader io.Reader, withTest bool, gqlModelname string, generators []string) error { +func Execute(vspecReader, definitionsReader io.Reader, generators []string, cfg Config) error { // TODO move params to a config struct. if len(generators) == 0 { @@ -47,7 +54,7 @@ func Execute(outputDir, packageName string, vspecReader, definitionsReader io.Re return fmt.Errorf("no generator selected") } - err := codegen.EnsureDir(outputDir) + err := codegen.EnsureDir(cfg.OutputDir) if err != nil { return fmt.Errorf("failed to ensure output directory: %w", err) } @@ -57,37 +64,37 @@ func Execute(outputDir, packageName string, vspecReader, definitionsReader io.Re return fmt.Errorf("failed to get defined signals: %w", err) } - tmplData.PackageName = packageName + tmplData.PackageName = cfg.PackageName if slices.Contains(generators, AllGenerator) || slices.Contains(generators, ModelGenerator) { - err = model.Generate(tmplData, outputDir) + err = model.Generate(tmplData, cfg.OutputDir) if err != nil { return fmt.Errorf("failed to generate model file: %w", err) } } if slices.Contains(generators, AllGenerator) || slices.Contains(generators, ClickhouseGenerator) { - err = clickhouse.Generate(tmplData, outputDir) + err = clickhouse.Generate(tmplData, cfg.OutputDir) if err != nil { return fmt.Errorf("failed to generate clickhouse file: %w", err) } } if slices.Contains(generators, AllGenerator) || slices.Contains(generators, ConvertGenerator) { - err = convert.Generate(tmplData, outputDir, withTest) + err = convert.Generate(tmplData, cfg.OutputDir, cfg.Convert) if err != nil { return fmt.Errorf("failed to generate convert file: %w", err) } } if slices.Contains(generators, AllGenerator) || slices.Contains(generators, GraphqlGenerator) { - err = graphql.Generate(tmplData, outputDir, gqlModelname) + err = graphql.Generate(tmplData, cfg.OutputDir, cfg.GraphQL) if err != nil { return fmt.Errorf("failed to generate graphql file: %w", err) } } if slices.Contains(generators, AllGenerator) || slices.Contains(generators, MigrationGenerator) { - err = migration.Generate(tmplData, outputDir) + err = migration.Generate(tmplData, cfg.OutputDir) if err != nil { return fmt.Errorf("failed to generate migration file: %w", err) }