Make use of fs.FS (new to go 1.16) to allow for reading source files from diverse filesystems (local, embed, custom). * `Options` has a new field `SourcecodeFilesystem fs.FS` so users can supply their own read-only filesystem containing source code. * Defaults to the local filesystems (via `RealFS` - a thin `os.Open` wrapper complying with `fs.FS`) so regular users should see no change in behaviour. * When no filesystem is available (e.g. WASM, or if you want to embed files to retain single binary distribution) an alternative filesystem is preferable to using `Eval(string)` as that requires the stringy code to be a single file monolith instead of multiple files. By using an `fs.FS` we can use `EvalPath()` and gain the ability to handle multiple files and packages. * You can make use of embed filesystems (https://pkg.go.dev/embed) and custom filesystems obeying the `fs.FS` interface (I use one for http served zip files when targeting wasm as there is no local filesystem on wasm). Tests can make use of `fstest.Map`. * NOTE: This does NOT affect what the running yaegi code considers its local filesystem, this is only for the interpreter finding the source code. See `example/fs/fs_test.go` for an example. Fixes #1200.
22 lines
492 B
Go
22 lines
492 B
Go
package interp
|
|
|
|
import (
|
|
"io/fs"
|
|
"os"
|
|
)
|
|
|
|
// RealFS complies with the fs.FS interface (go 1.16 onwards)
|
|
// We use this rather than os.DirFS as DirFS has no concept of
|
|
// what the current working directory is, whereas this simple
|
|
// passthru to os.Open knows about working dir automagically.
|
|
type RealFS struct{}
|
|
|
|
// Open complies with the fs.FS interface.
|
|
func (dir RealFS) Open(name string) (fs.File, error) {
|
|
f, err := os.Open(name)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return f, nil
|
|
}
|