github.com/profzone/eden-framework@v1.0.10/pkg/codegen/file.go (about) 1 package codegen 2 3 import ( 4 "bytes" 5 "fmt" 6 "io" 7 "os" 8 "path/filepath" 9 "reflect" 10 "strconv" 11 "strings" 12 13 "github.com/profzone/eden-framework/pkg/codegen/formatx" 14 "golang.org/x/tools/go/packages" 15 ) 16 17 func NewFile(pkgName string, filename string) *File { 18 return &File{ 19 PkgName: LowerSnakeCase(pkgName), 20 filename: filename, 21 } 22 } 23 24 type File struct { 25 PkgName string 26 filename string 27 imports map[string]string 28 bytes.Buffer 29 } 30 31 func (file *File) WriteBlock(ss ...Snippet) { 32 for _, s := range ss { 33 file.Write(s.Bytes()) 34 file.WriteString("\n\n") 35 } 36 } 37 38 func (file *File) Bytes() []byte { 39 buf := &bytes.Buffer{} 40 41 buf.WriteString(`package ` + LowerSnakeCase(file.PkgName) + ` 42 `) 43 44 if file.imports != nil { 45 buf.WriteString(`import ( 46 `) 47 for importPath, alias := range file.imports { 48 buf.WriteString(alias) 49 buf.WriteString(" ") 50 buf.WriteString(strconv.Quote(importPath)) 51 buf.WriteString("\n") 52 } 53 54 buf.WriteString(`) 55 `) 56 } 57 58 io.Copy(buf, &file.Buffer) 59 60 return formatx.MustFormat(file.filename, buf.Bytes(), formatx.SortImportsProcess) 61 } 62 63 func (file *File) Expr(f string, args ...interface{}) SnippetExpr { 64 return createExpr(file.importAliaser)(f, args...) 65 } 66 67 func (file *File) TypeOf(tpe reflect.Type) SnippetType { 68 return createTypeOf(file.importAliaser)(tpe) 69 } 70 71 func (file *File) Val(v interface{}) Snippet { 72 return createVal(file.importAliaser)(v) 73 } 74 75 func (file *File) importAliaser(importPath string) string { 76 if file.imports == nil { 77 file.imports = map[string]string{} 78 } 79 if file.imports[importPath] == "" { 80 pkgs, err := packages.Load(nil, importPath) 81 if err != nil { 82 panic(err) 83 } 84 if len(pkgs) == 0 { 85 panic(fmt.Errorf("`%s` not found", importPath)) 86 } 87 importPath = pkgs[0].PkgPath 88 file.imports[importPath] = LowerSnakeCase(importPath) 89 } 90 return file.imports[importPath] 91 } 92 93 func (file *File) Use(importPath string, exposedName string) string { 94 return file.importAliaser(importPath) + "." + exposedName 95 } 96 97 func deVendor(importPath string) string { 98 parts := strings.Split(importPath, "/vendor/") 99 return parts[len(parts)-1] 100 } 101 102 func (file *File) WriteFile() (int, error) { 103 dir := filepath.Dir(file.filename) 104 105 if dir != "" { 106 if err := os.MkdirAll(dir, os.ModePerm); err != nil { 107 return -1, err 108 } 109 } 110 111 f, err := os.Create(file.filename) 112 defer f.Close() 113 if err != nil { 114 return -1, err 115 } 116 117 n3, err := f.Write(file.Bytes()) 118 if err != nil { 119 return -1, err 120 } 121 122 if err := f.Sync(); err != nil { 123 return -1, err 124 } 125 126 return n3, nil 127 }