代码拉取完成,页面将自动刷新
package main
import (
"flag"
"fmt"
"go/ast"
"go/parser"
"go/token"
"io/ioutil"
"os"
"os/exec"
"strings"
"text/template"
"time"
)
type arrayImports []string
func (i *arrayImports) String() string {
return "// custom imports:\n\n" + strings.Join(*i, "\n")
}
func (i *arrayImports) Set(value string) error {
*i = append(*i, value)
return nil
}
const TEMPLATE = `package main
import (
"fmt"
"{{ .ModelsPackage }}"
" gitee.com/cdququ/typescriptify-golang-structs/typescriptify"
)
func main() {
t := typescriptify.New()
t.CreateInterface = {{ .Interface }}
{{ range $key, $value := .InitParams }} t.{{ $key }}={{ $value }}
{{ end }}
{{ range .Structs }} t.Add({{ . }}{})
{{ end }}
{{ range .CustomImports }} t.AddImport("{{ . }}")
{{ end }}
err := t.ConvertToFile("{{ .TargetFile }}")
if err != nil {
panic(err.Error())
}
fmt.Println("OK")
}`
type Params struct {
ModelsPackage string
TargetFile string
Structs []string
InitParams map[string]interface{}
CustomImports arrayImports
Interface bool
}
func main() {
var p Params
var backupDir string
flag.StringVar(&p.ModelsPackage, "package", "", "Path of the package with models")
flag.StringVar(&p.TargetFile, "target", "", "Target typescript file")
flag.StringVar(&backupDir, "backup", "", "Directory where backup files are saved")
flag.BoolVar(&p.Interface, "interface", false, "Create interfaces (not classes)")
flag.Var(&p.CustomImports, "import", "Typescript import for your custom type, repeat this option for each import needed")
flag.Parse()
structs := []string{}
for _, structOrGoFile := range flag.Args() {
if strings.HasSuffix(structOrGoFile, ".go") {
fmt.Println("Parsing:", structOrGoFile)
fileStructs, err := GetGolangFileStructs(structOrGoFile)
if err != nil {
panic(fmt.Sprintf("Error loading/parsing golang file %s: %s", structOrGoFile, err.Error()))
}
structs = append(structs, fileStructs...)
} else {
structs = append(structs, structOrGoFile)
}
}
if len(p.ModelsPackage) == 0 {
fmt.Fprintln(os.Stderr, "No package given")
os.Exit(1)
}
if len(p.TargetFile) == 0 {
fmt.Fprintln(os.Stderr, "No target file")
os.Exit(1)
}
packageParts := strings.Split(p.ModelsPackage, "/")
pckg := packageParts[len(packageParts)-1]
t := template.Must(template.New("").Parse(TEMPLATE))
filename, err := ioutil.TempDir(os.TempDir(), "")
handleErr(err)
filename = fmt.Sprintf("%s/typescriptify_%d.go", filename, time.Now().Nanosecond())
f, err := os.Create(filename)
handleErr(err)
defer f.Close()
structsArr := make([]string, 0)
for _, str := range structs {
str = strings.TrimSpace(str)
if len(str) > 0 {
structsArr = append(structsArr, pckg+"."+str)
}
}
p.Structs = structsArr
p.InitParams = map[string]interface{}{
"BackupDir": fmt.Sprintf(`"%s"`, backupDir),
}
err = t.Execute(f, p)
handleErr(err)
cmd := exec.Command("go", "run", filename)
fmt.Println(strings.Join(cmd.Args, " "))
output, err := cmd.CombinedOutput()
if err != nil {
fmt.Println(string(output))
handleErr(err)
}
fmt.Println(string(output))
}
func GetGolangFileStructs(filename string) ([]string, error) {
fset := token.NewFileSet() // positions are relative to fset
f, err := parser.ParseFile(fset, filename, nil, 0)
if err != nil {
return nil, err
}
v := &AVisitor{}
ast.Walk(v, f)
return v.structs, nil
}
type AVisitor struct {
structNameCandidate string
structs []string
}
func (v *AVisitor) Visit(node ast.Node) ast.Visitor {
if node != nil {
switch t := node.(type) {
case *ast.Ident:
v.structNameCandidate = t.Name
case *ast.StructType:
if len(v.structNameCandidate) > 0 {
v.structs = append(v.structs, v.structNameCandidate)
v.structNameCandidate = ""
}
default:
v.structNameCandidate = ""
}
}
return v
}
func handleErr(err error) {
if err != nil {
panic(err.Error())
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。