gas-stack/cmd/subcmd_generate_models.go
wispem-wantex 208c1eb26c
All checks were successful
CI / build-docker (push) Successful in 13s
CI / build-docker-bootstrap (push) Has been skipped
CI / release-test (push) Successful in 40s
Add model generator based on AST
2025-11-09 16:37:01 -08:00

82 lines
2.3 KiB
Go

package main
import (
"errors"
"fmt"
"go/ast"
"go/printer"
"go/token"
"os"
"github.com/spf13/cobra"
"git.offline-twitter.com/offline-labs/gas-stack/pkg/codegen/modelgenerate"
. "git.offline-twitter.com/offline-labs/gas-stack/pkg/flowutils"
"git.offline-twitter.com/offline-labs/gas-stack/pkg/schema"
)
var ErrNoSuchTable = errors.New("no such table")
var generate_model = &cobra.Command{
Use: "generate <model_name>",
Short: "Generate a model type",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
path := Must(cmd.Flags().GetString("schema"))
modname := Must(cmd.Flags().GetString("modname"))
schema_sql, err := os.ReadFile(path)
if err != nil {
return fmt.Errorf("reading path %s: %w", path, err)
}
db := schema.InitDB(string(schema_sql))
tables := schema.SchemaFromDB(db).Tables
table, isOk := tables[args[0]]
if !isOk {
return ErrNoSuchTable
}
fset := token.NewFileSet()
if Must(cmd.Flags().GetBool("test")) {
file2 := modelgenerate.GenerateModelTestAST(table, modname)
PanicIf(printer.Fprint(os.Stdout, fset, file2))
} else {
file := &ast.File{
Name: ast.NewIdent("db"), // TODO: parameterize
Decls: []ast.Decl{
&ast.GenDecl{
Tok: token.IMPORT,
Specs: []ast.Spec{
&ast.ImportSpec{Path: &ast.BasicLit{Kind: token.STRING, Value: `"database/sql"`}},
&ast.ImportSpec{Path: &ast.BasicLit{Kind: token.STRING, Value: `"errors"`}},
&ast.ImportSpec{Path: &ast.BasicLit{Kind: token.STRING, Value: `"fmt"`}},
&ast.ImportSpec{
Name: ast.NewIdent("."),
Path: &ast.BasicLit{Kind: token.STRING, Value: `"git.offline-twitter.com/offline-labs/gas-stack/pkg/db"`},
},
},
},
modelgenerate.GenerateIDType(table),
modelgenerate.GenerateModelAST(table),
modelgenerate.GenerateSaveItemFunc(table),
modelgenerate.GenerateGetItemByIDFunc(table),
modelgenerate.GenerateDeleteItemFunc(table),
},
}
PanicIf(printer.Fprint(os.Stdout, fset, file))
}
return nil
},
}
func init() {
generate_model.Flags().String("schema", "pkg/db/schema.sql", "Path to SQL schema file")
generate_model.Flags().String("modname", "mymodule", "Name of project's Go module (TODO: detect automatically)")
generate_model.Flags().Bool("test", false, "Generate test file instead of regular file")
}