github.com/traefik/yaegi@v0.15.1/internal/cmd/extract/extract.go (about)

     1  //go:generate go build
     2  
     3  /*
     4  extract generates wrappers of stdlib package exported symbols. This command
     5  is reserved for internal use in yaegi project.
     6  
     7  For a similar purpose with third party packages, see the yaegi extract subcommand,
     8  based on the same code.
     9  
    10  Output files are written in the current directory, and prefixed with the go version.
    11  
    12  Usage:
    13  
    14  	extract package...
    15  
    16  The same program is used for all target operating systems and architectures.
    17  The GOOS and GOARCH environment variables set the desired target.
    18  */
    19  package main
    20  
    21  import (
    22  	"bytes"
    23  	"flag"
    24  	"io"
    25  	"log"
    26  	"os"
    27  	"path"
    28  	"runtime"
    29  	"strings"
    30  
    31  	"github.com/traefik/yaegi/extract"
    32  )
    33  
    34  var (
    35  	exclude = flag.String("exclude", "", "comma separated list of regexp matching symbols to exclude")
    36  	include = flag.String("include", "", "comma separated list of regexp matching symbols to include")
    37  )
    38  
    39  func main() {
    40  	flag.Parse()
    41  
    42  	if flag.NArg() == 0 {
    43  		flag.Usage()
    44  		log.Fatalf("missing package path")
    45  	}
    46  
    47  	wd, err := os.Getwd()
    48  	if err != nil {
    49  		log.Fatal(err)
    50  	}
    51  
    52  	ext := extract.Extractor{
    53  		Dest: path.Base(wd),
    54  	}
    55  
    56  	goos, goarch := os.Getenv("GOOS"), os.Getenv("GOARCH")
    57  
    58  	if *exclude != "" {
    59  		ext.Exclude = strings.Split(*exclude, ",")
    60  	}
    61  
    62  	if *include != "" {
    63  		ext.Include = strings.Split(*include, ",")
    64  	}
    65  
    66  	for _, pkgIdent := range flag.Args() {
    67  		var buf bytes.Buffer
    68  
    69  		if pkgIdent == "syscall" && goos == "solaris" {
    70  			// Syscall6 is broken on solaris (https://github.com/golang/go/issues/24357),
    71  			// it breaks build, skip related symbols.
    72  			ext.Exclude = append(ext.Exclude, "Syscall6")
    73  		}
    74  
    75  		importPath, err := ext.Extract(pkgIdent, "", &buf)
    76  		if err != nil {
    77  			log.Fatal(err)
    78  		}
    79  
    80  		var oFile string
    81  		if pkgIdent == "syscall" {
    82  			oFile = strings.ReplaceAll(importPath, "/", "_") + "_" + goos + "_" + goarch + ".go"
    83  		} else {
    84  			oFile = strings.ReplaceAll(importPath, "/", "_") + ".go"
    85  		}
    86  
    87  		version := runtime.Version()
    88  		if strings.HasPrefix(version, "devel") {
    89  			log.Fatalf("extracting only supported with stable releases of Go, not %v", version)
    90  		}
    91  		parts := strings.Split(version, ".")
    92  		prefix := parts[0] + "_" + extract.GetMinor(parts[1])
    93  
    94  		f, err := os.Create(prefix + "_" + oFile)
    95  		if err != nil {
    96  			log.Fatal(err)
    97  		}
    98  
    99  		if _, err := io.Copy(f, &buf); err != nil {
   100  			_ = f.Close()
   101  			log.Fatal(err)
   102  		}
   103  
   104  		if err := f.Close(); err != nil {
   105  			log.Fatal(err)
   106  		}
   107  	}
   108  }