github.com/traefik/yaegi@v0.15.1/cmd/yaegi/extract.go (about) 1 package main 2 3 import ( 4 "bufio" 5 "bytes" 6 "flag" 7 "fmt" 8 "io" 9 "os" 10 "path/filepath" 11 "strings" 12 13 "github.com/traefik/yaegi/extract" 14 ) 15 16 func extractCmd(arg []string) error { 17 var licensePath string 18 var name string 19 var exclude string 20 var include string 21 var tag string 22 23 eflag := flag.NewFlagSet("run", flag.ContinueOnError) 24 eflag.StringVar(&licensePath, "license", "", "path to a LICENSE file") 25 eflag.StringVar(&name, "name", "", "the namespace for the extracted symbols") 26 eflag.StringVar(&exclude, "exclude", "", "comma separated list of regexp matching symbols to exclude") 27 eflag.StringVar(&include, "include", "", "comma separated list of regexp matching symbols to include") 28 eflag.StringVar(&tag, "tag", "", "comma separated list of build tags to be added to the created package") 29 eflag.Usage = func() { 30 fmt.Println("Usage: yaegi extract [options] packages...") 31 fmt.Println("Options:") 32 eflag.PrintDefaults() 33 } 34 35 if err := eflag.Parse(arg); err != nil { 36 return err 37 } 38 39 args := eflag.Args() 40 if len(args) == 0 { 41 return fmt.Errorf("missing package") 42 } 43 44 license, err := genLicense(licensePath) 45 if err != nil { 46 return err 47 } 48 49 wd, err := os.Getwd() 50 if err != nil { 51 return err 52 } 53 54 if name == "" { 55 name = filepath.Base(wd) 56 } 57 ext := extract.Extractor{ 58 Dest: name, 59 License: license, 60 } 61 if tag != "" { 62 ext.Tag = strings.Split(tag, ",") 63 } 64 65 if exclude != "" { 66 ext.Exclude = strings.Split(exclude, ",") 67 } 68 if include != "" { 69 ext.Include = strings.Split(include, ",") 70 } 71 72 r := strings.NewReplacer("/", "-", ".", "_") 73 74 for _, pkgIdent := range args { 75 var buf bytes.Buffer 76 importPath, err := ext.Extract(pkgIdent, name, &buf) 77 if err != nil { 78 fmt.Fprintln(os.Stderr, err) 79 continue 80 } 81 82 oFile := r.Replace(importPath) + ".go" 83 f, err := os.Create(oFile) 84 if err != nil { 85 return err 86 } 87 88 if _, err := io.Copy(f, &buf); err != nil { 89 _ = f.Close() 90 return err 91 } 92 93 if err := f.Close(); err != nil { 94 return err 95 } 96 } 97 98 return nil 99 } 100 101 // genLicense generates the correct LICENSE header text from the provided 102 // path to a LICENSE file. 103 func genLicense(fname string) (string, error) { 104 if fname == "" { 105 return "", nil 106 } 107 108 f, err := os.Open(fname) 109 if err != nil { 110 return "", fmt.Errorf("could not open LICENSE file: %w", err) 111 } 112 defer func() { _ = f.Close() }() 113 114 license := new(strings.Builder) 115 sc := bufio.NewScanner(f) 116 for sc.Scan() { 117 txt := sc.Text() 118 if txt != "" { 119 txt = " " + txt 120 } 121 license.WriteString("//" + txt + "\n") 122 } 123 if sc.Err() != nil { 124 return "", fmt.Errorf("could not scan LICENSE file: %w", err) 125 } 126 127 return license.String(), nil 128 }