Add model generator based on AST
This commit is contained in:
@@ -21,10 +21,9 @@ func main() {
|
||||
}
|
||||
root_cmd.AddCommand(sqlite_lint)
|
||||
root_cmd.AddCommand(cmd_init)
|
||||
root_cmd.AddCommand(generate_model)
|
||||
if err := root_cmd.Execute(); err != nil {
|
||||
fmt.Println(RED + err.Error() + RESET)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
// Subcommand "generate_models"
|
||||
|
||||
81
cmd/subcmd_generate_models.go
Normal file
81
cmd/subcmd_generate_models.go
Normal file
@@ -0,0 +1,81 @@
|
||||
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")
|
||||
}
|
||||
Reference in New Issue
Block a user