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  }