github.com/goplus/gossa@v0.3.25/cmd/qexp/main.go (about) 1 package main 2 3 import ( 4 "flag" 5 "fmt" 6 "go/build" 7 "log" 8 "path/filepath" 9 "strings" 10 ) 11 12 var ( 13 flagExportDir string 14 flagUseGoApi bool 15 flagBuildContext string 16 flagCustomTags string 17 flagExportFileName string 18 ) 19 20 func init() { 21 flag.StringVar(&flagExportDir, "outdir", "", "set export pkg path") 22 //flag.BoolVar(&flagUseGoApi, "api", false, "export by $GOROOT/api") 23 flag.StringVar(&flagBuildContext, "contexts", "", "set customer build contexts goos_goarch list. eg \"drawin_amd64 darwin_arm64\"") 24 flag.StringVar(&flagCustomTags, "addtags", "", "add custom tags, split by ;") 25 flag.StringVar(&flagExportFileName, "filename", "export", "set export file name") 26 } 27 28 func main() { 29 flag.Parse() 30 args := flag.Args() 31 if len(args) == 0 { 32 flag.Usage() 33 } 34 if len(args) == 1 && args[0] == "std" { 35 args = stdList 36 } 37 if flagExportFileName == "" { 38 flagExportFileName = "export" 39 } 40 ctxList := parserContextList(flagBuildContext) 41 //flagUseGoApi = false 42 var ac *ApiCheck 43 if flagUseGoApi { 44 ac = NewApiCheck() 45 err := ac.LoadBase("go1", "go1.1", "go1.2", "go1.3", "go1.4", "go1.5", "go1.6", "go1.7", "go1.8", "go1.9", "go1.10", "go1.11", "go1.12", "go1.13", "go1.14") 46 if err != nil { 47 panic(err) 48 } 49 err = ac.LoadApi("go1.15", "go1.16") 50 if err != nil { 51 fmt.Println("warning load api error", err) 52 } 53 var imports []string 54 for _, pkg := range args { 55 fileMap, err := ac.Export(pkg) 56 if err != nil { 57 panic(err) 58 } 59 if fileMap == nil { 60 fmt.Println("warning skip empty export pkg", pkg) 61 continue 62 } 63 imports = append(imports, fmt.Sprintf(`_ "github.com/goplus/interp/pkg/%v"`, pkg)) 64 if _, ok := fileMap[""]; !ok { 65 fileMap[""] = &File{} 66 } 67 for _, v := range fileMap { 68 data, err := exportSource(pkg, v.Name, v.Tags, v.ExtList, v.TypList) 69 if err != nil { 70 panic(err) 71 } 72 if flagExportDir == "" { 73 fmt.Println("========", "export"+v.Name+".go") 74 fmt.Println(string(data)) 75 continue 76 } 77 err = writeFile(filepath.Join(flagExportDir, pkg), "export"+v.Name+".go", data) 78 if err != nil { 79 panic(err) 80 } 81 } 82 fmt.Println("export", pkg) 83 } 84 fmt.Printf("\nimport (\n\t%v\n)\n", strings.Join(imports, "\n\t")) 85 } else { 86 for _, pkg := range args { 87 if pkg == "unsafe" { 88 continue 89 } 90 Export(pkg, ctxList) 91 } 92 } 93 } 94 95 func Export(pkg string, ctxList []*build.Context) { 96 log.Println("process", pkg) 97 if len(ctxList) == 0 { 98 fpath, err := ExportPkg(pkg, nil) 99 if err != nil { 100 log.Println("export failed", err) 101 } else { 102 log.Println("export", fpath) 103 } 104 } else { 105 for _, ctx := range ctxList { 106 fpath, err := ExportPkg(pkg, ctx) 107 if err != nil { 108 log.Println("export failed", err) 109 } else { 110 log.Println("export", fpath) 111 } 112 } 113 } 114 } 115 116 func ExportPkg(pkg string, ctx *build.Context) (string, error) { 117 prog, err := loadProgram(pkg, ctx) 118 if err != nil { 119 return "", fmt.Errorf("load pkg %v error: %v", pkg, err) 120 } 121 e := prog.ExportPkg(pkg, "q") 122 var tags []string 123 if flagCustomTags != "" { 124 tags = strings.Split(flagCustomTags, ";") 125 } 126 data, err := exportPkg(e, "q", "", tags) 127 if err != nil { 128 panic(err) 129 } 130 if flagExportDir == "" { 131 fmt.Println(string(data)) 132 return "", nil 133 } 134 fpath := filepath.Join(flagExportDir, pkg) 135 var fname string 136 if ctx != nil { 137 fname = flagExportFileName + "_" + ctx.GOOS + "_" + ctx.GOARCH + ".go" 138 } else { 139 fname = flagExportFileName + ".go" 140 } 141 err = writeFile(fpath, fname, data) 142 return filepath.Join(fpath, fname), err 143 } 144 145 func parserContextList(list string) (ctxs []*build.Context) { 146 for _, info := range strings.Split(list, " ") { 147 info = strings.TrimSpace(info) 148 ar := strings.Split(info, "_") 149 if len(ar) != 2 { 150 continue 151 } 152 ctx := build.Default 153 ctx.GOOS = ar[0] 154 ctx.GOARCH = ar[1] 155 ctxs = append(ctxs, &ctx) 156 } 157 return 158 }