diff --git a/cmd/yaegi/extract.go b/cmd/yaegi/extract.go index 64f579f82..54617872b 100644 --- a/cmd/yaegi/extract.go +++ b/cmd/yaegi/extract.go @@ -20,6 +20,7 @@ func extractCmd(arg []string) error { var exclude string var include string var tag string + var outer bool eflag := flag.NewFlagSet("run", flag.ContinueOnError) eflag.StringVar(&licensePath, "license", "", "path to a LICENSE file") @@ -27,6 +28,8 @@ func extractCmd(arg []string) error { eflag.StringVar(&exclude, "exclude", "", "comma separated list of regexp matching symbols to exclude") eflag.StringVar(&include, "include", "", "comma separated list of regexp matching symbols to include") eflag.StringVar(&tag, "tag", "", "comma separated list of build tags to be added to the created package") + eflag.BoolVar(&outer, "outer", false, "generated code is not in github.com/traefik/yaegi/stdlib") + eflag.Usage = func() { fmt.Println("Usage: yaegi extract [options] packages...") fmt.Println("Options:") @@ -58,6 +61,7 @@ func extractCmd(arg []string) error { ext := extract.Extractor{ Dest: name, License: license, + Outer: outer, } if tag != "" { ext.Tag = strings.Split(tag, ",") diff --git a/extract/extract.go b/extract/extract.go index e2198b6df..43402a67a 100644 --- a/extract/extract.go +++ b/extract/extract.go @@ -34,6 +34,9 @@ const model = `// Code generated by 'yaegi extract {{.ImportPath}}'. DO NOT EDIT package {{.Dest}} import ( +{{- if .Outer }} + "github.com/traefik/yaegi/stdlib" +{{- end}} {{- range $key, $value := .Imports }} {{- if $value}} "{{$key}}" @@ -46,7 +49,7 @@ import ( ) func init() { - Symbols["{{.PkgName}}"] = map[string]reflect.Value{ + {{if .Outer}}stdlib.{{end}}Symbols["{{.PkgName}}"] = map[string]reflect.Value{ {{- if .Val}} // function, constant and variable definitions {{range $key, $value := .Val -}} @@ -139,6 +142,7 @@ type Extractor struct { Exclude []string // Comma separated list of regexp matching symbols to exclude. Include []string // Comma separated list of regexp matching symbols to include. Tag []string // Comma separated of build tags to be added to the created package. + Outer bool // The project that generates code is not github.com/traefik/yaegi/stdlib. } func (e *Extractor) genContent(importPath string, p *types.Package) ([]byte, error) { @@ -321,6 +325,7 @@ func (e *Extractor) genContent(importPath string, p *types.Package) ([]byte, err "Wrap": wrap, "BuildTags": buildTags, "License": e.License, + "Outer": e.Outer, } err = parse.Execute(b, data) if err != nil { diff --git a/extract/extract_test.go b/extract/extract_test.go index a08e34faf..f7208e974 100644 --- a/extract/extract_test.go +++ b/extract/extract_test.go @@ -25,6 +25,24 @@ func init() { } ` +var expectedOutputOuter = `// Code generated by 'yaegi extract guthib.com/baz'. DO NOT EDIT. + +package bar + +import ( + "github.com/traefik/yaegi/stdlib" + "guthib.com/baz" + "reflect" +) + +func init() { + stdlib.Symbols["guthib.com/baz/baz"] = map[string]reflect.Value{ + // function, constant and variable definitions + "Hello": reflect.ValueOf(baz.Hello), + } +} +` + func TestPackages(t *testing.T) { testCases := []struct { desc string @@ -35,6 +53,7 @@ func TestPackages(t *testing.T) { expected string contains string dest string + outer bool }{ { desc: "stdlib math pkg, using go/importer", @@ -51,6 +70,13 @@ func TestPackages(t *testing.T) { arg: "../baz", expected: expectedOutput, }, + { + desc: "using relative path, using go.mod, out of stdlib", + wd: "./testdata/1/src/guthib.com/bar", + arg: "../baz", + outer: true, + expected: expectedOutputOuter, + }, { desc: "using relative path, manual import path", wd: "./testdata/2/src/guthib.com/bar", @@ -149,7 +175,8 @@ func (W _guthib_com_variadic_Variadic) Call(method string, args ...[]interface{} dest = test.dest } ext := Extractor{ - Dest: dest, + Dest: dest, + Outer: test.outer, } var out bytes.Buffer