Yaegi Documentation

repository·master·Indexed 27 days ago

https://github.com/traefik/yaegi

Yaegi is a Go interpreter that enables running Go code as scripts or plugins. It can be embedded into Go applications via the `interp` package to provide dynamic extension capabilities or used as a standalone interactive shell (REPL). The project includes a CLI tool for executing Go programs, running tests, and extracting symbols from packages using the `extract` command. Note that it has limitations regarding assembly, C interop, and Go modules.

Tokens
3.3K
Snippets
9
Records
17
Agent score
94%

What's inside Yaegi

  1. Install Yaegi via CI Integration script

    master

    Use the provided installation script for CI environments. You can specify the target binary directory using the -b flag.

    curl -sfL https://raw.githubusercontent.com/traefik/yaegi/master/install.sh | bash -s -- -b $GOPATH/bin v0.9.0
  2. Use Yaegi as a dynamic extension framework

    master

    You can bridge compiled Go code with interpreted code by evaluating a script and then retrieving symbols as reflect.Value objects. Use the Interface() method and type assertion to convert these values into usable Go functions or types.

    package main
    
    import "github.com/traefik/yaegi/interp"
    
    const src = `package foo
    func Bar(s string) string { return s + "-Foo" }`
    
    func main() {
    	i := interp.New(interp.Options{})
    
    	_, err := i.Eval(src)
    	if err != nil {
    		panic(err)
    	}
    
    	v, err := i.Eval("foo.Bar")
    	if err != nil {
    		panic(err)
    	}
    
    	bar := v.Interface().(func(string) string)
    
    	r := bar("Kung")
    	println(r)
    }
  3. Use Yaegi as a command-line interpreter

    master

    The yaegi binary provides an interactive REPL. In interactive mode, all standard library packages are pre-imported and available for direct use. You can also run specific Go packages, directories, or files directly from the CLI.

    # Start interactive REPL
    $ yaegi
    > import "fmt"
    > fmt.Println("Hello World")
    Hello World
    
    # Run a specific package with syscall and unsafe support
    $ yaegi -syscall -unsafe -unrestricted github.com/traefik/yaegi/cmd/yaegi
    
    # Use as a shebang for Go scripting
    #!/usr/bin/env yaegi
    package main
    import "fmt"
    func main() { fmt.Println("test") }
  4. Use Yaegi as an embedded interpreter

    master

    To embed Yaegi, create a new interpreter using interp.New(), provide configuration via interp.Options{}, and load required symbols (such as the standard library) using i.Use(). Execute Go code strings using i.Eval().

    package main
    
    import (
    	"github.com/traefik/yaegi/interp"
    	"github.com/traefik/yaegi/stdlib"
    )
    
    func main() {
    	i := interp.New(interp.Options{})
    
    	i.Use(stdlib.Symbols)
    
    	_, err := i.Eval(`import "fmt"`)
    	if err != nil {
    		panic(err)
    	}
    
    	_, err = i.Eval(`fmt.Println("Hello Yaegi")`)
    	if err != nil {
    		panic(err)
    	}
    }
  5. Install the Yaegi command-line executable

    master

    You can install the yaegi CLI tool using go install. For an improved interactive experience with command history and editing, it is recommended to use rlwrap and alias the command.

    go install github.com/traefik/yaegi/cmd/yaegi@latest
    
    # Recommended: use rlwrap for history and editing
    alias yaegi='rlwrap yaegi'
  6. Use the yaegi CLI to run Go code

    master

    The yaegi executable interprets Go programs from standard input, string parameters, or files.

    Execution Modes

    • File Mode: Used when reading source files. Files are read entirely before parsing and evaluation, supporting forward declarations and multi-file packages. This is the default for all files unless the initial file uses a shebang (e.g., #!/usr/bin/env yaegi).
    • REPL Mode: Used for interactive sessions or when a file starts with a shebang. Code is parsed incrementally. In this mode, identifiers must be defined before use, and statements are evaluated in the global space within an implicit main package. You do not need a package statement or a main function.

    Commands

    • run: The default command. Executes the provided Go code.
    • extract: Extracts information (specific implementation details depend on the version).
    • test: Runs tests.
    • help: Displays help information.
    • version: Displays the current version.

    If no command is provided, yaegi defaults to the run command.

    # Run a one-liner string
    $ yaegi -e 'println(reflect.TypeOf(fmt.Print))'
    
    # Run an executable script with a shebang
    #!/usr/bin/env yaegi
    helloHandler := func(w http.ResponseWriter, req *http.Request) {
       io.WriteString(w, "Hello, world!\n")
    }
    http.HandleFunc("/hello", helloHandler)
    log.Fatal(http.ListenAndServe(":8080", nil))
  7. Yaegi limitations

    master

    Be aware of the following unsupported features and limitations:

    • Assembly: .s files are not supported.
    • C Interop: Calling C code is not supported.
    • Compiler Directives: Directives for the compiler, linker, or embedding files are not supported.
    • Dynamic Interfaces: Interfaces used from pre-compiled code cannot be added dynamically (requires pre-compiled interface wrappers).
    • Reflection/Printing: reflect type representation and %T printing may differ between compiled and interpreted modes.
    • Performance: Computationally intensive code is significantly slower in interpreted mode.
    • Go Modules: Go modules are not yet supported; source must be installed into $GOPATH/src for testing.
  8. Configure yaegi test symbol sets via environment variables

    master

    When using the yaegi test command, you can control which symbol sets are included by setting the following environment variables. This is useful for configuring the interpreter behavior in CI or shell environments without passing flags explicitly.

    • YAEGI_SYSCALL: Set to true to include syscall symbols.
    • YAEGI_UNRESTRICTED: Set to true to include unrestricted symbols.
    • YAEGI_UNSAFE: Set to true to include unsafe symbols.
  9. Configure `yaegi run` flags and environment variables

    master

    The yaegi run command supports several flags to control the interpreter's capabilities and behavior. Some of these can also be configured via environment variables.

    CLI Flags

    FlagTypeDescription
    -iboolStart an interactive REPL
    -syscallboolInclude syscall symbols
    -unrestrictedboolInclude unrestricted symbols
    -tagsstringSet a comma-separated list of build tags
    -unsafeboolInclude unsafe symbols
    -noautoimportboolDo not auto-import pre-compiled packages. Colliding names (e.g., crypto/rand vs math/rand) are automatically renamed (e.g., crypto_rand, math_rand)
    -estringSet the command to be executed (instead of script or shell)

    Environment Variables

    Setting these variables is equivalent to using the corresponding CLI flags:

    • YAEGI_SYSCALL: Enable syscall symbols.
    • YAEGI_UNRESTRICTED: Enable unrestricted symbols.
    • YAEGI_UNSAFE: Enable unsafe symbols.
  10. Configure yaegi CLI flags

    master

    Use the following flags to modify the behavior of the yaegi interpreter during execution:

    FlagDescription
    -e stringEvaluate the provided string and then return.
    -iStart an interactive REPL after the file execution completes.
    -syscallInclude syscall symbols in the interpreter.
    -tags tag,listA comma-separated list of build tags to satisfy during interpretation.
    -unsafeInclude unsafe symbols in the interpreter.
  11. Reference the Yaegi CLI commands

    master

    The following commands are available in the yaegi executable:

    CommandDescription
    extractgenerate a wrapper file from a source package
    helpprint usage information
    runexecute a Go program from source
    testexecute test functions in a Go package
    versionprint version