gosh/interceptor/interceptor.go

67 lines
1.4 KiB
Go

package interceptor
import (
"fmt"
"os"
"path/filepath"
"github.com/mattn/anko/env"
"github.com/mattn/anko/vm"
)
type Ankointerceptor struct {
importMap map[string]interface{}
ankoEnv *env.Env
}
func NewAnkointerceptor(ankoEnv *env.Env) *Ankointerceptor {
a := &Ankointerceptor{
importMap: make(map[string]interface{}),
ankoEnv: ankoEnv,
}
a.ankoEnv.Define("println", fmt.Println)
a.importMap["fs"] = &FileModule{}
a.importMap["net"] = &NetModule{}
a.importMap["process"] = &ProcessModule{}
a.importMap["shell"] = &ShellModule{}
return a
}
func (a *Ankointerceptor) Exec(script string) (interface{}, error) {
e := a.ankoEnv.Copy()
e.Define("Require", a.genRequireMethod(script))
e.Define("__filename", script)
e.Define("__dirname", filepath.Dir(script))
scriptbytes, frr := os.ReadFile(script)
if frr != nil {
return nil, frr
}
scriptcode := string(scriptbytes)
result, err := vm.Execute(e, nil, scriptcode)
if err != nil {
return nil, err
}
return result, nil
}
func (a *Ankointerceptor) genRequireMethod(basePath string) interface{} {
return func(s string) interface{} {
if r, ok := a.importMap[s]; ok {
return r
}
if !filepath.IsAbs(s) {
s = filepath.Join(filepath.Dir(basePath), s)
}
if _, ok := a.importMap[s]; ok {
return a.importMap[s]
}
result, err := a.Exec(s)
if err != nil {
panic(err)
}
a.importMap[s] = result
return result
}
}