Skip to content

Instantly share code, notes, and snippets.

@slaskis
Created Sep 14, 2017
Embed
What would you like to do?
Silly command to add db tags to pb.go
package main
import (
"bytes"
"go/ast"
"go/format"
"go/parser"
"go/token"
"io/ioutil"
"log"
"os"
"strings"
"github.com/azer/snakecase"
"github.com/fatih/structtag"
)
func main() {
path := os.Args[len(os.Args)-1]
err := transform(path)
if err != nil {
log.Fatal(err)
}
}
func transform(path string) error {
log.Printf("parsing file %q for inject tag comments", path)
fset := token.NewFileSet()
f, err := parser.ParseFile(fset, path, nil, parser.ParseComments)
if err != nil {
return err
}
for _, decl := range f.Decls {
genDecl, ok := decl.(*ast.GenDecl)
if !ok {
continue
}
var typeSpec *ast.TypeSpec
for _, spec := range genDecl.Specs {
if ts, tsOK := spec.(*ast.TypeSpec); tsOK {
typeSpec = ts
break
}
}
if typeSpec == nil {
continue
}
structDecl, ok := typeSpec.Type.(*ast.StructType)
if !ok {
continue
}
// log.Printf("found a struct! %+v", typeSpec)
for _, field := range structDecl.Fields.List {
if len(field.Names) > 0 && field.Tag != nil {
// log.Printf("found a field with a tag! %s (%s)", field.Names[0].Name, field.Tag.Value)
tags, err := structtag.Parse(strings.Trim(field.Tag.Value, "`"))
if err != nil {
log.Printf("failed to parse field tag: %v", err)
continue
}
json, err := tags.Get("json")
if err != nil {
// log.Printf("failed to get json tag: %v", err)
continue
}
db := &structtag.Tag{
Key: "db",
Name: snakecase.SnakeCase(json.Name),
}
if db.Name == "id" {
db.Name = snakecase.SnakeCase(typeSpec.Name.Name) + "_id"
}
tags.Set(db)
field.Tag.Value = "`" + tags.String() + "`"
}
}
}
buf := &bytes.Buffer{}
err = format.Node(buf, fset, f)
if err != nil {
return err
}
out := buf.Bytes()
return ioutil.WriteFile(path, out, 0644)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment