mirror of
https://github.com/coder/coder.git
synced 2025-07-06 15:41:45 +00:00
chore: generate and order dbfake funcs automatically (#7986)
* chore: rename `databasefake` to `dbfake` * Remove unused method * chore: add generation to dbfake * Auto gen on make gen * Fix preserving imports * gen dbfake * Add goimports * Fix the makefile * Make it panic instead of a comment
This commit is contained in:
File diff suppressed because it is too large
Load Diff
199
coderd/database/gen/fake/main.go
Normal file
199
coderd/database/gen/fake/main.go
Normal file
@ -0,0 +1,199 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"go/format"
|
||||
"go/token"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/dave/dst"
|
||||
"github.com/dave/dst/decorator"
|
||||
"github.com/dave/dst/decorator/resolver/goast"
|
||||
"github.com/dave/dst/decorator/resolver/guess"
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
func main() {
|
||||
err := run()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func run() error {
|
||||
funcs, err := readStoreInterface()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
funcByName := map[string]struct{}{}
|
||||
for _, f := range funcs {
|
||||
funcByName[f.Name] = struct{}{}
|
||||
}
|
||||
declByName := map[string]*dst.FuncDecl{}
|
||||
|
||||
dbfake, err := os.ReadFile("./dbfake/dbfake.go")
|
||||
if err != nil {
|
||||
return xerrors.Errorf("read dbfake: %w", err)
|
||||
}
|
||||
|
||||
// Required to preserve imports!
|
||||
f, err := decorator.NewDecoratorWithImports(token.NewFileSet(), "dbfake", goast.New()).Parse(dbfake)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("parse dbfake: %w", err)
|
||||
}
|
||||
|
||||
for i := 0; i < len(f.Decls); i++ {
|
||||
funcDecl, ok := f.Decls[i].(*dst.FuncDecl)
|
||||
if !ok || funcDecl.Recv == nil || len(funcDecl.Recv.List) == 0 {
|
||||
continue
|
||||
}
|
||||
// Check if the receiver is the struct we're interested in
|
||||
starExpr, ok := funcDecl.Recv.List[0].Type.(*dst.StarExpr)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
ident, ok := starExpr.X.(*dst.Ident)
|
||||
if !ok || ident.Name != "fakeQuerier" {
|
||||
continue
|
||||
}
|
||||
if _, ok := funcByName[funcDecl.Name.Name]; !ok {
|
||||
continue
|
||||
}
|
||||
declByName[funcDecl.Name.Name] = funcDecl
|
||||
f.Decls = append(f.Decls[:i], f.Decls[i+1:]...)
|
||||
i--
|
||||
}
|
||||
|
||||
for _, fn := range funcs {
|
||||
decl, ok := declByName[fn.Name]
|
||||
if !ok {
|
||||
// Not implemented!
|
||||
decl = &dst.FuncDecl{
|
||||
Name: dst.NewIdent(fn.Name),
|
||||
Type: &dst.FuncType{
|
||||
Func: true,
|
||||
TypeParams: fn.Func.TypeParams,
|
||||
Params: fn.Func.Params,
|
||||
Results: fn.Func.Results,
|
||||
Decs: fn.Func.Decs,
|
||||
},
|
||||
Recv: &dst.FieldList{
|
||||
List: []*dst.Field{{
|
||||
Names: []*dst.Ident{dst.NewIdent("q")},
|
||||
Type: dst.NewIdent("*fakeQuerier"),
|
||||
}},
|
||||
},
|
||||
Decs: dst.FuncDeclDecorations{
|
||||
NodeDecs: dst.NodeDecs{
|
||||
Before: dst.EmptyLine,
|
||||
After: dst.EmptyLine,
|
||||
},
|
||||
},
|
||||
Body: &dst.BlockStmt{
|
||||
List: []dst.Stmt{
|
||||
&dst.ExprStmt{
|
||||
X: &dst.CallExpr{
|
||||
Fun: &dst.Ident{
|
||||
Name: "panic",
|
||||
},
|
||||
Args: []dst.Expr{
|
||||
&dst.BasicLit{
|
||||
Kind: token.STRING,
|
||||
Value: "\"Not implemented\"",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
f.Decls = append(f.Decls, decl)
|
||||
}
|
||||
|
||||
file, err := os.OpenFile("./dbfake/dbfake.go", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0o755)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("open dbfake: %w", err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
// Required to preserve imports!
|
||||
restorer := decorator.NewRestorerWithImports("dbfake", guess.New())
|
||||
restored, err := restorer.RestoreFile(f)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("restore dbfake: %w", err)
|
||||
}
|
||||
err = format.Node(file, restorer.Fset, restored)
|
||||
return err
|
||||
}
|
||||
|
||||
type storeMethod struct {
|
||||
Name string
|
||||
Func *dst.FuncType
|
||||
}
|
||||
|
||||
func readStoreInterface() ([]storeMethod, error) {
|
||||
querier, err := os.ReadFile("./querier.go")
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("read querier: %w", err)
|
||||
}
|
||||
f, err := decorator.Parse(querier)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var sqlcQuerier *dst.InterfaceType
|
||||
for _, decl := range f.Decls {
|
||||
genDecl, ok := decl.(*dst.GenDecl)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, spec := range genDecl.Specs {
|
||||
typeSpec, ok := spec.(*dst.TypeSpec)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if typeSpec.Name.Name != "sqlcQuerier" {
|
||||
continue
|
||||
}
|
||||
sqlcQuerier, ok = typeSpec.Type.(*dst.InterfaceType)
|
||||
if !ok {
|
||||
return nil, xerrors.Errorf("unexpected sqlcQuerier type: %T", typeSpec.Type)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
if sqlcQuerier == nil {
|
||||
return nil, xerrors.Errorf("sqlcQuerier not found")
|
||||
}
|
||||
funcs := []storeMethod{}
|
||||
for _, method := range sqlcQuerier.Methods.List {
|
||||
funcType, ok := method.Type.(*dst.FuncType)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, t := range []*dst.FieldList{funcType.Params, funcType.Results} {
|
||||
if t == nil {
|
||||
continue
|
||||
}
|
||||
for _, f := range t.List {
|
||||
ident, ok := f.Type.(*dst.Ident)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if !ident.IsExported() {
|
||||
continue
|
||||
}
|
||||
ident.Path = "github.com/coder/coder/coderd/database"
|
||||
}
|
||||
}
|
||||
|
||||
funcs = append(funcs, storeMethod{
|
||||
Name: method.Names[0].Name,
|
||||
Func: funcType,
|
||||
})
|
||||
}
|
||||
return funcs, nil
|
||||
}
|
@ -58,4 +58,8 @@ SCRIPT_DIR=$(dirname "${BASH_SOURCE[0]}")
|
||||
|
||||
# Generate enums (e.g. unique constraints).
|
||||
go run gen/enum/main.go
|
||||
|
||||
# Generate the database fake!
|
||||
go run gen/fake/main.go
|
||||
go run golang.org/x/tools/cmd/goimports@latest -w ./dbfake/dbfake.go
|
||||
)
|
||||
|
Reference in New Issue
Block a user